diff --git a/turbopack/.editorconfig b/turbopack/.editorconfig new file mode 100644 index 0000000000000..6b84715c4a3a6 --- /dev/null +++ b/turbopack/.editorconfig @@ -0,0 +1,24 @@ +# http://editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.t] +trim_trailing_whitespace = false + +[Makefile] +indent_style = tab + +[{go.mod,go.sum,*.go}] +indent_style = tab + +[*.rs] +# Keep in sync with rustfmt +max_line_length = 100 +indent_size = 4 diff --git a/turbopack/crates/node-file-trace/Cargo.toml b/turbopack/crates/node-file-trace/Cargo.toml new file mode 100644 index 0000000000000..febd05f0d04b0 --- /dev/null +++ b/turbopack/crates/node-file-trace/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "node-file-trace" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[[bin]] +name = "node-file-trace" +path = "src/main.rs" +bench = false + +[features] +default = ["cli", "custom_allocator"] +cli = ["dep:clap", "turbo-tasks-malloc"] +persistent_cache = [] +serializable = [] +tokio_console = [ + "dep:console-subscriber", + "tokio/tracing", + "turbo-tasks/tokio_tracing", +] +node-api = [] +custom_allocator = ["turbo-tasks-malloc", "turbo-tasks-malloc/custom_allocator"] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, optional = true, features = ["derive"] } +console-subscriber = { workspace = true, optional = true } +serde = { workspace = true, features = ["derive"] } +serde_json = { workspace = true } +tokio = { workspace = true, features = ["full"] } + +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-malloc = { workspace = true, optional = true, default-features = false } +turbo-tasks-memory = { workspace = true } +turbopack = { workspace = true } +turbopack-cli-utils = { workspace = true } +turbopack-core = { workspace = true } +turbopack-resolve = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/node-file-trace/build.rs b/turbopack/crates/node-file-trace/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/node-file-trace/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/node-file-trace/src/lib.rs b/turbopack/crates/node-file-trace/src/lib.rs new file mode 100644 index 0000000000000..47adb8f028463 --- /dev/null +++ b/turbopack/crates/node-file-trace/src/lib.rs @@ -0,0 +1,680 @@ +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +mod nft_json; + +use std::{ + collections::{BTreeSet, HashMap}, + env::current_dir, + future::Future, + path::{Path, PathBuf}, + pin::Pin, + sync::Arc, + time::{Duration, Instant}, +}; + +use anyhow::{anyhow, Context, Result}; +#[cfg(feature = "cli")] +use clap::Parser; +#[cfg(feature = "node-api")] +use serde::Deserialize; +#[cfg(feature = "node-api")] +use serde::Serialize; +use tokio::sync::mpsc::channel; +use turbo_tasks::{ + backend::Backend, util::FormatDuration, RcStr, TaskId, TransientInstance, TransientValue, + TurboTasks, UpdateInfo, Value, Vc, +}; +use turbo_tasks_fs::{ + glob::Glob, DirectoryEntry, DiskFileSystem, FileSystem, FileSystemPath, ReadGlobResult, +}; +use turbo_tasks_memory::MemoryBackend; +use turbopack::{ + emit_asset, emit_with_completion, module_options::ModuleOptionsContext, rebase::RebasedAsset, + ModuleAssetContext, +}; +use turbopack_cli_utils::issue::{ConsoleUi, IssueSeverityCliOption, LogOptions}; +use turbopack_core::{ + compile_time_info::CompileTimeInfo, + context::AssetContext, + environment::{Environment, ExecutionEnvironment, NodeJsEnvironment}, + file_source::FileSource, + issue::{IssueDescriptionExt, IssueReporter, IssueSeverity}, + module::{Module, Modules}, + output::OutputAsset, + reference::all_modules_and_affecting_sources, + resolve::options::{ImportMapping, ResolvedMap}, +}; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; + +use crate::nft_json::NftJsonAsset; + +#[cfg(feature = "persistent_cache")] +#[cfg_attr(feature = "cli", derive(clap::Args))] +#[cfg_attr( + feature = "node-api", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[derive(Debug, Clone)] +struct CacheArgs { + #[clap(long)] + cache: Option, + + #[clap(long)] + cache_fully: bool, +} + +#[cfg(not(feature = "persistent_cache"))] +#[cfg_attr(feature = "cli", derive(clap::Args))] +#[cfg_attr( + feature = "node-api", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[derive(Debug, Clone, Default)] +pub struct CacheArgs {} + +#[cfg_attr(feature = "cli", derive(clap::Args))] +#[cfg_attr( + feature = "node-api", + derive(Serialize, Deserialize), + serde(rename_all = "camelCase") +)] +#[derive(Debug, Clone)] +pub struct CommonArgs { + input: Vec, + + #[cfg_attr(feature = "cli", clap(short, long))] + #[cfg_attr(feature = "node-api", serde(default))] + context_directory: Option, + + #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "node-api", serde(default))] + process_cwd: Option, + + #[cfg_attr(feature = "cli", clap(flatten))] + #[cfg_attr(feature = "node-api", serde(default))] + cache: CacheArgs, + + #[cfg_attr(feature = "cli", clap(short, long))] + #[cfg_attr(feature = "node-api", serde(default))] + watch: bool, + + #[cfg_attr(feature = "cli", clap(short, long))] + #[cfg_attr(feature = "node-api", serde(default))] + /// Filter by issue severity. + log_level: Option, + + #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "node-api", serde(default))] + /// Show all log messages without limit. + show_all: bool, + + #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "node-api", serde(default))] + /// Expand the log details. + log_detail: bool, + + /// Whether to skip the glob logic + /// assume the provided input is not glob even if it contains `*` and `[]` + #[cfg_attr(feature = "cli", clap(short, long))] + #[cfg_attr(feature = "node-api", serde(default))] + exact: bool, + + /// Enable experimental garbage collection with the provided memory limit in + /// MB. + #[cfg_attr(feature = "cli", clap(long))] + #[cfg_attr(feature = "serializable", serde(default))] + pub memory_limit: Option, +} + +#[cfg_attr(feature = "cli", derive(Parser))] +#[cfg_attr(feature = "cli", clap(author, version, about, long_about = None))] +#[cfg_attr( + feature = "node-api", + derive(Serialize, Deserialize), + serde(tag = "action", rename_all = "camelCase") +)] +#[derive(Debug)] +pub enum Args { + // Print all files that the input files reference + Print { + #[cfg_attr(feature = "cli", clap(flatten))] + #[cfg_attr(feature = "node-api", serde(flatten))] + common: CommonArgs, + }, + + // Adds a *.nft.json file next to each input file which lists the referenced files + Annotate { + #[cfg_attr(feature = "cli", clap(flatten))] + #[cfg_attr(feature = "node-api", serde(flatten))] + common: CommonArgs, + }, + + // Copy input files and all referenced files to the output directory + Build { + #[cfg_attr(feature = "cli", clap(flatten))] + #[cfg_attr(feature = "node-api", serde(flatten))] + common: CommonArgs, + + #[cfg_attr(feature = "cli", clap(short, long, default_value_t = String::from("dist")))] + #[cfg_attr(feature = "node-api", serde(default = "default_output_directory"))] + output_directory: String, + }, + + // Print total size of input and referenced files + Size { + #[cfg_attr(feature = "cli", clap(flatten))] + #[cfg_attr(feature = "node-api", serde(flatten))] + common: CommonArgs, + }, +} + +#[cfg(feature = "node-api")] +fn default_output_directory() -> String { + "dist".to_string() +} + +impl Args { + fn common(&self) -> &CommonArgs { + match self { + Args::Print { common, .. } + | Args::Annotate { common, .. } + | Args::Build { common, .. } + | Args::Size { common, .. } => common, + } + } +} + +async fn create_fs(name: &str, root: &str, watch: bool) -> Result>> { + let fs = DiskFileSystem::new(name.into(), root.into(), vec![]); + if watch { + fs.await?.start_watching()?; + } else { + fs.await?.invalidate(); + } + Ok(Vc::upcast(fs)) +} + +async fn add_glob_results( + asset_context: Vc>, + result: Vc, + list: &mut Vec>>, +) -> Result<()> { + let result = result.await?; + for entry in result.results.values() { + if let DirectoryEntry::File(path) = entry { + let source = Vc::upcast(FileSource::new(*path)); + let module = asset_context + .process( + source, + Value::new(turbopack_core::reference_type::ReferenceType::Undefined), + ) + .module(); + list.push(module); + } + } + for result in result.inner.values() { + fn recurse<'a>( + asset_context: Vc>, + result: Vc, + list: &'a mut Vec>>, + ) -> Pin> + Send + 'a>> { + Box::pin(add_glob_results(asset_context, result, list)) + } + // Boxing for async recursion + recurse(asset_context, *result, list).await?; + } + Ok(()) +} + +#[turbo_tasks::function] +async fn input_to_modules( + fs: Vc>, + input: Vec, + exact: bool, + process_cwd: Option, + context_directory: RcStr, + module_options: TransientInstance, + resolve_options: TransientInstance, +) -> Result> { + let root = fs.root(); + let process_cwd = process_cwd + .clone() + .map(|p| format!("/ROOT{}", p.trim_start_matches(&*context_directory)).into()); + + let asset_context: Vc> = Vc::upcast(create_module_asset( + root, + process_cwd, + module_options, + resolve_options, + )); + + let mut list = Vec::new(); + for input in input { + if exact { + let source = Vc::upcast(FileSource::new(root.join(input))); + let module = asset_context + .process( + source, + Value::new(turbopack_core::reference_type::ReferenceType::Undefined), + ) + .module(); + list.push(module); + } else { + let glob = Glob::new(input); + add_glob_results(asset_context, root.read_glob(glob, false), &mut list).await?; + }; + } + Ok(Vc::cell(list)) +} + +fn process_context(dir: &Path, context_directory: Option<&String>) -> Result { + let mut context_directory = PathBuf::from(context_directory.map_or(".", |s| s)); + if !context_directory.is_absolute() { + context_directory = dir.join(context_directory); + } + // context = context.canonicalize().unwrap(); + Ok(context_directory + .to_str() + .ok_or_else(|| anyhow!("context directory contains invalid characters")) + .unwrap() + .to_string()) +} + +fn make_relative_path(dir: &Path, context_directory: &str, input: &str) -> Result { + let mut input = PathBuf::from(input); + if !input.is_absolute() { + input = dir.join(input); + } + // input = input.canonicalize()?; + let input = input.strip_prefix(context_directory).with_context(|| { + anyhow!( + "{} is not part of the context directory {}", + input.display(), + context_directory + ) + })?; + Ok(input + .to_str() + .ok_or_else(|| anyhow!("input contains invalid characters"))? + .replace('\\', "/") + .into()) +} + +fn process_input(dir: &Path, context_directory: &str, input: &[String]) -> Result> { + input + .iter() + .map(|input| make_relative_path(dir, context_directory, input)) + .collect() +} + +pub async fn start( + args: Arc, + turbo_tasks: Option<&Arc>>, + module_options: Option, + resolve_options: Option, +) -> Result> { + register(); + let &CommonArgs { + memory_limit, + #[cfg(feature = "persistent_cache")] + cache: CacheArgs { + ref cache, + ref cache_fully, + }, + .. + } = args.common(); + #[cfg(feature = "persistent_cache")] + if let Some(cache) = cache { + use tokio::time::timeout; + use turbo_tasks_memory::MemoryBackendWithPersistedGraph; + use turbo_tasks_rocksdb::RocksDbPersistedGraph; + + run( + &args, + || { + let start = Instant::now(); + let backend = MemoryBackendWithPersistedGraph::new( + RocksDbPersistedGraph::new(cache).unwrap(), + ); + let tt = TurboTasks::new(backend); + let elapsed = start.elapsed(); + println!("restored cache {}", FormatDuration(elapsed)); + tt + }, + |tt, _, duration| async move { + let mut start = Instant::now(); + if *cache_fully { + tt.wait_background_done().await; + tt.stop_and_wait().await; + let elapsed = start.elapsed(); + println!("flushed cache {}", FormatDuration(elapsed)); + } else { + let background_timeout = + std::cmp::max(duration / 5, Duration::from_millis(100)); + let timed_out = timeout(background_timeout, tt.wait_background_done()) + .await + .is_err(); + tt.stop_and_wait().await; + let elapsed = start.elapsed(); + if timed_out { + println!("flushed cache partially {}", FormatDuration(elapsed)); + } else { + println!("flushed cache completely {}", FormatDuration(elapsed)); + } + } + start = Instant::now(); + drop(tt); + let elapsed = start.elapsed(); + println!("writing cache {}", FormatDuration(elapsed)); + }, + ) + .await; + return; + } + + run( + args.clone(), + || { + turbo_tasks.cloned().unwrap_or_else(|| { + TurboTasks::new(MemoryBackend::new(memory_limit.unwrap_or(usize::MAX))) + }) + }, + |_, _, _| async move {}, + module_options, + resolve_options, + ) + .await +} + +async fn run>( + args: Arc, + create_tt: impl Fn() -> Arc>, + final_finish: impl FnOnce(Arc>, TaskId, Duration) -> F, + module_options: Option, + resolve_options: Option, +) -> Result> { + let &CommonArgs { + watch, + show_all, + log_detail, + log_level, + .. + } = args.common(); + + let start = Instant::now(); + let finish = |tt: Arc>, root_task: TaskId| async move { + if watch { + if let Err(e) = tt.wait_task_completion(root_task, true).await { + println!("{}", e); + } + let UpdateInfo { + duration, tasks, .. + } = tt + .get_or_wait_aggregated_update_info(Duration::from_millis(100)) + .await; + println!( + "done in {} ({} task execution, {} tasks)", + FormatDuration(start.elapsed()), + FormatDuration(duration), + tasks + ); + + loop { + let UpdateInfo { + duration, tasks, .. + } = tt + .get_or_wait_aggregated_update_info(Duration::from_millis(100)) + .await; + println!("updated {} tasks in {}", tasks, FormatDuration(duration)); + } + } else { + let result = tt.wait_task_completion(root_task, true).await; + let dur = start.elapsed(); + let UpdateInfo { + duration, tasks, .. + } = tt + .get_or_wait_aggregated_update_info(Duration::from_millis(100)) + .await; + final_finish(tt, root_task, dur).await; + let dur2 = start.elapsed(); + println!( + "done in {} ({} compilation, {} task execution, {} tasks)", + FormatDuration(dur2), + FormatDuration(dur), + FormatDuration(duration), + tasks + ); + result + } + }; + let has_return_value = + matches!(&*args, Args::Annotate { .. }) || matches!(&*args, Args::Print { .. }); + let (sender, mut receiver) = channel(1); + let dir = current_dir().unwrap(); + let tt = create_tt(); + let module_options = TransientInstance::new(module_options.unwrap_or_default()); + let resolve_options = TransientInstance::new(resolve_options.unwrap_or_default()); + let log_options = TransientInstance::new(LogOptions { + current_dir: dir.clone(), + project_dir: dir.clone(), + show_all, + log_detail, + log_level: log_level.map_or_else(|| IssueSeverity::Error, |l| l.0), + }); + let task = tt.spawn_root_task(move || { + let dir = dir.clone(); + let args = args.clone(); + let sender = sender.clone(); + let module_options = module_options.clone(); + let resolve_options = resolve_options.clone(); + let log_options = log_options.clone(); + Box::pin(async move { + let output = main_operation( + TransientValue::new(dir.clone()), + TransientInstance::new(args.clone()), + module_options, + resolve_options, + ); + let _ = output.resolve_strongly_consistent().await?; + + let source = TransientValue::new(Vc::into_raw(output)); + let issues = output.peek_issues_with_path().await?; + + let console_ui = ConsoleUi::new(log_options); + Vc::upcast::>(console_ui) + .report_issues( + TransientInstance::new(issues), + source, + IssueSeverity::Error.cell(), + ) + .await?; + + if has_return_value { + let output_read_ref = output.await?; + let output_iter = output_read_ref.iter().cloned(); + sender.send(output_iter.collect::>()).await?; + drop(sender); + } + Ok::, _>(Default::default()) + }) + }); + finish(tt, task).await?; + let output = if has_return_value { + receiver.try_recv()? + } else { + Vec::new() + }; + Ok(output) +} + +#[turbo_tasks::function] +async fn main_operation( + current_dir: TransientValue, + args: TransientInstance>, + module_options: TransientInstance, + resolve_options: TransientInstance, +) -> Result>> { + let dir = current_dir.into_value(); + let args = &*args; + let &CommonArgs { + ref input, + watch, + exact, + ref context_directory, + ref process_cwd, + .. + } = args.common(); + let context_directory: RcStr = process_context(&dir, context_directory.as_ref()) + .unwrap() + .into(); + let fs = create_fs("context directory", &context_directory, watch).await?; + let process_cwd = process_cwd.clone().map(RcStr::from); + + match **args { + Args::Print { common: _ } => { + let input = process_input(&dir, &context_directory, input).unwrap(); + let mut result = BTreeSet::new(); + let modules = input_to_modules( + fs, + input, + exact, + process_cwd.clone(), + context_directory, + module_options, + resolve_options, + ) + .await?; + for module in modules.iter() { + let set = all_modules_and_affecting_sources(*module) + .issue_file_path(module.ident().path(), "gathering list of assets") + .await?; + for asset in set.await?.iter() { + let path = asset.ident().path().await?; + result.insert(RcStr::from(&*path.path)); + } + } + + return Ok(Vc::cell(result.into_iter().collect::>())); + } + Args::Annotate { common: _ } => { + let input = process_input(&dir, &context_directory, input).unwrap(); + let mut output_nft_assets = Vec::new(); + let mut emits = Vec::new(); + for module in input_to_modules( + fs, + input, + exact, + process_cwd.clone(), + context_directory, + module_options, + resolve_options, + ) + .await? + .iter() + { + let nft_asset = NftJsonAsset::new(*module); + let path = nft_asset.ident().path().await?.path.clone(); + output_nft_assets.push(path); + emits.push(emit_asset(Vc::upcast(nft_asset))); + } + // Wait for all files to be emitted + for emit in emits { + emit.await?; + } + return Ok(Vc::cell(output_nft_assets)); + } + Args::Build { + ref output_directory, + common: _, + } => { + let output = process_context(&dir, Some(output_directory)).unwrap(); + let input = process_input(&dir, &context_directory, input).unwrap(); + let out_fs = create_fs("output directory", &output, watch).await?; + let input_dir = fs.root(); + let output_dir = out_fs.root(); + let mut emits = Vec::new(); + for module in input_to_modules( + fs, + input, + exact, + process_cwd.clone(), + context_directory, + module_options, + resolve_options, + ) + .await? + .iter() + { + let rebased = Vc::upcast(RebasedAsset::new(*module, input_dir, output_dir)); + emits.push(emit_with_completion(rebased, output_dir)); + } + // Wait for all files to be emitted + for emit in emits { + emit.await?; + } + } + Args::Size { common: _ } => todo!(), + } + Ok(Vc::cell(Vec::new())) +} + +#[turbo_tasks::function] +async fn create_module_asset( + root: Vc, + process_cwd: Option, + module_options: TransientInstance, + resolve_options: TransientInstance, +) -> Result> { + let env = Environment::new(Value::new(ExecutionEnvironment::NodeJsLambda( + NodeJsEnvironment { + cwd: Vc::cell(process_cwd), + ..Default::default() + } + .into(), + ))); + let compile_time_info = CompileTimeInfo::builder(env).cell(); + let glob_mappings = vec![ + ( + root, + Glob::new("**/*/next/dist/server/next.js".into()), + ImportMapping::Ignore.into(), + ), + ( + root, + Glob::new("**/*/next/dist/bin/next".into()), + ImportMapping::Ignore.into(), + ), + ]; + let mut resolve_options = ResolveOptionsContext::clone(&*resolve_options); + if resolve_options.emulate_environment.is_none() { + resolve_options.emulate_environment = Some(env); + } + if resolve_options.resolved_map.is_none() { + resolve_options.resolved_map = Some( + ResolvedMap { + by_glob: glob_mappings, + } + .cell(), + ); + } + + Ok(ModuleAssetContext::new( + Vc::cell(HashMap::new()), + compile_time_info, + ModuleOptionsContext::clone(&*module_options).cell(), + resolve_options.cell(), + Vc::cell("node_file_trace".into()), + )) +} + +fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack::register(); + turbopack_cli_utils::register(); + turbopack_resolve::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/node-file-trace/src/main.rs b/turbopack/crates/node-file-trace/src/main.rs new file mode 100644 index 0000000000000..2e435166363da --- /dev/null +++ b/turbopack/crates/node-file-trace/src/main.rs @@ -0,0 +1,25 @@ +#![feature(min_specialization)] + +use std::sync::Arc; + +use anyhow::Result; +use clap::Parser; +use node_file_trace::{start, Args}; + +#[global_allocator] +static ALLOC: turbo_tasks_malloc::TurboMalloc = turbo_tasks_malloc::TurboMalloc; + +#[tokio::main] +async fn main() -> Result<()> { + #[cfg(feature = "tokio_console")] + console_subscriber::init(); + let args = Arc::new(Args::parse()); + let should_print = matches!(&*args, Args::Print { .. }); + let result = start(args, None, None, None).await?; + if should_print { + for file in result.iter() { + println!("{}", file); + } + } + Ok(()) +} diff --git a/turbopack/crates/node-file-trace/src/nft_json.rs b/turbopack/crates/node-file-trace/src/nft_json.rs new file mode 100644 index 0000000000000..1e57d80a5d5f2 --- /dev/null +++ b/turbopack/crates/node-file-trace/src/nft_json.rs @@ -0,0 +1,67 @@ +use anyhow::Result; +use serde_json::json; +use turbo_tasks::Vc; +use turbo_tasks_fs::{File, FileSystem}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + ident::AssetIdent, + module::Module, + output::OutputAsset, + reference::all_modules_and_affecting_sources, +}; + +#[turbo_tasks::value(shared)] +pub struct NftJsonAsset { + entry: Vc>, +} + +#[turbo_tasks::value_impl] +impl NftJsonAsset { + #[turbo_tasks::function] + pub fn new(entry: Vc>) -> Vc { + NftJsonAsset { entry }.cell() + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for NftJsonAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let path = self.entry.ident().path().await?; + Ok(AssetIdent::from_path( + path.fs + .root() + .join(format!("{}.nft.json", path.path).into()), + )) + } +} + +#[turbo_tasks::value_impl] +impl Asset for NftJsonAsset { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let parent_dir = self.entry.ident().path().parent().await?; + // For clippy -- This explicit deref is necessary + let entry_path = &*self.entry.ident().path().await?; + let mut result = Vec::new(); + if let Some(self_path) = parent_dir.get_relative_path_to(entry_path) { + let set = all_modules_and_affecting_sources(self.entry); + for asset in set.await?.iter() { + let path = asset.ident().path().await?; + if let Some(rel_path) = parent_dir.get_relative_path_to(&path) { + if rel_path != self_path { + result.push(rel_path); + } + } + } + result.sort(); + result.dedup(); + } + let json = json!({ + "version": 1, + "files": result + }); + + Ok(AssetContent::file(File::from(json.to_string()).into())) + } +} diff --git a/turbopack/crates/tower-uds/Cargo.toml b/turbopack/crates/tower-uds/Cargo.toml new file mode 100644 index 0000000000000..451fea5c71a18 --- /dev/null +++ b/turbopack/crates/tower-uds/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "tower-uds" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +tokio = { workspace = true, features = ["net"] } +tower = { version = "0.4.13", features = ["util"] } + + +[target.'cfg(target_os = "windows")'.dependencies] +tokio-util = { workspace = true, features = ["compat"] } +uds_windows = "1.0.2" +async-io = "1.12.0" diff --git a/turbopack/crates/tower-uds/src/lib.rs b/turbopack/crates/tower-uds/src/lib.rs new file mode 100644 index 0000000000000..a4cab89194730 --- /dev/null +++ b/turbopack/crates/tower-uds/src/lib.rs @@ -0,0 +1,61 @@ +//! tower-uds +//! +//! A unix domain socket server for the `tower` ecosystem. + +#![feature(impl_trait_in_assoc_type)] + +use std::{future::Future, path::Path}; + +use tower::Service; + +pub struct UDSConnector<'a> { + path: &'a Path, +} + +impl<'a> UDSConnector<'a> { + pub fn new(path: &'a Path) -> Self { + Self { path } + } +} + +impl<'a, T> Service for UDSConnector<'a> { + #[cfg(not(target_os = "windows"))] + type Response = tokio::net::UnixStream; + + // tokio does not support UDS on windows, so we need to use async-io + // with a tokio compat layer instead + #[cfg(target_os = "windows")] + type Response = tokio_util::compat::Compat>; + + type Error = std::io::Error; + + type Future = impl Future> + 'a; + + fn poll_ready( + &mut self, + _cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + Ok(()).into() + } + + fn call(&mut self, _req: T) -> Self::Future { + // we need to make sure our ref is immutable so that the closure has a lifetime + // of 'a, not the anonymous lifetime of the call method + let path = self.path; + + #[cfg(not(target_os = "windows"))] + { + async move { tokio::net::UnixStream::connect(path).await } + } + #[cfg(target_os = "windows")] + { + async move { + use tokio_util::compat::FuturesAsyncReadCompatExt; + let stream = uds_windows::UnixStream::connect(path)?; + Ok(FuturesAsyncReadCompatExt::compat(async_io::Async::new( + stream, + )?)) + } + } + } +} diff --git a/turbopack/crates/turbo-prehash/Cargo.toml b/turbopack/crates/turbo-prehash/Cargo.toml new file mode 100644 index 0000000000000..e2f6856763c65 --- /dev/null +++ b/turbopack/crates/turbo-prehash/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "turbo-prehash" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" + +[dependencies] + +[lints] +workspace = true diff --git a/turbopack/crates/turbo-prehash/src/lib.rs b/turbopack/crates/turbo-prehash/src/lib.rs new file mode 100644 index 0000000000000..bf187fd72602c --- /dev/null +++ b/turbopack/crates/turbo-prehash/src/lib.rs @@ -0,0 +1,145 @@ +//! turbo-prehash +//! +//! A small wrapper around `std::hash::Hasher` that allows you to pre-hash a +//! value before hashing it. +//! +//! This is useful for when you want to hash a value that is expensive to +//! compute (e.g. a large string) but you want to avoid re-hashing it every +//! time. +//! +//! # Example +//! +//! ``` +//! use turbo_prehash::{BuildHasherExt, PreHashed}; +//! use std::collections::HashMap; +//! use std::hash::{BuildHasherDefault, RandomState, Hash}; +//! +//! /// hash a key, returning a prehashed value +//! fn hash_key(key: T) -> PreHashed { +//! RandomState::new().prehash(key) +//! } +//! +//! // create hashmap to hold pre-hashed values +//! let mut map: HashMap, String> = Default::default(); +//! +//! // insert a prehashed value +//! let hashed_key = hash_key("hello".to_string()); +//! map.insert(hashed_key.clone(), "world".to_string()); +//! +//! // get the value +//! assert_eq!(map.get(&hashed_key), Some(&"world".to_string())); +//! ``` + +use std::{ + fmt, + hash::{BuildHasher, Hash, Hasher}, + ops::Deref, +}; + +/// A wrapper type that hashes some `inner` on creation, implementing [Hash] +/// by simply returning the pre-computed hash. +#[derive(Copy, Debug, Clone)] +pub struct PreHashed { + hash: H, + inner: I, +} + +impl PreHashed { + /// Create a new [PreHashed] value with the given hash and inner value. + /// + /// SAFETY: The hash must be a valid hash of the inner value. + pub fn new(hash: H, inner: I) -> Self { + Self { hash, inner } + } + + /// Split the [PreHashed] value into its hash and inner value. + pub fn into_parts(self) -> (H, I) { + (self.hash, self.inner) + } + + fn inner(&self) -> &I { + &self.inner + } +} + +impl PreHashed { + /// Create a new [PreHashed] value from a [BuildHasher]. + fn new_from_builder(hasher: &B, inner: I) -> Self { + Self::new(hasher.hash_one(&inner), inner) + } +} + +impl Deref for PreHashed { + type Target = I; + + fn deref(&self) -> &Self::Target { + self.inner() + } +} + +impl AsRef for PreHashed { + fn as_ref(&self) -> &I { + self.inner() + } +} + +impl Hash for PreHashed { + fn hash(&self, state: &mut S) { + self.hash.hash(state) + } +} + +impl Eq for PreHashed {} + +impl PartialEq for PreHashed { + // note: we compare the values, not the hashes + fn eq(&self, other: &Self) -> bool { + self.inner.eq(&other.inner) + } +} + +impl fmt::Display for PreHashed { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.inner.fmt(f) + } +} + +/// An implementer of [Hash] that simply returns the pre-computed hash. +#[derive(Copy, Clone, Debug, Default)] +pub struct PassThroughHash(u64); + +impl PassThroughHash { + pub fn new() -> Self { + Default::default() + } +} + +impl Hasher for PassThroughHash { + fn write(&mut self, _bytes: &[u8]) { + unimplemented!("do not use") + } + + fn write_u64(&mut self, i: u64) { + self.0 = i; + } + + fn finish(&self) -> u64 { + self.0 + } +} + +/// An extension trait for [BuildHasher] that provides the +/// [BuildHasherExt::prehash] method. +pub trait BuildHasherExt: BuildHasher { + type Hash; + + fn prehash(&self, value: T) -> PreHashed; +} + +impl BuildHasherExt for B { + type Hash = u64; + + fn prehash(&self, value: T) -> PreHashed { + PreHashed::new_from_builder(self, value) + } +} diff --git a/turbopack/crates/turbo-static/.gitignore b/turbopack/crates/turbo-static/.gitignore new file mode 100644 index 0000000000000..32d96908cdc6b --- /dev/null +++ b/turbopack/crates/turbo-static/.gitignore @@ -0,0 +1,2 @@ +call_resolver.bincode +graph.cypherl diff --git a/turbopack/crates/turbo-static/Cargo.toml b/turbopack/crates/turbo-static/Cargo.toml new file mode 100644 index 0000000000000..699c00f64f88c --- /dev/null +++ b/turbopack/crates/turbo-static/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "turbo-static" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" + +[dependencies] +bincode = "1.3.3" +clap = { workspace = true, features = ["derive"] } +ctrlc = "3.4.4" +ignore = "0.4.22" +itertools.workspace = true +lsp-server = "0.7.6" +lsp-types = "0.95.1" +proc-macro2 = { workspace = true, features = ["span-locations"] } +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +serde_path_to_error = "0.1.16" +syn = { version = "2", features = ["parsing", "full", "visit", "extra-traits"] } +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +tracing.workspace = true +walkdir = "2.5.0" + +[lints] +workspace = true diff --git a/turbopack/crates/turbo-static/readme.md b/turbopack/crates/turbo-static/readme.md new file mode 100644 index 0000000000000..4ad86f1490410 --- /dev/null +++ b/turbopack/crates/turbo-static/readme.md @@ -0,0 +1,33 @@ +# Turbo Static + +Leverages rust-analyzer to build a complete view into the static dependency +graph for your turbo tasks project. + +## How it works + +- find all occurences of #[turbo_tasks::function] across all the packages you + want to query +- for each of the tasks we find, query rust analyzer to see which tasks call + them +- apply some very basis control flow analysis to determine whether the call is + made 1 time, 0/1 times, or 0+ times, corresponding to direct calls, + conditionals, or for loops +- produce a cypher file that can be loaded into a graph database to query the + static dependency graph + +## Usage + +This uses an in memory persisted database to cache rust-analyzer queries. +To reset the cache, pass the `--reindex` flag. Running will produce a +`graph.cypherl` file which can be loaded into any cypher-compatible database. + +```bash +# pass in the root folders you want to analyze. the system will recursively +# parse all rust code looking for turbo tasks functions +cargo run --release -- ../../../turbo ../../../next.js +# now you can load graph.cypherl into your database of choice, such as neo4j +docker run \ + --publish=7474:7474 --publish=7687:7687 \ + --volume=$HOME/neo4j/data:/data \ + neo4j +``` diff --git a/turbopack/crates/turbo-static/src/call_resolver.rs b/turbopack/crates/turbo-static/src/call_resolver.rs new file mode 100644 index 0000000000000..aec97607a9438 --- /dev/null +++ b/turbopack/crates/turbo-static/src/call_resolver.rs @@ -0,0 +1,165 @@ +use std::{collections::HashMap, fs::OpenOptions, path::PathBuf}; + +use crate::{lsp_client::RAClient, Identifier, IdentifierReference}; + +/// A wrapper around a rust-analyzer client that can resolve call references. +/// This is quite expensive so we cache the results in an on-disk key-value +/// store. +pub struct CallResolver<'a> { + client: &'a mut RAClient, + state: HashMap>, + path: Option, +} + +/// On drop, serialize the state to disk +impl<'a> Drop for CallResolver<'a> { + fn drop(&mut self) { + let file = OpenOptions::new() + .create(true) + .truncate(false) + .write(true) + .open(self.path.as_ref().unwrap()) + .unwrap(); + bincode::serialize_into(file, &self.state).unwrap(); + } +} + +impl<'a> CallResolver<'a> { + pub fn new(client: &'a mut RAClient, path: Option) -> Self { + // load bincode-encoded HashMap from path + let state = path + .as_ref() + .and_then(|path| { + let file = OpenOptions::new() + .create(true) + .truncate(false) + .read(true) + .write(true) + .open(path) + .unwrap(); + let reader = std::io::BufReader::new(file); + bincode::deserialize_from::<_, HashMap>>( + reader, + ) + .map_err(|e| { + tracing::warn!("failed to load existing cache, restarting"); + e + }) + .ok() + }) + .unwrap_or_default(); + Self { + client, + state, + path, + } + } + + pub fn cached_count(&self) -> usize { + self.state.len() + } + + pub fn cleared(mut self) -> Self { + // delete file if exists and clear state + self.state = Default::default(); + if let Some(path) = self.path.as_ref() { + std::fs::remove_file(path).unwrap(); + } + self + } + + pub fn resolve(&mut self, ident: &Identifier) -> Vec { + if let Some(data) = self.state.get(ident) { + tracing::info!("skipping {}", ident); + return data.to_owned(); + }; + + tracing::info!("checking {}", ident); + + let mut count = 0; + let _response = loop { + let Some(response) = self.client.request(lsp_server::Request { + id: 1.into(), + method: "textDocument/prepareCallHierarchy".to_string(), + params: serde_json::to_value(&lsp_types::CallHierarchyPrepareParams { + text_document_position_params: lsp_types::TextDocumentPositionParams { + position: ident.range.start, + text_document: lsp_types::TextDocumentIdentifier { + uri: lsp_types::Url::from_file_path(&ident.path).unwrap(), + }, + }, + work_done_progress_params: lsp_types::WorkDoneProgressParams { + work_done_token: Some(lsp_types::ProgressToken::String( + "prepare".to_string(), + )), + }, + }) + .unwrap(), + }) else { + tracing::warn!("RA server shut down"); + return vec![]; + }; + + if let Some(Some(value)) = response.result.as_ref().map(|r| r.as_array()) { + if !value.is_empty() { + break value.to_owned(); + } + count += 1; + } + + // textDocument/prepareCallHierarchy will sometimes return an empty array so try + // at most 5 times + if count > 5 { + tracing::warn!("discovered isolated task {}", ident); + break vec![]; + } + + std::thread::sleep(std::time::Duration::from_secs(1)); + }; + + // callHierarchy/incomingCalls + let Some(response) = self.client.request(lsp_server::Request { + id: 1.into(), + method: "callHierarchy/incomingCalls".to_string(), + params: serde_json::to_value(lsp_types::CallHierarchyIncomingCallsParams { + partial_result_params: lsp_types::PartialResultParams::default(), + item: lsp_types::CallHierarchyItem { + name: ident.name.to_owned(), + kind: lsp_types::SymbolKind::FUNCTION, + data: None, + tags: None, + detail: None, + uri: lsp_types::Url::from_file_path(&ident.path).unwrap(), + range: ident.range, + selection_range: ident.range, + }, + work_done_progress_params: lsp_types::WorkDoneProgressParams { + work_done_token: Some(lsp_types::ProgressToken::String("prepare".to_string())), + }, + }) + .unwrap(), + }) else { + tracing::warn!("RA server shut down"); + return vec![]; + }; + + let links = if let Some(e) = response.error { + tracing::warn!("unable to resolve {}: {:?}", ident, e); + vec![] + } else { + let response: Result, _> = + serde_path_to_error::deserialize(response.result.unwrap()); + + response + .unwrap() + .into_iter() + .map(|i| i.into()) + .collect::>() + }; + + tracing::debug!("links: {:?}", links); + + self.state.insert(ident.to_owned(), links.clone()); + links + } +} diff --git a/turbopack/crates/turbo-static/src/identifier.rs b/turbopack/crates/turbo-static/src/identifier.rs new file mode 100644 index 0000000000000..c92a3da7bb5d2 --- /dev/null +++ b/turbopack/crates/turbo-static/src/identifier.rs @@ -0,0 +1,95 @@ +use std::{fs, path::PathBuf}; + +use lsp_types::{CallHierarchyIncomingCall, CallHierarchyItem, Range}; + +/// A task that references another, with the range of the reference +#[derive(Hash, PartialEq, Eq, serde::Deserialize, serde::Serialize, Clone, Debug)] +pub struct IdentifierReference { + pub identifier: Identifier, + pub references: Vec, // the places where this identifier is used +} + +/// identifies a task by its file, and range in the file +#[derive(Hash, PartialEq, Eq, serde::Deserialize, serde::Serialize, Clone)] +pub struct Identifier { + pub path: String, + // technically you can derive this from the name and range but it's easier to just store it + pub name: String, + // post_transform_name: Option, + pub range: lsp_types::Range, +} + +impl Identifier { + /// check the span matches and the text matches + /// + /// `same_location` is used to check if the location of the identifier is + /// the same as the other + pub fn equals_ident(&self, other: &syn::Ident, match_location: bool) -> bool { + *other == self.name + && (!match_location + || (self.range.start.line == other.span().start().line as u32 + && self.range.start.character == other.span().start().column as u32)) + } + + /// We cannot use `item.name` here in all cases as, during testing, the name + /// does not always align with the exact text in the range. + fn get_name(item: &CallHierarchyItem) -> String { + // open file, find range inside, extract text + let file = fs::read_to_string(item.uri.path()).unwrap(); + let start = item.selection_range.start; + let end = item.selection_range.end; + file.lines() + .nth(start.line as usize) + .unwrap() + .chars() + .skip(start.character as usize) + .take(end.character as usize - start.character as usize) + .collect() + } +} + +impl From<(PathBuf, syn::Ident)> for Identifier { + fn from((path, ident): (PathBuf, syn::Ident)) -> Self { + Self { + path: path.display().to_string(), + name: ident.to_string(), + // post_transform_name: None, + range: Range { + start: lsp_types::Position { + line: ident.span().start().line as u32 - 1, + character: ident.span().start().column as u32, + }, + end: lsp_types::Position { + line: ident.span().end().line as u32 - 1, + character: ident.span().end().column as u32, + }, + }, + } + } +} + +impl From for IdentifierReference { + fn from(item: CallHierarchyIncomingCall) -> Self { + Self { + identifier: Identifier { + name: Identifier::get_name(&item.from), + // post_transform_name: Some(item.from.name), + path: item.from.uri.path().to_owned(), + range: item.from.selection_range, + }, + references: item.from_ranges, + } + } +} + +impl std::fmt::Debug for Identifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(self, f) + } +} + +impl std::fmt::Display for Identifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}:{}#{}", self.path, self.range.start.line, self.name,) + } +} diff --git a/turbopack/crates/turbo-static/src/lsp_client.rs b/turbopack/crates/turbo-static/src/lsp_client.rs new file mode 100644 index 0000000000000..25d29a7efd26d --- /dev/null +++ b/turbopack/crates/turbo-static/src/lsp_client.rs @@ -0,0 +1,161 @@ +use std::{path::PathBuf, process, sync::mpsc}; + +use lsp_server::Message; + +/// An LSP client for Rust Analyzer (RA) that launches it as a subprocess. +pub struct RAClient { + /// Handle to the client + handle: process::Child, + sender: Option>, + receiver: Option>, +} + +impl RAClient { + /// Create a new LSP client for Rust Analyzer. + pub fn new() -> Self { + let stdin = process::Stdio::piped(); + let stdout = process::Stdio::piped(); + let stderr = process::Stdio::inherit(); + + let child = process::Command::new("rust-analyzer") + .stdin(stdin) + .stdout(stdout) + .stderr(stderr) + // .env("RA_LOG", "info") + .env("RUST_BACKTRACE", "1") + .spawn() + .expect("Failed to start RA LSP server"); + Self { + handle: child, + sender: None, + receiver: None, + } + } + + pub fn start(&mut self, folders: &[PathBuf]) { + let stdout = self.handle.stdout.take().unwrap(); + let mut stdin = self.handle.stdin.take().unwrap(); + + let (writer_sender, writer_receiver) = mpsc::sync_channel::(0); + _ = std::thread::spawn(move || { + writer_receiver + .into_iter() + .try_for_each(|it| it.write(&mut stdin)) + }); + + let (reader_sender, reader_receiver) = mpsc::sync_channel::(0); + _ = std::thread::spawn(move || { + let mut reader = std::io::BufReader::new(stdout); + while let Ok(Some(msg)) = Message::read(&mut reader) { + reader_sender + .send(msg) + .expect("receiver was dropped, failed to send a message"); + } + }); + + self.sender = Some(writer_sender); + self.receiver = Some(reader_receiver); + + let workspace_paths = folders + .iter() + .map(|p| std::fs::canonicalize(p).unwrap()) + .map(|p| lsp_types::WorkspaceFolder { + name: p.file_name().unwrap().to_string_lossy().to_string(), + uri: lsp_types::Url::from_file_path(p).unwrap(), + }) + .collect::>(); + + _ = self.request(lsp_server::Request { + id: 1.into(), + method: "initialize".to_string(), + params: serde_json::to_value(lsp_types::InitializeParams { + workspace_folders: Some(workspace_paths), + process_id: Some(std::process::id()), + capabilities: lsp_types::ClientCapabilities { + workspace: Some(lsp_types::WorkspaceClientCapabilities { + workspace_folders: Some(true), + ..Default::default() + }), + ..Default::default() + }, + work_done_progress_params: lsp_types::WorkDoneProgressParams { + work_done_token: Some(lsp_types::ProgressToken::String("prepare".to_string())), + }, + // we use workspace_folders so root_path and root_uri can be + // empty + ..Default::default() + }) + .unwrap(), + }); + + self.notify(lsp_server::Notification { + method: "initialized".to_string(), + params: serde_json::to_value(lsp_types::InitializedParams {}).unwrap(), + }); + } + + /// Send an LSP request to the server. This returns an option + /// in the case of an error such as the server being shut down + /// from pressing `Ctrl+C`. + pub fn request(&mut self, message: lsp_server::Request) -> Option { + tracing::debug!("sending {:?}", message); + self.sender + .as_mut() + .unwrap() + .send(Message::Request(message)) + .ok()?; + + loop { + match self.receiver.as_mut().unwrap().recv() { + Ok(lsp_server::Message::Response(response)) => { + tracing::debug!("received {:?}", response); + return Some(response); + } + Ok(m) => tracing::trace!("unexpected message: {:?}", m), + Err(_) => { + tracing::trace!("error receiving message"); + return None; + } + } + } + } + + pub fn notify(&mut self, message: lsp_server::Notification) { + self.sender + .as_mut() + .unwrap() + .send(Message::Notification(message)) + .expect("failed to send message"); + } +} + +impl Drop for RAClient { + fn drop(&mut self) { + if self.sender.is_some() { + let Some(resp) = self.request(lsp_server::Request { + id: 1.into(), + method: "shutdown".to_string(), + params: serde_json::to_value(()).unwrap(), + }) else { + return; + }; + + if resp.error.is_none() { + tracing::info!("shutting down RA LSP server"); + self.notify(lsp_server::Notification { + method: "exit".to_string(), + params: serde_json::to_value(()).unwrap(), + }); + self.handle + .wait() + .expect("failed to wait for RA LSP server"); + tracing::info!("shut down RA LSP server"); + } else { + tracing::error!("failed to shutdown RA LSP server: {:#?}", resp); + } + } + + self.sender = None; + self.receiver = None; + } +} diff --git a/turbopack/crates/turbo-static/src/main.rs b/turbopack/crates/turbo-static/src/main.rs new file mode 100644 index 0000000000000..a3eece260d62c --- /dev/null +++ b/turbopack/crates/turbo-static/src/main.rs @@ -0,0 +1,303 @@ +#![feature(entry_insert)] + +use std::{ + collections::{HashMap, HashSet}, + error::Error, + fs, + path::PathBuf, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, +}; + +use call_resolver::CallResolver; +use clap::Parser; +use identifier::{Identifier, IdentifierReference}; +use itertools::Itertools; +use syn::visit::Visit; +use visitor::CallingStyleVisitor; + +use crate::visitor::CallingStyle; + +mod call_resolver; +mod identifier; +mod lsp_client; +mod visitor; + +#[derive(Parser)] +struct Opt { + #[clap(required = true)] + paths: Vec, + + /// reparse all files + #[clap(long)] + reparse: bool, + + /// reindex all files + #[clap(long)] + reindex: bool, +} + +fn main() -> Result<(), Box> { + tracing_subscriber::fmt::init(); + let opt = Opt::parse(); + + let mut connection = lsp_client::RAClient::new(); + connection.start(&opt.paths); + + let call_resolver = CallResolver::new(&mut connection, Some("call_resolver.bincode".into())); + let mut call_resolver = if opt.reindex { + call_resolver.cleared() + } else { + call_resolver + }; + + let halt = Arc::new(AtomicBool::new(false)); + let halt_clone = halt.clone(); + ctrlc::set_handler({ + move || { + halt_clone.store(true, Ordering::SeqCst); + } + })?; + + tracing::info!("getting tasks"); + let mut tasks = get_all_tasks(&opt.paths); + let dep_tree = resolve_tasks(&mut tasks, &mut call_resolver, halt.clone()); + let concurrency = resolve_concurrency(&tasks, &dep_tree, halt.clone()); + + write_dep_tree(&tasks, concurrency, std::path::Path::new("graph.cypherl")); + + if halt.load(Ordering::Relaxed) { + tracing::info!("ctrl-c detected, exiting"); + } + + Ok(()) +} + +/// search the given folders recursively and attempt to find all tasks inside +#[tracing::instrument(skip_all)] +fn get_all_tasks(folders: &[PathBuf]) -> HashMap> { + let mut out = HashMap::new(); + + for folder in folders { + let walker = ignore::Walk::new(folder); + for entry in walker { + let entry = entry.unwrap(); + let rs_file = if let Some(true) = entry.file_type().map(|t| t.is_file()) { + let path = entry.path(); + let ext = path.extension().unwrap_or_default(); + if ext == "rs" { + std::fs::canonicalize(path).unwrap() + } else { + continue; + } + } else { + continue; + }; + + let file = fs::read_to_string(&rs_file).unwrap(); + let lines = file.lines(); + let mut occurences = vec![]; + + tracing::debug!("processing {}", rs_file.display()); + + for ((_, line), (line_no, _)) in lines.enumerate().tuple_windows() { + if line.contains("turbo_tasks::function") { + tracing::debug!("found at {:?}:L{}", rs_file, line_no); + occurences.push(line_no + 1); + } + } + + if occurences.is_empty() { + continue; + } + + // parse the file using syn and get the span of the functions + let file = syn::parse_file(&file).unwrap(); + let occurences_count = occurences.len(); + let mut visitor = visitor::TaskVisitor::new(); + syn::visit::visit_file(&mut visitor, &file); + if visitor.results.len() != occurences_count { + tracing::warn!( + "file {:?} passed the heuristic with {:?} but the visitor found {:?}", + rs_file, + occurences_count, + visitor.results.len() + ); + } + + out.extend( + visitor + .results + .into_iter() + .map(move |(ident, tags)| ((rs_file.clone(), ident).into(), tags)), + ) + } + } + + out +} + +/// Given a list of tasks, get all the tasks that call that one +fn resolve_tasks( + tasks: &mut HashMap>, + client: &mut CallResolver, + halt: Arc, +) -> HashMap> { + tracing::info!( + "found {} tasks, of which {} cached", + tasks.len(), + client.cached_count() + ); + + let mut unresolved = tasks.keys().cloned().collect::>(); + let mut resolved = HashMap::new(); + + while let Some(top) = unresolved.iter().next().cloned() { + unresolved.remove(&top); + + let callers = client.resolve(&top); + + // add all non-task callers to the unresolved list if they are not in the + // resolved list + for caller in callers.iter() { + if !resolved.contains_key(&caller.identifier) + && !unresolved.contains(&caller.identifier) + { + tracing::debug!("adding {} to unresolved", caller.identifier); + unresolved.insert(caller.identifier.to_owned()); + } + } + resolved.insert(top.to_owned(), callers); + + if halt.load(Ordering::Relaxed) { + break; + } + } + + resolved +} + +/// given a map of tasks and functions that call it, produce a map of tasks and +/// those tasks that it calls +/// +/// returns a list of pairs with a task, the task that calls it, and the calling +/// style +fn resolve_concurrency( + task_list: &HashMap>, + dep_tree: &HashMap>, // pairs of tasks and call trees + halt: Arc, +) -> Vec<(Identifier, Identifier, CallingStyle)> { + // println!("{:?}", dep_tree); + // println!("{:#?}", task_list); + + let mut edges = vec![]; + + for (ident, references) in dep_tree { + for reference in references { + if !dep_tree.contains_key(&reference.identifier) { + // this is a task that is not in the task list + // so we can't resolve it + tracing::error!("missing task for {}: {}", ident, reference.identifier); + for task in task_list.keys() { + if task.name == reference.identifier.name { + // we found a task that is not in the task list + // so we can't resolve it + tracing::trace!("- found {}", task); + continue; + } + } + continue; + } else { + // load the source file and get the calling style + let target = IdentifierReference { + identifier: ident.clone(), + references: reference.references.clone(), + }; + let mut visitor = CallingStyleVisitor::new(target); + tracing::info!("looking for {} from {}", ident, reference.identifier); + let file = + syn::parse_file(&fs::read_to_string(&reference.identifier.path).unwrap()) + .unwrap(); + visitor.visit_file(&file); + + edges.push(( + ident.clone(), + reference.identifier.clone(), + visitor.result().unwrap_or(CallingStyle::Once), + )); + } + + if halt.load(Ordering::Relaxed) { + break; + } + } + } + + // parse each fn between parent and child and get the max calling style + + edges +} + +/// Write the dep tree into the given file using cypher syntax +fn write_dep_tree( + task_list: &HashMap>, + dep_tree: Vec<(Identifier, Identifier, CallingStyle)>, + out: &std::path::Path, +) { + use std::io::Write; + + let mut node_ids = HashMap::new(); + let mut counter = 0; + + let mut file = std::fs::File::create(out).unwrap(); + + let empty = vec![]; + + // collect all tasks as well as all intermediate nodes + // tasks come last to ensure the tags are preserved + let node_list = dep_tree + .iter() + .flat_map(|(dest, src, _)| [(src, &empty), (dest, &empty)]) + .chain(task_list) + .collect::>(); + + for (ident, tags) in node_list { + counter += 1; + + let label = if !task_list.contains_key(ident) { + "Function" + } else if tags.contains(&"fs".to_string()) || tags.contains(&"network".to_string()) { + "ImpureTask" + } else { + "Task" + }; + + _ = writeln!( + file, + "CREATE (n_{}:{} {{name: '{}', file: '{}', line: {}, tags: [{}]}})", + counter, + label, + ident.name, + ident.path, + ident.range.start.line, + tags.iter().map(|t| format!("\"{}\"", t)).join(",") + ); + node_ids.insert(ident, counter); + } + + for (dest, src, style) in &dep_tree { + let style = match style { + CallingStyle::Once => "ONCE", + CallingStyle::ZeroOrOnce => "ZERO_OR_ONCE", + CallingStyle::ZeroOrMore => "ZERO_OR_MORE", + CallingStyle::OneOrMore => "ONE_OR_MORE", + }; + + let src_id = *node_ids.get(src).unwrap(); + let dst_id = *node_ids.get(dest).unwrap(); + + _ = writeln!(file, "CREATE (n_{})-[:{}]->(n_{})", src_id, style, dst_id,); + } +} diff --git a/turbopack/crates/turbo-static/src/visitor.rs b/turbopack/crates/turbo-static/src/visitor.rs new file mode 100644 index 0000000000000..113c1a4e1218f --- /dev/null +++ b/turbopack/crates/turbo-static/src/visitor.rs @@ -0,0 +1,275 @@ +//! A visitor that traverses the AST and collects all functions or methods that +//! are annotated with `#[turbo_tasks::function]`. + +use std::{collections::VecDeque, ops::Add}; + +use lsp_types::Range; +use syn::{visit::Visit, Expr, Meta}; + +use crate::identifier::Identifier; + +pub struct TaskVisitor { + /// the list of results as pairs of an identifier and its tags + pub results: Vec<(syn::Ident, Vec)>, +} + +impl TaskVisitor { + pub fn new() -> Self { + Self { + results: Default::default(), + } + } +} + +impl Visit<'_> for TaskVisitor { + #[tracing::instrument(skip_all)] + fn visit_item_fn(&mut self, i: &syn::ItemFn) { + if let Some(tags) = extract_tags(i.attrs.iter()) { + tracing::trace!("L{}: {}", i.sig.ident.span().start().line, i.sig.ident,); + self.results.push((i.sig.ident.clone(), tags)); + } + } + + #[tracing::instrument(skip_all)] + fn visit_impl_item_fn(&mut self, i: &syn::ImplItemFn) { + if let Some(tags) = extract_tags(i.attrs.iter()) { + tracing::trace!("L{}: {}", i.sig.ident.span().start().line, i.sig.ident,); + self.results.push((i.sig.ident.clone(), tags)); + } + } +} + +fn extract_tags<'a>(mut meta: impl Iterator) -> Option> { + meta.find_map(|a| match &a.meta { + // path has two segments, turbo_tasks and function + Meta::Path(path) if path.segments.len() == 2 => { + let first = &path.segments[0]; + let second = &path.segments[1]; + (first.ident == "turbo_tasks" && second.ident == "function").then(std::vec::Vec::new) + } + Meta::List(list) if list.path.segments.len() == 2 => { + let first = &list.path.segments[0]; + let second = &list.path.segments[1]; + if first.ident != "turbo_tasks" || second.ident != "function" { + return None; + } + + // collect ident tokens as args + let tags: Vec<_> = list + .tokens + .clone() + .into_iter() + .filter_map(|t| { + if let proc_macro2::TokenTree::Ident(ident) = t { + Some(ident.to_string()) + } else { + None + } + }) + .collect(); + + Some(tags) + } + _ => { + tracing::trace!("skipping unknown annotation"); + None + } + }) +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd)] +pub enum CallingStyle { + Once = 0b0010, + ZeroOrOnce = 0b0011, + ZeroOrMore = 0b0111, + OneOrMore = 0b0110, +} + +impl CallingStyle { + fn bitset(self) -> u8 { + self as u8 + } +} + +impl Add for CallingStyle { + type Output = Self; + + /// Add two calling styles together to determine the calling style of the + /// target function within the source function. + /// + /// Consider it as a bitset over properties. + /// - 0b000: Nothing + /// - 0b001: Zero + /// - 0b010: Once + /// - 0b011: Zero Or Once + /// - 0b100: More Than Once + /// - 0b101: Zero Or More Than Once (?) + /// - 0b110: Once Or More + /// - 0b111: Zero Or More + /// + /// Note that zero is not a valid calling style. + fn add(self, rhs: Self) -> Self { + let left = self.bitset(); + let right = rhs.bitset(); + + // we treat this as a bitset under addition + #[allow(clippy::suspicious_arithmetic_impl)] + match left | right { + 0b0010 => CallingStyle::Once, + 0b011 => CallingStyle::ZeroOrOnce, + 0b0111 => CallingStyle::ZeroOrMore, + 0b0110 => CallingStyle::OneOrMore, + // the remaining 4 (null, zero, more than once, zero or more than once) + // are unreachable because we don't detect 'zero' or 'more than once' + _ => unreachable!(), + } + } +} + +pub struct CallingStyleVisitor { + pub reference: crate::IdentifierReference, + state: VecDeque, + halt: bool, +} + +impl CallingStyleVisitor { + /// Create a new visitor that will traverse the AST and determine the + /// calling style of the target function within the source function. + pub fn new(reference: crate::IdentifierReference) -> Self { + Self { + reference, + state: Default::default(), + halt: false, + } + } + + pub fn result(self) -> Option { + self.state + .into_iter() + .map(|b| match b { + CallingStyleVisitorState::Block => CallingStyle::Once, + CallingStyleVisitorState::Loop => CallingStyle::ZeroOrMore, + CallingStyleVisitorState::If => CallingStyle::ZeroOrOnce, + CallingStyleVisitorState::Closure => CallingStyle::ZeroOrMore, + }) + .reduce(|a, b| a + b) + } +} + +#[derive(Debug, Clone, Copy)] +enum CallingStyleVisitorState { + Block, + Loop, + If, + Closure, +} + +impl Visit<'_> for CallingStyleVisitor { + fn visit_item_fn(&mut self, i: &'_ syn::ItemFn) { + self.state.push_back(CallingStyleVisitorState::Block); + syn::visit::visit_item_fn(self, i); + if !self.halt { + self.state.pop_back(); + } + } + + fn visit_impl_item_fn(&mut self, i: &'_ syn::ImplItemFn) { + self.state.push_back(CallingStyleVisitorState::Block); + syn::visit::visit_impl_item_fn(self, i); + if !self.halt { + self.state.pop_back(); + } + } + + fn visit_expr_loop(&mut self, i: &'_ syn::ExprLoop) { + self.state.push_back(CallingStyleVisitorState::Loop); + syn::visit::visit_expr_loop(self, i); + if !self.halt { + self.state.pop_back(); + } + } + + fn visit_expr_for_loop(&mut self, i: &'_ syn::ExprForLoop) { + self.state.push_back(CallingStyleVisitorState::Loop); + syn::visit::visit_expr_for_loop(self, i); + if !self.halt { + self.state.pop_back(); + } + } + + fn visit_expr_if(&mut self, i: &'_ syn::ExprIf) { + self.state.push_back(CallingStyleVisitorState::If); + syn::visit::visit_expr_if(self, i); + if !self.halt { + self.state.pop_back(); + } + } + + fn visit_expr_closure(&mut self, i: &'_ syn::ExprClosure) { + self.state.push_back(CallingStyleVisitorState::Closure); + syn::visit::visit_expr_closure(self, i); + if !self.halt { + self.state.pop_back(); + } + } + + fn visit_expr_call(&mut self, i: &'_ syn::ExprCall) { + syn::visit::visit_expr_call(self, i); + if let Expr::Path(p) = i.func.as_ref() { + if let Some(last) = p.path.segments.last() { + if is_match( + &self.reference.identifier, + &last.ident, + &self.reference.references, + ) { + self.halt = true; + } + } + } + } + + // to validate this, we first check if the name is the same and then compare it + // against any of the references we are holding + fn visit_expr_method_call(&mut self, i: &'_ syn::ExprMethodCall) { + if is_match( + &self.reference.identifier, + &i.method, + &self.reference.references, + ) { + self.halt = true; + } + + syn::visit::visit_expr_method_call(self, i); + } +} + +/// Check if some ident referenced by `check` is calling the `target` by +/// looking it up in the list of known `ranges`. +fn is_match(target: &Identifier, check: &syn::Ident, ranges: &[Range]) -> bool { + if target.equals_ident(check, false) { + let span = check.span(); + // syn is 1-indexed, range is not + for reference in ranges { + if reference.start.line != span.start().line as u32 - 1 { + continue; + } + + if reference.start.character != span.start().column as u32 { + continue; + } + + if reference.end.line != span.end().line as u32 - 1 { + continue; + } + + if reference.end.character != span.end().column as u32 { + continue; + } + + // match, just exit the visitor + return true; + } + } + + false +} diff --git a/turbopack/crates/turbo-tasks-auto-hash-map/Cargo.toml b/turbopack/crates/turbo-tasks-auto-hash-map/Cargo.toml new file mode 100644 index 0000000000000..0c2d4a8579ae5 --- /dev/null +++ b/turbopack/crates/turbo-tasks-auto-hash-map/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "auto-hash-map" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lints] +workspace = true + +[dependencies] +serde = { workspace = true, features = ["derive"] } +smallvec = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-auto-hash-map/src/lib.rs b/turbopack/crates/turbo-tasks-auto-hash-map/src/lib.rs new file mode 100644 index 0000000000000..17361c57a72c8 --- /dev/null +++ b/turbopack/crates/turbo-tasks-auto-hash-map/src/lib.rs @@ -0,0 +1,14 @@ +#![feature(hash_raw_entry)] + +pub mod map; +pub mod set; + +pub use map::AutoMap; +pub use set::AutoSet; + +// Values based on data from https://github.com/yegor256/micromap#benchmark + +/// Maximum size of list variant. Must convert to HashMap when bigger. +pub const MAX_LIST_SIZE: usize = 32; +/// Minimum size of HashMap variant. Must convert to List when smaller. +pub const MIN_HASH_SIZE: usize = 16; diff --git a/turbopack/crates/turbo-tasks-auto-hash-map/src/map.rs b/turbopack/crates/turbo-tasks-auto-hash-map/src/map.rs new file mode 100644 index 0000000000000..5285285fcea17 --- /dev/null +++ b/turbopack/crates/turbo-tasks-auto-hash-map/src/map.rs @@ -0,0 +1,859 @@ +use std::{ + borrow::Borrow, + collections::{hash_map::RandomState, HashMap}, + fmt::{Debug, Formatter}, + hash::{BuildHasher, Hash}, + marker::PhantomData, +}; + +use serde::{ + de::{MapAccess, Visitor}, + ser::SerializeMap, + Deserialize, Deserializer, Serialize, Serializer, +}; +use smallvec::SmallVec; + +use crate::{MAX_LIST_SIZE, MIN_HASH_SIZE}; + +#[derive(Clone)] +pub enum AutoMap { + List(SmallVec<[(K, V); I]>), + Map(Box>), +} + +impl Default for AutoMap { + fn default() -> Self { + Self::List(Default::default()) + } +} + +impl Debug for AutoMap { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_map().entries(self.iter()).finish() + } +} + +impl AutoMap { + /// see [HashMap::new](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.new) + pub const fn new() -> Self { + AutoMap::List(SmallVec::new_const()) + } + + /// see [HashMap::with_capacity](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.with_capacity) + pub fn with_capacity(capacity: usize) -> Self { + if capacity < MAX_LIST_SIZE { + AutoMap::List(SmallVec::with_capacity(capacity)) + } else { + AutoMap::Map(Box::new(HashMap::with_capacity_and_hasher( + capacity, + Default::default(), + ))) + } + } +} + +impl AutoMap { + /// see [HashMap::with_hasher](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.with_hasher) + pub const fn with_hasher() -> Self { + AutoMap::List(SmallVec::new_const()) + } + + /// see [HashMap::with_capacity_and_hasher](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.with_capacity_and_hasher) + pub fn with_capacity_and_hasher(capacity: usize, hasher: H) -> Self { + if capacity <= MAX_LIST_SIZE { + AutoMap::List(SmallVec::with_capacity(capacity)) + } else { + AutoMap::Map(Box::new(HashMap::with_capacity_and_hasher( + capacity, hasher, + ))) + } + } + + /// see [HashMap::clear](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.clear) + pub fn clear(&mut self) { + match self { + AutoMap::List(list) => list.clear(), + AutoMap::Map(map) => map.clear(), + } + } +} + +impl AutoMap { + fn convert_to_map(&mut self) -> &mut HashMap { + if let AutoMap::List(list) = self { + let mut map = HashMap::with_capacity_and_hasher(MAX_LIST_SIZE * 2, Default::default()); + map.extend(list.drain(..)); + *self = AutoMap::Map(Box::new(map)); + } + if let AutoMap::Map(map) = self { + map + } else { + unreachable!() + } + } + + fn convert_to_list(&mut self) -> &mut SmallVec<[(K, V); I]> { + if let AutoMap::Map(map) = self { + let mut list = SmallVec::with_capacity(MAX_LIST_SIZE); + list.extend(map.drain()); + *self = AutoMap::List(list); + } + if let AutoMap::List(list) = self { + list + } else { + unreachable!() + } + } + + /// see [HashMap::insert](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.insert) + pub fn insert(&mut self, key: K, value: V) -> Option { + match self { + AutoMap::List(list) => { + for (k, v) in list.iter_mut() { + if *k == key { + return Some(std::mem::replace(v, value)); + } + } + if list.len() >= MAX_LIST_SIZE { + let map = self.convert_to_map(); + map.insert(key, value); + } else { + list.push((key, value)); + } + None + } + AutoMap::Map(map) => map.insert(key, value), + } + } + + /// see [HashMap::remove](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.remove) + pub fn remove(&mut self, key: &K) -> Option { + match self { + AutoMap::List(list) => { + for i in 0..list.len() { + if list[i].0 == *key { + return Some(list.swap_remove(i).1); + } + } + None + } + AutoMap::Map(map) => map.remove(key), + } + } + + /// see [HashMap::extend](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.extend) + pub fn extend(&mut self, iter: impl IntoIterator) { + let iter = iter.into_iter(); + match self { + AutoMap::List(list) => { + let (lower, _) = iter.size_hint(); + if list.len() + lower > MAX_LIST_SIZE { + let map = self.convert_to_map(); + map.extend(iter); + // The hint is not enforced + if map.len() < MIN_HASH_SIZE { + self.convert_to_list(); + } + return; + } + for (k, v) in iter { + self.insert(k, v); + } + } + AutoMap::Map(map) => { + map.extend(iter); + } + } + } + + /// see [HashMap::entry](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.entry) + pub fn entry(&mut self, key: K) -> Entry<'_, K, V, H, I> { + let this = self as *mut Self; + match self { + AutoMap::List(list) => match list.iter().position(|(k, _)| *k == key) { + Some(index) => Entry::Occupied(OccupiedEntry::List { list, index }), + None => Entry::Vacant(VacantEntry::List { this, list, key }), + }, + AutoMap::Map(map) => match map.entry(key) { + std::collections::hash_map::Entry::Occupied(entry) => { + Entry::Occupied(OccupiedEntry::Map { this, entry }) + } + std::collections::hash_map::Entry::Vacant(entry) => { + Entry::Vacant(VacantEntry::Map(entry)) + } + }, + } + } + + pub fn raw_entry_mut(&mut self, key: &Q) -> RawEntry<'_, K, V, H, I> + where + K: Borrow, + Q: Hash + Eq + ?Sized, + { + let this = self as *mut Self; + match self { + AutoMap::List(list) => match list.iter().position(|(k, _)| k.borrow() == key) { + Some(index) => RawEntry::Occupied(OccupiedRawEntry::List { list, index }), + None => RawEntry::Vacant(VacantRawEntry::List { this, list }), + }, + AutoMap::Map(map) => match map.raw_entry_mut().from_key(key) { + std::collections::hash_map::RawEntryMut::Occupied(entry) => { + RawEntry::Occupied(OccupiedRawEntry::Map { this, entry }) + } + std::collections::hash_map::RawEntryMut::Vacant(entry) => { + RawEntry::Vacant(VacantRawEntry::Map(entry)) + } + }, + } + } + + /// see [HashMap::retain](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.retain) + pub fn retain(&mut self, mut f: F) + where + F: FnMut(&K, &mut V) -> bool, + { + match self { + AutoMap::List(list) => { + // Don't use `Vec::retain`, as that uses a slower algorithm to maintain order, + // which we don't care about + let mut len = list.len(); + let mut i = 0; + while i < len { + let (key, value) = &mut list[i]; + if !f(key, value) { + list.swap_remove(i); + len -= 1; + } else { + i += 1; + } + } + } + AutoMap::Map(map) => { + map.retain(f); + } + } + } + + /// see [HashMap::shrink_to_fit](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.shrink_to_fit) + pub fn shrink_to_fit(&mut self) { + match self { + AutoMap::List(list) => list.shrink_to_fit(), + AutoMap::Map(map) => { + if map.len() <= MAX_LIST_SIZE { + let mut list = SmallVec::with_capacity(map.len()); + list.extend(map.drain()); + *self = AutoMap::List(list); + } else { + map.shrink_to_fit(); + } + } + } + } + + pub fn shrink_amortized(&mut self) { + match self { + AutoMap::List(list) => { + if list.capacity() > list.len() * 3 { + list.shrink_to_fit(); + } + } + AutoMap::Map(map) => { + if map.len() <= MIN_HASH_SIZE { + let mut list = SmallVec::with_capacity(map.len()); + list.extend(map.drain()); + *self = AutoMap::List(list); + } else if map.capacity() > map.len() * 3 { + map.shrink_to_fit(); + } + } + } + } +} + +impl AutoMap { + /// see [HashMap::get](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.get) + pub fn get(&self, key: &Q) -> Option<&V> + where + K: Borrow, + Q: Hash + Eq + ?Sized, + { + match self { + AutoMap::List(list) => { + list.iter() + .find_map(|(k, v)| if *k.borrow() == *key { Some(v) } else { None }) + } + AutoMap::Map(map) => map.get(key), + } + } + + /// see [HashMap::get_mut](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.get_mut) + pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { + match self { + AutoMap::List(list) => { + list.iter_mut() + .find_map(|(k, v)| if *k == *key { Some(v) } else { None }) + } + AutoMap::Map(map) => map.get_mut(key), + } + } + + /// see [HashMap::contains_key](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.contains_key) + pub fn contains_key(&self, key: &K) -> bool { + match self { + AutoMap::List(list) => list.iter().any(|(k, _)| *k == *key), + AutoMap::Map(map) => map.contains_key(key), + } + } +} + +impl AutoMap { + /// see [HashMap::iter](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.iter) + pub fn iter(&self) -> Iter<'_, K, V> { + match self { + AutoMap::List(list) => Iter::List(list.iter()), + AutoMap::Map(map) => Iter::Map(map.iter()), + } + } + /// see [HashMap::iter_mut](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.iter_mut) + pub fn iter_mut(&mut self) -> IterMut<'_, K, V> { + match self { + AutoMap::List(list) => IterMut::List(list.iter_mut()), + AutoMap::Map(map) => IterMut::Map(map.iter_mut()), + } + } + + /// see [HashMap::is_empty](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.is_empty) + pub fn is_empty(&self) -> bool { + match self { + AutoMap::List(list) => list.is_empty(), + AutoMap::Map(map) => map.is_empty(), + } + } + + /// see [HashMap::len](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.len) + pub fn len(&self) -> usize { + match self { + AutoMap::List(list) => list.len(), + AutoMap::Map(map) => map.len(), + } + } + + /// see [HashMap::values_mut](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.values_mut) + pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> { + match self { + AutoMap::List(list) => ValuesMut::List(list.iter_mut()), + AutoMap::Map(map) => ValuesMut::Map(map.values_mut()), + } + } + + /// see [HashMap::values](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.values) + pub fn values(&self) -> Values<'_, K, V> { + match self { + AutoMap::List(list) => Values::List(list.iter()), + AutoMap::Map(map) => Values::Map(map.values()), + } + } + + /// see [HashMap::into_values](https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.into_values) + pub fn into_values(self) -> IntoValues { + match self { + AutoMap::List(list) => IntoValues::List(list.into_iter()), + AutoMap::Map(map) => IntoValues::Map(map.into_values()), + } + } +} + +impl IntoIterator for AutoMap { + type Item = (K, V); + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + match self { + AutoMap::List(list) => IntoIter::List(list.into_iter()), + AutoMap::Map(map) => IntoIter::Map(map.into_iter()), + } + } +} + +impl<'a, K, V, H, const I: usize> IntoIterator for &'a AutoMap { + type Item = (&'a K, &'a V); + type IntoIter = Iter<'a, K, V>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +pub enum Iter<'a, K, V> { + List(std::slice::Iter<'a, (K, V)>), + Map(std::collections::hash_map::Iter<'a, K, V>), +} + +impl<'a, K, V> Iterator for Iter<'a, K, V> { + type Item = (&'a K, &'a V); + + // This clippy lint doesn't account for lifetimes + #[allow(clippy::map_identity)] + fn next(&mut self) -> Option { + match self { + Iter::List(iter) => iter.next().map(|(k, v)| (k, v)), + Iter::Map(iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + match self { + Iter::List(iter) => iter.size_hint(), + Iter::Map(iter) => iter.size_hint(), + } + } +} + +impl<'a, K, V> Clone for Iter<'a, K, V> { + fn clone(&self) -> Self { + match self { + Iter::List(iter) => Iter::List(iter.clone()), + Iter::Map(iter) => Iter::Map(iter.clone()), + } + } +} + +pub enum IterMut<'a, K, V> { + List(std::slice::IterMut<'a, (K, V)>), + Map(std::collections::hash_map::IterMut<'a, K, V>), +} + +impl<'a, K, V> Iterator for IterMut<'a, K, V> { + type Item = (&'a K, &'a mut V); + + fn next(&mut self) -> Option { + match self { + IterMut::List(iter) => iter.next().map(|(k, v)| (&*k, v)), + IterMut::Map(iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + match self { + IterMut::List(iter) => iter.size_hint(), + IterMut::Map(iter) => iter.size_hint(), + } + } +} + +pub enum IntoIter { + List(smallvec::IntoIter<[(K, V); I]>), + Map(std::collections::hash_map::IntoIter), +} + +impl Iterator for IntoIter { + type Item = (K, V); + + fn next(&mut self) -> Option { + match self { + IntoIter::List(iter) => iter.next(), + IntoIter::Map(iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + match self { + IntoIter::List(iter) => iter.size_hint(), + IntoIter::Map(iter) => iter.size_hint(), + } + } +} + +pub enum Values<'a, K, V> { + List(std::slice::Iter<'a, (K, V)>), + Map(std::collections::hash_map::Values<'a, K, V>), +} + +impl<'a, K, V> Iterator for Values<'a, K, V> { + type Item = &'a V; + + fn next(&mut self) -> Option { + match self { + Values::List(iter) => iter.next().map(|(_, v)| v), + Values::Map(iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + match self { + Values::List(iter) => iter.size_hint(), + Values::Map(iter) => iter.size_hint(), + } + } +} + +pub enum ValuesMut<'a, K, V> { + List(std::slice::IterMut<'a, (K, V)>), + Map(std::collections::hash_map::ValuesMut<'a, K, V>), +} + +impl<'a, K, V> Iterator for ValuesMut<'a, K, V> { + type Item = &'a mut V; + + fn next(&mut self) -> Option { + match self { + ValuesMut::List(iter) => iter.next().map(|(_, v)| v), + ValuesMut::Map(iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + match self { + ValuesMut::List(iter) => iter.size_hint(), + ValuesMut::Map(iter) => iter.size_hint(), + } + } +} + +pub enum IntoValues { + List(smallvec::IntoIter<[(K, V); I]>), + Map(std::collections::hash_map::IntoValues), +} + +impl Iterator for IntoValues { + type Item = V; + + fn next(&mut self) -> Option { + match self { + IntoValues::List(iter) => iter.next().map(|(_, v)| v), + IntoValues::Map(iter) => iter.next(), + } + } + + fn size_hint(&self) -> (usize, Option) { + match self { + IntoValues::List(iter) => iter.size_hint(), + IntoValues::Map(iter) => iter.size_hint(), + } + } +} + +pub enum Entry<'a, K, V, H, const I: usize> { + Occupied(OccupiedEntry<'a, K, V, H, I>), + Vacant(VacantEntry<'a, K, V, H, I>), +} + +impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize> Entry<'a, K, V, H, I> { + /// see [HashMap::Entry::or_insert](https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_insert) + pub fn or_insert_with(self, default: impl FnOnce() -> V) -> &'a mut V { + match self { + Entry::Occupied(entry) => entry.into_mut(), + Entry::Vacant(entry) => entry.insert(default()), + } + } +} + +impl<'a, K: Eq + Hash, V: Default, H: BuildHasher + Default + 'a, const I: usize> + Entry<'a, K, V, H, I> +{ + /// see [HashMap::Entry::or_default](https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_default) + pub fn or_default(self) -> &'a mut V { + match self { + Entry::Occupied(entry) => entry.into_mut(), + Entry::Vacant(entry) => entry.insert(Default::default()), + } + } +} + +pub enum OccupiedEntry<'a, K, V, H, const I: usize> { + List { + list: &'a mut SmallVec<[(K, V); I]>, + index: usize, + }, + Map { + this: *mut AutoMap, + entry: std::collections::hash_map::OccupiedEntry<'a, K, V>, + }, +} + +impl<'a, K: Eq + Hash, V, H: BuildHasher, const I: usize> OccupiedEntry<'a, K, V, H, I> { + /// see [HashMap::OccupiedEntry::get_mut](https://doc.rust-lang.org/std/collections/hash_map/enum.OccupiedEntry.html#method.get_mut) + pub fn get_mut(&mut self) -> &mut V { + match self { + OccupiedEntry::List { list, index } => &mut list[*index].1, + OccupiedEntry::Map { entry, .. } => entry.get_mut(), + } + } + + /// see [HashMap::OccupiedEntry::into_mut](https://doc.rust-lang.org/std/collections/hash_map/enum.OccupiedEntry.html#method.into_mut) + pub fn into_mut(self) -> &'a mut V { + match self { + OccupiedEntry::List { list, index } => &mut list[index].1, + OccupiedEntry::Map { entry, .. } => entry.into_mut(), + } + } +} + +impl<'a, K: Eq + Hash, V, H: BuildHasher + Default, const I: usize> OccupiedEntry<'a, K, V, H, I> { + /// see [HashMap::OccupiedEntry::remove](https://doc.rust-lang.org/std/collections/hash_map/enum.OccupiedEntry.html#method.remove) + pub fn remove(self) -> V { + match self { + OccupiedEntry::List { list, index } => list.swap_remove(index).1, + OccupiedEntry::Map { entry, this: _ } => entry.remove(), + } + } +} + +pub enum VacantEntry<'a, K, V, H, const I: usize> { + List { + this: *mut AutoMap, + list: &'a mut SmallVec<[(K, V); I]>, + key: K, + }, + Map(std::collections::hash_map::VacantEntry<'a, K, V>), +} + +impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize> + VacantEntry<'a, K, V, H, I> +{ + /// see [HashMap::VacantEntry::insert](https://doc.rust-lang.org/std/collections/hash_map/enum.VacantEntry.html#method.insert) + pub fn insert(self, value: V) -> &'a mut V { + match self { + VacantEntry::List { this, list, key } => { + if list.len() >= MAX_LIST_SIZE { + let this = unsafe { &mut *this }; + this.convert_to_map().entry(key).or_insert(value) + } else { + list.push((key, value)); + &mut list.last_mut().unwrap().1 + } + } + VacantEntry::Map(entry) => entry.insert(value), + } + } +} + +pub enum RawEntry<'a, K, V, H, const I: usize> { + Occupied(OccupiedRawEntry<'a, K, V, H, I>), + Vacant(VacantRawEntry<'a, K, V, H, I>), +} + +pub enum OccupiedRawEntry<'a, K, V, H, const I: usize> { + List { + list: &'a mut SmallVec<[(K, V); I]>, + index: usize, + }, + Map { + this: *mut AutoMap, + entry: std::collections::hash_map::RawOccupiedEntryMut<'a, K, V, H>, + }, +} + +impl<'a, K: Eq + Hash, V, H: BuildHasher, const I: usize> OccupiedRawEntry<'a, K, V, H, I> { + /// see [HashMap::RawOccupiedEntryMut::get_mut](https://doc.rust-lang.org/std/collections/hash_map/struct.RawOccupiedEntryMut.html#method.get_mut) + pub fn get_mut(&mut self) -> &mut V { + match self { + OccupiedRawEntry::List { list, index } => &mut list[*index].1, + OccupiedRawEntry::Map { entry, .. } => entry.get_mut(), + } + } + + /// see [HashMap::RawOccupiedEntryMut::into_mut](https://doc.rust-lang.org/std/collections/hash_map/struct.RawOccupiedEntryMut.html#method.into_mut) + pub fn into_mut(self) -> &'a mut V { + match self { + OccupiedRawEntry::List { list, index } => &mut list[index].1, + OccupiedRawEntry::Map { entry, .. } => entry.into_mut(), + } + } +} + +impl<'a, K: Eq + Hash, V, H: BuildHasher + Default, const I: usize> + OccupiedRawEntry<'a, K, V, H, I> +{ + /// see [HashMap::OccupiedEntry::remove](https://doc.rust-lang.org/std/collections/hash_map/enum.OccupiedEntry.html#method.remove) + pub fn remove(self) -> V { + match self { + OccupiedRawEntry::List { list, index } => list.swap_remove(index).1, + OccupiedRawEntry::Map { entry, this: _ } => entry.remove(), + } + } +} + +pub enum VacantRawEntry<'a, K, V, H, const I: usize> { + List { + this: *mut AutoMap, + list: &'a mut SmallVec<[(K, V); I]>, + }, + Map(std::collections::hash_map::RawVacantEntryMut<'a, K, V, H>), +} + +impl<'a, K: Eq + Hash, V, H: BuildHasher + Default + 'a, const I: usize> + VacantRawEntry<'a, K, V, H, I> +{ + /// see [HashMap::RawVacantEntryMut::insert](https://doc.rust-lang.org/std/collections/hash_map/struct.RawVacantEntryMut.html#method.insert) + pub fn insert(self, key: K, value: V) -> &'a mut V { + match self { + VacantRawEntry::List { this, list } => { + if list.len() >= MAX_LIST_SIZE { + let this = unsafe { &mut *this }; + this.convert_to_map().entry(key).or_insert(value) + } else { + list.push((key, value)); + &mut list.last_mut().unwrap().1 + } + } + VacantRawEntry::Map(entry) => entry.insert(key, value).1, + } + } +} + +impl Serialize for AutoMap +where + K: Eq + Hash + Serialize, + V: Serialize, + H: BuildHasher, +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + AutoMap::List(list) => { + let mut map = serializer.serialize_map(Some(list.len()))?; + for (k, v) in list { + map.serialize_entry(k, v)?; + } + map.end() + } + AutoMap::Map(map) => (**map).serialize(serializer), + } + } +} + +impl<'de, K, V, H, const I: usize> Deserialize<'de> for AutoMap +where + K: Eq + Hash + Deserialize<'de>, + V: Deserialize<'de>, + H: BuildHasher + Default, +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct AutoMapVisitor { + phantom: PhantomData>, + } + + impl<'de, K, V, H, const I: usize> Visitor<'de> for AutoMapVisitor + where + K: Eq + Hash + Deserialize<'de>, + V: Deserialize<'de>, + H: BuildHasher + Default, + { + type Value = AutoMap; + + fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result { + formatter.write_str("a map") + } + + fn visit_map(self, mut m: M) -> Result + where + M: MapAccess<'de>, + { + if let Some(size) = m.size_hint() { + if size < MAX_LIST_SIZE { + let mut list = SmallVec::with_capacity(size); + while let Some((k, v)) = m.next_entry()? { + list.push((k, v)); + } + return Ok(AutoMap::List(list)); + } else { + let mut map = + Box::new(HashMap::with_capacity_and_hasher(size, H::default())); + while let Some((k, v)) = m.next_entry()? { + map.insert(k, v); + } + return Ok(AutoMap::Map(map)); + } + } + let mut map = AutoMap::with_hasher(); + while let Some((k, v)) = m.next_entry()? { + map.insert(k, v); + } + Ok(map) + } + } + + deserializer.deserialize_map(AutoMapVisitor { + phantom: PhantomData::>, + }) + } +} + +impl PartialEq for AutoMap { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (AutoMap::Map(a), AutoMap::Map(b)) => a == b, + (AutoMap::List(a), b) => { + if a.len() != b.len() { + return false; + } + a.iter().all(|(k, v)| b.get(k) == Some(v)) + } + (a, AutoMap::List(b)) => { + if a.len() != b.len() { + return false; + } + b.iter().all(|(k, v)| a.get(k) == Some(v)) + } + } + } +} + +impl Eq for AutoMap +where + K: Eq, + V: Eq, +{ +} + +impl FromIterator<(K, V)> for AutoMap +where + K: Eq + Hash, + H: BuildHasher + Default, +{ + fn from_iter>(iter: T) -> Self { + let iter = iter.into_iter(); + let (lower, _) = iter.size_hint(); + if lower > MAX_LIST_SIZE { + let map = iter.collect::>(); + // The hint is not enforced + if map.len() < MIN_HASH_SIZE { + return AutoMap::List(map.into_iter().collect()); + } + return AutoMap::Map(Box::new(map)); + } + let mut map = AutoMap::with_hasher(); + for (k, v) in iter { + map.insert(k, v); + } + map + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_auto_map() { + let mut map = AutoMap::new(); + for i in 0..MAX_LIST_SIZE * 2 { + map.insert(i, i); + } + for i in 0..MAX_LIST_SIZE * 2 { + assert_eq!(map.get(&i), Some(&i)); + } + assert_eq!(map.get(&(MAX_LIST_SIZE * 2)), None); + for i in 0..MAX_LIST_SIZE * 2 { + assert_eq!(map.remove(&(MAX_LIST_SIZE * 2)), None); + assert_eq!(map.remove(&i), Some(i)); + } + assert_eq!(map.remove(&(MAX_LIST_SIZE * 2)), None); + } +} diff --git a/turbopack/crates/turbo-tasks-auto-hash-map/src/set.rs b/turbopack/crates/turbo-tasks-auto-hash-map/src/set.rs new file mode 100644 index 0000000000000..a211d8eb3d2b9 --- /dev/null +++ b/turbopack/crates/turbo-tasks-auto-hash-map/src/set.rs @@ -0,0 +1,264 @@ +use std::{ + collections::hash_map::RandomState, + fmt::Debug, + hash::{BuildHasher, Hash}, + marker::PhantomData, +}; + +use serde::{Deserialize, Serialize}; + +use crate::AutoMap; + +#[derive(Clone)] +pub struct AutoSet { + map: AutoMap, +} + +impl Default for AutoSet { + fn default() -> Self { + Self { + map: Default::default(), + } + } +} + +impl Debug for AutoSet { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_set().entries(self.iter()).finish() + } +} + +impl AutoSet { + /// see [HashSet::new](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.new) + pub const fn new() -> Self { + Self { + map: AutoMap::new(), + } + } + + /// see [HashSet::with_capacity](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.with_capacity) + pub fn with_capacity(capacity: usize) -> Self { + Self { + map: AutoMap::with_capacity(capacity), + } + } +} + +impl AutoSet { + /// see [HashSet::with_hasher](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.with_hasher) + pub const fn with_hasher() -> Self { + Self { + map: AutoMap::with_hasher(), + } + } + + /// see [HashSet::with_capacity_and_hasher](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.with_capacity_and_hasher) + pub fn with_capacity_and_hasher(capacity: usize, hasher: H) -> Self { + Self { + map: AutoMap::with_capacity_and_hasher(capacity, hasher), + } + } + + /// see [HashSet::clear](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.clear) + pub fn clear(&mut self) { + self.map.clear(); + } +} + +impl AutoSet { + /// see [HashSet::insert](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.insert) + pub fn insert(&mut self, key: K) -> bool { + self.map.insert(key, ()).is_none() + } + + /// see [HashSet::remove](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.remove) + pub fn remove(&mut self, key: &K) -> bool { + self.map.remove(key).is_some() + } + + /// see [HashSet::extend](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.extend) + pub fn extend(&mut self, iter: impl IntoIterator) { + self.map.extend(iter.into_iter().map(|item| (item, ()))) + } + + /// see [HashSet::shrink_to_fit](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.shrink_to_fit) + pub fn shrink_to_fit(&mut self) { + self.map.shrink_to_fit(); + } + + /// see [HashSet::contains](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.contains) + pub fn contains(&self, key: &K) -> bool { + self.map.contains_key(key) + } +} + +impl AutoSet { + /// see [HashSet::len](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.len) + pub fn len(&self) -> usize { + self.map.len() + } + + /// see [HashSet::is_empty](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.is_empty) + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + /// see [HashSet::iter](https://doc.rust-lang.org/std/collections/hash_set/struct.HashSet.html#method.iter) + pub fn iter(&self) -> Iter<'_, K> { + Iter(self.map.iter()) + } +} + +impl IntoIterator for AutoSet { + type Item = K; + type IntoIter = IntoIter; + + fn into_iter(self) -> Self::IntoIter { + IntoIter(self.map.into_iter()) + } +} + +impl<'a, K, H, const I: usize> IntoIterator for &'a AutoSet { + type Item = &'a K; + type IntoIter = Iter<'a, K>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +pub struct Iter<'a, K>(super::map::Iter<'a, K, ()>); + +impl<'a, K> Iterator for Iter<'a, K> { + type Item = &'a K; + + fn next(&mut self) -> Option { + self.0.next().map(|(k, _)| k) + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl<'a, K> Clone for Iter<'a, K> { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +pub struct IntoIter(super::map::IntoIter); + +impl Iterator for IntoIter { + type Item = K; + + fn next(&mut self) -> Option { + self.0.next().map(|(k, _)| k) + } + + fn size_hint(&self) -> (usize, Option) { + self.0.size_hint() + } +} + +impl Serialize for AutoSet +where + K: Serialize, + H: BuildHasher, +{ + fn serialize(&self, serializer: S) -> Result { + serializer.collect_seq(self.iter()) + } +} + +impl<'de, K, H, const I: usize> Deserialize<'de> for AutoSet +where + K: Deserialize<'de> + Hash + Eq, + H: BuildHasher + Default, +{ + fn deserialize>(deserializer: D) -> Result { + struct AutoSetVisitor(PhantomData>); + + impl<'de, K, H, const I: usize> serde::de::Visitor<'de> for AutoSetVisitor + where + K: Deserialize<'de> + Hash + Eq, + H: BuildHasher + Default, + { + type Value = AutoSet; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a set") + } + + fn visit_seq>( + self, + mut seq: A, + ) -> Result { + let mut set = if let Some(size) = seq.size_hint() { + AutoSet::with_capacity_and_hasher(size, H::default()) + } else { + AutoSet::with_hasher() + }; + while let Some(item) = seq.next_element()? { + set.insert(item); + } + Ok(set) + } + } + + deserializer.deserialize_seq(AutoSetVisitor(std::marker::PhantomData)) + } +} + +impl PartialEq for AutoSet { + fn eq(&self, other: &Self) -> bool { + self.map == other.map + } +} + +impl Eq for AutoSet {} + +impl FromIterator for AutoSet +where + K: Hash + Eq, + H: BuildHasher + Default, +{ + fn from_iter>(iter: T) -> Self { + Self { + map: AutoMap::from_iter(iter.into_iter().map(|item| (item, ()))), + } + } +} + +impl From<[K; N]> for AutoSet +where + K: Hash + Eq, + H: BuildHasher + Default, +{ + fn from(array: [K; N]) -> Self { + Self::from_iter(array) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::MAX_LIST_SIZE; + + #[test] + fn test_auto_set() { + let mut set = AutoSet::new(); + for i in 0..MAX_LIST_SIZE * 2 { + set.insert(i); + } + for i in 0..MAX_LIST_SIZE * 2 { + assert!(set.contains(&i)); + } + assert!(!set.contains(&(MAX_LIST_SIZE * 2))); + for i in 0..MAX_LIST_SIZE * 2 { + assert!(!set.remove(&(MAX_LIST_SIZE * 2))); + assert!(set.remove(&i)); + } + assert!(!set.remove(&(MAX_LIST_SIZE * 2))); + } +} diff --git a/turbopack/crates/turbo-tasks-build/Cargo.toml b/turbopack/crates/turbo-tasks-build/Cargo.toml new file mode 100644 index 0000000000000..10c91dfeb8798 --- /dev/null +++ b/turbopack/crates/turbo-tasks-build/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "turbo-tasks-build" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +cargo-lock = "8.0.2" +glob = "0.3.0" +quote = { workspace = true } +syn = { workspace = true, features = ["full"] } +turbo-tasks-macros-shared = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-build/src/lib.rs b/turbopack/crates/turbo-tasks-build/src/lib.rs new file mode 100644 index 0000000000000..266797b3a6130 --- /dev/null +++ b/turbopack/crates/turbo-tasks-build/src/lib.rs @@ -0,0 +1,602 @@ +use std::{ + collections::{HashMap, HashSet}, + env::{self, current_dir}, + fmt::{Display, Write}, + fs::read_dir, + path::{PathBuf, MAIN_SEPARATOR as PATH_SEP}, + sync::Arc, +}; + +use anyhow::{Context, Result}; +use glob::glob; +use quote::ToTokens; +use syn::{ + parse_quote, Attribute, Ident, Item, ItemEnum, ItemFn, ItemImpl, ItemMacro, ItemMod, + ItemStruct, ItemTrait, TraitItem, TraitItemMethod, +}; +use turbo_tasks_macros_shared::{ + get_impl_function_ident, get_native_function_ident, get_path_ident, + get_register_trait_methods_ident, get_register_value_type_ident, + get_trait_default_impl_function_ident, get_trait_impl_function_ident, get_trait_type_ident, + get_type_ident, GenericTypeInput, PrimitiveInput, +}; + +pub fn generate_register() { + println!("cargo:rerun-if-changed=build.rs"); + + let crate_dir = current_dir().unwrap(); + let workspace_dir = env::var_os("CARGO_WORKSPACE_DIR") + .map(PathBuf::from) + .unwrap_or_else(|| crate_dir.clone()); + let crate_name = env::var("CARGO_PKG_NAME").unwrap(); + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + + let src_dir = crate_dir.join("src"); + let examples_dir = crate_dir.join("examples"); + let tests_dir = crate_dir.join("tests"); + let benches_dir = crate_dir.join("benches"); + let cargo_lock_path = workspace_dir.join("Cargo.lock"); + + // TODO: use (ask @sokra) + let _lock = cargo_lock::Lockfile::load(cargo_lock_path).ok(); + + let mut entries = Vec::new(); + + let lib_entry = src_dir.join("lib.rs"); + if lib_entry.exists() { + entries.push(("register.rs".to_string(), lib_entry)); + } else { + let bin_entry = src_dir.join("main.rs"); + if bin_entry.exists() { + entries.push(("register.rs".to_string(), bin_entry)); + } + } + + if examples_dir.exists() { + for item in read_dir(examples_dir).unwrap() { + let item = item.unwrap(); + if item.file_type().unwrap().is_file() { + let name = item.file_name(); + let name = name.to_string_lossy(); + if name.ends_with(".rs") { + entries.push((format!("register_example_{name}"), item.path())); + } + } + } + } + + if tests_dir.exists() { + for item in read_dir(tests_dir).unwrap() { + let item = item.unwrap(); + if item.file_type().unwrap().is_file() { + let name = item.file_name(); + let name = name.to_string_lossy(); + if name.ends_with(".rs") { + entries.push((format!("register_test_{name}"), item.path())); + } + } + } + } + + if benches_dir.exists() { + let bench_mod = benches_dir.join("mod.rs"); + if bench_mod.is_file() { + let name = bench_mod.file_name().unwrap(); + let name = name.to_string_lossy(); + if name.ends_with(".rs") { + entries.push(("register_benches.rs".to_string(), bench_mod)); + } + } + } + + for (filename, entry) in entries { + // TODO hash src dir + let hash = "TODO"; + + let prefix = format!("{crate_name}@{hash}::"); + + let mut register_code = String::new(); + let mut values = HashMap::new(); + + let out_file = out_dir.join(filename); + + let mut queue = vec![QueueEntry { + file_path: entry, + mod_path: "".to_string(), + attributes: Vec::new(), + }]; + + while let Some(QueueEntry { + file_path, + mod_path, + attributes, + }) = queue.pop() + { + println!("cargo:rerun-if-changed={}", file_path.to_string_lossy()); + let src = std::fs::read_to_string(&file_path).unwrap(); + + let mut ctx = RegisterContext { + queue: &mut queue, + + file_path: &file_path, + prefix: &prefix, + mod_path, + attributes, + + register: &mut register_code, + values: &mut values, + }; + + match syn::parse_file(&src) + .with_context(|| format!("failed to parse {}", file_path.display())) + { + Ok(file) => { + for item in file.items { + ctx.process_item(&item).unwrap(); + } + } + Err(err) => println!("{}", err), + } + } + + let mut values_code = String::new(); + for ((mod_path, ident), entry) in values { + for attribute in &entry.attributes { + values_code.push_str(attribute); + } + writeln!( + values_code, + "crate{}::{}({}, #[allow(unused_variables)] |value| {{", + mod_path, + get_register_value_type_ident(&ident), + entry.global_name, + ) + .unwrap(); + for trait_ident in entry.trait_idents { + writeln!( + values_code, + " crate{}::{}(value);", + mod_path, + get_register_trait_methods_ident(&trait_ident, &ident), + ) + .unwrap(); + } + writeln!(values_code, "}});").unwrap(); + } + + let code = format!( + "{{\nstatic ONCE: std::sync::Once = std::sync::Once::new();\nONCE.call_once(|| \ + {{\n{register_code}{values_code}}});\n}}\n" + ); + std::fs::write(out_file, code).unwrap(); + + // println!("cargo:warning={}", out_file.display()); + // for line in code.lines() { + // println!("cargo:warning={line}"); + // } + } +} + +pub fn rerun_if_glob(globs: &str, root: &str) { + let cwd = env::current_dir().unwrap(); + let globs = cwd.join(globs.replace('/', PATH_SEP.to_string().as_str())); + let root = cwd.join(root.replace('/', PATH_SEP.to_string().as_str())); + println!("cargo:rerun-if-changed={}", root.display()); + let mut seen = HashSet::from([root]); + for entry in glob(globs.to_str().unwrap()).unwrap() { + let path = entry.unwrap(); + for ancestor in path.ancestors() { + if seen.insert(ancestor.to_owned()) { + println!("cargo:rerun-if-changed={}", ancestor.display()); + } else { + break; + } + } + } +} + +/// (mod_path, type_ident) +type ValueKey = (String, Ident); +/// (global_name, trait_register_fns) +struct ValueEntry { + attributes: Vec>, + global_name: String, + trait_idents: Vec, +} + +struct QueueEntry { + /// The on-disk path to the file representing this module. + file_path: PathBuf, + /// The `syn::Path`-style representation of the module. Each component is + /// separated by `::`. + mod_path: String, + /// Attributes (`#[cfg(...)]`) applied to the `ItemMod`. + attributes: Vec>, +} + +struct RegisterContext<'a> { + queue: &'a mut Vec, + + file_path: &'a PathBuf, + mod_path: String, + attributes: Vec>, + prefix: &'a str, + + register: &'a mut String, + values: &'a mut HashMap, +} + +impl<'a> RegisterContext<'a> { + fn process_item(&mut self, item: &Item) -> Result<()> { + match item { + Item::Enum(enum_item) => self.process_enum(enum_item), + Item::Fn(fn_item) => self.process_fn(fn_item), + Item::Impl(impl_item) => self.process_impl(impl_item), + Item::Mod(mod_item) => self.process_mod(mod_item), + Item::Struct(struct_item) => self.process_struct(struct_item), + Item::Trait(trait_item) => self.process_trait(trait_item), + Item::Macro(macro_item) => self.process_macro(macro_item), + _ => Ok(()), + } + } + + fn process_enum(&mut self, item: &ItemEnum) -> Result<()> { + self.with_cfg_attrs(&item.attrs, move |this| this.process_enum_inner(item)) + } + + fn process_enum_inner(&mut self, enum_item: &ItemEnum) -> Result<()> { + if has_turbo_attribute(&enum_item.attrs, "value") { + self.add_value(&enum_item.ident); + self.add_value_debug_impl(&enum_item.ident); + } + Ok(()) + } + + fn process_fn(&mut self, item: &ItemFn) -> Result<()> { + self.with_cfg_attrs(&item.attrs, move |this| this.process_fn_inner(item)) + } + + fn process_fn_inner(&mut self, fn_item: &ItemFn) -> Result<()> { + if has_turbo_attribute(&fn_item.attrs, "function") { + let ident = &fn_item.sig.ident; + let type_ident = get_native_function_ident(ident); + + self.register(type_ident, self.get_global_name(&[ident]))?; + } + Ok(()) + } + + fn process_impl(&mut self, item: &ItemImpl) -> Result<()> { + self.with_cfg_attrs(&item.attrs, move |this| this.process_impl_inner(item)) + } + + fn process_impl_inner(&mut self, impl_item: &ItemImpl) -> Result<()> { + if has_turbo_attribute(&impl_item.attrs, "value_impl") { + let struct_ident = get_type_ident(&impl_item.self_ty).unwrap(); + + let trait_ident = impl_item + .trait_ + .as_ref() + .map(|(_, trait_path, _)| get_path_ident(trait_path)); + + if let Some(trait_ident) = &trait_ident { + self.add_value_trait(&struct_ident, trait_ident); + } + + for item in &impl_item.items { + if let syn::ImplItem::Method(method_item) = item { + // TODO: if method_item.attrs.iter().any(|a| + // is_attribute(a, + // "function")) { + let method_ident = &method_item.sig.ident; + let function_type_ident = if let Some(trait_ident) = &trait_ident { + get_trait_impl_function_ident(&struct_ident, trait_ident, method_ident) + } else { + get_impl_function_ident(&struct_ident, method_ident) + }; + + let global_name = if let Some(trait_ident) = &trait_ident { + self.get_global_name(&[&struct_ident, trait_ident, method_ident]) + } else { + self.get_global_name(&[&struct_ident, method_ident]) + }; + + self.register(function_type_ident, global_name)?; + } + } + } + Ok(()) + } + + fn process_mod(&mut self, item: &ItemMod) -> Result<()> { + self.with_cfg_attrs(&item.attrs, move |this| this.process_mod_inner(item)) + } + + fn process_mod_inner(&mut self, mod_item: &ItemMod) -> Result<()> { + let child_mod_name = mod_item.ident.to_string(); + let child_mod_path = format!("{}::{}", self.mod_path, child_mod_name); + if let Some((_, items)) = &mod_item.content { + let parent_mod_path = std::mem::replace(&mut self.mod_path, child_mod_path); + for item in items { + self.process_item(item)?; + } + self.mod_path = parent_mod_path; + } else { + let parent_file_path = self.file_path.parent().unwrap(); + let direct = parent_file_path.join(format!("{child_mod_name}.rs")); + if direct.exists() { + self.queue.push(QueueEntry { + file_path: direct, + mod_path: child_mod_path, + attributes: self.attributes.clone(), + }); + } else { + let nested = parent_file_path.join(&child_mod_name).join("mod.rs"); + if nested.exists() { + self.queue.push(QueueEntry { + file_path: nested, + mod_path: child_mod_path, + attributes: self.attributes.clone(), + }); + } + } + } + Ok(()) + } + + fn process_struct(&mut self, item: &ItemStruct) -> Result<()> { + self.with_cfg_attrs(&item.attrs, move |this| this.process_struct_inner(item)) + } + + fn process_struct_inner(&mut self, struct_item: &ItemStruct) -> Result<()> { + if has_turbo_attribute(&struct_item.attrs, "value") { + self.add_value(&struct_item.ident); + self.add_value_debug_impl(&struct_item.ident); + } + Ok(()) + } + + fn process_trait(&mut self, item: &ItemTrait) -> Result<()> { + self.with_cfg_attrs(&item.attrs, move |this| this.process_trait_inner(item)) + } + + fn process_trait_inner(&mut self, trait_item: &ItemTrait) -> Result<()> { + if trait_item + .attrs + .iter() + .any(|a| is_turbo_attribute(a, "value_trait")) + { + let trait_ident = &trait_item.ident; + + for item in &trait_item.items { + if let TraitItem::Method(TraitItemMethod { + default: Some(_), + sig, + .. + }) = item + { + let method_ident = &sig.ident; + let function_type_ident = + get_trait_default_impl_function_ident(trait_ident, method_ident); + + self.register( + function_type_ident, + self.get_global_name(&[trait_ident, method_ident]), + )?; + } + } + + let trait_type_ident = get_trait_type_ident(trait_ident); + self.register(trait_type_ident, self.get_global_name(&[trait_ident]))?; + } + Ok(()) + } + + fn process_macro(&mut self, item: &ItemMacro) -> Result<()> { + self.with_cfg_attrs(&item.attrs, move |this| this.process_macro_inner(item)) + } + + fn process_macro_inner(&mut self, macro_item: &ItemMacro) -> Result<()> { + if macro_item + .mac + .path + .is_ident("__turbo_tasks_internal_primitive") + { + let input = macro_item.mac.tokens.clone(); + let input = syn::parse2::(input).unwrap(); + + let ty = input.ty; + let Some(ident) = get_type_ident(&ty) else { + return Ok(()); + }; + + self.add_value(&ident); + self.add_value_debug_impl(&ident); + self.add_value_default_impl(&ident); + } else if macro_item + .mac + .path + .is_ident("__turbo_tasks_internal_generic_type") + { + let input = macro_item.mac.tokens.clone(); + let input = syn::parse2::(input).unwrap(); + + let ty = input.ty; + let Some(ident) = get_type_ident(&ty) else { + return Ok(()); + }; + + // Generic types must implement `ValueDebug` manually, as there's currently no + // easy way to automate the process. + self.add_value(&ident); + } + + Ok(()) + } +} + +impl<'a> RegisterContext<'a> { + fn get_global_name(&self, parts: &[&Ident]) -> String { + format!( + "r##\"{}{}::{}\"##", + self.prefix, + self.mod_path, + parts + .iter() + .map(ToString::to_string) + .collect::>() + .join("::") + ) + } + + fn add_value(&mut self, ident: &Ident) { + let key: ValueKey = (self.mod_path.clone(), ident.clone()); + let value = ValueEntry { + attributes: self.attributes.clone(), + global_name: self.get_global_name(&[ident]), + trait_idents: Vec::new(), + }; + + assert!( + self.values.insert(key, value).is_none(), + "{} is declared more than once", + ident + ); + } + + fn add_value_debug_impl(&mut self, ident: &Ident) { + // register default debug impl generated by proc macro + self.register_debug_impl(ident).unwrap(); + self.add_value_trait( + ident, + &get_type_ident(&parse_quote! { + turbo_tasks::debug::ValueDebug + }) + .unwrap(), + ); + } + + fn add_value_default_impl(&mut self, ident: &Ident) { + // register default ValueDefault impl generated by proc macro + self.register_default_impl(ident).unwrap(); + self.add_value_trait( + ident, + &get_type_ident(&parse_quote! { + turbo_tasks::ValueDefault + }) + .unwrap(), + ); + } + + fn add_value_trait(&mut self, ident: &Ident, trait_ident: &Ident) { + let key: ValueKey = (self.mod_path.clone(), ident.clone()); + + let entry = self.values.get_mut(&key); + if entry.is_none() { + panic!( + "failed to add value trait {} to {} in {}. Did you try to implement a trait on a \ + Vc instead of its value?", + trait_ident, + ident, + self.file_path.display() + ); + } + entry.unwrap().trait_idents.push(trait_ident.clone()); + } + + fn register( + &mut self, + type_ident: impl Display, + global_name: impl Display, + ) -> std::fmt::Result { + for attribute in &self.attributes { + self.register.push_str(attribute); + } + writeln!( + self.register, + "crate{}::{}.register({});", + self.mod_path, type_ident, global_name + ) + } + + /// Declares a derive of the given trait and its methods. + fn register_impl( + &mut self, + ident: &Ident, + trait_ident: &Ident, + fn_names: &[&'static str], + ) -> std::fmt::Result { + for fn_name in fn_names { + let fn_ident = Ident::new(fn_name, ident.span()); + + let (impl_fn_ident, global_name) = ( + get_trait_impl_function_ident(ident, trait_ident, &fn_ident), + self.get_global_name(&[ident, trait_ident, &fn_ident]), + ); + + self.register(impl_fn_ident, global_name)?; + } + + Ok(()) + } + + /// Declares the default derive of the `ValueDebug` trait. + fn register_debug_impl(&mut self, ident: &Ident) -> std::fmt::Result { + self.register_impl( + ident, + &get_type_ident(&parse_quote! { + turbo_tasks::debug::ValueDebug + }) + .unwrap(), + &["dbg", "dbg_depth"], + ) + } + + /// Declares the default derive of the `ValueDefault` trait. + fn register_default_impl(&mut self, ident: &Ident) -> std::fmt::Result { + self.register_impl( + ident, + &get_type_ident(&parse_quote! { + turbo_tasks::ValueDefault + }) + .unwrap(), + &["value_default"], + ) + } + + fn with_cfg_attrs(&mut self, attrs: &[Attribute], func: impl FnOnce(&mut Self) -> T) -> T { + let orig_len = self.attributes.len(); + for attr in attrs.iter().filter(|a| is_cfg_attribute(a)) { + self.attributes + .push(Arc::new(attr.to_token_stream().to_string())); + } + let ret = func(self); + self.attributes.truncate(orig_len); + ret + } +} + +fn has_turbo_attribute(attrs: &[Attribute], name: &str) -> bool { + attrs.iter().any(|a| is_turbo_attribute(a, name)) +} + +fn is_turbo_attribute(attr: &Attribute, name: &str) -> bool { + let path = &attr.path; + if path.leading_colon.is_some() { + return false; + } + let mut iter = path.segments.iter(); + match iter.next() { + Some(seg) if seg.arguments.is_empty() && seg.ident == "turbo_tasks" => match iter.next() { + Some(seg) if seg.arguments.is_empty() && seg.ident == name => iter.next().is_none(), + _ => false, + }, + _ => false, + } +} + +fn is_cfg_attribute(attr: &Attribute) -> bool { + attr.path + .get_ident() + .is_some_and(|ident| ident == "cfg" || ident == "cfg_attr") +} diff --git a/turbopack/crates/turbo-tasks-bytes/Cargo.toml b/turbopack/crates/turbo-tasks-bytes/Cargo.toml new file mode 100644 index 0000000000000..657a9ebcdca38 --- /dev/null +++ b/turbopack/crates/turbo-tasks-bytes/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "turbo-tasks-bytes" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +bytes = { workspace = true } +futures = { workspace = true } +serde = { workspace = true } +serde_bytes = "0.11.9" +turbo-tasks = { workspace = true } + +[dev-dependencies] +serde_test = "1.0.157" + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-bytes/build.rs b/turbopack/crates/turbo-tasks-bytes/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbo-tasks-bytes/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbo-tasks-bytes/src/bytes.rs b/turbopack/crates/turbo-tasks-bytes/src/bytes.rs new file mode 100644 index 0000000000000..437b2e907f04e --- /dev/null +++ b/turbopack/crates/turbo-tasks-bytes/src/bytes.rs @@ -0,0 +1,120 @@ +use std::{ + ops::Deref, + str::{from_utf8, Utf8Error}, +}; + +use anyhow::Result; +use bytes::Bytes as CBytes; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +/// Bytes is a thin wrapper around [bytes::Bytes], implementing easy +/// conversion to/from, ser/de support, and Vc containers. +#[derive(Clone, Debug, Default)] +#[turbo_tasks::value(transparent, serialization = "custom")] +pub struct Bytes(#[turbo_tasks(trace_ignore)] CBytes); + +impl Bytes { + pub fn to_str(&self) -> Result<&'_ str, Utf8Error> { + from_utf8(&self.0) + } +} + +impl Serialize for Bytes { + fn serialize(&self, serializer: S) -> Result { + serde_bytes::Bytes::new(&self.0).serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Bytes { + fn deserialize>(deserializer: D) -> Result { + let bytes = serde_bytes::ByteBuf::deserialize(deserializer)?; + Ok(Bytes(bytes.into_vec().into())) + } +} + +impl Deref for Bytes { + type Target = CBytes; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +/// Types that implement From for Bytes {} +/// Unfortunately, we cannot just use the more generic `Into` without +/// running afoul of the `From for X` base case, causing conflicting impls. +pub trait IntoBytes: Into {} +impl IntoBytes for &'static [u8] {} +impl IntoBytes for &'static str {} +impl IntoBytes for Vec {} +impl IntoBytes for Box<[u8]> {} +impl IntoBytes for String {} + +impl From for Bytes { + fn from(value: T) -> Self { + Bytes(value.into()) + } +} + +impl From for Bytes { + fn from(value: CBytes) -> Self { + Bytes(value) + } +} + +impl From for CBytes { + fn from(value: Bytes) -> Self { + value.0 + } +} + +#[cfg(test)] +mod tests { + use bytes::Bytes as CBytes; + use serde_test::{assert_tokens, Token}; + + use super::Bytes; + impl PartialEq<&str> for Bytes { + fn eq(&self, other: &&str) -> bool { + self.0 == other + } + } + + #[test] + fn into_bytes() { + let s = "foo".to_string(); + assert_eq!(Bytes::from(b"foo" as &'static [u8]), "foo"); + assert_eq!(Bytes::from("foo"), "foo"); + assert_eq!(Bytes::from(s.as_bytes().to_vec()), "foo"); + assert_eq!(Bytes::from(s.as_bytes().to_vec().into_boxed_slice()), "foo"); + assert_eq!(Bytes::from(s), "foo"); + } + + #[test] + fn serde() { + let s = Bytes::from("test"); + assert_tokens(&s, &[Token::Bytes(b"test")]) + } + + #[test] + fn from_into() { + let b = Bytes::from("foo"); + let cb = CBytes::from("foo"); + assert_eq!(Bytes::from(cb), "foo"); + assert_eq!(CBytes::from(b), "foo"); + } + + #[test] + fn deref() { + let b = Bytes::from("foo"); + assert_eq!(*b, CBytes::from("foo")); + } + + #[test] + fn to_str() { + let cb = Bytes::from("foo"); + assert_eq!(cb.to_str(), Ok("foo")); + + let b = Bytes::from("💩".as_bytes()[0..3].to_vec()); + assert!(b.to_str().is_err()); + } +} diff --git a/turbopack/crates/turbo-tasks-bytes/src/lib.rs b/turbopack/crates/turbo-tasks-bytes/src/lib.rs new file mode 100644 index 0000000000000..2576a5bcfe784 --- /dev/null +++ b/turbopack/crates/turbo-tasks-bytes/src/lib.rs @@ -0,0 +1,14 @@ +#![feature(arbitrary_self_types)] + +pub mod bytes; +pub mod stream; + +pub use crate::{ + bytes::Bytes, + stream::{Stream, StreamRead}, +}; + +pub fn register() { + turbo_tasks::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbo-tasks-bytes/src/stream.rs b/turbopack/crates/turbo-tasks-bytes/src/stream.rs new file mode 100644 index 0000000000000..c51518702e3ac --- /dev/null +++ b/turbopack/crates/turbo-tasks-bytes/src/stream.rs @@ -0,0 +1,226 @@ +use std::{ + fmt, + pin::Pin, + sync::{Arc, Mutex}, + task::{Context as TaskContext, Poll}, +}; + +use anyhow::Result; +use futures::{Stream as StreamTrait, StreamExt, TryStreamExt}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +/// Streams allow for streaming values from source to sink. +/// +/// A Stream implements both a reader (which implements the Stream trait), and a +/// writer (which can be sent to another thread). As new values are written, any +/// pending readers will be woken up to receive the new value. +#[derive(Clone, Debug)] +pub struct Stream { + inner: Arc>>, +} + +/// The StreamState actually holds the data of a Stream. +struct StreamState { + source: Option + Send>>>, + pulled: Vec, +} + +impl Stream { + /// Constructs a new Stream, and immediately closes it with only the passed + /// values. + pub fn new_closed(pulled: Vec) -> Self { + Self { + inner: Arc::new(Mutex::new(StreamState { + source: None, + pulled, + })), + } + } + + /// Creates a new Stream, which will lazily pull from the source stream. + pub fn new_open( + pulled: Vec, + source: Box + Send + 'static>, + ) -> Self { + Self { + inner: Arc::new(Mutex::new(StreamState { + source: Some(Box::into_pin(source)), + pulled, + })), + } + } + + /// Returns a [StreamTrait] implementation to poll values out of our Stream. + pub fn read(&self) -> StreamRead { + StreamRead { + source: self.clone(), + index: 0, + } + } + + pub async fn into_single(&self) -> SingleValue { + let mut stream = self.read(); + let Some(first) = stream.next().await else { + return SingleValue::None; + }; + + if stream.next().await.is_some() { + return SingleValue::Multiple; + } + + SingleValue::Single(first) + } +} + +impl Stream> { + /// Converts a TryStream into a single value when possible. + pub async fn try_into_single(&self) -> Result, E> { + let mut stream = self.read(); + let Some(first) = stream.try_next().await? else { + return Ok(SingleValue::None); + }; + + if stream.try_next().await?.is_some() { + return Ok(SingleValue::Multiple); + } + + Ok(SingleValue::Single(first)) + } +} + +pub enum SingleValue { + /// The Stream did not hold a value. + None, + + /// The Stream held multiple values. + Multiple, + + /// The held only a single value. + Single(T), +} + +impl fmt::Debug for SingleValue { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + SingleValue::None => f.debug_struct("SingleValue::None").finish(), + SingleValue::Multiple => f.debug_struct("SingleValue::Multiple").finish(), + SingleValue::Single(v) => f.debug_tuple("SingleValue::Single").field(v).finish(), + } + } +} + +impl + Send + Unpin + 'static> From for Stream { + fn from(source: S) -> Self { + Self::new_open(vec![], Box::new(source)) + } +} + +impl Default for Stream { + fn default() -> Self { + Self::new_closed(vec![]) + } +} + +impl PartialEq for Stream { + // A Stream is equal if it's the same internal pointer, or both streams are + // closed with equivalent values. + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.inner, &other.inner) || { + let left = self.inner.lock().unwrap(); + let right = other.inner.lock().unwrap(); + + match (&*left, &*right) { + ( + StreamState { + pulled: a, + source: None, + }, + StreamState { + pulled: b, + source: None, + }, + ) => a == b, + _ => false, + } + } + } +} +impl Eq for Stream {} + +impl Serialize for Stream { + fn serialize(&self, serializer: S) -> Result { + use serde::ser::Error; + let lock = self.inner.lock().map_err(Error::custom)?; + match &*lock { + StreamState { + pulled, + source: None, + } => pulled.serialize(serializer), + _ => Err(Error::custom("cannot serialize open stream")), + } + } +} + +impl<'de, T: Clone + Send + Deserialize<'de>> Deserialize<'de> for Stream { + fn deserialize>(deserializer: D) -> Result { + let data = >::deserialize(deserializer)?; + Ok(Stream::new_closed(data)) + } +} + +impl fmt::Debug for StreamState { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("StreamState") + .field("pulled", &self.pulled) + .finish() + } +} + +/// Implements [StreamTrait] over our Stream. +#[derive(Debug)] +pub struct StreamRead { + index: usize, + source: Stream, +} + +impl StreamTrait for StreamRead { + type Item = T; + + fn poll_next(self: Pin<&mut Self>, cx: &mut TaskContext<'_>) -> Poll> { + let this = self.get_mut(); + let index = this.index; + let mut inner = this.source.inner.lock().unwrap(); + + if let Some(v) = inner.pulled.get(index) { + // If the current reader can be satisfied by a value we've already pulled, then + // just do that. + this.index += 1; + return Poll::Ready(Some(v.clone())); + }; + + let Some(source) = &mut inner.source else { + // If the source has been closed, there's nothing left to pull. + return Poll::Ready(None); + }; + + match source.poll_next_unpin(cx) { + // If the source stream is ready to give us a new value, we can immediately store that + // and return it to the caller. Any other readers will be able to read the value from + // the already-pulled data. + Poll::Ready(Some(v)) => { + this.index += 1; + inner.pulled.push(v.clone()); + Poll::Ready(Some(v)) + } + // If the source stream is finished, then we can transition to the closed state + // to drop the source stream. + Poll::Ready(None) => { + inner.source.take(); + Poll::Ready(None) + } + // Else, we need to wait for the source stream to give us a new value. The + // source stream will be responsible for waking the TaskContext. + Poll::Pending => Poll::Pending, + } + } +} diff --git a/turbopack/crates/turbo-tasks-env/Cargo.toml b/turbopack/crates/turbo-tasks-env/Cargo.toml new file mode 100644 index 0000000000000..ed9c8ca19dbf5 --- /dev/null +++ b/turbopack/crates/turbo-tasks-env/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "turbo-tasks-env" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +dotenvs = "0.1.0" +indexmap = { workspace = true, features = ["serde"] } +serde = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-env/build.rs b/turbopack/crates/turbo-tasks-env/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbo-tasks-env/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbo-tasks-env/src/command_line.rs b/turbopack/crates/turbo-tasks-env/src/command_line.rs new file mode 100644 index 0000000000000..e3ffa7e70765c --- /dev/null +++ b/turbopack/crates/turbo-tasks-env/src/command_line.rs @@ -0,0 +1,30 @@ +use indexmap::IndexMap; +use turbo_tasks::{RcStr, Vc}; + +use crate::{sorted_env_vars, EnvMap, ProcessEnv, GLOBAL_ENV_LOCK}; + +/// Load the environment variables defined via command line. +#[turbo_tasks::value] +pub struct CommandLineProcessEnv; + +#[turbo_tasks::value_impl] +impl CommandLineProcessEnv { + #[turbo_tasks::function] + pub fn new() -> Vc { + CommandLineProcessEnv.cell() + } +} + +/// Clones the current env vars into a IndexMap. +fn env_snapshot() -> IndexMap { + let _lock = GLOBAL_ENV_LOCK.lock().unwrap(); + sorted_env_vars() +} + +#[turbo_tasks::value_impl] +impl ProcessEnv for CommandLineProcessEnv { + #[turbo_tasks::function] + fn read_all(&self) -> Vc { + Vc::cell(env_snapshot()) + } +} diff --git a/turbopack/crates/turbo-tasks-env/src/custom.rs b/turbopack/crates/turbo-tasks-env/src/custom.rs new file mode 100644 index 0000000000000..2f3eec2c770dd --- /dev/null +++ b/turbopack/crates/turbo-tasks-env/src/custom.rs @@ -0,0 +1,42 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Vc}; + +use crate::{case_insensitive_read, EnvMap, ProcessEnv}; + +/// Allows providing any custom env values that you'd like, deferring the prior +/// envs if a key is not overridden. +#[turbo_tasks::value] +pub struct CustomProcessEnv { + prior: Vc>, + custom: Vc, +} + +#[turbo_tasks::value_impl] +impl CustomProcessEnv { + #[turbo_tasks::function] + pub fn new(prior: Vc>, custom: Vc) -> Vc { + CustomProcessEnv { prior, custom }.cell() + } +} + +#[turbo_tasks::value_impl] +impl ProcessEnv for CustomProcessEnv { + #[turbo_tasks::function] + async fn read_all(&self) -> Result> { + let prior = self.prior.read_all().await?; + let custom = self.custom.await?; + + let mut extended = prior.clone_value(); + extended.extend(custom.clone_value()); + Ok(Vc::cell(extended)) + } + + #[turbo_tasks::function] + async fn read(&self, name: RcStr) -> Result>> { + let custom = case_insensitive_read(self.custom, name.clone()); + match &*custom.await? { + Some(_) => Ok(custom), + None => Ok(self.prior.read(name)), + } + } +} diff --git a/turbopack/crates/turbo-tasks-env/src/dotenv.rs b/turbopack/crates/turbo-tasks-env/src/dotenv.rs new file mode 100644 index 0000000000000..9f65765cf7001 --- /dev/null +++ b/turbopack/crates/turbo-tasks-env/src/dotenv.rs @@ -0,0 +1,99 @@ +use std::{env, sync::MutexGuard}; + +use anyhow::{anyhow, Context, Result}; +use indexmap::IndexMap; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks_fs::{FileContent, FileSystemPath}; + +use crate::{sorted_env_vars, EnvMap, ProcessEnv, GLOBAL_ENV_LOCK}; + +/// Load the environment variables defined via a dotenv file, with an +/// optional prior state that we can lookup already defined variables +/// from. +#[turbo_tasks::value] +pub struct DotenvProcessEnv { + prior: Option>>, + path: Vc, +} + +#[turbo_tasks::value_impl] +impl DotenvProcessEnv { + #[turbo_tasks::function] + pub fn new(prior: Option>>, path: Vc) -> Vc { + DotenvProcessEnv { prior, path }.cell() + } + + #[turbo_tasks::function] + pub async fn read_prior(self: Vc) -> Result> { + let this = self.await?; + match this.prior { + None => Ok(EnvMap::empty()), + Some(p) => Ok(p.read_all()), + } + } + + #[turbo_tasks::function] + pub async fn read_all_with_prior(self: Vc, prior: Vc) -> Result> { + let this = self.await?; + let prior = prior.await?; + + let file = this.path.read().await?; + if let FileContent::Content(f) = &*file { + let res; + let vars; + { + let lock = GLOBAL_ENV_LOCK.lock().unwrap(); + + // Unfortunately, dotenvy only looks up variable references from the global env. + // So we must mutate while we process. Afterwards, we can restore the initial + // state. + let initial = sorted_env_vars(); + + restore_env(&initial, &prior, &lock); + + // from_read will load parse and evalute the Read, and set variables + // into the global env. If a later dotenv defines an already defined + // var, it'll be ignored. + res = dotenv::from_read(f.read()).map(|e| e.load()); + + vars = sorted_env_vars(); + restore_env(&vars, &initial, &lock); + } + + if let Err(e) = res { + return Err(e).context(anyhow!( + "unable to read {} for env vars", + this.path.to_string().await? + )); + } + + Ok(Vc::cell(vars)) + } else { + Ok(Vc::cell(prior.clone_value())) + } + } +} + +#[turbo_tasks::value_impl] +impl ProcessEnv for DotenvProcessEnv { + #[turbo_tasks::function] + async fn read_all(self: Vc) -> Result> { + let prior = self.read_prior(); + Ok(self.read_all_with_prior(prior)) + } +} + +/// Restores the global env variables to mirror `to`. +fn restore_env(from: &IndexMap, to: &IndexMap, _lock: &MutexGuard<()>) { + for key in from.keys() { + if !to.contains_key(key) { + env::remove_var(key); + } + } + for (key, value) in to { + match from.get(key) { + Some(v) if v == value => {} + _ => env::set_var(key, value), + } + } +} diff --git a/turbopack/crates/turbo-tasks-env/src/filter.rs b/turbopack/crates/turbo-tasks-env/src/filter.rs new file mode 100644 index 0000000000000..5b5da3639e3ee --- /dev/null +++ b/turbopack/crates/turbo-tasks-env/src/filter.rs @@ -0,0 +1,57 @@ +use anyhow::Result; +use indexmap::IndexMap; +use turbo_tasks::{RcStr, Vc}; + +use crate::{EnvMap, ProcessEnv}; + +/// Filters env variables by some prefix. Casing of the env vars is ignored for +/// filtering. +#[turbo_tasks::value] +pub struct FilterProcessEnv { + prior: Vc>, + filters: Vec, +} + +#[turbo_tasks::value_impl] +impl FilterProcessEnv { + #[turbo_tasks::function] + pub fn new(prior: Vc>, filters: Vec) -> Vc { + FilterProcessEnv { + prior, + filters: filters + .into_iter() + .map(|f| f.to_uppercase().into()) + .collect(), + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl ProcessEnv for FilterProcessEnv { + #[turbo_tasks::function] + async fn read_all(&self) -> Result> { + let prior = self.prior.read_all().await?; + let mut filtered = IndexMap::new(); + for (key, value) in &*prior { + let uppercase = key.to_uppercase(); + for filter in &self.filters { + if uppercase.starts_with(&**filter) { + filtered.insert(key.clone(), value.clone()); + break; + } + } + } + Ok(Vc::cell(filtered)) + } + + #[turbo_tasks::function] + fn read(&self, name: RcStr) -> Vc> { + for filter in &self.filters { + if name.to_uppercase().starts_with(&**filter) { + return self.prior.read(name); + } + } + Vc::cell(None) + } +} diff --git a/turbopack/crates/turbo-tasks-env/src/lib.rs b/turbopack/crates/turbo-tasks-env/src/lib.rs new file mode 100644 index 0000000000000..6d4880ff6fbaf --- /dev/null +++ b/turbopack/crates/turbo-tasks-env/src/lib.rs @@ -0,0 +1,92 @@ +#![feature(arbitrary_self_types)] + +mod command_line; +mod custom; +mod dotenv; +mod filter; + +use std::{env, sync::Mutex}; + +use anyhow::Result; +use indexmap::IndexMap; +use turbo_tasks::{RcStr, Vc}; + +pub use self::{ + command_line::CommandLineProcessEnv, custom::CustomProcessEnv, dotenv::DotenvProcessEnv, + filter::FilterProcessEnv, +}; + +#[turbo_tasks::value(transparent)] +pub struct EnvMap(#[turbo_tasks(trace_ignore)] IndexMap); + +#[turbo_tasks::value_impl] +impl EnvMap { + #[turbo_tasks::function] + pub fn empty() -> Vc { + EnvMap(IndexMap::new()).cell() + } +} + +#[turbo_tasks::value_impl] +impl ProcessEnv for EnvMap { + #[turbo_tasks::function] + async fn read_all(self: Vc) -> Result> { + Ok(self) + } + + #[turbo_tasks::function] + async fn read(self: Vc, name: RcStr) -> Vc> { + case_insensitive_read(self, name) + } +} + +#[turbo_tasks::value_trait] +pub trait ProcessEnv { + // TODO SECURITY: From security perspective it's not good that we read *all* env + // vars into the cache. This might store secrects into the persistent cache + // which we want to avoid. + // Instead we should use only `read_prefix` to read all env vars with a specific + // prefix. + /// Reads all env variables into a Map + fn read_all(self: Vc) -> Vc; + + /// Reads a single env variable. Ignores casing. + fn read(self: Vc, name: RcStr) -> Vc> { + case_insensitive_read(self.read_all(), name) + } +} + +pub fn sorted_env_vars() -> IndexMap { + let mut vars = env::vars() + .map(|(k, v)| (k.into(), v.into())) + .collect::>(); + vars.sort_keys(); + vars +} + +#[turbo_tasks::function] +pub async fn case_insensitive_read(map: Vc, name: RcStr) -> Result>> { + Ok(Vc::cell( + to_uppercase_map(map) + .await? + .get(&RcStr::from(name.to_uppercase())) + .cloned(), + )) +} + +#[turbo_tasks::function] +async fn to_uppercase_map(map: Vc) -> Result> { + let map = &*map.await?; + let mut new = IndexMap::with_capacity(map.len()); + for (k, v) in map { + new.insert(k.to_uppercase().into(), v.clone()); + } + Ok(Vc::cell(new)) +} + +pub static GLOBAL_ENV_LOCK: Mutex<()> = Mutex::new(()); + +pub fn register() { + turbo_tasks::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbo-tasks-fetch/Cargo.toml b/turbopack/crates/turbo-tasks-fetch/Cargo.toml new file mode 100644 index 0000000000000..59a2ed5d63df2 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fetch/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "turbo-tasks-fetch" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[features] +default = ["native-tls"] +# Allow to configure specific tls backend for reqwest. +# See top level Cargo.toml for more details. +native-tls = ["reqwest/native-tls"] +rustls-tls = ["reqwest/rustls-tls"] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +reqwest = { workspace = true } +serde = { workspace = true } +tokio = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } + +[dev-dependencies] +httpmock = { workspace = true } +tokio = { workspace = true, features = ["full"] } +turbo-tasks-testing = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-fetch/build.rs b/turbopack/crates/turbo-tasks-fetch/build.rs new file mode 100644 index 0000000000000..1d071886229f6 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fetch/build.rs @@ -0,0 +1,19 @@ +use turbo_tasks_build::generate_register; + +#[cfg(any(feature = "native-tls", feature = "rustls-tls"))] +fn check_tls_config() { + // do nothing +} +#[cfg(not(any(feature = "native-tls", feature = "rustls-tls")))] +fn check_tls_config() { + panic!("You must enable one of the TLS features: native-tls or rustls-tls"); +} + +fn main() { + generate_register(); + + // Check if tls feature for reqwest is properly configured. + // Technically reqwest falls back to non-tls http request if none of the tls + // features are enabled, But we won't allow it. + check_tls_config(); +} diff --git a/turbopack/crates/turbo-tasks-fetch/src/lib.rs b/turbopack/crates/turbo-tasks-fetch/src/lib.rs new file mode 100644 index 0000000000000..c4f3e12e0f164 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fetch/src/lib.rs @@ -0,0 +1,208 @@ +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +use anyhow::Result; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::issue::{Issue, IssueSeverity, IssueStage, OptionStyledString, StyledString}; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} + +#[turbo_tasks::value(transparent)] +pub struct FetchResult(Result, Vc>); + +#[turbo_tasks::value(shared)] +#[derive(Debug)] +pub struct HttpResponse { + pub status: u16, + pub body: Vc, +} + +#[turbo_tasks::value(shared)] +#[derive(Debug)] +pub struct HttpResponseBody(pub Vec); + +#[turbo_tasks::value_impl] +impl HttpResponseBody { + #[turbo_tasks::function] + pub async fn to_string(self: Vc) -> Result> { + let this = &*self.await?; + Ok(Vc::cell(std::str::from_utf8(&this.0)?.into())) + } +} + +#[turbo_tasks::value(shared)] +#[derive(Debug)] +pub enum ProxyConfig { + Http(String), + Https(String), +} + +#[turbo_tasks::value(transparent)] +pub struct OptionProxyConfig(Option); + +#[turbo_tasks::function(network)] +pub async fn fetch( + url: Vc, + user_agent: Vc>, + proxy_option: Vc, +) -> Result> { + let url = &*url.await?; + let user_agent = &*user_agent.await?; + let proxy_option = &*proxy_option.await?; + + let client_builder = reqwest::Client::builder(); + let client_builder = match proxy_option { + Some(ProxyConfig::Http(proxy)) => client_builder.proxy(reqwest::Proxy::http(proxy)?), + Some(ProxyConfig::Https(proxy)) => client_builder.proxy(reqwest::Proxy::https(proxy)?), + _ => client_builder, + }; + + let client = client_builder.build()?; + + let mut builder = client.get(url.as_str()); + if let Some(user_agent) = user_agent { + builder = builder.header("User-Agent", user_agent.as_str()); + } + + let response = builder.send().await.and_then(|r| r.error_for_status()); + match response { + Ok(response) => { + let status = response.status().as_u16(); + let body = response.bytes().await?.to_vec(); + + Ok(Vc::cell(Ok(HttpResponse { + status, + body: HttpResponseBody::cell(HttpResponseBody(body)), + } + .cell()))) + } + Err(err) => Ok(Vc::cell(Err( + FetchError::from_reqwest_error(&err, url).cell() + ))), + } +} + +#[derive(Debug)] +#[turbo_tasks::value(shared)] +pub enum FetchErrorKind { + Connect, + Timeout, + Status(u16), + Other, +} + +#[turbo_tasks::value(shared)] +pub struct FetchError { + pub url: Vc, + pub kind: Vc, + pub detail: Vc, +} + +impl FetchError { + fn from_reqwest_error(error: &reqwest::Error, url: &str) -> FetchError { + let kind = if error.is_connect() { + FetchErrorKind::Connect + } else if error.is_timeout() { + FetchErrorKind::Timeout + } else if let Some(status) = error.status() { + FetchErrorKind::Status(status.as_u16()) + } else { + FetchErrorKind::Other + }; + + FetchError { + detail: StyledString::Text(error.to_string().into()).cell(), + url: Vc::cell(url.into()), + kind: kind.into(), + } + } +} + +#[turbo_tasks::value_impl] +impl FetchError { + #[turbo_tasks::function] + pub async fn to_issue( + self: Vc, + severity: Vc, + issue_context: Vc, + ) -> Result> { + let this = &*self.await?; + Ok(FetchIssue { + issue_context, + severity, + url: this.url, + kind: this.kind, + detail: this.detail, + } + .into()) + } +} + +#[turbo_tasks::value(shared)] +pub struct FetchIssue { + pub issue_context: Vc, + pub severity: Vc, + pub url: Vc, + pub kind: Vc, + pub detail: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for FetchIssue { + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.issue_context + } + + #[turbo_tasks::function] + fn severity(&self) -> Vc { + self.severity + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Error while requesting resource".into()).cell() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Load.into() + } + + #[turbo_tasks::function] + async fn description(&self) -> Result> { + let url = &*self.url.await?; + let kind = &*self.kind.await?; + + Ok(Vc::cell(Some( + StyledString::Text(match kind { + FetchErrorKind::Connect => format!( + "There was an issue establishing a connection while requesting {}.", + url + ) + .into(), + FetchErrorKind::Status(status) => format!( + "Received response with status {} when requesting {}", + status, url + ) + .into(), + FetchErrorKind::Timeout => { + format!("Connection timed out when requesting {}", url).into() + } + FetchErrorKind::Other => format!("There was an issue requesting {}", url).into(), + }) + .cell(), + ))) + } + + #[turbo_tasks::function] + fn detail(&self) -> Vc { + Vc::cell(Some(self.detail)) + } +} diff --git a/turbopack/crates/turbo-tasks-fetch/tests/fetch.rs b/turbopack/crates/turbo-tasks-fetch/tests/fetch.rs new file mode 100644 index 0000000000000..12e97eede4ee2 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fetch/tests/fetch.rs @@ -0,0 +1,161 @@ +#![cfg(test)] + +use turbo_tasks::Vc; +use turbo_tasks_fetch::{fetch, FetchErrorKind}; +use turbo_tasks_fs::{DiskFileSystem, FileSystem, FileSystemPath}; +use turbo_tasks_testing::{register, run, Registration}; +use turbopack_core::issue::{Issue, IssueSeverity, StyledString}; + +static REGISTRATION: Registration = register!(turbo_tasks_fetch::register); + +#[tokio::test] +async fn basic_get() { + run(®ISTRATION, async { + let server = httpmock::MockServer::start(); + let resource_mock = server.mock(|when, then| { + when.path("/foo.woff"); + then.status(200).body("responsebody"); + }); + + let result = &*fetch( + Vc::cell(server.url("/foo.woff").into()), + Vc::cell(None), + Vc::cell(None), + ) + .await + .unwrap(); + resource_mock.assert(); + + match result { + Err(_) => panic!(), + Ok(response) => { + let response = response.await.unwrap(); + assert_eq!(response.status, 200); + assert_eq!(*response.body.to_string().await.unwrap(), "responsebody"); + } + } + }) + .await +} + +#[tokio::test] +async fn sends_user_agent() { + run(®ISTRATION, async { + let server = httpmock::MockServer::start(); + let resource_mock = server.mock(|when, then| { + when.path("/foo.woff").header("User-Agent", "foo"); + then.status(200).body("responsebody"); + }); + + let result = &*fetch( + Vc::cell(server.url("/foo.woff").into()), + Vc::cell(Some("foo".into())), + Vc::cell(None), + ) + .await + .unwrap(); + resource_mock.assert(); + + let Ok(response) = result else { panic!() }; + + let response = response.await.unwrap(); + assert_eq!(response.status, 200); + assert_eq!(*response.body.to_string().await.unwrap(), "responsebody"); + }) + .await +} + +// This is temporary behavior. +// TODO: Implement invalidation that respects Cache-Control headers. +#[tokio::test] +async fn invalidation_does_not_invalidate() { + run(®ISTRATION, async { + let server = httpmock::MockServer::start(); + let resource_mock = server.mock(|when, then| { + when.path("/foo.woff").header("User-Agent", "foo"); + then.status(200).body("responsebody"); + }); + + let url = Vc::cell(server.url("/foo.woff").into()); + let user_agent = Vc::cell(Some("foo".into())); + let proxy = Vc::cell(None); + let result = &*fetch(url, user_agent, proxy).await.unwrap(); + resource_mock.assert(); + + let Ok(response_vc) = result else { panic!() }; + let response = response_vc.await.unwrap(); + assert_eq!(response.status, 200); + assert_eq!(*response.body.to_string().await.unwrap(), "responsebody"); + + let second_result = &*fetch(url, user_agent, proxy).await.unwrap(); + let Ok(second_response_vc) = second_result else { + panic!() + }; + let second_response = second_response_vc.await.unwrap(); + + // Assert that a second request is never sent -- the result is cached via turbo + // tasks + resource_mock.assert_hits(1); + assert_eq!(response, second_response); + }) + .await +} + +#[tokio::test] +async fn errors_on_failed_connection() { + run(®ISTRATION, async { + let url = "https://doesnotexist/foo.woff"; + let result = &*fetch(Vc::cell(url.into()), Vc::cell(None), Vc::cell(None)).await.unwrap(); + let Err(err_vc) = result else { + panic!() + }; + let err = &*err_vc.await.unwrap(); + assert_eq!(*err.kind.await.unwrap(), FetchErrorKind::Connect); + assert_eq!(*err.url.await.unwrap(), url); + + let issue = err_vc.to_issue(IssueSeverity::Error.into(), get_issue_context()); + assert_eq!(*issue.severity().await.unwrap(), IssueSeverity::Error); + assert_eq!(*issue.description().await.unwrap().unwrap().await.unwrap(), StyledString::Text("There was an issue establishing a connection while requesting https://doesnotexist/foo.woff.".into())); + }) + .await +} + +#[tokio::test] +async fn errors_on_404() { + run(®ISTRATION, async { + let server = httpmock::MockServer::start(); + let resource_url = server.url("/"); + let result = &*fetch( + Vc::cell(resource_url.clone().into()), + Vc::cell(None), + Vc::cell(None), + ) + .await + .unwrap(); + let Err(err_vc) = result else { panic!() }; + let err = &*err_vc.await.unwrap(); + assert!(matches!( + *err.kind.await.unwrap(), + FetchErrorKind::Status(404) + )); + assert_eq!(*err.url.await.unwrap(), resource_url); + + let issue = err_vc.to_issue(IssueSeverity::Error.into(), get_issue_context()); + assert_eq!(*issue.severity().await.unwrap(), IssueSeverity::Error); + assert_eq!( + *issue.description().await.unwrap().unwrap().await.unwrap(), + StyledString::Text( + format!( + "Received response with status 404 when requesting {}", + &resource_url + ) + .into() + ) + ); + }) + .await +} + +fn get_issue_context() -> Vc { + DiskFileSystem::new("root".into(), "/".into(), vec![]).root() +} diff --git a/turbopack/crates/turbo-tasks-fs/Cargo.toml b/turbopack/crates/turbo-tasks-fs/Cargo.toml new file mode 100644 index 0000000000000..59c616c4bb054 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/Cargo.toml @@ -0,0 +1,60 @@ +[package] +name = "turbo-tasks-fs" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[[bench]] +name = "mod" +harness = false + +[features] +# Enables dynamic linking (and hot reloading) of embedded files/dirs. +# A binary built with this option **is not portable**, the directory +# path will be embedded into the binary. +dynamic_embed_contents = [] +# Write a hashed version of each file to allow to debug conflicting writes +write_version = [] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +auto-hash-map = { workspace = true } +bitflags = "1.3.2" +bytes = { workspace = true } +concurrent-queue = { workspace = true } +dashmap = { workspace = true } +dunce = { workspace = true } +futures = { workspace = true } +futures-retry = { workspace = true } +include_dir = { version = "0.7.2", features = ["nightly"] } +indexmap = { workspace = true } +jsonc-parser = { version = "0.21.0", features = ["serde"] } +mime = { workspace = true } +notify = { workspace = true } +parking_lot = { workspace = true } +serde = { workspace = true, features = ["rc"] } +serde_json = { workspace = true } +serde_path_to_error = "0.1.9" +tokio = { workspace = true } +tracing = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-hash = { workspace = true } +unicode-segmentation = { workspace = true } + +[dev-dependencies] +criterion = { workspace = true, features = ["async_tokio"] } +rstest = { workspace = true } +sha2 = "0.10.2" +tempfile = { workspace = true } +turbo-tasks-memory = { workspace = true } +turbo-tasks-testing = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-fs/benches/mod.rs b/turbopack/crates/turbo-tasks-fs/benches/mod.rs new file mode 100644 index 0000000000000..ec5a14eba482e --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/benches/mod.rs @@ -0,0 +1,109 @@ +use std::{ + fs, + sync::{mpsc::channel, Arc}, + thread, + time::{Duration, Instant}, +}; + +use criterion::{ + criterion_group, criterion_main, + measurement::{Measurement, WallTime}, + BenchmarkId, Criterion, +}; +use notify::{Config, RecommendedWatcher, RecursiveMode, Watcher}; +use tokio::runtime::Runtime; +use turbo_tasks::event::Event; +use turbo_tasks_fs::rope::{Rope, RopeBuilder}; + +fn bench_file_watching(c: &mut Criterion) { + let mut g = c.benchmark_group("turbo-tasks-fs"); + g.sample_size(10); + g.measurement_time(Duration::from_secs(10)); + + let temp = tempfile::TempDir::new().unwrap(); + let start = Instant::now(); + let temp_path = temp.path(); + fs::write( + temp_path.join("file.txt"), + start.elapsed().as_micros().to_string(), + ) + .unwrap(); + + g.bench_function( + BenchmarkId::new("bench_file_watching", "change file"), + move |b| { + let (tx, rx) = channel(); + let event = Arc::new(Event::new(|| "test event".to_string())); + + let mut watcher = RecommendedWatcher::new(tx, Config::default()).unwrap(); + watcher.watch(temp_path, RecursiveMode::Recursive).unwrap(); + + let t = thread::spawn({ + let event = event.clone(); + move || loop { + match rx.recv() { + Ok(_) => event.notify(usize::MAX), + Err(_) => return, + } + } + }); + + b.to_async(Runtime::new().unwrap()) + .iter_custom(move |iters| { + let event = event.clone(); + async move { + let m = WallTime; + let mut value = m.zero(); + for _ in 0..iters { + std::thread::sleep(Duration::from_millis(1)); + let l = event.listen(); + let path = temp_path.join("file.txt"); + let content = start.elapsed().as_micros().to_string(); + let s = m.start(); + fs::write(path, content).unwrap(); + l.await; + let duration = m.end(s); + value = m.add(&value, &duration); + } + value + } + }); + + drop(watcher); + t.join().unwrap(); + }, + ); +} + +fn bench_rope_iteration(c: &mut Criterion) { + let mut g = c.benchmark_group("turbo-tasks-fs"); + g.sample_size(10); + g.measurement_time(Duration::from_secs(10)); + + g.bench_function( + BenchmarkId::new("bench_rope_iteration", "next collect"), + move |b| { + b.iter(|| { + let mut root = RopeBuilder::default(); + for _ in 0..5 { + let mut inner = RopeBuilder::default(); + for _ in 0..5 { + let r = Rope::from("abc".to_string().into_bytes()); + inner += &r; + } + root += &inner.build(); + } + + let rope = root.build(); + let _v = rope.read().collect::>(); + }) + }, + ); +} + +criterion_group!( + name = benches; + config = Criterion::default(); + targets = bench_file_watching, bench_rope_iteration +); +criterion_main!(benches); diff --git a/turbopack/crates/turbo-tasks-fs/build.rs b/turbopack/crates/turbo-tasks-fs/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbo-tasks-fs/examples/hash_directory.rs b/turbopack/crates/turbo-tasks-fs/examples/hash_directory.rs new file mode 100644 index 0000000000000..a8d3fb72502dc --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/examples/hash_directory.rs @@ -0,0 +1,124 @@ +#![feature(trivial_bounds)] + +use std::{ + collections::BTreeMap, + env::current_dir, + io::Read, + time::{Duration, Instant}, +}; + +use anyhow::Result; +use sha2::{Digest, Sha256}; +use turbo_tasks::{util::FormatDuration, RcStr, TurboTasks, UpdateInfo, Vc}; +use turbo_tasks_fs::{ + register, DirectoryContent, DirectoryEntry, DiskFileSystem, FileContent, FileSystem, + FileSystemPath, +}; +use turbo_tasks_memory::MemoryBackend; + +#[tokio::main] +async fn main() -> Result<()> { + register(); + include!(concat!( + env!("OUT_DIR"), + "/register_example_hash_directory.rs" + )); + + let tt = TurboTasks::new(MemoryBackend::default()); + let start = Instant::now(); + + let task = tt.spawn_root_task(|| { + Box::pin(async { + let root = current_dir().unwrap().to_str().unwrap().into(); + let disk_fs = DiskFileSystem::new("project".into(), root, vec![]); + disk_fs.await?.start_watching()?; + + // Smart Pointer cast + let fs: Vc> = Vc::upcast(disk_fs); + let input = fs.root().join("demo".into()); + let dir_hash = hash_directory(input); + print_hash(dir_hash).await?; + Ok::, _>(Default::default()) + }) + }); + tt.wait_task_completion(task, true).await.unwrap(); + println!("done in {}", FormatDuration(start.elapsed())); + + loop { + let UpdateInfo { + duration, tasks, .. + } = tt + .get_or_wait_aggregated_update_info(Duration::from_millis(100)) + .await; + println!("updated {} tasks in {}", tasks, FormatDuration(duration)); + } +} + +#[turbo_tasks::function] +async fn print_hash(dir_hash: Vc) -> Result> { + println!("DIR HASH: {}", dir_hash.await?.as_str()); + Ok(Default::default()) +} + +async fn filename(path: Vc) -> Result { + Ok(path.await?.path.split('/').last().unwrap().to_string()) +} + +#[turbo_tasks::function] +async fn hash_directory(directory: Vc) -> Result> { + let dir_path = &directory.await?.path; + let content = directory.read_dir(); + let mut hashes = BTreeMap::new(); + match &*content.await? { + DirectoryContent::Entries(entries) => { + for entry in entries.values() { + match entry { + DirectoryEntry::File(path) => { + let name = filename(*path).await?; + hashes.insert(name, hash_file(*path).await?.clone_value()); + } + DirectoryEntry::Directory(path) => { + let name = filename(*path).await?; + hashes.insert(name, hash_directory(*path).await?.clone_value()); + } + _ => {} + } + } + } + DirectoryContent::NotFound => { + println!("{}: not found", directory.await?.path); + } + }; + let hash = hash_content( + &mut hashes + .into_values() + .collect::>() + .join(",") + .as_bytes(), + ); + println!("hash_directory({})", dir_path); + Ok(hash) +} + +#[turbo_tasks::function] +async fn hash_file(file_path: Vc) -> Result> { + let content = file_path.read().await?; + Ok(match &*content { + FileContent::Content(file) => hash_content(&mut file.read()), + FileContent::NotFound => { + // report error + Vc::cell(Default::default()) + } + }) +} + +fn hash_content(content: &mut R) -> Vc { + let mut hasher = Sha256::new(); + let mut buf = [0; 1024]; + while let Ok(size) = content.read(&mut buf) { + hasher.update(&buf[0..size]); + } + let result = format!("{:x}", hasher.finalize()); + + Vc::cell(result.into()) +} diff --git a/turbopack/crates/turbo-tasks-fs/examples/hash_glob.rs b/turbopack/crates/turbo-tasks-fs/examples/hash_glob.rs new file mode 100644 index 0000000000000..50dcdad53f05e --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/examples/hash_glob.rs @@ -0,0 +1,116 @@ +#![feature(trivial_bounds)] + +use std::{ + collections::BTreeMap, + env::current_dir, + io::Read, + time::{Duration, Instant}, +}; + +use anyhow::Result; +use sha2::{Digest, Sha256}; +use turbo_tasks::{util::FormatDuration, RcStr, TurboTasks, UpdateInfo, Vc}; +use turbo_tasks_fs::{ + glob::Glob, register, DirectoryEntry, DiskFileSystem, FileContent, FileSystem, FileSystemPath, + ReadGlobResult, +}; +use turbo_tasks_memory::MemoryBackend; + +#[tokio::main] +async fn main() -> Result<()> { + register(); + include!(concat!(env!("OUT_DIR"), "/register_example_hash_glob.rs")); + + let tt = TurboTasks::new(MemoryBackend::default()); + let start = Instant::now(); + + let task = tt.spawn_root_task(|| { + Box::pin(async { + let root = current_dir().unwrap().to_str().unwrap().into(); + let disk_fs = DiskFileSystem::new("project".into(), root, vec![]); + disk_fs.await?.start_watching()?; + + // Smart Pointer cast + let fs: Vc> = Vc::upcast(disk_fs); + let input = fs.root().join("crates".into()); + let glob = Glob::new("**/*.rs".into()); + let glob_result = input.read_glob(glob, true); + let dir_hash = hash_glob_result(glob_result); + print_hash(dir_hash).await?; + Ok::, _>(Default::default()) + }) + }); + tt.wait_task_completion(task, true).await.unwrap(); + println!("done in {}", FormatDuration(start.elapsed())); + + loop { + let UpdateInfo { + duration, tasks, .. + } = tt + .get_or_wait_aggregated_update_info(Duration::from_millis(100)) + .await; + println!("updated {} tasks in {}", tasks, FormatDuration(duration)); + } +} + +#[turbo_tasks::function] +pub fn empty_string() -> Vc { + Vc::cell(Default::default()) +} + +#[turbo_tasks::function] +async fn print_hash(dir_hash: Vc) -> Result> { + println!("DIR HASH: {}", dir_hash.await?.as_str()); + Ok(Default::default()) +} + +#[turbo_tasks::function] +async fn hash_glob_result(result: Vc) -> Result> { + let result = result.await?; + let mut hashes = BTreeMap::new(); + for (name, entry) in result.results.iter() { + if let DirectoryEntry::File(path) = entry { + hashes.insert(name, hash_file(*path).await?.clone_value()); + } + } + for (name, result) in result.inner.iter() { + let hash = hash_glob_result(*result).await?; + if !hash.is_empty() { + hashes.insert(name, hash.clone_value()); + } + } + if hashes.is_empty() { + return Ok(empty_string()); + } + let hash = hash_content( + &mut hashes + .into_values() + .collect::>() + .join(",") + .as_bytes(), + ); + Ok(hash) +} + +#[turbo_tasks::function] +async fn hash_file(file_path: Vc) -> Result> { + let content = file_path.read().await?; + Ok(match &*content { + FileContent::Content(file) => hash_content(&mut file.read()), + FileContent::NotFound => { + // report error + Vc::cell(Default::default()) + } + }) +} + +fn hash_content(content: &mut R) -> Vc { + let mut hasher = Sha256::new(); + let mut buf = [0; 1024]; + while let Ok(size) = content.read(&mut buf) { + hasher.update(&buf[0..size]); + } + let result = format!("{:x}", hasher.finalize()); + + Vc::cell(result.into()) +} diff --git a/turbopack/crates/turbo-tasks-fs/src/attach.rs b/turbopack/crates/turbo-tasks-fs/src/attach.rs new file mode 100644 index 0000000000000..7705aad035361 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/attach.rs @@ -0,0 +1,195 @@ +use anyhow::{bail, Result}; +use auto_hash_map::AutoMap; +use turbo_tasks::{Completion, RcStr, ValueToString, Vc}; + +use crate::{ + DirectoryContent, DirectoryEntry, FileContent, FileMeta, FileSystem, FileSystemPath, + LinkContent, +}; + +/// A wrapper [FileSystem] which attaches a child [FileSystem] as a +/// "subdirectory" in the given root [FileSystem]. +/// +/// Caveat: The `child_path` itself is not visible as a directory entry. +#[turbo_tasks::value] +pub struct AttachedFileSystem { + root_fs: Vc>, + // we turn this into a string because creating a FileSystemPath requires the filesystem which + // we are creating (circular reference) + child_path: RcStr, + child_fs: Vc>, +} + +#[turbo_tasks::value_impl] +impl AttachedFileSystem { + /// Create a new [AttachedFileSystem] which will have the `child_fs` as + /// an invisible subdirectory of the `child_path` + #[turbo_tasks::function] + pub async fn new( + child_path: Vc, + child_fs: Vc>, + ) -> Result> { + let child_path = child_path.await?; + + Ok(AttachedFileSystem { + root_fs: child_path.fs, + child_path: child_path.path.clone(), + child_fs, + } + .cell()) + } + + /// Converts the given [Vc] to a path in this [FileSystem]. + /// + /// The given path has to be inside of the root [FileSystem], the child + /// [FileSystem] or this [AttachedFileSystem]. + #[turbo_tasks::function] + pub async fn convert_path( + self: Vc, + contained_path_vc: Vc, + ) -> Result> { + let contained_path = contained_path_vc.await?; + let self_fs: Vc> = Vc::upcast(self); + let this = self.await?; + + match contained_path.fs { + // already on this filesystem + fs if fs == self_fs => Ok(contained_path_vc), + // in the root filesystem, just need to rebase on this filesystem + fs if fs == this.root_fs => Ok(self + .root() + .resolve() + .await? + .join(contained_path.path.clone())), + // in the child filesystem, so we expand to the full path by appending to child_path + fs if fs == this.child_fs => Ok(self + .child_path() + .resolve() + .await? + .join(contained_path.path.clone())), + _ => bail!( + "path {} not part of self, the root fs or the child fs", + contained_path_vc.to_string().await? + ), + } + } + + /// Constructs a [Vc] of the attachment point referencing + /// this [AttachedFileSystem] + #[turbo_tasks::function] + async fn child_path(self: Vc) -> Result> { + Ok(self + .root() + .resolve() + .await? + .join(self.await?.child_path.clone())) + } + + /// Resolves the local path of the root or child filesystem from a path + /// on the [AttachedFileSystem] + #[turbo_tasks::function] + pub async fn get_inner_fs_path( + self: Vc, + path: Vc, + ) -> Result> { + let this = self.await?; + let path = path.await?; + let self_fs: Vc> = Vc::upcast(self); + + if path.fs != self_fs { + let self_fs_str = self_fs.to_string().await?; + let path_fs_str = path.fs.to_string().await?; + bail!( + "path fs does not match (expected {}, got {})", + self_fs_str, + path_fs_str + ) + } + + let child_path = self.child_path().await?; + Ok(if let Some(inner_path) = child_path.get_path_to(&path) { + this.child_fs + .root() + .resolve() + .await? + .join(inner_path.into()) + } else { + this.root_fs.root().resolve().await?.join(path.path.clone()) + }) + } +} + +#[turbo_tasks::value_impl] +impl FileSystem for AttachedFileSystem { + #[turbo_tasks::function(fs)] + fn read(self: Vc, path: Vc) -> Vc { + self.get_inner_fs_path(path).read() + } + + #[turbo_tasks::function(fs)] + fn read_link(self: Vc, path: Vc) -> Vc { + self.get_inner_fs_path(path).read_link() + } + + #[turbo_tasks::function(fs)] + async fn read_dir(self: Vc, path: Vc) -> Result> { + let dir_content = self.get_inner_fs_path(path).read_dir().await?; + let entries = match &*dir_content { + DirectoryContent::Entries(e) => e, + DirectoryContent::NotFound => return Ok(DirectoryContent::not_found()), + }; + + let mut converted_entries = AutoMap::with_capacity(entries.len()); + for (name, entry) in entries { + use DirectoryEntry::*; + + let entry = match *entry { + File(path) => File(self.convert_path(path)), + Directory(path) => Directory(self.convert_path(path)), + Symlink(path) => Symlink(self.convert_path(path)), + Other(path) => Other(self.convert_path(path)), + Error => Error, + }; + + converted_entries.insert(name.clone(), entry); + } + + Ok(DirectoryContent::new(converted_entries)) + } + + #[turbo_tasks::function(fs)] + fn track(self: Vc, path: Vc) -> Vc { + self.get_inner_fs_path(path).track() + } + + #[turbo_tasks::function(fs)] + fn write(self: Vc, path: Vc, content: Vc) -> Vc { + self.get_inner_fs_path(path).write(content) + } + + #[turbo_tasks::function(fs)] + fn write_link( + self: Vc, + path: Vc, + target: Vc, + ) -> Vc { + self.get_inner_fs_path(path).write_link(target) + } + + #[turbo_tasks::function] + fn metadata(self: Vc, path: Vc) -> Vc { + self.get_inner_fs_path(path).metadata() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for AttachedFileSystem { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + let root_fs_str = self.root_fs.to_string().await?; + let child_fs_str = self.child_fs.to_string().await?; + Ok(Vc::cell( + format!("{}-with-{}", root_fs_str, child_fs_str).into(), + )) + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/embed/dir.rs b/turbopack/crates/turbo-tasks-fs/src/embed/dir.rs new file mode 100644 index 0000000000000..93031ecf60aef --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/embed/dir.rs @@ -0,0 +1,79 @@ +pub use ::include_dir::{ + include_dir, {self}, +}; +use anyhow::Result; +use turbo_tasks::{RcStr, TransientInstance, Vc}; + +use crate::{embed::EmbeddedFileSystem, DiskFileSystem, FileSystem}; + +#[turbo_tasks::function] +pub async fn directory_from_relative_path( + name: RcStr, + path: RcStr, +) -> Result>> { + let disk_fs = DiskFileSystem::new(name, path, vec![]); + disk_fs.await?.start_watching()?; + + Ok(Vc::upcast(disk_fs)) +} + +#[turbo_tasks::function] +pub async fn directory_from_include_dir( + name: RcStr, + dir: TransientInstance<&'static include_dir::Dir<'static>>, +) -> Result>> { + Ok(Vc::upcast(EmbeddedFileSystem::new(name, dir))) +} + +/// Returns an embedded [Vc>] for the given path. +/// +/// This will embed a directory's content into the binary and +/// create an [Vc]. +/// +/// If you enable the `dynamic_embed_contents` feature, calling +/// the macro will return a [Vc]. +/// +/// This enables dynamic linking (and hot reloading) of embedded files/dirs. +/// A binary built with `dynamic_embed_contents` enabled is **is not portable**, +/// only the directory path will be embedded into the binary. +#[macro_export] +macro_rules! embed_directory { + ($name:tt, $path:tt) => {{ // make sure the path contains `$CARGO_MANIFEST_DIR` + assert!($path.contains("$CARGO_MANIFEST_DIR")); + // make sure `CARGO_MANIFEST_DIR` is the only env variable in the path + assert!(!$path.replace("$CARGO_MANIFEST_DIR", "").contains('$')); + + turbo_tasks_fs::embed_directory_internal!($name, $path) + }}; +} + +#[cfg(feature = "dynamic_embed_contents")] +#[macro_export] +#[doc(hidden)] +macro_rules! embed_directory_internal { + ($name:tt, $path:tt) => {{ + // make sure the types the `include_dir!` proc macro refers to are in scope + use turbo_tasks_fs::embed::include_dir; + + let path = $path.replace("$CARGO_MANIFEST_DIR", env!("CARGO_MANIFEST_DIR")); + + turbo_tasks_fs::embed::directory_from_relative_path($name.to_string(), path) + }}; +} + +#[cfg(not(feature = "dynamic_embed_contents"))] +#[macro_export] +#[doc(hidden)] +macro_rules! embed_directory_internal { + ($name:tt, $path:tt) => {{ + // make sure the types the `include_dir!` proc macro refers to are in scope + use turbo_tasks_fs::embed::include_dir; + + static dir: include_dir::Dir<'static> = turbo_tasks_fs::embed::include_dir!($path); + + turbo_tasks_fs::embed::directory_from_include_dir( + $name.into(), + turbo_tasks::TransientInstance::new(&dir), + ) + }}; +} diff --git a/turbopack/crates/turbo-tasks-fs/src/embed/file.rs b/turbopack/crates/turbo-tasks-fs/src/embed/file.rs new file mode 100644 index 0000000000000..74646862b8ff4 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/embed/file.rs @@ -0,0 +1,63 @@ +use std::path::PathBuf; + +use anyhow::{Context, Result}; +use dunce::canonicalize; +use turbo_tasks::{RcStr, Vc}; + +use crate::{DiskFileSystem, File, FileContent, FileSystem}; + +#[turbo_tasks::function] +pub async fn content_from_relative_path( + package_path: RcStr, + path: RcStr, +) -> Result> { + let package_path = PathBuf::from(package_path); + let resolved_path = package_path.join(path); + let resolved_path = + canonicalize(&resolved_path).context("failed to canonicalize embedded file path")?; + let root_path = resolved_path.parent().unwrap(); + let path = resolved_path.file_name().unwrap().to_str().unwrap(); + + let disk_fs = DiskFileSystem::new( + root_path.to_string_lossy().into(), + root_path.to_string_lossy().into(), + vec![], + ); + disk_fs.await?.start_watching()?; + + let fs_path = disk_fs.root().join(path.into()); + Ok(fs_path.read()) +} + +#[turbo_tasks::function] +pub async fn content_from_str(string: RcStr) -> Result> { + Ok(File::from(string).into()) +} + +/// Loads a file's content from disk and invalidates on change (debug builds). +/// +/// In production, this will embed a file's content into the binary directly. +#[cfg(feature = "dynamic_embed_contents")] +#[macro_export] +macro_rules! embed_file { + ($path:expr) => {{ + // check that the file exists at compile time + let _ = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path)); + + turbo_tasks_fs::embed::content_from_relative_path( + env!("CARGO_MANIFEST_DIR").to_string(), + $path.to_string(), + ) + }}; +} + +/// Embeds a file's content into the binary (production). +#[cfg(not(feature = "dynamic_embed_contents"))] +#[macro_export] +macro_rules! embed_file { + ($path:expr) => { + turbo_tasks_fs::embed::content_from_str( + include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/", $path)).into(), + ) + }; +} diff --git a/turbopack/crates/turbo-tasks-fs/src/embed/fs.rs b/turbopack/crates/turbo-tasks-fs/src/embed/fs.rs new file mode 100644 index 0000000000000..e0f24c32e54c4 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/embed/fs.rs @@ -0,0 +1,118 @@ +use anyhow::{bail, Result}; +use include_dir::{Dir, DirEntry}; +use turbo_tasks::{Completion, RcStr, TransientInstance, ValueToString, Vc}; + +use crate::{ + DirectoryContent, DirectoryEntry, File, FileContent, FileMeta, FileSystem, FileSystemPath, + LinkContent, +}; + +#[turbo_tasks::value(serialization = "none")] +pub struct EmbeddedFileSystem { + name: RcStr, + #[turbo_tasks(trace_ignore)] + dir: TransientInstance<&'static Dir<'static>>, +} + +#[turbo_tasks::value_impl] +impl EmbeddedFileSystem { + #[turbo_tasks::function] + pub(super) fn new( + name: RcStr, + dir: TransientInstance<&'static Dir<'static>>, + ) -> Vc { + EmbeddedFileSystem { name, dir }.cell() + } +} + +#[turbo_tasks::value_impl] +impl FileSystem for EmbeddedFileSystem { + #[turbo_tasks::function] + async fn read(&self, path: Vc) -> Result> { + let file = match self.dir.get_file(&path.await?.path) { + Some(file) => file, + None => return Ok(FileContent::NotFound.cell()), + }; + + Ok(File::from(file.contents()).into()) + } + + #[turbo_tasks::function] + fn read_link(&self, _path: Vc) -> Vc { + LinkContent::NotFound.cell() + } + + #[turbo_tasks::function] + async fn read_dir(&self, path: Vc) -> Result> { + let path_str = &path.await?.path; + let dir = match (path_str.as_str(), self.dir.get_dir(path_str)) { + ("", _) => *self.dir, + (_, Some(dir)) => dir, + (_, None) => return Ok(DirectoryContent::NotFound.cell()), + }; + + let entries = dir + .entries() + .iter() + .map(|e| { + let entry_name: RcStr = e + .path() + .file_name() + .unwrap_or_default() + .to_string_lossy() + .into(); + let entry_path = path.join(entry_name.clone()); + + ( + entry_name, + match e { + DirEntry::Dir(_) => DirectoryEntry::Directory(entry_path), + DirEntry::File(_) => DirectoryEntry::File(entry_path), + }, + ) + }) + .collect(); + + Ok(DirectoryContent::new(entries)) + } + + #[turbo_tasks::function] + fn track(&self, _path: Vc) -> Vc { + Completion::immutable() + } + + #[turbo_tasks::function] + fn write( + &self, + _path: Vc, + _content: Vc, + ) -> Result> { + bail!("Writing is not possible to the embedded filesystem") + } + + #[turbo_tasks::function] + fn write_link( + &self, + _path: Vc, + _target: Vc, + ) -> Result> { + bail!("Writing is not possible to the embedded filesystem") + } + + #[turbo_tasks::function] + async fn metadata(&self, path: Vc) -> Result> { + if self.dir.get_entry(&path.await?.path).is_none() { + bail!("path not found, can't read metadata"); + } + + Ok(FileMeta::default().cell()) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EmbeddedFileSystem { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(self.name.clone()) + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/embed/mod.rs b/turbopack/crates/turbo-tasks-fs/src/embed/mod.rs new file mode 100644 index 0000000000000..d388918c78b2f --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/embed/mod.rs @@ -0,0 +1,5 @@ +pub(crate) mod dir; +pub(crate) mod file; +pub(crate) mod fs; + +pub use self::{dir::*, file::*, fs::*}; diff --git a/turbopack/crates/turbo-tasks-fs/src/glob.rs b/turbopack/crates/turbo-tasks-fs/src/glob.rs new file mode 100644 index 0000000000000..43e72853ed1f5 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/glob.rs @@ -0,0 +1,519 @@ +use std::mem::take; + +use anyhow::{anyhow, bail, Context, Result}; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, RcStr, TryJoinIterExt, Vc}; +use unicode_segmentation::GraphemeCursor; + +#[derive(PartialEq, Eq, Debug, Clone, TraceRawVcs, Serialize, Deserialize)] +enum GlobPart { + /// `/**/`: Matches any path of directories + AnyDirectories, + + /// `*`: Matches any filename (no path separator) + AnyFile, + + /// `?`: Matches a single filename character (no path separator) + AnyFileChar, + + /// `/`: Matches the path separator + PathSeparator, + + /// `[abc]`: Matches any char of the list + FileChar(Vec), + + /// `abc`: Matches literal filename + File(String), + + /// `{a,b,c}`: Matches any of the globs in the list + Alternatives(Vec), +} + +// Examples: +// - file.js = File(file.js) +// - *.js = AnyFile, File(.js) +// - file*.js = File(file), AnyFile, File(.js) +// - dir/file.js = File(dir), PathSeparator, File(file.js) +// - **/*.js = AnyDirectories, PathSeparator, AnyFile, File(.js) +// - {a/**,*}/file = Alternatives([File(a), PathSeparator, AnyDirectories], +// [AnyFile]), PathSeparator, File(file) + +// Note: a/**/b does match a/b, so we need some special logic about path +// separators + +#[turbo_tasks::value] +#[derive(Debug, Clone)] +pub struct Glob { + expression: Vec, +} + +impl Glob { + pub fn execute(&self, path: &str) -> bool { + let match_partial = path.ends_with('/'); + self.iter_matches(path, true, match_partial) + .any(|result| matches!(result, ("", _))) + } + + fn iter_matches<'a>( + &'a self, + path: &'a str, + previous_part_is_path_separator_equivalent: bool, + match_partial: bool, + ) -> GlobMatchesIterator<'a> { + GlobMatchesIterator { + current: path, + glob: self, + match_partial, + is_path_separator_equivalent: previous_part_is_path_separator_equivalent, + stack: Vec::new(), + index: 0, + } + } + + pub fn parse(input: &str) -> Result { + let mut current = input; + let mut expression = Vec::new(); + + while !current.is_empty() { + let (part, remainder) = GlobPart::parse(current, false) + .with_context(|| anyhow!("Failed to parse glob {input}"))?; + expression.push(part); + current = remainder; + } + + Ok(Glob { expression }) + } +} + +struct GlobMatchesIterator<'a> { + current: &'a str, + glob: &'a Glob, + match_partial: bool, + is_path_separator_equivalent: bool, + stack: Vec>, + index: usize, +} + +impl<'a> Iterator for GlobMatchesIterator<'a> { + type Item = (&'a str, bool); + + fn next(&mut self) -> Option { + loop { + if let Some(part) = self.glob.expression.get(self.index) { + let iter = if let Some(iter) = self.stack.get_mut(self.index) { + iter + } else { + let iter = part.iter_matches( + self.current, + self.is_path_separator_equivalent, + self.match_partial, + ); + self.stack.push(iter); + self.stack.last_mut().unwrap() + }; + if let Some((new_path, new_is_path_separator_equivalent)) = iter.next() { + self.current = new_path; + self.is_path_separator_equivalent = new_is_path_separator_equivalent; + + self.index += 1; + + if self.match_partial && self.current.is_empty() { + return Some(("", self.is_path_separator_equivalent)); + } + } else { + if self.index == 0 { + // failed to match + return None; + } + // backtrack + self.stack.pop(); + self.index -= 1; + } + } else { + // end of expression, matched successfully + + // backtrack for the next iteration + self.index -= 1; + + return Some((self.current, self.is_path_separator_equivalent)); + } + } + } +} + +impl GlobPart { + /// Iterates over all possible matches of this part with the provided path. + /// The least greedy match is returned first. This is usually used for + /// backtracking. The string slice returned is the remaining part or the + /// path. The boolean flag returned specifies if the matched part should + /// be considered as path-separator equivalent. + fn iter_matches<'a>( + &'a self, + path: &'a str, + previous_part_is_path_separator_equivalent: bool, + match_partial: bool, + ) -> GlobPartMatchesIterator<'a> { + GlobPartMatchesIterator { + path, + part: self, + match_partial, + previous_part_is_path_separator_equivalent, + cursor: GraphemeCursor::new(0, path.len(), true), + index: 0, + glob_iterator: None, + } + } + + fn parse(input: &str, inside_of_braces: bool) -> Result<(GlobPart, &str)> { + debug_assert!(!input.is_empty()); + let two_chars = { + let mut chars = input.chars(); + (chars.next().unwrap(), chars.next()) + }; + match two_chars { + ('/', _) => Ok((GlobPart::PathSeparator, &input[1..])), + ('*', Some('*')) => Ok((GlobPart::AnyDirectories, &input[2..])), + ('*', _) => Ok((GlobPart::AnyFile, &input[1..])), + ('?', _) => Ok((GlobPart::AnyFileChar, &input[1..])), + ('[', Some('[')) => todo!("glob char classes are not implemented yet"), + ('[', _) => todo!("glob char sequences are not implemented yet"), + ('{', Some(_)) => { + let mut current = &input[1..]; + let mut alternatives = Vec::new(); + let mut expression = Vec::new(); + + loop { + let (part, remainder) = GlobPart::parse(current, true)?; + expression.push(part); + current = remainder; + match current.chars().next() { + Some(',') => { + alternatives.push(Glob { + expression: take(&mut expression), + }); + current = ¤t[1..]; + } + Some('}') => { + alternatives.push(Glob { + expression: take(&mut expression), + }); + current = ¤t[1..]; + break; + } + None => bail!("Unterminated glob braces"), + _ => { + // next part of the glob + } + } + } + + Ok((GlobPart::Alternatives(alternatives), current)) + } + ('{', None) => { + bail!("Unterminated glob braces") + } + _ => { + let mut is_escaped = false; + let mut literal = String::new(); + + let mut cursor = GraphemeCursor::new(0, input.len(), true); + + let mut start = cursor.cur_cursor(); + let mut end_cursor = cursor + .next_boundary(input, 0) + .map_err(|e| anyhow!("{:?}", e))?; + + while let Some(end) = end_cursor { + let c = &input[start..end]; + if is_escaped { + is_escaped = false; + } else if c == "\\" { + is_escaped = true; + } else if c == "/" + || c == "*" + || c == "?" + || c == "[" + || c == "{" + || (inside_of_braces && (c == "," || c == "}")) + { + break; + } + literal.push_str(c); + + start = cursor.cur_cursor(); + end_cursor = cursor + .next_boundary(input, end) + .map_err(|e| anyhow!("{:?}", e))?; + } + + Ok((GlobPart::File(literal), &input[start..])) + } + } + } +} + +struct GlobPartMatchesIterator<'a> { + path: &'a str, + part: &'a GlobPart, + match_partial: bool, + previous_part_is_path_separator_equivalent: bool, + cursor: GraphemeCursor, + index: usize, + glob_iterator: Option>>, +} + +impl<'a> Iterator for GlobPartMatchesIterator<'a> { + type Item = (&'a str, bool); + + fn next(&mut self) -> Option { + match self.part { + GlobPart::AnyDirectories => { + if self.cursor.cur_cursor() == 0 { + let Ok(Some(_)) = self.cursor.next_boundary(self.path, 0) else { + return None; + }; + return Some((self.path, true)); + } + + if self.cursor.cur_cursor() == self.path.len() { + return None; + } + + loop { + let start = self.cursor.cur_cursor(); + // next_boundary does not set cursor offset to the end of the string + // if there is no next boundary - manually set cursor to the end + let end = match self.cursor.next_boundary(self.path, 0) { + Ok(end) => { + if let Some(end) = end { + end + } else { + self.cursor.set_cursor(self.path.len()); + self.cursor.cur_cursor() + } + } + _ => return None, + }; + + if &self.path[start..end] == "/" { + return Some((&self.path[end..], true)); + } else if start == end { + return Some((&self.path[start..], false)); + } + } + } + GlobPart::AnyFile => { + let Ok(Some(c)) = self.cursor.next_boundary(self.path, 0) else { + return None; + }; + + let idx = self.path[0..c].len(); + + // TODO verify if `*` does match zero chars? + if let Some(slice) = self.path.get(0..c) { + if slice.ends_with('/') { + None + } else { + Some(( + &self.path[c..], + self.previous_part_is_path_separator_equivalent && idx == 1, + )) + } + } else { + None + } + } + GlobPart::AnyFileChar => todo!(), + GlobPart::PathSeparator => { + if self.cursor.cur_cursor() == 0 { + let Ok(Some(b)) = self.cursor.next_boundary(self.path, 0) else { + return None; + }; + if self.path.starts_with('/') { + Some((&self.path[b..], true)) + } else if self.previous_part_is_path_separator_equivalent { + Some((self.path, true)) + } else { + None + } + } else { + None + } + } + GlobPart::FileChar(chars) => { + let start = self.cursor.cur_cursor(); + let Ok(Some(end)) = self.cursor.next_boundary(self.path, 0) else { + return None; + }; + let mut chars_in_path = self.path[start..end].chars(); + let c = chars_in_path.next()?; + if chars_in_path.next().is_some() { + return None; + } + chars.contains(&c).then(|| (&self.path[end..], false)) + } + GlobPart::File(name) => { + if self.cursor.cur_cursor() == 0 && self.path.starts_with(name) { + let Ok(Some(_)) = self.cursor.next_boundary(self.path, 0) else { + return None; + }; + Some((&self.path[name.len()..], false)) + } else { + None + } + } + GlobPart::Alternatives(alternatives) => loop { + if let Some(glob_iterator) = &mut self.glob_iterator { + if let Some((path, is_path_separator_equivalent)) = glob_iterator.next() { + return Some((path, is_path_separator_equivalent)); + } else { + self.index += 1; + self.glob_iterator = None; + } + } else if let Some(alternative) = alternatives.get(self.index) { + self.glob_iterator = Some(Box::new(alternative.iter_matches( + self.path, + self.previous_part_is_path_separator_equivalent, + self.match_partial, + ))); + } else { + return None; + } + }, + } + } +} + +impl TryFrom<&str> for Glob { + type Error = anyhow::Error; + + fn try_from(value: &str) -> Result { + Glob::parse(value) + } +} + +#[turbo_tasks::value_impl] +impl Glob { + #[turbo_tasks::function] + pub fn new(glob: RcStr) -> Result> { + Ok(Self::cell(Glob::try_from(glob.as_str())?)) + } + + #[turbo_tasks::function] + pub async fn alternatives(globs: Vec>) -> Result> { + if globs.len() == 1 { + return Ok(globs.into_iter().next().unwrap()); + } + Ok(Self::cell(Glob { + expression: vec![GlobPart::Alternatives( + globs + .into_iter() + .try_join() + .await? + .into_iter() + .map(|g| g.clone_value()) + .collect(), + )], + })) + } +} + +#[cfg(test)] +mod tests { + use rstest::*; + + use super::Glob; + + #[rstest] + #[case::file("file.js", "file.js")] + #[case::dir_and_file("../public/äöüščří.png", "../public/äöüščří.png")] + #[case::dir_and_file("dir/file.js", "dir/file.js")] + #[case::dir_and_file_partial("dir/file.js", "dir/")] + #[case::file_braces("file.{ts,js}", "file.js")] + #[case::dir_and_file_braces("dir/file.{ts,js}", "dir/file.js")] + #[case::dir_and_file_dir_braces("{dir,other}/file.{ts,js}", "dir/file.js")] + #[case::star("*.js", "file.js")] + #[case::dir_star("dir/*.js", "dir/file.js")] + #[case::dir_star_partial("dir/*.js", "dir/")] + #[case::globstar("**/*.js", "file.js")] + #[case::globstar("**/*.js", "dir/file.js")] + #[case::globstar("**/*.js", "dir/sub/file.js")] + #[case::globstar("**/**/*.js", "file.js")] + #[case::globstar("**/**/*.js", "dir/sub/file.js")] + #[case::globstar_partial("**/**/*.js", "dir/sub/")] + #[case::globstar_partial("**/**/*.js", "dir/")] + #[case::globstar_in_dir("dir/**/sub/file.js", "dir/sub/file.js")] + #[case::globstar_in_dir("dir/**/sub/file.js", "dir/a/sub/file.js")] + #[case::globstar_in_dir("dir/**/sub/file.js", "dir/a/b/sub/file.js")] + #[case::globstar_in_dir( + "**/next/dist/**/*.shared-runtime.js", + "next/dist/shared/lib/app-router-context.shared-runtime.js" + )] + #[case::globstar_in_dir_partial("dir/**/sub/file.js", "dir/a/b/sub/")] + #[case::globstar_in_dir_partial("dir/**/sub/file.js", "dir/a/b/")] + #[case::globstar_in_dir_partial("dir/**/sub/file.js", "dir/a/")] + #[case::globstar_in_dir_partial("dir/**/sub/file.js", "dir/")] + #[case::star_dir( + "**/*/next/dist/server/next.js", + "node_modules/next/dist/server/next.js" + )] + #[case::node_modules_root("**/node_modules/**", "node_modules/next/dist/server/next.js")] + #[case::node_modules_root_package( + "**/node_modules/next/**", + "node_modules/next/dist/server/next.js" + )] + #[case::node_modules_nested( + "**/node_modules/**", + "apps/some-app/node_modules/regenerate-unicode-properties/Script_Extensions/Osage.js" + )] + #[case::node_modules_nested_package( + "**/node_modules/regenerate-unicode-properties/**", + "apps/some-app/node_modules/regenerate-unicode-properties/Script_Extensions/Osage.js" + )] + #[case::node_modules_pnpm( + "**/node_modules/**", + "node_modules/.pnpm/regenerate-unicode-properties@9.0.0/node_modules/\ + regenerate-unicode-properties/Script_Extensions/Osage.js" + )] + #[case::node_modules_pnpm_package( + "**/node_modules/{regenerate,regenerate-unicode-properties}/**", + "node_modules/.pnpm/regenerate-unicode-properties@9.0.0/node_modules/\ + regenerate-unicode-properties/Script_Extensions/Osage.js" + )] + #[case::node_modules_pnpm_prefixed_package( + "**/node_modules/{@blockfrost/blockfrost-js,@highlight-run/node,@libsql/client,@jpg-store/\ + lucid-cardano,@mikro-orm/core,@mikro-orm/knex,@prisma/client,@sentry/nextjs,@sentry/node,\ + @swc/core,argon2,autoprefixer,bcrypt,better-sqlite3,canvas,cpu-features,cypress,eslint,\ + express,next-seo,node-pty,payload,pg,playwright,postcss,prettier,prisma,puppeteer,rimraf,\ + sharp,shiki,sqlite3,tailwindcss,ts-node,typescript,vscode-oniguruma,webpack,websocket,@\ + aws-sdk/client-dynamodb,@aws-sdk/lib-dynamodb}/**", + "node_modules/.pnpm/@aws-sdk+lib-dynamodb@3.445.0_@aws-sdk+client-dynamodb@3.445.0/\ + node_modules/@aws-sdk/lib-dynamodb/dist-es/index.js" + )] + #[case::alternatives_nested1("{a,b/c,d/e/{f,g/h}}", "a")] + #[case::alternatives_nested2("{a,b/c,d/e/{f,g/h}}", "b/c")] + #[case::alternatives_nested3("{a,b/c,d/e/{f,g/h}}", "d/e/f")] + #[case::alternatives_nested4("{a,b/c,d/e/{f,g/h}}", "d/e/g/h")] + // #[case::alternatives_chars("[abc]", "b")] + fn glob_match(#[case] glob: &str, #[case] path: &str) { + let glob = Glob::parse(glob).unwrap(); + + println!("{glob:?} {path}"); + + assert!(glob.execute(path)); + } + + #[rstest] + #[case::early_end("*.raw", "hello.raw.js")] + #[case::early_end( + "**/next/dist/esm/*.shared-runtime.js", + "next/dist/shared/lib/app-router-context.shared-runtime.js" + )] + fn glob_not_matching(#[case] glob: &str, #[case] path: &str) { + let glob = Glob::parse(glob).unwrap(); + + println!("{glob:?} {path}"); + + assert!(!glob.execute(path)); + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/invalidation.rs b/turbopack/crates/turbo-tasks-fs/src/invalidation.rs new file mode 100644 index 0000000000000..22976c49dc4e4 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/invalidation.rs @@ -0,0 +1,130 @@ +use std::fmt::{Display, Formatter}; + +use indexmap::IndexSet; +use turbo_tasks::{util::StaticOrArc, InvalidationReason, InvalidationReasonKind, RcStr}; + +/// Invalidation was caused by a file change detected by the file watcher +#[derive(PartialEq, Eq, Hash)] +pub struct WatchChange { + pub path: String, +} + +impl InvalidationReason for WatchChange { + fn kind(&self) -> Option> { + Some(StaticOrArc::Static(&WATCH_CHANGE_KIND)) + } +} + +impl Display for WatchChange { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{} changed", self.path) + } +} + +/// Invalidation kind for [WatchChange] +#[derive(PartialEq, Eq, Hash)] +struct WatchChangeKind; + +static WATCH_CHANGE_KIND: WatchChangeKind = WatchChangeKind; + +impl InvalidationReasonKind for WatchChangeKind { + fn fmt( + &self, + reasons: &IndexSet>, + f: &mut Formatter<'_>, + ) -> std::fmt::Result { + write!( + f, + "{} files changed ({}, ...)", + reasons.len(), + reasons[0] + .as_any() + .downcast_ref::() + .unwrap() + .path + ) + } +} + +/// Invalidation was caused by a directory starting to watch from which was read +/// before. +#[derive(PartialEq, Eq, Hash)] +pub struct WatchStart { + pub name: RcStr, +} + +impl InvalidationReason for WatchStart { + fn kind(&self) -> Option> { + Some(StaticOrArc::Static(&WATCH_START_KIND)) + } +} + +impl Display for WatchStart { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{} started watching", self.name) + } +} + +/// Invalidation kind for [WatchStart] +#[derive(PartialEq, Eq, Hash)] +struct WatchStartKind; + +static WATCH_START_KIND: WatchStartKind = WatchStartKind; + +impl InvalidationReasonKind for WatchStartKind { + fn fmt( + &self, + reasons: &IndexSet>, + f: &mut Formatter<'_>, + ) -> std::fmt::Result { + write!( + f, + "{} directories started watching (e. g. {})", + reasons.len(), + reasons[0] + .as_any() + .downcast_ref::() + .unwrap() + .name + ) + } +} + +/// Invalidation was caused by a write operation on the filesystem +#[derive(PartialEq, Eq, Hash)] +pub struct Write { + pub path: String, +} + +impl InvalidationReason for Write { + fn kind(&self) -> Option> { + Some(StaticOrArc::Static(&WRITE_KIND)) + } +} + +impl Display for Write { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{} written", self.path) + } +} + +/// Invalidation kind for [Write] +#[derive(PartialEq, Eq, Hash)] +struct WriteKind; + +static WRITE_KIND: WriteKind = WriteKind; + +impl InvalidationReasonKind for WriteKind { + fn fmt( + &self, + reasons: &IndexSet>, + f: &mut Formatter<'_>, + ) -> std::fmt::Result { + write!( + f, + "{} files written ({}, ...)", + reasons.len(), + reasons[0].as_any().downcast_ref::().unwrap().path + ) + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/invalidator_map.rs b/turbopack/crates/turbo-tasks-fs/src/invalidator_map.rs new file mode 100644 index 0000000000000..9ecaf6b1aee2e --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/invalidator_map.rs @@ -0,0 +1,86 @@ +use std::{ + collections::{HashMap, HashSet}, + sync::{LockResult, Mutex, MutexGuard}, +}; + +use concurrent_queue::ConcurrentQueue; +use serde::{de::Visitor, Deserialize, Serialize}; +use turbo_tasks::Invalidator; + +pub struct InvalidatorMap { + queue: ConcurrentQueue<(String, Invalidator)>, + map: Mutex>>, +} + +impl InvalidatorMap { + pub fn new() -> Self { + Self { + queue: ConcurrentQueue::unbounded(), + map: Default::default(), + } + } + + pub fn lock(&self) -> LockResult>>> { + let mut guard = self.map.lock()?; + while let Ok((key, value)) = self.queue.pop() { + guard.entry(key).or_default().insert(value); + } + Ok(guard) + } + + #[allow(unused_must_use)] + pub fn insert(&self, key: String, invalidator: Invalidator) { + self.queue.push((key, invalidator)); + } +} + +impl Serialize for InvalidatorMap { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_newtype_struct("InvalidatorMap", &*self.lock().unwrap()) + } +} + +impl<'de> Deserialize<'de> for InvalidatorMap { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct V; + + impl<'de> Visitor<'de> for V { + type Value = InvalidatorMap; + + fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "an InvalidatorMap") + } + + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Ok(InvalidatorMap { + queue: ConcurrentQueue::unbounded(), + map: Mutex::new(Deserialize::deserialize(deserializer)?), + }) + } + } + + deserializer.deserialize_newtype_struct("InvalidatorMap", V) + } +} + +impl Drop for InvalidatorMap { + fn drop(&mut self) { + while let Ok((_, value)) = self.queue.pop() { + value.invalidate(); + } + for (_, invalidators) in self.map.lock().unwrap().drain() { + for invalidator in invalidators { + invalidator.invalidate(); + } + } + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/json.rs b/turbopack/crates/turbo-tasks-fs/src/json.rs new file mode 100644 index 0000000000000..27c2793b87ad7 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/json.rs @@ -0,0 +1,123 @@ +use std::{ + borrow::Cow, + fmt::{Display, Formatter, Write}, +}; + +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use turbo_tasks::trace::TraceRawVcs; + +use crate::{rope::Rope, source_context::get_source_context}; + +#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, TraceRawVcs)] +pub struct UnparseableJson { + #[turbo_tasks(trace_ignore)] + pub message: Cow<'static, str>, + pub path: Option, + /// The start line and column of the error. + /// Line and column is 0-based. + pub start_location: Option<(usize, usize)>, + /// The end line and column of the error. + /// Line and column is 0-based. + pub end_location: Option<(usize, usize)>, +} + +/// Converts a byte position to a 0-based line and column. +fn byte_to_location(pos: usize, text: &str) -> (usize, usize) { + let text = &text[..pos]; + let mut lines = text.lines().rev(); + let last = lines.next().unwrap_or(""); + let column = last.len(); + let line = lines.count(); + (line, column) +} + +impl UnparseableJson { + pub fn from_jsonc_error(e: jsonc_parser::errors::ParseError, text: &str) -> Self { + Self { + message: e.message.clone().into(), + path: None, + start_location: Some(byte_to_location(e.range.start, text)), + end_location: Some(byte_to_location(e.range.end, text)), + } + } + + pub fn from_serde_path_to_error(e: serde_path_to_error::Error) -> Self { + let inner = e.inner(); + Self { + message: inner.to_string().into(), + path: Some(e.path().to_string()), + start_location: Some(( + inner.line().saturating_sub(1), + inner.column().saturating_sub(1), + )), + end_location: None, + } + } + + pub fn write_with_content(&self, writer: &mut impl Write, text: &str) -> std::fmt::Result { + writeln!(writer, "{}", self.message)?; + if let Some(path) = &self.path { + writeln!(writer, " at {}", path)?; + } + match (self.start_location, self.end_location) { + (Some((line, column)), Some((end_line, end_column))) => { + write!( + writer, + "{}", + get_source_context(text.lines(), line, column, end_line, end_column,) + )?; + } + (Some((line, column)), None) | (None, Some((line, column))) => { + write!( + writer, + "{}", + get_source_context(text.lines(), line, column, line, column) + )?; + } + (None, None) => { + write!(writer, "{}", get_source_context(text.lines(), 0, 0, 0, 0))?; + } + } + Ok(()) + } + + pub fn to_string_with_content(&self, text: &str) -> String { + let mut result = String::new(); + self.write_with_content(&mut result, text).unwrap(); + result + } +} + +impl Display for UnparseableJson { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.message)?; + if let Some(path) = &self.path { + write!(f, " at {}", path)?; + } + Ok(()) + } +} + +pub fn parse_json_with_source_context<'de, T: Deserialize<'de>>(text: &'de str) -> Result { + let de = &mut serde_json::Deserializer::from_str(text); + match serde_path_to_error::deserialize(de) { + Ok(data) => Ok(data), + Err(e) => Err(anyhow::Error::msg( + UnparseableJson::from_serde_path_to_error(e).to_string_with_content(text), + )), + } +} + +pub fn parse_json_rope_with_source_context<'de, T: Deserialize<'de>>(rope: &'de Rope) -> Result { + let de = &mut serde_json::Deserializer::from_reader(rope.read()); + match serde_path_to_error::deserialize(de) { + Ok(data) => Ok(data), + Err(e) => { + let cow = rope.to_str()?; + Err(anyhow::Error::msg( + UnparseableJson::from_serde_path_to_error(e).to_string_with_content(&cow), + )) + } + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/lib.rs b/turbopack/crates/turbo-tasks-fs/src/lib.rs new file mode 100644 index 0000000000000..ce8bac1752816 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/lib.rs @@ -0,0 +1,2006 @@ +#![feature(trivial_bounds)] +#![feature(hash_extract_if)] +#![feature(min_specialization)] +#![feature(iter_advance_by)] +#![feature(io_error_more)] +#![feature(round_char_boundary)] +#![feature(arbitrary_self_types)] +#![feature(lint_reasons)] +#![allow(clippy::mutable_key_type)] + +pub mod attach; +pub mod embed; +pub mod glob; +mod invalidation; +mod invalidator_map; +pub mod json; +mod mutex_map; +mod read_glob; +mod retry; +pub mod rope; +pub mod source_context; +pub mod util; +pub(crate) mod virtual_fs; +mod watcher; + +use std::{ + borrow::Cow, + cmp::min, + collections::HashSet, + fmt::{ + Debug, Display, Formatter, {self}, + }, + fs::FileType, + io::{ + BufRead, ErrorKind, {self}, + }, + mem::take, + path::{Path, PathBuf, MAIN_SEPARATOR}, + sync::Arc, +}; + +use anyhow::{anyhow, bail, Context, Result}; +use auto_hash_map::AutoMap; +use bitflags::bitflags; +use dunce::simplified; +use glob::Glob; +use invalidator_map::InvalidatorMap; +use jsonc_parser::{parse_to_serde_value, ParseOptions}; +use mime::Mime; +use read_glob::read_glob; +pub use read_glob::ReadGlobResult; +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use tokio::{ + fs, + io::{AsyncBufReadExt, AsyncReadExt, BufReader}, + sync::{RwLock, RwLockReadGuard}, +}; +use tracing::Instrument; +use turbo_tasks::{ + mark_stateful, trace::TraceRawVcs, Completion, InvalidationReason, Invalidator, RcStr, ReadRef, + ValueToString, Vc, +}; +use turbo_tasks_hash::{hash_xxh3_hash64, DeterministicHash, DeterministicHasher}; +use util::{extract_disk_access, join_path, normalize_path, sys_to_unix, unix_to_sys}; +pub use virtual_fs::VirtualFileSystem; +use watcher::DiskWatcher; + +use self::{invalidation::Write, json::UnparseableJson, mutex_map::MutexMap}; +use crate::{ + attach::AttachedFileSystem, + retry::{retry_blocking, retry_future}, + rope::{Rope, RopeReader}, +}; + +#[turbo_tasks::value_trait] +pub trait FileSystem: ValueToString { + /// Returns the path to the root of the file system. + fn root(self: Vc) -> Vc { + FileSystemPath::new_normalized(self, RcStr::default()) + } + fn read(self: Vc, fs_path: Vc) -> Vc; + fn read_link(self: Vc, fs_path: Vc) -> Vc; + fn read_dir(self: Vc, fs_path: Vc) -> Vc; + fn track(self: Vc, fs_path: Vc) -> Vc; + fn write( + self: Vc, + fs_path: Vc, + content: Vc, + ) -> Vc; + fn write_link( + self: Vc, + fs_path: Vc, + target: Vc, + ) -> Vc; + fn metadata(self: Vc, fs_path: Vc) -> Vc; +} + +#[turbo_tasks::value(cell = "new", eq = "manual")] +pub struct DiskFileSystem { + pub name: RcStr, + pub root: RcStr, + #[turbo_tasks(debug_ignore, trace_ignore)] + #[serde(skip)] + mutex_map: MutexMap, + #[turbo_tasks(debug_ignore, trace_ignore)] + invalidator_map: Arc, + #[turbo_tasks(debug_ignore, trace_ignore)] + dir_invalidator_map: Arc, + /// Lock that makes invalidation atomic. It will keep a write lock during + /// watcher invalidation and a read lock during other operations. + #[turbo_tasks(debug_ignore, trace_ignore)] + #[serde(skip)] + invalidation_lock: Arc>, + #[turbo_tasks(debug_ignore, trace_ignore)] + watcher: Arc, +} + +impl DiskFileSystem { + /// Returns the root as Path + fn root_path(&self) -> &Path { + simplified(Path::new(&*self.root)) + } + + /// registers the path as an invalidator for the current task, + /// has to be called within a turbo-tasks function + fn register_invalidator(&self, path: &Path) -> Result<()> { + let invalidator = turbo_tasks::get_invalidator(); + self.invalidator_map.insert(path_to_key(path), invalidator); + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + if let Some(dir) = path.parent() { + self.watcher.ensure_watching(dir, self.root_path())?; + } + Ok(()) + } + + /// registers the path as an invalidator for the current task, + /// has to be called within a turbo-tasks function. It removes and returns + /// the current list of invalidators. + fn register_sole_invalidator(&self, path: &Path) -> Result> { + let invalidator = turbo_tasks::get_invalidator(); + let mut invalidator_map = self.invalidator_map.lock().unwrap(); + let old_invalidators = invalidator_map.insert(path_to_key(path), [invalidator].into()); + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + if let Some(dir) = path.parent() { + self.watcher.ensure_watching(dir, self.root_path())?; + } + Ok(old_invalidators.unwrap_or_default()) + } + + /// registers the path as an invalidator for the current task, + /// has to be called within a turbo-tasks function + fn register_dir_invalidator(&self, path: &Path) -> Result<()> { + let invalidator = turbo_tasks::get_invalidator(); + self.dir_invalidator_map + .insert(path_to_key(path), invalidator); + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + self.watcher.ensure_watching(path, self.root_path())?; + Ok(()) + } + + async fn lock_path(&self, full_path: &Path) -> PathLockGuard<'_> { + let lock1 = self.invalidation_lock.read().await; + let lock2 = self.mutex_map.lock(full_path.to_path_buf()).await; + PathLockGuard(lock1, lock2) + } + + pub fn invalidate(&self) { + for (_, invalidators) in take(&mut *self.invalidator_map.lock().unwrap()).into_iter() { + invalidators.into_iter().for_each(|i| i.invalidate()); + } + for (_, invalidators) in take(&mut *self.dir_invalidator_map.lock().unwrap()).into_iter() { + invalidators.into_iter().for_each(|i| i.invalidate()); + } + } + + pub fn invalidate_with_reason(&self, reason: T) { + for (_, invalidators) in take(&mut *self.invalidator_map.lock().unwrap()).into_iter() { + invalidators + .into_iter() + .for_each(|i| i.invalidate_with_reason(reason.clone())); + } + for (_, invalidators) in take(&mut *self.dir_invalidator_map.lock().unwrap()).into_iter() { + invalidators + .into_iter() + .for_each(|i| i.invalidate_with_reason(reason.clone())); + } + } + + pub fn start_watching(&self) -> Result<()> { + self.start_watching_internal(false) + } + + pub fn start_watching_with_invalidation_reason(&self) -> Result<()> { + self.start_watching_internal(true) + } + + fn start_watching_internal(&self, report_invalidation_reason: bool) -> Result<()> { + let invalidator_map = self.invalidator_map.clone(); + let dir_invalidator_map = self.dir_invalidator_map.clone(); + let root_path = self.root_path().to_path_buf(); + + let report_invalidation_reason = + report_invalidation_reason.then(|| (self.name.clone(), root_path.clone())); + let invalidation_lock = self.invalidation_lock.clone(); + + self.watcher.clone().start_watching( + self.name.clone(), + root_path, + report_invalidation_reason, + invalidation_lock, + invalidator_map, + dir_invalidator_map, + )?; + + Ok(()) + } + + pub fn stop_watching(&self) { + self.watcher.stop_watching(); + } + + pub async fn to_sys_path(&self, fs_path: Vc) -> Result { + // just in case there's a windows unc path prefix we remove it with `dunce` + let path = self.root_path(); + let fs_path = fs_path.await?; + Ok(if fs_path.path.is_empty() { + path.to_path_buf() + } else { + path.join(&*unix_to_sys(&fs_path.path)) + }) + } + + fn invalidate_from_write(&self, full_path: &Path, invalidators: HashSet) { + if !invalidators.is_empty() { + if let Some(path) = format_absolute_fs_path(full_path, &self.name, self.root_path()) { + if invalidators.len() == 1 { + let invalidator = invalidators.into_iter().next().unwrap(); + invalidator.invalidate_with_reason(Write { path }); + } else { + invalidators.into_iter().for_each(|invalidator| { + invalidator.invalidate_with_reason(Write { path: path.clone() }); + }); + } + } else { + invalidators.into_iter().for_each(|invalidator| { + invalidator.invalidate(); + }); + } + } + } +} + +#[allow(dead_code, reason = "we need to hold onto the locks")] +struct PathLockGuard<'a>( + #[allow(dead_code)] RwLockReadGuard<'a, ()>, + #[allow(dead_code)] mutex_map::MutexMapGuard<'a, PathBuf>, +); + +fn format_absolute_fs_path(path: &Path, name: &str, root_path: &Path) -> Option { + let path = if let Ok(rel_path) = path.strip_prefix(root_path) { + let path = if MAIN_SEPARATOR != '/' { + let rel_path = rel_path.to_string_lossy().replace(MAIN_SEPARATOR, "/"); + format!("[{name}]/{}", rel_path) + } else { + format!("[{name}]/{}", rel_path.display()) + }; + Some(path) + } else { + None + }; + path +} + +pub fn path_to_key(path: impl AsRef) -> String { + path.as_ref().to_string_lossy().to_string() +} + +#[turbo_tasks::value_impl] +impl DiskFileSystem { + /// Create a new instance of `DiskFileSystem`. + /// # Arguments + /// + /// * `name` - Name of the filesystem. + /// * `root` - Path to the given filesystem's root. + /// * `ignored_subpaths` - A list of subpaths that should not trigger + /// invalidation. This should be a full path, since it is possible that + /// root & project dir is different and requires to ignore specific + /// subpaths from each. + #[turbo_tasks::function] + pub async fn new(name: RcStr, root: RcStr, ignored_subpaths: Vec) -> Result> { + mark_stateful(); + // create the directory for the filesystem on disk, if it doesn't exist + fs::create_dir_all(&root).await?; + + let instance = DiskFileSystem { + name, + root, + mutex_map: Default::default(), + invalidation_lock: Default::default(), + invalidator_map: Arc::new(InvalidatorMap::new()), + dir_invalidator_map: Arc::new(InvalidatorMap::new()), + watcher: Arc::new(DiskWatcher::new( + ignored_subpaths.into_iter().map(PathBuf::from).collect(), + )), + }; + + Ok(Self::cell(instance)) + } +} + +impl Debug for DiskFileSystem { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "name: {}, root: {}", self.name, self.root) + } +} + +#[turbo_tasks::value_impl] +impl FileSystem for DiskFileSystem { + #[turbo_tasks::function(fs)] + async fn read(&self, fs_path: Vc) -> Result> { + let full_path = self.to_sys_path(fs_path).await?; + self.register_invalidator(&full_path)?; + + let _lock = self.lock_path(&full_path).await; + let content = match retry_future(|| File::from_path(full_path.clone())) + .instrument(tracing::info_span!( + "read file", + path = display(full_path.display()) + )) + .await + { + Ok(file) => FileContent::new(file), + Err(e) if e.kind() == ErrorKind::NotFound || e.kind() == ErrorKind::InvalidFilename => { + FileContent::NotFound + } + Err(e) => { + bail!(anyhow!(e).context(format!("reading file {}", full_path.display()))) + } + }; + Ok(content.cell()) + } + + #[turbo_tasks::function(fs)] + async fn read_dir(&self, fs_path: Vc) -> Result> { + let full_path = self.to_sys_path(fs_path).await?; + self.register_dir_invalidator(&full_path)?; + let fs_path = fs_path.await?; + + // we use the sync std function here as it's a lot faster (600%) in + // node-file-trace + let read_dir = match retry_blocking( + &full_path, + tracing::info_span!("read directory", path = display(full_path.display())), + |path| std::fs::read_dir(path), + ) + .await + { + Ok(dir) => dir, + Err(e) + if e.kind() == ErrorKind::NotFound + || e.kind() == ErrorKind::NotADirectory + || e.kind() == ErrorKind::InvalidFilename => + { + return Ok(DirectoryContent::not_found()); + } + Err(e) => { + bail!(anyhow!(e).context(format!("reading dir {}", full_path.display()))) + } + }; + + let entries = read_dir + .filter_map(|r| { + let e = match r { + Ok(e) => e, + Err(err) => return Some(Err(err.into())), + }; + + let path = e.path(); + + // we filter out any non unicode names and paths without the same root here + let file_name: RcStr = path.file_name()?.to_str()?.into(); + let path_to_root = sys_to_unix(path.strip_prefix(&self.root).ok()?.to_str()?); + + let fs_path = FileSystemPath::new_normalized(fs_path.fs, path_to_root.into()); + + let entry = match e.file_type() { + Ok(t) if t.is_file() => DirectoryEntry::File(fs_path), + Ok(t) if t.is_dir() => DirectoryEntry::Directory(fs_path), + Ok(t) if t.is_symlink() => DirectoryEntry::Symlink(fs_path), + Ok(_) => DirectoryEntry::Other(fs_path), + Err(err) => return Some(Err(err.into())), + }; + + Some(anyhow::Ok((file_name, entry))) + }) + .collect::>() + .with_context(|| format!("reading directory item in {}", full_path.display()))?; + + Ok(DirectoryContent::new(entries)) + } + + #[turbo_tasks::function(fs)] + async fn read_link(&self, fs_path: Vc) -> Result> { + let full_path = self.to_sys_path(fs_path).await?; + self.register_invalidator(&full_path)?; + + let _lock = self.lock_path(&full_path).await; + let link_path = match retry_future(|| fs::read_link(&full_path)) + .instrument(tracing::info_span!( + "read symlink", + path = display(full_path.display()) + )) + .await + { + Ok(res) => res, + Err(_) => return Ok(LinkContent::NotFound.cell()), + }; + let is_link_absolute = link_path.is_absolute(); + + let mut file = link_path.clone(); + if !is_link_absolute { + if let Some(normalized_linked_path) = full_path.parent().and_then(|p| { + normalize_path(&sys_to_unix(p.join(&file).to_string_lossy().as_ref())) + }) { + #[cfg(target_family = "windows")] + { + file = PathBuf::from(normalized_linked_path); + } + // `normalize_path` stripped the leading `/` of the path + // add it back here or the `strip_prefix` will return `Err` + #[cfg(not(target_family = "windows"))] + { + file = PathBuf::from(format!("/{normalized_linked_path}")); + } + } else { + return Ok(LinkContent::Invalid.cell()); + } + } + + // strip the root from the path, it serves two purpose + // 1. ensure the linked path is under the root + // 2. strip the root path if the linked path is absolute + // + // we use `dunce::simplify` to strip a potential UNC prefix on windows, on any + // other OS this gets compiled away + let result = simplified(&file).strip_prefix(simplified(Path::new(&self.root))); + + let relative_to_root_path = match result { + Ok(file) => PathBuf::from(sys_to_unix(&file.to_string_lossy()).as_ref()), + Err(_) => return Ok(LinkContent::Invalid.cell()), + }; + + let (target, file_type) = if is_link_absolute { + let target_string: RcStr = relative_to_root_path.to_string_lossy().into(); + ( + target_string.clone(), + FileSystemPath::new_normalized(fs_path.fs(), target_string) + .get_type() + .await?, + ) + } else { + let link_path_string_cow = link_path.to_string_lossy(); + let link_path_unix: RcStr = sys_to_unix(&link_path_string_cow).into(); + ( + link_path_unix.clone(), + fs_path.parent().join(link_path_unix).get_type().await?, + ) + }; + + Ok(LinkContent::Link { + target, + link_type: { + let mut link_type = Default::default(); + if link_path.is_absolute() { + link_type |= LinkType::ABSOLUTE; + } + if matches!(&*file_type, FileSystemEntryType::Directory) { + link_type |= LinkType::DIRECTORY; + } + link_type + }, + } + .cell()) + } + + #[turbo_tasks::function(fs)] + async fn track(&self, fs_path: Vc) -> Result> { + let full_path = self.to_sys_path(fs_path).await?; + self.register_invalidator(&full_path)?; + Ok(Completion::new()) + } + + #[turbo_tasks::function(fs)] + async fn write( + &self, + fs_path: Vc, + content: Vc, + ) -> Result> { + let full_path = self.to_sys_path(fs_path).await?; + let content = content.await?; + + let _lock = self.lock_path(&full_path).await; + + // Track the file, so that we will rewrite it if it ever changes. + let old_invalidators = self.register_sole_invalidator(&full_path)?; + + // We perform an untracked comparison here, so that this write is not dependent + // on a read's Vc (and the memory it holds). Our untracked read can + // be freed immediately. Given this is an output file, it's unlikely any Turbo + // code will need to read the file from disk into a Vc, so we're + // not wasting cycles. + let compare = content + .streaming_compare(full_path.clone()) + .instrument(tracing::info_span!( + "read file before write", + path = display(full_path.display()) + )) + .await?; + if compare == FileComparison::Equal { + if !old_invalidators.is_empty() { + let key = path_to_key(&full_path); + for i in old_invalidators { + self.invalidator_map.insert(key.clone(), i); + } + } + return Ok(Completion::unchanged()); + } + + let create_directory = compare == FileComparison::Create; + + match &*content { + FileContent::Content(file) => { + if create_directory { + if let Some(parent) = full_path.parent() { + retry_future(move || fs::create_dir_all(parent)) + .instrument(tracing::info_span!( + "create directory", + path = display(parent.display()) + )) + .await + .with_context(|| { + format!( + "failed to create directory {} for write to {}", + parent.display(), + full_path.display() + ) + })?; + } + } + let full_path_to_write = full_path.clone(); + retry_future(move || { + let full_path = full_path_to_write.clone(); + async move { + let mut f = fs::File::create(&full_path).await?; + tokio::io::copy(&mut file.read(), &mut f).await?; + #[cfg(target_family = "unix")] + f.set_permissions(file.meta.permissions.into()).await?; + #[cfg(feature = "write_version")] + { + let mut full_path = full_path; + let hash = hash_xxh3_hash64(file); + let ext = full_path.extension(); + let ext = if let Some(ext) = ext { + format!("{:016x}.{}", hash, ext.to_string_lossy()) + } else { + format!("{:016x}", hash) + }; + full_path.set_extension(ext); + let mut f = fs::File::create(&full_path).await?; + tokio::io::copy(&mut file.read(), &mut f).await?; + #[cfg(target_family = "unix")] + f.set_permissions(file.meta.permissions.into()).await?; + } + Ok::<(), io::Error>(()) + } + }) + .instrument(tracing::info_span!( + "write file", + path = display(full_path.display()) + )) + .await + .with_context(|| format!("failed to write to {}", full_path.display()))?; + } + FileContent::NotFound => { + retry_future(|| fs::remove_file(full_path.clone())) + .instrument(tracing::info_span!( + "remove file", + path = display(full_path.display()) + )) + .await + .or_else(|err| { + if err.kind() == ErrorKind::NotFound { + Ok(()) + } else { + Err(err) + } + }) + .with_context(|| anyhow!("removing {} failed", full_path.display()))?; + } + } + + self.invalidate_from_write(&full_path, old_invalidators); + + Ok(Completion::new()) + } + + #[turbo_tasks::function(fs)] + async fn write_link( + &self, + fs_path: Vc, + target: Vc, + ) -> Result> { + let full_path = self.to_sys_path(fs_path).await?; + // TODO(sokra) preform a untracked read here, register an invalidator and get + // all existing invalidators + let old_content = fs_path + .read_link() + .await + .with_context(|| format!("reading old symlink target of {}", full_path.display()))?; + let target_link = target.await?; + if target_link == old_content { + return Ok(Completion::unchanged()); + } + let file_type = &*fs_path.get_type().await?; + let create_directory = file_type == &FileSystemEntryType::NotFound; + if create_directory { + if let Some(parent) = full_path.parent() { + retry_future(move || fs::create_dir_all(parent)) + .instrument(tracing::info_span!( + "create directory", + path = display(parent.display()) + )) + .await + .with_context(|| { + format!( + "failed to create directory {} for write to {}", + parent.display(), + full_path.display() + ) + })?; + } + } + let _lock = self.lock_path(&full_path).await; + match &*target_link { + LinkContent::Link { target, link_type } => { + let link_type = *link_type; + let target_path = if link_type.contains(LinkType::ABSOLUTE) { + Path::new(&self.root).join(unix_to_sys(target).as_ref()) + } else { + PathBuf::from(unix_to_sys(target).as_ref()) + }; + retry_blocking( + &target_path, + tracing::info_span!("write symlink", path = display(full_path.display())), + move |target_path| { + // we use the sync std method here because `symlink` is fast + // if we put it into a task, it will be slower + #[cfg(not(target_family = "windows"))] + { + std::os::unix::fs::symlink(target_path, &full_path) + } + #[cfg(target_family = "windows")] + { + if link_type.contains(LinkType::DIRECTORY) { + std::os::windows::fs::symlink_dir(target_path, &full_path) + } else { + std::os::windows::fs::symlink_file(target_path, &full_path) + } + } + }, + ) + .await + .with_context(|| format!("create symlink to {}", target))?; + } + LinkContent::Invalid => { + return Err(anyhow!("invalid symlink target: {}", full_path.display())); + } + LinkContent::NotFound => { + retry_future(|| fs::remove_file(&full_path)) + .await + .or_else(|err| { + if err.kind() == ErrorKind::NotFound { + Ok(()) + } else { + Err(err) + } + }) + .with_context(|| anyhow!("removing {} failed", full_path.display()))?; + } + } + Ok(Completion::new()) + } + + #[turbo_tasks::function(fs)] + async fn metadata(&self, fs_path: Vc) -> Result> { + let full_path = self.to_sys_path(fs_path).await?; + self.register_invalidator(&full_path)?; + + let _lock = self.lock_path(&full_path).await; + let meta = retry_future(|| fs::metadata(full_path.clone())) + .instrument(tracing::info_span!( + "read metadata", + path = display(full_path.display()) + )) + .await + .with_context(|| format!("reading metadata for {}", full_path.display()))?; + + Ok(FileMeta::cell(meta.into())) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for DiskFileSystem { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(self.name.clone()) + } +} + +#[turbo_tasks::value] +#[derive(Debug, Clone)] +pub struct FileSystemPath { + pub fs: Vc>, + pub path: RcStr, +} + +impl FileSystemPath { + pub fn is_inside_ref(&self, other: &FileSystemPath) -> bool { + if self.fs == other.fs && self.path.starts_with(&*other.path) { + if other.path.is_empty() { + true + } else { + self.path.as_bytes().get(other.path.len()) == Some(&b'/') + } + } else { + false + } + } + + pub fn is_inside_or_equal_ref(&self, other: &FileSystemPath) -> bool { + if self.fs == other.fs && self.path.starts_with(&*other.path) { + if other.path.is_empty() { + true + } else { + matches!( + self.path.as_bytes().get(other.path.len()), + Some(&b'/') | None + ) + } + } else { + false + } + } + + pub fn is_root(&self) -> bool { + self.path.is_empty() + } + + /// Returns the path of `inner` relative to `self`. + /// + /// Note: this method always strips the leading `/` from the result. + pub fn get_path_to<'a>(&self, inner: &'a FileSystemPath) -> Option<&'a str> { + if self.fs != inner.fs { + return None; + } + let path = inner.path.strip_prefix(&*self.path)?; + if self.path.is_empty() { + Some(path) + } else if let Some(stripped) = path.strip_prefix('/') { + Some(stripped) + } else { + None + } + } + + pub fn get_relative_path_to(&self, other: &FileSystemPath) -> Option { + if self.fs != other.fs { + return None; + } + fn split(s: &str) -> impl Iterator { + let empty = s.is_empty(); + let mut iterator = s.split('/'); + if empty { + iterator.next(); + } + iterator + } + let mut self_segments = split(&self.path).peekable(); + let mut other_segments = split(&other.path).peekable(); + while self_segments.peek() == other_segments.peek() { + self_segments.next(); + if other_segments.next().is_none() { + return Some(".".into()); + } + } + let mut result = Vec::new(); + if self_segments.peek().is_none() { + result.push("."); + } else { + while self_segments.next().is_some() { + result.push(".."); + } + } + for segment in other_segments { + result.push(segment); + } + Some(result.join("/").into()) + } + + /// Returns the final component of the FileSystemPath, or an empty string + /// for the root path. + pub fn file_name(&self) -> &str { + let (_, file_name) = self.split_file_name(); + file_name + } + + pub fn extension_ref(&self) -> Option<&str> { + let (_, extension) = self.split_extension(); + extension + } + + /// Splits the path into two components: + /// 1. The path without the extension; + /// 2. The extension, if any. + fn split_extension(&self) -> (&str, Option<&str>) { + if let Some((path_before_extension, extension)) = self.path.rsplit_once('.') { + if extension.contains('/') || + // The file name begins with a `.` and has no other `.`s within. + path_before_extension.ends_with('/') || path_before_extension.is_empty() + { + (self.path.as_str(), None) + } else { + (path_before_extension, Some(extension)) + } + } else { + (self.path.as_str(), None) + } + } + + /// Splits the path into two components: + /// 1. The parent directory, if any; + /// 2. The file name; + fn split_file_name(&self) -> (Option<&str>, &str) { + // Since the path is normalized, we know `parent`, if any, must not be empty. + if let Some((parent, file_name)) = self.path.rsplit_once('/') { + (Some(parent), file_name) + } else { + (None, self.path.as_str()) + } + } + + /// Splits the path into three components: + /// 1. The parent directory, if any; + /// 2. The file stem; + /// 3. The extension, if any. + fn split_file_stem_extension(&self) -> (Option<&str>, &str, Option<&str>) { + let (path_before_extension, extension) = self.split_extension(); + + if let Some((parent, file_stem)) = path_before_extension.rsplit_once('/') { + (Some(parent), file_stem, extension) + } else { + (None, path_before_extension, extension) + } + } +} + +#[turbo_tasks::value(transparent)] +pub struct FileSystemPathOption(Option>); + +#[turbo_tasks::value_impl] +impl FileSystemPathOption { + #[turbo_tasks::function] + pub fn none() -> Vc { + Vc::cell(None) + } +} + +#[turbo_tasks::value_impl] +impl FileSystemPath { + /// Create a new Vc from a path withing a FileSystem. The + /// /-separated path is expected to be already normalized (this is asserted + /// in dev mode). + #[turbo_tasks::function] + fn new_normalized(fs: Vc>, path: RcStr) -> Vc { + // On Windows, the path must be converted to a unix path before creating. But on + // Unix, backslashes are a valid char in file names, and the path can be + // provided by the user, so we allow it. + debug_assert!( + MAIN_SEPARATOR != '\\' || !path.contains('\\'), + "path {} must not contain a Windows directory '\\', it must be normalized to Unix '/'", + path, + ); + debug_assert!( + normalize_path(&path).as_deref() == Some(&*path), + "path {} must be normalized", + path, + ); + Self::cell(FileSystemPath { fs, path }) + } + + /// Adds a subpath to the current path. The /-separate path argument might + /// contain ".." or "." seqments, but it must not leave the root of the + /// filesystem. + #[turbo_tasks::function] + pub async fn join(self: Vc, path: RcStr) -> Result> { + let this = self.await?; + if let Some(path) = join_path(&this.path, &path) { + Ok(Self::new_normalized(this.fs, path.into())) + } else { + bail!( + "Vc(\"{}\").join(\"{}\") leaves the filesystem root", + this.path, + path + ); + } + } + + /// Adds a suffix to the filename. [path] must not contain `/`. + #[turbo_tasks::function] + pub async fn append(self: Vc, path: RcStr) -> Result> { + let this = self.await?; + if path.contains('/') { + bail!( + "Vc(\"{}\").append(\"{}\") must not append '/'", + this.path, + path + ) + } + Ok(Self::new_normalized( + this.fs, + format!("{}{}", this.path, path).into(), + )) + } + + /// Adds a suffix to the basename of the filename. [appending] must not + /// contain `/`. Extension will stay intact. + #[turbo_tasks::function] + pub async fn append_to_stem(self: Vc, appending: RcStr) -> Result> { + let this = self.await?; + if appending.contains('/') { + bail!( + "Vc(\"{}\").append_to_stem(\"{}\") must not append '/'", + this.path, + appending + ) + } + if let (path, Some(ext)) = this.split_extension() { + return Ok(Self::new_normalized( + this.fs, + format!("{}{}.{}", path, appending, ext).into(), + )); + } + Ok(Self::new_normalized( + this.fs, + format!("{}{}", this.path, appending).into(), + )) + } + + /// Similar to [FileSystemPath::join], but returns an Option that will be + /// None when the joined path would leave the filesystem root. + #[turbo_tasks::function] + pub async fn try_join(self: Vc, path: RcStr) -> Result> { + let this = self.await?; + if let Some(path) = join_path(&this.path, &path) { + Ok(Vc::cell(Some( + Self::new_normalized(this.fs, path.into()).resolve().await?, + ))) + } else { + Ok(FileSystemPathOption::none()) + } + } + + /// Similar to [FileSystemPath::join], but returns an Option that will be + /// None when the joined path would leave the current path. + #[turbo_tasks::function] + pub async fn try_join_inside(self: Vc, path: RcStr) -> Result> { + let this = self.await?; + if let Some(path) = join_path(&this.path, &path) { + if path.starts_with(&*this.path) { + return Ok(Vc::cell(Some( + Self::new_normalized(this.fs, path.into()).resolve().await?, + ))); + } + } + Ok(FileSystemPathOption::none()) + } + + #[turbo_tasks::function] + pub async fn read_glob( + self: Vc, + glob: Vc, + include_dot_files: bool, + ) -> Vc { + read_glob(self, glob, include_dot_files) + } + + #[turbo_tasks::function] + pub fn root(self: Vc) -> Vc { + self.fs().root() + } + + #[turbo_tasks::function] + pub async fn fs(self: Vc) -> Result>> { + Ok(self.await?.fs) + } + + #[turbo_tasks::function] + pub async fn extension(self: Vc) -> Result> { + let this = self.await?; + Ok(Vc::cell(this.extension_ref().unwrap_or("").into())) + } + + #[turbo_tasks::function] + pub async fn is_inside(self: Vc, other: Vc) -> Result> { + Ok(Vc::cell(self.await?.is_inside_ref(&*other.await?))) + } + + #[turbo_tasks::function] + pub async fn is_inside_or_equal(self: Vc, other: Vc) -> Result> { + Ok(Vc::cell(self.await?.is_inside_or_equal_ref(&*other.await?))) + } + + /// Creates a new [`Vc`] like `self` but with the given + /// extension. + #[turbo_tasks::function] + pub async fn with_extension(self: Vc, extension: RcStr) -> Result> { + let this = self.await?; + let (path_without_extension, _) = this.split_extension(); + Ok(Self::new_normalized( + this.fs, + // Like `Path::with_extension` and `PathBuf::set_extension`, if the extension is empty, + // we remove the extension altogether. + match extension.is_empty() { + true => path_without_extension.into(), + false => format!("{path_without_extension}.{extension}").into(), + }, + )) + } + + /// Extracts the stem (non-extension) portion of self.file_name. + /// + /// The stem is: + /// + /// * [`None`], if there is no file name; + /// * The entire file name if there is no embedded `.`; + /// * The entire file name if the file name begins with `.` and has no other + /// `.`s within; + /// * Otherwise, the portion of the file name before the final `.` + #[turbo_tasks::function] + pub async fn file_stem(self: Vc) -> Result>> { + let this = self.await?; + let (_, file_stem, _) = this.split_file_stem_extension(); + if file_stem.is_empty() { + return Ok(Vc::cell(None)); + } + Ok(Vc::cell(Some(file_stem.into()))) + } +} + +impl Display for FileSystemPath { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.path) + } +} + +#[turbo_tasks::function] +pub async fn rebase( + fs_path: Vc, + old_base: Vc, + new_base: Vc, +) -> Result> { + let fs_path = &*fs_path.await?; + let old_base = &*old_base.await?; + let new_base = &*new_base.await?; + let new_path; + if old_base.path.is_empty() { + if new_base.path.is_empty() { + new_path = fs_path.path.clone(); + } else { + new_path = [new_base.path.as_str(), "/", &fs_path.path].concat().into(); + } + } else { + let base_path = [&old_base.path, "/"].concat(); + if !fs_path.path.starts_with(&base_path) { + bail!( + "rebasing {} from {} onto {} doesn't work because it's not part of the source path", + fs_path.to_string(), + old_base.to_string(), + new_base.to_string() + ); + } + if new_base.path.is_empty() { + new_path = [&fs_path.path[base_path.len()..]].concat().into(); + } else { + new_path = [new_base.path.as_str(), &fs_path.path[old_base.path.len()..]] + .concat() + .into(); + } + } + Ok(new_base.fs.root().join(new_path)) +} + +// Not turbo-tasks functions, only delegating +impl FileSystemPath { + pub fn read(self: Vc) -> Vc { + self.fs().read(self) + } + + pub fn read_link(self: Vc) -> Vc { + self.fs().read_link(self) + } + + pub fn read_json(self: Vc) -> Vc { + self.fs().read(self).parse_json() + } + + /// Reads content of a directory. + /// + /// DETERMINISM: Result is in random order. Either sort result or do not + /// depend on the order. + pub fn read_dir(self: Vc) -> Vc { + self.fs().read_dir(self) + } + + pub fn track(self: Vc) -> Vc { + self.fs().track(self) + } + + pub fn write(self: Vc, content: Vc) -> Vc { + self.fs().write(self, content) + } + + pub fn write_link(self: Vc, target: Vc) -> Vc { + self.fs().write_link(self, target) + } + + pub fn metadata(self: Vc) -> Vc { + self.fs().metadata(self) + } + + pub fn realpath(self: Vc) -> Vc { + self.realpath_with_links().path() + } + + pub fn rebase( + fs_path: Vc, + old_base: Vc, + new_base: Vc, + ) -> Vc { + rebase(fs_path, old_base, new_base) + } +} + +#[turbo_tasks::value_impl] +impl FileSystemPath { + #[turbo_tasks::function] + pub async fn parent(self: Vc) -> Result> { + let this = self.await?; + let path = &this.path; + if path.is_empty() { + return Ok(self); + } + let p = match str::rfind(path, '/') { + Some(index) => path[..index].to_string(), + None => "".to_string(), + }; + Ok(FileSystemPath::new_normalized(this.fs, p.into())) + } + + #[turbo_tasks::function] + // It is important that get_type uses read_dir and not stat/metadata. + // - `get_type` is called very very often during resolving and stat would + // make it 1 syscall per call, whereas read_dir would make it 1 syscall per + // directory. + // - `metadata` allows you to use the "wrong" casing on + // case-insenstive filesystems, while read_dir gives you the "correct" + // casing. We want to enforce "correct" casing to avoid broken builds on + // Vercel deployments (case-sensitive). + pub async fn get_type(self: Vc) -> Result> { + let this = self.await?; + if this.is_root() { + return Ok(FileSystemEntryType::cell(FileSystemEntryType::Directory)); + } + let parent = self.parent().resolve().await?; + let dir_content = parent.read_dir().await?; + match &*dir_content { + DirectoryContent::NotFound => { + Ok(FileSystemEntryType::cell(FileSystemEntryType::NotFound)) + } + DirectoryContent::Entries(entries) => { + let (_, file_name) = this.split_file_name(); + if let Some(entry) = entries.get(file_name) { + Ok(FileSystemEntryType::cell(entry.into())) + } else { + Ok(FileSystemEntryType::cell(FileSystemEntryType::NotFound)) + } + } + } + } + + #[turbo_tasks::function] + pub async fn realpath_with_links(self: Vc) -> Result> { + let this = self.await?; + if this.is_root() { + return Ok(RealPathResult { + path: self, + symlinks: Vec::new(), + } + .cell()); + } + let parent = self.parent().resolve().await?; + let parent_result = parent.realpath_with_links().await?; + let basename = this + .path + .rsplit_once('/') + .map_or(this.path.as_str(), |(_, name)| name); + let real_self = if parent_result.path != parent { + parent_result.path.join(basename.into()).resolve().await? + } else { + self + }; + let mut result = parent_result.clone_value(); + if matches!(*real_self.get_type().await?, FileSystemEntryType::Symlink) { + if let LinkContent::Link { target, link_type } = &*real_self.read_link().await? { + result.symlinks.push(real_self); + result.path = if link_type.contains(LinkType::ABSOLUTE) { + real_self.root().resolve().await? + } else { + result.path + } + .join(target.clone()) + .resolve() + .await?; + return Ok(result.cell()); + } + } + result.path = real_self; + Ok(result.cell()) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for FileSystemPath { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("[{}]/{}", self.fs.to_string().await?, self.path).into(), + )) + } +} + +#[derive(Clone, Debug)] +#[turbo_tasks::value(shared)] +pub struct RealPathResult { + pub path: Vc, + pub symlinks: Vec>, +} + +#[turbo_tasks::value_impl] +impl RealPathResult { + #[turbo_tasks::function] + pub async fn path(self: Vc) -> Result> { + Ok(self.await?.path) + } +} + +#[derive(Clone, Copy, Debug, DeterministicHash)] +#[turbo_tasks::value(shared)] +pub enum Permissions { + Readable, + Writable, + Executable, +} + +impl Default for Permissions { + fn default() -> Self { + Self::Writable + } +} + +// Only handle the permissions on unix platform for now + +#[cfg(target_family = "unix")] +impl From for std::fs::Permissions { + fn from(perm: Permissions) -> Self { + use std::os::unix::fs::PermissionsExt; + match perm { + Permissions::Readable => std::fs::Permissions::from_mode(0o444), + Permissions::Writable => std::fs::Permissions::from_mode(0o664), + Permissions::Executable => std::fs::Permissions::from_mode(0o755), + } + } +} + +#[cfg(target_family = "unix")] +impl From for Permissions { + fn from(perm: std::fs::Permissions) -> Self { + use std::os::unix::fs::PermissionsExt; + if perm.readonly() { + Permissions::Readable + } else { + // https://github.com/fitzgen/is_executable/blob/master/src/lib.rs#L96 + if perm.mode() & 0o111 != 0 { + Permissions::Executable + } else { + Permissions::Writable + } + } + } +} + +#[cfg(not(target_family = "unix"))] +impl From for Permissions { + fn from(_: std::fs::Permissions) -> Self { + Permissions::default() + } +} + +#[turbo_tasks::value(shared)] +#[derive(Clone, Debug, DeterministicHash)] +pub enum FileContent { + Content(File), + NotFound, +} + +impl From for FileContent { + fn from(file: File) -> Self { + FileContent::Content(file) + } +} + +impl From for Vc { + fn from(file: File) -> Self { + FileContent::Content(file).cell() + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +enum FileComparison { + Create, + Equal, + NotEqual, +} + +impl FileContent { + /// Performs a comparison of self's data against a disk file's streamed + /// read. + async fn streaming_compare(&self, path: PathBuf) -> Result { + let old_file = extract_disk_access(retry_future(|| fs::File::open(&path)).await, &path)?; + let Some(mut old_file) = old_file else { + return Ok(match self { + FileContent::NotFound => FileComparison::Equal, + _ => FileComparison::Create, + }); + }; + // We know old file exists, does the new file? + let FileContent::Content(new_file) = self else { + return Ok(FileComparison::NotEqual); + }; + + let old_meta = extract_disk_access(retry_future(|| old_file.metadata()).await, &path)?; + let Some(old_meta) = old_meta else { + // If we failed to get meta, then the old file has been deleted between the + // handle open. In which case, we just pretend the file never + // existed. + return Ok(FileComparison::Create); + }; + // If the meta is different, we need to rewrite the file to update it. + if new_file.meta != old_meta.into() { + return Ok(FileComparison::NotEqual); + } + + // So meta matches, and we have a file handle. Let's stream the contents to see + // if they match. + let mut new_contents = new_file.read(); + let mut old_contents = BufReader::new(&mut old_file); + Ok(loop { + let new_chunk = new_contents.fill_buf()?; + let Ok(old_chunk) = old_contents.fill_buf().await else { + break FileComparison::NotEqual; + }; + + let len = min(new_chunk.len(), old_chunk.len()); + if len == 0 { + if new_chunk.len() == old_chunk.len() { + break FileComparison::Equal; + } else { + break FileComparison::NotEqual; + } + } + + if new_chunk[0..len] != old_chunk[0..len] { + break FileComparison::NotEqual; + } + + new_contents.consume(len); + old_contents.consume(len); + }) + } +} + +bitflags! { + #[derive(Default, Serialize, Deserialize, TraceRawVcs)] + pub struct LinkType: u8 { + const DIRECTORY = 0b00000001; + const ABSOLUTE = 0b00000010; + } +} + +#[turbo_tasks::value(shared)] +#[derive(Debug)] +pub enum LinkContent { + // for the relative link, the target is raw value read from the link + // for the absolute link, the target is stripped of the root path while reading + // We don't use the `Vc` here for now, because the `FileSystemPath` is always + // normalized, which means in `fn write_link` we couldn't restore the raw value of the file + // link because there is only **dist** path in `fn write_link`, and we need the raw path if + // we want to restore the link value in `fn write_link` + Link { target: RcStr, link_type: LinkType }, + Invalid, + NotFound, +} + +#[turbo_tasks::value(shared)] +#[derive(Clone, DeterministicHash)] +pub struct File { + meta: FileMeta, + #[turbo_tasks(debug_ignore)] + content: Rope, +} + +impl File { + /// Reads a [File] from the given path + async fn from_path(p: PathBuf) -> io::Result { + let mut file = fs::File::open(p).await?; + let metadata = file.metadata().await?; + + let mut output = Vec::with_capacity(metadata.len() as usize); + file.read_to_end(&mut output).await?; + + Ok(File { + meta: metadata.into(), + content: Rope::from(output), + }) + } + + /// Creates a [File] from raw bytes. + fn from_bytes(content: Vec) -> Self { + File { + meta: FileMeta::default(), + content: Rope::from(content), + } + } + + /// Creates a [File] from a rope. + fn from_rope(content: Rope) -> Self { + File { + meta: FileMeta::default(), + content, + } + } + + /// Returns the content type associated with this file. + pub fn content_type(&self) -> Option<&Mime> { + self.meta.content_type.as_ref() + } + + /// Sets the content type associated with this file. + pub fn with_content_type(mut self, content_type: Mime) -> Self { + self.meta.content_type = Some(content_type); + self + } + + /// Returns a Read/AsyncRead/Stream/Iterator to access the File's contents. + pub fn read(&self) -> RopeReader { + self.content.read() + } +} + +impl Debug for File { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("File") + .field("meta", &self.meta) + .field("content (hash)", &hash_xxh3_hash64(&self.content)) + .finish() + } +} + +impl From for File { + fn from(s: RcStr) -> Self { + s.into_owned().into() + } +} + +impl From for File { + fn from(s: String) -> Self { + File::from_bytes(s.into_bytes()) + } +} + +impl From> for File { + fn from(s: ReadRef) -> Self { + File::from_bytes(s.as_bytes().to_vec()) + } +} + +impl From<&str> for File { + fn from(s: &str) -> Self { + File::from_bytes(s.as_bytes().to_vec()) + } +} + +impl From> for File { + fn from(bytes: Vec) -> Self { + File::from_bytes(bytes) + } +} + +impl From<&[u8]> for File { + fn from(bytes: &[u8]) -> Self { + File::from_bytes(bytes.to_vec()) + } +} + +impl From> for File { + fn from(rope: ReadRef) -> Self { + File::from_rope(rope.clone_value()) + } +} + +impl From for File { + fn from(rope: Rope) -> Self { + File::from_rope(rope) + } +} + +impl File { + pub fn new(meta: FileMeta, content: Vec) -> Self { + Self { + meta, + content: Rope::from(content), + } + } + + /// Returns the associated [FileMeta] of this file. + pub fn meta(&self) -> &FileMeta { + &self.meta + } + + /// Returns the immutable contents of this file. + pub fn content(&self) -> &Rope { + &self.content + } +} + +mod mime_option_serde { + use std::{fmt, str::FromStr}; + + use mime::Mime; + use serde::{de, Deserializer, Serializer}; + + pub fn serialize(mime: &Option, serializer: S) -> Result + where + S: Serializer, + { + if let Some(mime) = mime { + serializer.serialize_str(mime.as_ref()) + } else { + serializer.serialize_str("") + } + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + struct Visitor; + + impl<'de> de::Visitor<'de> for Visitor { + type Value = Option; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a valid MIME type or empty string") + } + + fn visit_str(self, value: &str) -> Result, E> + where + E: de::Error, + { + if value.is_empty() { + Ok(None) + } else { + Mime::from_str(value) + .map(Some) + .map_err(|e| E::custom(format!("{}", e))) + } + } + } + + deserializer.deserialize_str(Visitor) + } +} + +#[turbo_tasks::value(shared)] +#[derive(Debug, Clone, Default)] +pub struct FileMeta { + permissions: Permissions, + #[serde(with = "mime_option_serde")] + #[turbo_tasks(trace_ignore)] + content_type: Option, +} + +impl From for FileMeta { + fn from(meta: std::fs::Metadata) -> Self { + let permissions = meta.permissions().into(); + + Self { + permissions, + content_type: None, + } + } +} + +impl DeterministicHash for FileMeta { + fn deterministic_hash(&self, state: &mut H) { + self.permissions.deterministic_hash(state); + if let Some(content_type) = &self.content_type { + content_type.to_string().deterministic_hash(state); + } + } +} + +impl FileContent { + pub fn new(file: File) -> Self { + FileContent::Content(file) + } + + pub fn is_content(&self) -> bool { + matches!(self, FileContent::Content(_)) + } + + pub fn as_content(&self) -> Option<&File> { + match self { + FileContent::Content(file) => Some(file), + FileContent::NotFound => None, + } + } + + pub fn parse_json_ref(&self) -> FileJsonContent { + match self { + FileContent::Content(file) => { + let de = &mut serde_json::Deserializer::from_reader(file.read()); + match serde_path_to_error::deserialize(de) { + Ok(data) => FileJsonContent::Content(data), + Err(e) => FileJsonContent::Unparseable(Box::new( + UnparseableJson::from_serde_path_to_error(e), + )), + } + } + FileContent::NotFound => FileJsonContent::NotFound, + } + } + + pub fn parse_json_with_comments_ref(&self) -> FileJsonContent { + match self { + FileContent::Content(file) => match file.content.to_str() { + Ok(string) => match parse_to_serde_value( + &string, + &ParseOptions { + allow_comments: true, + allow_trailing_commas: true, + allow_loose_object_property_names: false, + }, + ) { + Ok(data) => match data { + Some(value) => FileJsonContent::Content(value), + None => FileJsonContent::unparseable( + "text content doesn't contain any json data", + ), + }, + Err(e) => FileJsonContent::Unparseable(Box::new( + UnparseableJson::from_jsonc_error(e, string.as_ref()), + )), + }, + Err(_) => FileJsonContent::unparseable("binary is not valid utf-8 text"), + }, + FileContent::NotFound => FileJsonContent::NotFound, + } + } + + pub fn lines_ref(&self) -> FileLinesContent { + match self { + FileContent::Content(file) => match file.content.to_str() { + Ok(string) => { + let mut bytes_offset = 0; + FileLinesContent::Lines( + string + .split('\n') + .map(|l| { + let line = FileLine { + content: l.to_string(), + bytes_offset, + }; + bytes_offset += l.len() + 1; + line + }) + .collect(), + ) + } + Err(_) => FileLinesContent::Unparseable, + }, + FileContent::NotFound => FileLinesContent::NotFound, + } + } +} + +#[turbo_tasks::value_impl] +impl FileContent { + #[turbo_tasks::function] + pub async fn parse_json(self: Vc) -> Result> { + let this = self.await?; + Ok(this.parse_json_ref().into()) + } + + #[turbo_tasks::function] + pub async fn parse_json_with_comments(self: Vc) -> Result> { + let this = self.await?; + Ok(this.parse_json_with_comments_ref().into()) + } + + #[turbo_tasks::function] + pub async fn lines(self: Vc) -> Result> { + let this = self.await?; + Ok(this.lines_ref().into()) + } + + #[turbo_tasks::function] + pub async fn hash(self: Vc) -> Result> { + Ok(Vc::cell(hash_xxh3_hash64(&self.await?))) + } +} + +/// A file's content interpreted as a JSON value. +#[turbo_tasks::value(shared, serialization = "none")] +pub enum FileJsonContent { + Content(Value), + Unparseable(Box), + NotFound, +} + +#[turbo_tasks::value_impl] +impl ValueToString for FileJsonContent { + /// Returns the JSON file content as a UTF-8 string. + /// + /// This operation will only succeed if the file contents are a valid JSON + /// value. + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + match self { + FileJsonContent::Content(json) => Ok(Vc::cell(json.to_string().into())), + FileJsonContent::Unparseable(e) => Err(anyhow!("File is not valid JSON: {}", e)), + FileJsonContent::NotFound => Err(anyhow!("File not found")), + } + } +} + +impl FileJsonContent { + pub fn unparseable(message: &'static str) -> Self { + FileJsonContent::Unparseable(Box::new(UnparseableJson { + message: Cow::Borrowed(message), + path: None, + start_location: None, + end_location: None, + })) + } + + pub fn unparseable_with_message(message: Cow<'static, str>) -> Self { + FileJsonContent::Unparseable(Box::new(UnparseableJson { + message, + path: None, + start_location: None, + end_location: None, + })) + } +} + +#[derive(Debug, PartialEq, Eq)] +pub struct FileLine { + pub content: String, + pub bytes_offset: usize, +} + +#[turbo_tasks::value(shared, serialization = "none")] +pub enum FileLinesContent { + Lines(#[turbo_tasks(trace_ignore)] Vec), + Unparseable, + NotFound, +} + +#[derive(Hash, Clone, Copy, Debug, PartialEq, Eq, TraceRawVcs, Serialize, Deserialize)] +pub enum DirectoryEntry { + File(Vc), + Directory(Vc), + Symlink(Vc), + Other(Vc), + Error, +} + +#[turbo_tasks::value] +#[derive(Hash, Clone, Copy, Debug)] +pub enum FileSystemEntryType { + NotFound, + File, + Directory, + Symlink, + Other, + Error, +} + +impl From for FileSystemEntryType { + fn from(file_type: FileType) -> Self { + match file_type { + t if t.is_dir() => FileSystemEntryType::Directory, + t if t.is_file() => FileSystemEntryType::File, + t if t.is_symlink() => FileSystemEntryType::Symlink, + _ => FileSystemEntryType::Other, + } + } +} + +impl From for FileSystemEntryType { + fn from(entry: DirectoryEntry) -> Self { + FileSystemEntryType::from(&entry) + } +} + +impl From<&DirectoryEntry> for FileSystemEntryType { + fn from(entry: &DirectoryEntry) -> Self { + match entry { + DirectoryEntry::File(_) => FileSystemEntryType::File, + DirectoryEntry::Directory(_) => FileSystemEntryType::Directory, + DirectoryEntry::Symlink(_) => FileSystemEntryType::Symlink, + DirectoryEntry::Other(_) => FileSystemEntryType::Other, + DirectoryEntry::Error => FileSystemEntryType::Error, + } + } +} + +#[turbo_tasks::value] +#[derive(Debug)] +pub enum DirectoryContent { + Entries(AutoMap), + NotFound, +} + +impl DirectoryContent { + pub fn new(entries: AutoMap) -> Vc { + Self::cell(DirectoryContent::Entries(entries)) + } + + pub fn not_found() -> Vc { + Self::cell(DirectoryContent::NotFound) + } +} + +#[turbo_tasks::value(shared)] +pub struct NullFileSystem; + +#[turbo_tasks::value_impl] +impl FileSystem for NullFileSystem { + #[turbo_tasks::function] + fn read(&self, _fs_path: Vc) -> Vc { + FileContent::NotFound.cell() + } + + #[turbo_tasks::function] + fn read_link(&self, _fs_path: Vc) -> Vc { + LinkContent::NotFound.into() + } + + #[turbo_tasks::function] + fn read_dir(&self, _fs_path: Vc) -> Vc { + DirectoryContent::not_found() + } + + #[turbo_tasks::function] + fn track(&self, _fs_path: Vc) -> Vc { + Completion::immutable() + } + + #[turbo_tasks::function] + fn write(&self, _fs_path: Vc, _content: Vc) -> Vc { + Completion::new() + } + + #[turbo_tasks::function] + fn write_link(&self, _fs_path: Vc, _target: Vc) -> Vc { + Completion::new() + } + + #[turbo_tasks::function] + fn metadata(&self, _fs_path: Vc) -> Vc { + FileMeta::default().cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for NullFileSystem { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(RcStr::from("null")) + } +} + +pub async fn to_sys_path(mut path: Vc) -> Result> { + loop { + if let Some(fs) = Vc::try_resolve_downcast_type::(path.fs()).await? { + path = fs.get_inner_fs_path(path); + continue; + } + + if let Some(fs) = Vc::try_resolve_downcast_type::(path.fs()).await? { + let sys_path = fs.await?.to_sys_path(path).await?; + return Ok(Some(sys_path)); + } + + return Ok(None); + } +} + +pub fn register() { + turbo_tasks::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn with_extension() { + crate::register(); + + turbo_tasks_testing::VcStorage::with(async { + let fs = Vc::upcast(VirtualFileSystem::new()); + + let path_txt = FileSystemPath::new_normalized(fs, "foo/bar.txt".into()); + + let path_json = path_txt.with_extension("json".into()); + assert_eq!(&*path_json.await.unwrap().path, "foo/bar.json"); + + let path_no_ext = path_txt.with_extension("".into()); + assert_eq!(&*path_no_ext.await.unwrap().path, "foo/bar"); + + let path_new_ext = path_no_ext.with_extension("json".into()); + assert_eq!(&*path_new_ext.await.unwrap().path, "foo/bar.json"); + + let path_no_slash_txt = FileSystemPath::new_normalized(fs, "bar.txt".into()); + + let path_no_slash_json = path_no_slash_txt.with_extension("json".into()); + assert_eq!(path_no_slash_json.await.unwrap().path.as_str(), "bar.json"); + + let path_no_slash_no_ext = path_no_slash_txt.with_extension("".into()); + assert_eq!(path_no_slash_no_ext.await.unwrap().path.as_str(), "bar"); + + let path_no_slash_new_ext = path_no_slash_no_ext.with_extension("json".into()); + assert_eq!( + path_no_slash_new_ext.await.unwrap().path.as_str(), + "bar.json" + ); + + anyhow::Ok(()) + }) + .await + .unwrap() + } + + #[tokio::test] + async fn file_stem() { + crate::register(); + + turbo_tasks_testing::VcStorage::with(async { + let fs = Vc::upcast::>(VirtualFileSystem::new()); + + let path = FileSystemPath::new_normalized(fs, "".into()); + assert_eq!(path.file_stem().await.unwrap().as_deref(), None); + + let path = FileSystemPath::new_normalized(fs, "foo/bar.txt".into()); + assert_eq!(path.file_stem().await.unwrap().as_deref(), Some("bar")); + + let path = FileSystemPath::new_normalized(fs, "bar.txt".into()); + assert_eq!(path.file_stem().await.unwrap().as_deref(), Some("bar")); + + let path = FileSystemPath::new_normalized(fs, "foo/bar".into()); + assert_eq!(path.file_stem().await.unwrap().as_deref(), Some("bar")); + + let path = FileSystemPath::new_normalized(fs, "foo/.bar".into()); + assert_eq!(path.file_stem().await.unwrap().as_deref(), Some(".bar")); + + anyhow::Ok(()) + }) + .await + .unwrap() + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/mutex_map.rs b/turbopack/crates/turbo-tasks-fs/src/mutex_map.rs new file mode 100644 index 0000000000000..4103247c6a409 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/mutex_map.rs @@ -0,0 +1,108 @@ +use std::{ + collections::{hash_map::Entry, HashMap}, + hash::Hash, + marker::PhantomData, +}; + +use parking_lot::Mutex; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use turbo_tasks::event::Event; + +pub struct MutexMap { + map: Mutex>>, +} + +impl Default for MutexMap { + fn default() -> Self { + Self { + map: Mutex::new(HashMap::new()), + } + } +} + +impl<'a, K: Eq + Hash + Clone> MutexMap { + pub async fn lock(&'a self, key: K) -> MutexMapGuard<'a, K> { + let listener = { + let mut map = self.map.lock(); + match map.entry(key.clone()) { + Entry::Occupied(mut e) => { + let state = e.get_mut(); + Some(match state { + Some((event, count)) => { + *count += 1; + event.listen() + } + None => { + let event = Event::new(|| "MutexMap".to_string()); + let listener = event.listen(); + *state = Some((event, 0)); + listener + } + }) + } + Entry::Vacant(e) => { + e.insert(None); + None + } + } + }; + if let Some(listener) = listener { + listener.await; + } + MutexMapGuard { + map: self, + key: Some(key), + } + } +} + +pub struct MutexMapGuard<'a, K: Eq + Hash> { + map: &'a MutexMap, + key: Option, +} + +impl<'a, K: Eq + Hash> Drop for MutexMapGuard<'a, K> { + fn drop(&mut self) { + if let Some(key) = self.key.take() { + let mut map = self.map.map.lock(); + if let Entry::Occupied(mut e) = map.entry(key) { + let value = e.get_mut(); + match value { + Some((event, count)) => { + event.notify(1); + if *count == 0 { + *value = None; + } else { + *count -= 1; + } + } + None => { + e.remove(); + } + } + } + } + } +} + +impl Serialize for MutexMap { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_unit() + } +} + +impl<'de, K> Deserialize<'de> for MutexMap { + fn deserialize>(deserializer: D) -> Result { + struct Visitor(PhantomData>); + impl<'de, K> serde::de::Visitor<'de> for Visitor { + type Value = MutexMap; + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a unit") + } + fn visit_unit(self) -> Result { + Ok(MutexMap::default()) + } + } + deserializer.deserialize_unit(Visitor(std::marker::PhantomData)) + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/read_glob.rs b/turbopack/crates/turbo-tasks-fs/src/read_glob.rs new file mode 100644 index 0000000000000..829ae206bf6b5 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/read_glob.rs @@ -0,0 +1,78 @@ +use std::collections::HashMap; + +use anyhow::Result; +use turbo_tasks::{RcStr, Vc}; + +use crate::{glob::Glob, DirectoryContent, DirectoryEntry, FileSystemPath}; + +#[turbo_tasks::value] +#[derive(Default, Debug)] +pub struct ReadGlobResult { + pub results: HashMap, + pub inner: HashMap>, +} + +/// Reads matches of a glob pattern. +/// +/// DETERMINISM: Result is in random order. Either sort result or do not depend +/// on the order. +#[turbo_tasks::function(fs)] +pub async fn read_glob( + directory: Vc, + glob: Vc, + include_dot_files: bool, +) -> Result> { + read_glob_internal("", directory, glob, include_dot_files).await +} + +#[turbo_tasks::function(fs)] +async fn read_glob_inner( + prefix: RcStr, + directory: Vc, + glob: Vc, + include_dot_files: bool, +) -> Result> { + read_glob_internal(&prefix, directory, glob, include_dot_files).await +} + +async fn read_glob_internal( + prefix: &str, + directory: Vc, + glob: Vc, + include_dot_files: bool, +) -> Result> { + let dir = directory.read_dir().await?; + let mut result = ReadGlobResult::default(); + let glob_value = glob.await?; + match &*dir { + DirectoryContent::Entries(entries) => { + for item in entries.iter() { + match item { + (segment, DirectoryEntry::Directory(path)) => { + let full_path = format!("{prefix}{segment}"); + let full_path_prefix: RcStr = format!("{full_path}/").into(); + if glob_value.execute(&full_path) { + result + .results + .insert(full_path.clone(), DirectoryEntry::Directory(*path)); + } + if glob_value.execute(&full_path_prefix) { + result.inner.insert( + full_path, + read_glob_inner(full_path_prefix, *path, glob, include_dot_files), + ); + } + } + (segment, entry) => { + let full_path = format!("{prefix}{segment}"); + if glob_value.execute(&full_path) { + result.results.insert(full_path, *entry); + } + } + } + } + } + DirectoryContent::NotFound => {} + } + Ok(ReadGlobResult::cell(result)) +} diff --git a/turbopack/crates/turbo-tasks-fs/src/retry.rs b/turbopack/crates/turbo-tasks-fs/src/retry.rs new file mode 100644 index 0000000000000..6f34aeb9d5e21 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/retry.rs @@ -0,0 +1,98 @@ +use std::{future::Future, io, io::ErrorKind, path::Path, thread::sleep, time::Duration}; + +use futures_retry::{ErrorHandler, FutureRetry, RetryPolicy}; +use tokio::task::spawn_blocking; + +const MAX_RETRY_ATTEMPTS: usize = 10; + +pub(crate) async fn retry_future<'a, R, F, Fut>(func: F) -> io::Result +where + F: FnMut() -> Fut + Unpin, + Fut: Future> + 'a, +{ + match FutureRetry::new( + func, + FsRetryHandler { + max_attempts: MAX_RETRY_ATTEMPTS, + }, + ) + .await + { + Ok((r, _attempts)) => Ok(r), + Err((err, _attempts)) => Err(err), + } +} + +pub(crate) async fn retry_blocking( + path: impl AsRef, + span: tracing::Span, + func: F, +) -> io::Result +where + F: Fn(&Path) -> io::Result + Send + 'static, + R: Send + 'static, +{ + let path = path.as_ref().to_owned(); + + let current_span = tracing::Span::current(); + asyncify(move || { + let _entered = current_span.entered(); + let _entered = span.entered(); + let mut attempt = 1; + + loop { + return match func(&path) { + Ok(r) => Ok(r), + Err(err) => { + if attempt < MAX_RETRY_ATTEMPTS && can_retry(&err) { + sleep(get_retry_wait_time(attempt)); + attempt += 1; + continue; + } + + Err(err) + } + }; + } + }) + .await +} + +fn can_retry(err: &io::Error) -> bool { + matches!( + err.kind(), + ErrorKind::PermissionDenied | ErrorKind::WouldBlock + ) +} + +fn get_retry_wait_time(attempt: usize) -> Duration { + Duration::from_millis((attempt as u64) * 100) +} + +struct FsRetryHandler { + max_attempts: usize, +} + +impl ErrorHandler for FsRetryHandler { + type OutError = io::Error; + + fn handle(&mut self, attempt: usize, e: io::Error) -> RetryPolicy { + if attempt == self.max_attempts || !can_retry(&e) { + RetryPolicy::ForwardError(e) + } else { + RetryPolicy::WaitRetry(get_retry_wait_time(attempt)) + } + } +} + +// stolen from tokio::fs +async fn asyncify(f: F) -> io::Result +where + F: FnOnce() -> io::Result + Send + 'static, + T: Send + 'static, +{ + match spawn_blocking(f).await { + Ok(res) => res, + Err(_) => Err(io::Error::new(ErrorKind::Other, "background task failed")), + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/rope.rs b/turbopack/crates/turbo-tasks-fs/src/rope.rs new file mode 100644 index 0000000000000..95f03ab64df72 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/rope.rs @@ -0,0 +1,985 @@ +use std::{ + borrow::Cow, + cmp::min, + fmt, + io::{BufRead, Read, Result as IoResult, Write}, + mem, + ops::{AddAssign, Deref}, + pin::Pin, + sync::Arc, + task::{Context as TaskContext, Poll}, +}; + +use anyhow::{Context, Result}; +use bytes::{Buf, Bytes}; +use futures::Stream; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use tokio::io::{AsyncRead, ReadBuf}; +use turbo_tasks_hash::{DeterministicHash, DeterministicHasher}; +use RopeElem::{Local, Shared}; + +static EMPTY_BUF: &[u8] = &[]; + +/// A Rope provides an efficient structure for sharing bytes/strings between +/// multiple sources. Cloning a Rope is extremely cheap (Arc and usize), and +/// sharing the contents of one Rope can be done by just cloning an Arc. +/// +/// Ropes are immutable, in order to construct one see [RopeBuilder]. +#[turbo_tasks::value(shared, serialization = "custom", eq = "manual")] +#[derive(Clone, Debug, Default)] +pub struct Rope { + /// Total length of all held bytes. + length: usize, + + /// A shareable container holding the rope's bytes. + #[turbo_tasks(debug_ignore, trace_ignore)] + data: InnerRope, +} + +/// An Arc container for ropes. This indirection allows for easily sharing the +/// contents between Ropes (and also RopeBuilders/RopeReaders). +#[derive(Clone, Debug)] +struct InnerRope(Arc<[RopeElem]>); + +/// Differentiates the types of stored bytes in a rope. +#[derive(Clone, Debug)] +enum RopeElem { + /// Local bytes are owned directly by this rope. + Local(Bytes), + + /// Shared holds the Arc container of another rope. + Shared(InnerRope), +} + +/// RopeBuilder provides a mutable container to append bytes/strings. This can +/// also append _other_ Rope instances cheaply, allowing efficient sharing of +/// the contents without a full clone of the bytes. +#[derive(Default, Debug)] +pub struct RopeBuilder { + /// Total length of all previously committed bytes. + length: usize, + + /// Immutable bytes references that have been appended to this builder. The + /// rope is the combination of all these committed bytes. + committed: Vec, + + /// Stores bytes that have been pushed, but are not yet committed. This is + /// either an attempt to push a static lifetime, or a push of owned bytes. + /// When the builder is flushed, we will commit these bytes into a real + /// Bytes instance. + uncommitted: Uncommitted, +} + +/// Stores any bytes which have been pushed, but we haven't decided to commit +/// yet. Uncommitted bytes allow us to build larger buffers out of possibly +/// small pushes. +#[derive(Default)] +enum Uncommitted { + #[default] + None, + + /// Stores our attempt to push static lifetime bytes into the rope. If we + /// build the Rope or concatenate another Rope, we can commit a static + /// Bytes reference and save memory. If not, we'll concatenate this into + /// writable bytes to be committed later. + Static(&'static [u8]), + + /// Mutable bytes collection where non-static/non-shared bytes are written. + /// This builds until the next time a static or shared bytes is + /// appended, in which case we split the buffer and commit. Finishing + /// the builder also commits these bytes. + Owned(Vec), +} + +impl Rope { + pub fn len(&self) -> usize { + self.length + } + + pub fn is_empty(&self) -> bool { + self.length == 0 + } + + /// Returns a [Read]/[AsyncRead]/[Iterator] instance over all bytes. + pub fn read(&self) -> RopeReader { + RopeReader::new(&self.data, 0) + } + + /// Returns a String instance of all bytes. + pub fn to_str(&self) -> Result> { + self.data.to_str(self.length) + } + + /// Returns a slice of all bytes + pub fn to_bytes(&self) -> Result> { + self.data.to_bytes(self.length) + } +} + +impl> From for Rope { + fn from(bytes: T) -> Self { + let bytes = bytes.into(); + // We can't have an InnerRope which contains an empty Local section. + if bytes.is_empty() { + Default::default() + } else { + Rope { + length: bytes.len(), + data: InnerRope(Arc::from([Local(bytes)])), + } + } + } +} + +impl RopeBuilder { + /// Push owned bytes into the Rope. + /// + /// If possible use [push_static_bytes] or `+=` operation instead, as they + /// will create a reference to shared memory instead of cloning the bytes. + pub fn push_bytes(&mut self, bytes: &[u8]) { + if bytes.is_empty() { + return; + } + + self.uncommitted.push_bytes(bytes); + } + + /// Push static lifetime bytes into the Rope. + /// + /// This is more efficient than pushing owned bytes, because the internal + /// data does not need to be copied when the rope is read. + pub fn push_static_bytes(&mut self, bytes: &'static [u8]) { + if bytes.is_empty() { + return; + } + + // If the string is smaller than the cost of a Bytes reference (4 usizes), then + // it's more efficient to own the bytes in a new buffer. We may be able to reuse + // that buffer when more bytes are pushed. + if bytes.len() < mem::size_of::() { + return self.uncommitted.push_static_bytes(bytes); + } + + // We may have pending bytes from a prior push. + self.finish(); + + self.length += bytes.len(); + self.committed.push(Local(bytes.into())); + } + + /// Concatenate another Rope instance into our builder. + /// + /// This is much more efficient than pushing actual bytes, since we can + /// share the other Rope's references without copying the underlying data. + pub fn concat(&mut self, other: &Rope) { + if other.is_empty() { + return; + } + + // We may have pending bytes from a prior push. + self.finish(); + + self.length += other.len(); + self.committed.push(Shared(other.data.clone())); + } + + /// Writes any pending bytes into our committed queue. + /// + /// This may be called multiple times without issue. + pub fn finish(&mut self) { + if let Some(b) = self.uncommitted.finish() { + debug_assert!(!b.is_empty(), "must not have empty uncommitted bytes"); + self.length += b.len(); + self.committed.push(Local(b)); + } + } + + pub fn len(&self) -> usize { + self.length + self.uncommitted.len() + } + + pub fn is_empty(&self) -> bool { + self.len() == 0 + } + + /// Constructs our final, immutable Rope instance. + pub fn build(mut self) -> Rope { + self.finish(); + Rope { + length: self.length, + data: InnerRope::from(self.committed), + } + } +} + +impl From<&'static str> for RopeBuilder { + default fn from(bytes: &'static str) -> Self { + let mut r = RopeBuilder::default(); + r += bytes; + r + } +} + +impl From> for RopeBuilder { + fn from(bytes: Vec) -> Self { + RopeBuilder { + // Directly constructing the Uncommitted allows us to skip copying the bytes. + uncommitted: Uncommitted::from(bytes), + ..Default::default() + } + } +} + +impl Write for RopeBuilder { + fn write(&mut self, bytes: &[u8]) -> IoResult { + self.push_bytes(bytes); + Ok(bytes.len()) + } + + fn flush(&mut self) -> IoResult<()> { + self.finish(); + Ok(()) + } +} + +impl AddAssign<&'static str> for RopeBuilder { + /// Pushes a reference to static memory onto the rope. + /// + /// This is more efficient than pushing owned bytes, because the internal + /// data does not need to be copied when the rope is read. + fn add_assign(&mut self, rhs: &'static str) { + self.push_static_bytes(rhs.as_bytes()); + } +} + +impl AddAssign<&Rope> for RopeBuilder { + fn add_assign(&mut self, rhs: &Rope) { + self.concat(rhs); + } +} + +impl Uncommitted { + fn len(&self) -> usize { + match self { + Uncommitted::None => 0, + Uncommitted::Static(s) => s.len(), + Uncommitted::Owned(v) => v.len(), + } + } + + /// Pushes owned bytes, converting the current representation to an Owned if + /// it's not already. + fn push_bytes(&mut self, bytes: &[u8]) { + debug_assert!(!bytes.is_empty(), "must not push empty uncommitted bytes"); + match self { + Self::None => *self = Self::Owned(bytes.to_vec()), + Self::Static(s) => { + // If we'd previously pushed static bytes, we instead concatenate those bytes + // with the new bytes in an attempt to use less memory rather than committing 2 + // Bytes references (2 * 4 usizes). + let v = [s, bytes].concat(); + *self = Self::Owned(v); + } + Self::Owned(v) => v.extend(bytes), + } + } + + /// Pushes static lifetime bytes, but only if the current representation is + /// None. Else, it coverts to an Owned. + fn push_static_bytes(&mut self, bytes: &'static [u8]) { + debug_assert!(!bytes.is_empty(), "must not push empty uncommitted bytes"); + match self { + // If we've not already pushed static bytes, we attempt to store the bytes for later. If + // we push owned bytes or another static bytes, then this attempt will fail and we'll + // instead concatenate into a single owned Bytes. But if we don't push anything (build + // the Rope), or concatenate another Rope (we can't join our bytes with the InnerRope of + // another Rope), we'll be able to commit a static Bytes reference and save overall + // memory (a small static Bytes reference is better than a small owned Bytes reference). + Self::None => *self = Self::Static(bytes), + _ => self.push_bytes(bytes), + } + } + + /// Converts the current uncommitted bytes into a Bytes, resetting our + /// representation to None. + fn finish(&mut self) -> Option { + match mem::take(self) { + Self::None => None, + Self::Static(s) => Some(s.into()), + Self::Owned(v) => Some(v.into()), + } + } +} + +impl fmt::Debug for Uncommitted { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Uncommitted::None => f.write_str("None"), + Uncommitted::Static(s) => f + .debug_tuple("Static") + .field(&Bytes::from_static(s)) + .finish(), + Uncommitted::Owned(v) => f + .debug_tuple("Owned") + .field(&Bytes::from(v.clone())) + .finish(), + } + } +} + +impl DeterministicHash for Rope { + /// Ropes with similar contents hash the same, regardless of their + /// structure. + fn deterministic_hash(&self, state: &mut H) { + state.write_usize(self.len()); + self.data.deterministic_hash(state); + } +} + +impl Serialize for Rope { + /// Ropes are always serialized into contiguous strings, because + /// deserialization won't deduplicate and share the Arcs (being the only + /// possible owner of a individual "shared" data doesn't make sense). + fn serialize(&self, serializer: S) -> Result { + use serde::ser::Error; + let s = self.to_str().map_err(Error::custom)?; + serializer.serialize_str(&s) + } +} + +impl<'de> Deserialize<'de> for Rope { + /// Deserializes strings into a contiguous, immutable Rope. + fn deserialize>(deserializer: D) -> Result { + let bytes = >::deserialize(deserializer)?; + Ok(Rope::from(bytes)) + } +} + +impl PartialEq for Rope { + // Ropes with similar contents are equals, regardless of their structure. + fn eq(&self, other: &Self) -> bool { + if Arc::ptr_eq(&self.data, &other.data) { + return true; + } + if self.len() != other.len() { + return false; + } + + // Fast path for structurally equal Ropes. With this, we can do memory reference + // checks and skip some contents equality. + let left = &self.data; + let right = &other.data; + let len = min(left.len(), right.len()); + let mut index = 0; + while index < len { + let a = &left[index]; + let b = &right[index]; + + match a.maybe_eq(b) { + // Bytes or InnerRope point to the same memory, or Bytes are contents equal. + Some(true) => index += 1, + // Bytes are not contents equal. + Some(false) => return false, + // InnerRopes point to different memory, or the Ropes weren't structurally equal. + None => break, + } + } + // If we reach the end of iteration without finding a mismatch (or early + // breaking), then we know the ropes are either equal or not equal. + if index == len { + // We know that any remaining RopeElem in the InnerRope must contain content, so + // if either one contains more RopeElem than they cannot be equal. + return left.len() == right.len(); + } + + // At this point, we need to do slower contents equality. It's possible we'll + // still get some memory reference equality for Bytes. + let mut left = RopeReader::new(left, index); + let mut right = RopeReader::new(right, index); + loop { + match (left.fill_buf(), right.fill_buf()) { + // fill_buf should always return Ok, with either some number of bytes or 0 bytes + // when consumed. + (Ok(a), Ok(b)) => { + let len = min(a.len(), b.len()); + + // When one buffer is consumed, both must be consumed. + if len == 0 { + return a.len() == b.len(); + } + + if a[0..len] != b[0..len] { + return false; + } + + left.consume(len); + right.consume(len); + } + + // If an error is ever returned (which shouldn't happen for us) for either/both, + // then we can't prove equality. + _ => return false, + } + } + } +} + +impl Eq for Rope {} + +impl From> for Uncommitted { + fn from(bytes: Vec) -> Self { + if bytes.is_empty() { + Uncommitted::None + } else { + Uncommitted::Owned(bytes) + } + } +} + +impl InnerRope { + /// Returns a String instance of all bytes. + fn to_str(&self, len: usize) -> Result> { + match &self[..] { + [] => Ok(Cow::Borrowed("")), + [Shared(inner)] => inner.to_str(len), + [Local(bytes)] => { + let utf8 = std::str::from_utf8(bytes); + utf8.context("failed to convert rope into string") + .map(Cow::Borrowed) + } + _ => { + let mut read = RopeReader::new(self, 0); + let mut string = String::with_capacity(len); + let res = read.read_to_string(&mut string); + res.context("failed to convert rope into string")?; + Ok(Cow::Owned(string)) + } + } + } + + /// Returns a slice of all bytes. + fn to_bytes(&self, len: usize) -> Result> { + match &self[..] { + [] => Ok(Cow::Borrowed(EMPTY_BUF)), + [Shared(inner)] => inner.to_bytes(len), + [Local(bytes)] => Ok(Cow::Borrowed(bytes)), + _ => { + let mut read = RopeReader::new(self, 0); + let mut buf = Vec::with_capacity(len); + read.read_to_end(&mut buf)?; + Ok(Cow::Owned(buf)) + } + } + } +} + +impl Default for InnerRope { + fn default() -> Self { + InnerRope(Arc::from([])) + } +} + +impl DeterministicHash for InnerRope { + /// Ropes with similar contents hash the same, regardless of their + /// structure. Notice the InnerRope does not contain a length (and any + /// shared InnerRopes won't either), so the exact structure isn't + /// relevant at this point. + fn deterministic_hash(&self, state: &mut H) { + for v in self.0.iter() { + v.deterministic_hash(state); + } + } +} + +impl From> for InnerRope { + fn from(els: Vec) -> Self { + if cfg!(debug_assertions) { + // It's important that an InnerRope never contain an empty Bytes section. + for el in els.iter() { + match el { + Local(b) => debug_assert!(!b.is_empty(), "must not have empty Bytes"), + Shared(s) => { + // We check whether the shared slice is empty, and not its elements. The + // only way to construct the Shared's InnerRope is + // in this mod, and we have already checked that + // none of its elements are empty. + debug_assert!(!s.is_empty(), "must not have empty InnerRope"); + } + } + } + } + InnerRope(Arc::from(els)) + } +} + +impl Deref for InnerRope { + type Target = Arc<[RopeElem]>; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl RopeElem { + fn maybe_eq(&self, other: &Self) -> Option { + match (self, other) { + (Local(a), Local(b)) => { + if a.len() == b.len() { + return Some(a == b); + } + + // But if not, the rope may still be contents equal if a following section + // contains the missing bytes. + None + } + (Shared(a), Shared(b)) => { + if Arc::ptr_eq(&a.0, &b.0) { + return Some(true); + } + + // But if not, they might still be equal and we need to fallback to slower + // equality. + None + } + _ => None, + } + } +} + +impl DeterministicHash for RopeElem { + /// Ropes with similar contents hash the same, regardless of their + /// structure. Notice the Bytes length is not hashed, and shared InnerRopes + /// do not contain a length. + fn deterministic_hash(&self, state: &mut H) { + match self { + Local(bytes) => state.write_bytes(bytes), + Shared(inner) => inner.deterministic_hash(state), + } + } +} + +#[derive(Debug, Default)] +/// Implements the [Read]/[AsyncRead]/[Iterator] trait over a [Rope]. +pub struct RopeReader { + /// The Rope's tree is kept as a cloned stack, allowing us to accomplish + /// incremental yielding. + stack: Vec, +} + +/// A StackElem holds the current index into either a Bytes or a shared Rope. +/// When the index reaches the end of the associated data, it is removed and we +/// continue onto the next item in the stack. +#[derive(Debug)] +enum StackElem { + Local(Bytes), + Shared(InnerRope, usize), +} + +impl RopeReader { + fn new(inner: &InnerRope, index: usize) -> Self { + if index >= inner.len() { + Default::default() + } else { + RopeReader { + stack: vec![StackElem::Shared(inner.clone(), index)], + } + } + } + + /// A shared implementation for reading bytes. This takes the basic + /// operations needed for both Read and AsyncRead. + fn read_internal(&mut self, want: usize, buf: &mut ReadBuf<'_>) -> usize { + let mut remaining = want; + + while remaining > 0 { + let mut bytes = match self.next() { + None => break, + Some(b) => b, + }; + + let amount = min(bytes.len(), remaining); + + buf.put_slice(&bytes[0..amount]); + + if amount < bytes.len() { + bytes.advance(amount); + self.stack.push(StackElem::Local(bytes)) + } + remaining -= amount; + } + + want - remaining + } +} + +impl Iterator for RopeReader { + type Item = Bytes; + + fn next(&mut self) -> Option { + // Iterates the rope's elements recursively until we find the next Local + // section, returning its Bytes. + loop { + let (inner, mut index) = match self.stack.pop() { + None => return None, + Some(StackElem::Local(b)) => { + debug_assert!(!b.is_empty(), "must not have empty Bytes section"); + return Some(b); + } + Some(StackElem::Shared(r, i)) => (r, i), + }; + + let el = inner[index].clone(); + index += 1; + if index < inner.len() { + self.stack.push(StackElem::Shared(inner, index)); + } + + self.stack.push(StackElem::from(el)); + } + } +} + +impl Read for RopeReader { + fn read(&mut self, buf: &mut [u8]) -> IoResult { + Ok(self.read_internal(buf.len(), &mut ReadBuf::new(buf))) + } +} + +impl AsyncRead for RopeReader { + fn poll_read( + self: Pin<&mut Self>, + _cx: &mut TaskContext<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + let this = self.get_mut(); + this.read_internal(buf.remaining(), buf); + Poll::Ready(Ok(())) + } +} + +impl BufRead for RopeReader { + fn fill_buf(&mut self) -> IoResult<&[u8]> { + // Returns the full buffer without coping any data. The same bytes will + // continue to be returned until [consume] is called. + let bytes = match self.next() { + None => return Ok(EMPTY_BUF), + Some(b) => b, + }; + + // This is just so we can get a reference to the asset that is kept alive by the + // RopeReader itself. We can then auto-convert that reference into the needed u8 + // slice reference. + self.stack.push(StackElem::Local(bytes)); + let Some(StackElem::Local(bytes)) = self.stack.last() else { + unreachable!() + }; + + Ok(bytes) + } + + fn consume(&mut self, amt: usize) { + if let Some(StackElem::Local(b)) = self.stack.last_mut() { + if amt == b.len() { + self.stack.pop(); + } else { + // Consume some amount of bytes from the current Bytes instance, ensuring + // those bytes are not returned on the next call to [fill_buf]. + b.advance(amt); + } + } + } +} + +impl Stream for RopeReader { + // The Result item type is required for this to be streamable into a + // [Hyper::Body]. + type Item = Result; + + // Returns a "result" of reading the next shared bytes reference. This + // differs from [Read::read] by not copying any memory. + fn poll_next(self: Pin<&mut Self>, _cx: &mut TaskContext<'_>) -> Poll> { + let this = self.get_mut(); + Poll::Ready(this.next().map(Ok)) + } +} + +impl From for StackElem { + fn from(el: RopeElem) -> Self { + match el { + Local(bytes) => Self::Local(bytes), + Shared(inner) => Self::Shared(inner, 0), + } + } +} + +#[cfg(test)] +mod test { + use std::{ + borrow::Cow, + cmp::min, + io::{BufRead, Read}, + }; + + use anyhow::Result; + + use super::{InnerRope, Rope, RopeBuilder, RopeElem}; + + // These are intentionally not exposed, because they do inefficient conversions + // in order to fully test cases. + impl From<&str> for RopeElem { + fn from(value: &str) -> Self { + RopeElem::Local(value.to_string().into()) + } + } + impl From> for RopeElem { + fn from(value: Vec) -> Self { + RopeElem::Shared(InnerRope::from(value)) + } + } + impl From for RopeElem { + fn from(value: Rope) -> Self { + RopeElem::Shared(value.data) + } + } + impl Rope { + fn new(value: Vec) -> Self { + let data = InnerRope::from(value); + Rope { + length: data.len(), + data, + } + } + } + impl InnerRope { + fn len(&self) -> usize { + self.iter().map(|v| v.len()).sum() + } + } + impl RopeElem { + fn len(&self) -> usize { + match self { + RopeElem::Local(b) => b.len(), + RopeElem::Shared(r) => r.len(), + } + } + } + + #[test] + fn empty_build_without_pushes() { + let empty = RopeBuilder::default().build(); + let mut reader = empty.read(); + assert!(reader.next().is_none()); + } + + #[test] + fn empty_build_with_empty_static_push() { + let mut builder = RopeBuilder::default(); + builder += ""; + + let empty = builder.build(); + let mut reader = empty.read(); + assert!(reader.next().is_none()); + } + + #[test] + fn empty_build_with_empty_bytes_push() { + let mut builder = RopeBuilder::default(); + builder.push_bytes(&[]); + + let empty = builder.build(); + let mut reader = empty.read(); + assert!(reader.next().is_none()); + } + + #[test] + fn empty_build_with_empty_concat() { + let mut builder = RopeBuilder::default(); + builder += &RopeBuilder::default().build(); + + let empty = builder.build(); + let mut reader = empty.read(); + assert!(reader.next().is_none()); + } + + #[test] + fn empty_from_empty_static_str() { + let empty = Rope::from(""); + let mut reader = empty.read(); + assert!(reader.next().is_none()); + } + + #[test] + fn empty_from_empty_string() { + let empty = Rope::from("".to_string()); + let mut reader = empty.read(); + assert!(reader.next().is_none()); + } + + #[test] + fn empty_equality() { + let a = Rope::from(""); + let b = Rope::from(""); + + assert_eq!(a, b); + } + + #[test] + fn cloned_equality() { + let a = Rope::from("abc"); + let b = a.clone(); + + assert_eq!(a, b); + } + + #[test] + fn value_equality() { + let a = Rope::from("abc".to_string()); + let b = Rope::from("abc".to_string()); + + assert_eq!(a, b); + } + + #[test] + fn value_inequality() { + let a = Rope::from("abc".to_string()); + let b = Rope::from("def".to_string()); + + assert_ne!(a, b); + } + + #[test] + fn value_equality_shared_1() { + let shared = Rope::from("def"); + let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ghi".into()]); + let b = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]); + + assert_eq!(a, b); + } + + #[test] + fn value_equality_shared_2() { + let a = Rope::new(vec!["abc".into(), vec!["def".into()].into(), "ghi".into()]); + let b = Rope::new(vec!["abc".into(), vec!["def".into()].into(), "ghi".into()]); + + assert_eq!(a, b); + } + + #[test] + fn value_equality_splits_1() { + let a = Rope::new(vec!["a".into(), "aa".into()]); + let b = Rope::new(vec!["aa".into(), "a".into()]); + + assert_eq!(a, b); + } + + #[test] + fn value_equality_splits_2() { + let a = Rope::new(vec![vec!["a".into()].into(), "aa".into()]); + let b = Rope::new(vec![vec!["aa".into()].into(), "a".into()]); + + assert_eq!(a, b); + } + + #[test] + fn value_inequality_shared_1() { + let shared = Rope::from("def"); + let a = Rope::new(vec!["aaa".into(), shared.clone().into(), "ghi".into()]); + let b = Rope::new(vec!["bbb".into(), shared.into(), "ghi".into()]); + + assert_ne!(a, b); + } + + #[test] + fn value_inequality_shared_2() { + let a = Rope::new(vec!["abc".into(), vec!["ddd".into()].into(), "ghi".into()]); + let b = Rope::new(vec!["abc".into(), vec!["eee".into()].into(), "ghi".into()]); + + assert_ne!(a, b); + } + + #[test] + fn value_inequality_shared_3() { + let shared = Rope::from("def"); + let a = Rope::new(vec!["abc".into(), shared.clone().into(), "ggg".into()]); + let b = Rope::new(vec!["abc".into(), shared.into(), "hhh".into()]); + + assert_ne!(a, b); + } + + #[test] + fn iteration() { + let shared = Rope::from("def"); + let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]); + + let chunks = rope.read().collect::>(); + + assert_eq!(chunks, vec!["abc", "def", "ghi"]); + } + + #[test] + fn read() { + let shared = Rope::from("def"); + let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]); + + let mut chunks = vec![]; + let mut buf = [0_u8; 2]; + let mut reader = rope.read(); + loop { + let amt = reader.read(&mut buf).unwrap(); + if amt == 0 { + break; + } + chunks.push(Vec::from(&buf[0..amt])); + } + + assert_eq!( + chunks, + vec![ + Vec::from(*b"ab"), + Vec::from(*b"cd"), + Vec::from(*b"ef"), + Vec::from(*b"gh"), + Vec::from(*b"i") + ] + ); + } + + #[test] + fn fill_buf() { + let shared = Rope::from("def"); + let rope = Rope::new(vec!["abc".into(), shared.into(), "ghi".into()]); + + let mut chunks = vec![]; + let mut reader = rope.read(); + loop { + let buf = reader.fill_buf().unwrap(); + if buf.is_empty() { + break; + } + let c = min(2, buf.len()); + chunks.push(Vec::from(buf)); + reader.consume(c); + } + + assert_eq!( + chunks, + // We're receiving a full buf, then only consuming 2 bytes, so we'll still get the + // third. + vec![ + Vec::from(*b"abc"), + Vec::from(*b"c"), + Vec::from(*b"def"), + Vec::from(*b"f"), + Vec::from(*b"ghi"), + Vec::from(*b"i") + ] + ); + } + + #[test] + fn test_to_bytes() -> Result<()> { + let rope = Rope::from("abc"); + assert_eq!(rope.to_bytes()?, Cow::Borrowed::<[u8]>(&[0x61, 0x62, 0x63])); + Ok(()) + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/source_context.rs b/turbopack/crates/turbo-tasks-fs/src/source_context.rs new file mode 100644 index 0000000000000..b32cd76a16d03 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/source_context.rs @@ -0,0 +1,187 @@ +use std::{borrow::Cow, cmp::Ordering, fmt::Display}; + +pub enum SourceContextLine<'a> { + Context { + line: usize, + outside: Cow<'a, str>, + }, + Start { + line: usize, + before: Cow<'a, str>, + inside: Cow<'a, str>, + }, + End { + line: usize, + inside: Cow<'a, str>, + after: Cow<'a, str>, + }, + StartAndEnd { + line: usize, + before: Cow<'a, str>, + inside: Cow<'a, str>, + after: Cow<'a, str>, + }, + Inside { + line: usize, + inside: Cow<'a, str>, + }, +} + +impl<'a> Display for SourceContextLine<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + SourceContextLine::Context { line, outside } => { + writeln!(f, "{line:>6} | {outside}") + } + SourceContextLine::Start { + line, + before, + inside, + } => { + writeln!( + f, + " | {}v{}", + " ".repeat(before.len()), + "-".repeat(inside.len()), + )?; + writeln!(f, "{line:>6} + {before}{inside}") + } + SourceContextLine::End { + line, + inside, + after, + } => { + writeln!(f, "{line:>6} + {inside}{after}")?; + writeln!(f, " +{}^", "-".repeat(inside.len())) + } + SourceContextLine::StartAndEnd { + line, + before, + inside, + after, + } => { + if inside.len() >= 2 { + writeln!( + f, + " | {}v{}v", + " ".repeat(before.len()), + "-".repeat(inside.len() - 2) + )?; + } else { + writeln!(f, " | {}v", " ".repeat(before.len()))?; + } + writeln!(f, "{line:>6} + {before}{inside}{after}")?; + if inside.len() >= 2 { + writeln!( + f, + " | {}^{}^", + " ".repeat(before.len()), + "-".repeat(inside.len() - 2), + ) + } else { + writeln!(f, " | {}^", " ".repeat(before.len())) + } + } + SourceContextLine::Inside { line, inside } => { + writeln!(f, "{line:>6} + {inside}") + } + } + } +} + +pub struct SourceContextLines<'a>(pub Vec>); + +impl<'a> Display for SourceContextLines<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for line in &self.0 { + write!(f, "{}", line)?; + } + Ok(()) + } +} + +/// Compute the source context for a given range of lines, including selected +/// ranges in these lines. (Lines are 0-indexed) +pub fn get_source_context<'a>( + lines: impl Iterator, + start_line: usize, + start_column: usize, + end_line: usize, + end_column: usize, +) -> SourceContextLines<'a> { + let mut result = Vec::new(); + let context_start = start_line.saturating_sub(4); + let context_end = end_line + 4; + for (i, l) in lines.enumerate().take(context_end + 1).skip(context_start) { + let n = i + 1; + fn safe_split_at(s: &str, i: usize) -> (&str, &str) { + if i < s.len() { + s.split_at(s.floor_char_boundary(i)) + } else { + (s, "") + } + } + fn limit_len(s: &str) -> Cow<'_, str> { + if s.len() < 200 { + return Cow::Borrowed(s); + } + let (a, b) = s.split_at(s.floor_char_boundary(98)); + let (_, c) = b.split_at(b.ceil_char_boundary(b.len() - 99)); + Cow::Owned(format!("{}...{}", a, c)) + } + match (i.cmp(&start_line), i.cmp(&end_line)) { + // outside + (Ordering::Less, _) | (_, Ordering::Greater) => { + result.push(SourceContextLine::Context { + line: n, + outside: limit_len(l), + }); + } + // start line + (Ordering::Equal, Ordering::Less) => { + let (before, inside) = safe_split_at(l, start_column); + let before = limit_len(before); + let inside = limit_len(inside); + result.push(SourceContextLine::Start { + line: n, + before, + inside, + }); + } + // start and end line + (Ordering::Equal, Ordering::Equal) => { + let real_start = l.floor_char_boundary(start_column); + let (before, temp) = safe_split_at(l, real_start); + let (inside, after) = safe_split_at(temp, end_column - real_start); + let before = limit_len(before); + let inside = limit_len(inside); + let after = limit_len(after); + result.push(SourceContextLine::StartAndEnd { + line: n, + before, + inside, + after, + }); + } + // end line + (Ordering::Greater, Ordering::Equal) => { + let (inside, after) = safe_split_at(l, end_column); + let inside = limit_len(inside); + let after = limit_len(after); + result.push(SourceContextLine::End { + line: n, + inside, + after, + }); + } + // middle line + (Ordering::Greater, Ordering::Less) => { + result.push(SourceContextLine::Inside { + line: n, + inside: limit_len(l), + }); + } + } + } + SourceContextLines(result) +} diff --git a/turbopack/crates/turbo-tasks-fs/src/util.rs b/turbopack/crates/turbo-tasks-fs/src/util.rs new file mode 100644 index 0000000000000..ef85765fff4dd --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/util.rs @@ -0,0 +1,135 @@ +use std::{ + borrow::Cow, + io::{self, ErrorKind}, + path::Path, +}; + +use anyhow::{anyhow, Result}; + +/// Joins two /-separated paths into a normalized path. +/// Paths are concatenated with /. +/// +/// see also [normalize_path] for normalization. +pub fn join_path(fs_path: &str, join: &str) -> Option { + // Paths that we join are written as source code (eg, `join_path(fs_path, + // "foo/bar.js")`) and it's expected that they will never contain a + // backslash. + debug_assert!( + !join.contains('\\'), + "joined path {} must not contain a Windows directory '\\', it must be normalized to Unix \ + '/'", + join + ); + + // TODO: figure out why this freezes the benchmarks. + // // an absolute path would leave the file system root + // if Path::new(join).is_absolute() { + // return None; + // } + + if fs_path.is_empty() { + normalize_path(join) + } else if join.is_empty() { + normalize_path(fs_path) + } else { + normalize_path(&[fs_path, "/", join].concat()) + } +} + +/// Converts System paths into Unix paths. This is a noop on Unix systems, and +/// replaces backslash directory separators with forward slashes on Windows. +#[inline] +pub fn sys_to_unix(path: &str) -> Cow<'_, str> { + #[cfg(not(target_family = "windows"))] + { + Cow::from(path) + } + #[cfg(target_family = "windows")] + { + Cow::Owned(path.replace(std::path::MAIN_SEPARATOR_STR, "/")) + } +} + +/// Converts Unix paths into System paths. This is a noop on Unix systems, and +/// replaces forward slash directory separators with backslashes on Windows. +#[inline] +pub fn unix_to_sys(path: &str) -> Cow<'_, str> { + #[cfg(not(target_family = "windows"))] + { + Cow::from(path) + } + #[cfg(target_family = "windows")] + { + Cow::Owned(path.replace('/', std::path::MAIN_SEPARATOR_STR)) + } +} + +/// Normalizes a /-separated path into a form that contains no leading /, no +/// double /, no "." seqment, no ".." seqment. +/// +/// Returns None if the path would need to start with ".." to be equal. +pub fn normalize_path(str: &str) -> Option { + let mut seqments = Vec::new(); + for seqment in str.split('/') { + match seqment { + "." | "" => {} + ".." => { + seqments.pop()?; + } + seqment => { + seqments.push(seqment); + } + } + } + Some(seqments.join("/")) +} + +/// Normalizes a /-separated request into a form that contains no leading /, no +/// double /, and no "." or ".." seqments in the middle of the request. A +/// request might only start with a single "." seqment and no ".." segements, or +/// any positive number of ".." seqments but no "." seqment. +pub fn normalize_request(str: &str) -> String { + let mut seqments = vec!["."]; + // Keeps track of our directory depth so that we can pop directories when + // encountering a "..". If this is positive, then we're inside a directory + // and we can pop that. If it's 0, then we can't pop the directory and we must + // keep the ".." in our seqments. This is not the same as the seqments.len(), + // because we cannot pop a kept ".." when encountering another "..". + let mut depth = 0; + let mut popped_dot = false; + for seqment in str.split('/') { + match seqment { + "." => {} + ".." => { + if depth > 0 { + depth -= 1; + seqments.pop(); + } else { + // The first time we push a "..", we need to remove the "." we include by + // default. + if !popped_dot { + popped_dot = true; + seqments.pop(); + } + seqments.push(seqment); + } + } + seqment => { + seqments.push(seqment); + depth += 1; + } + } + } + seqments.join("/") +} + +/// Converts a disk access Result into a Result>, where a NotFound +/// error results in a None value. This is purely to reduce boilerplate code +/// comparing NotFound errors against all other errors. +pub fn extract_disk_access(value: io::Result, path: &Path) -> Result> { + match value { + Ok(v) => Ok(Some(v)), + Err(e) if matches!(e.kind(), ErrorKind::NotFound | ErrorKind::InvalidFilename) => Ok(None), + Err(e) => Err(anyhow!(e).context(format!("reading file {}", path.display()))), + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/virtual_fs.rs b/turbopack/crates/turbo-tasks-fs/src/virtual_fs.rs new file mode 100644 index 0000000000000..f578e6b037bd8 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/virtual_fs.rs @@ -0,0 +1,97 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{Completion, RcStr, ValueDefault, ValueToString, Vc}; + +use super::{DirectoryContent, FileContent, FileMeta, FileSystem, FileSystemPath, LinkContent}; + +#[turbo_tasks::value] +pub struct VirtualFileSystem { + name: RcStr, +} + +impl VirtualFileSystem { + /// Creates a new [`Vc`]. + /// + /// NOTE: This function is not a `turbo_tasks::function` to avoid instances + /// being equivalent identity-wise. This ensures that a + /// [`Vc`] created from this [`Vc`] + /// will never be equivalent, nor be interoperable, with a + /// [`Vc`] created from another + /// [`Vc`]. + pub fn new() -> Vc { + Self::cell(VirtualFileSystem { + name: "virtual file system".into(), + }) + } + + /// Creates a new [`Vc`] with a name. + /// + /// NOTE: This function is not a `turbo_tasks::function` to avoid instances + /// being equivalent identity-wise. This ensures that a + /// [`Vc`] created from this [`Vc`] + /// will never be equivalent, nor be interoperable, with a + /// [`Vc`] created from another + /// [`Vc`]. + pub fn new_with_name(name: RcStr) -> Vc { + Self::cell(VirtualFileSystem { name }) + } +} + +impl ValueDefault for VirtualFileSystem { + fn value_default() -> Vc { + Self::new() + } +} + +#[turbo_tasks::value_impl] +impl FileSystem for VirtualFileSystem { + #[turbo_tasks::function] + fn read(&self, _fs_path: Vc) -> Result> { + bail!("Reading is not possible on the virtual file system") + } + + #[turbo_tasks::function] + fn read_link(&self, _fs_path: Vc) -> Result> { + bail!("Reading is not possible on the virtual file system") + } + + #[turbo_tasks::function] + fn read_dir(&self, _fs_path: Vc) -> Result> { + bail!("Reading is not possible on the virtual file system") + } + + #[turbo_tasks::function] + fn track(&self, _fs_path: Vc) -> Result> { + bail!("Tracking is not possible on the virtual file system") + } + + #[turbo_tasks::function] + fn write( + &self, + _fs_path: Vc, + _content: Vc, + ) -> Result> { + bail!("Writing is not possible on the virtual file system") + } + + #[turbo_tasks::function] + fn write_link( + &self, + _fs_path: Vc, + _target: Vc, + ) -> Result> { + bail!("Writing is not possible on the virtual file system") + } + + #[turbo_tasks::function] + fn metadata(&self, _fs_path: Vc) -> Result> { + bail!("Reading is not possible on the virtual file system") + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for VirtualFileSystem { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(self.name.clone()) + } +} diff --git a/turbopack/crates/turbo-tasks-fs/src/watcher.rs b/turbopack/crates/turbo-tasks-fs/src/watcher.rs new file mode 100644 index 0000000000000..c674a58807b07 --- /dev/null +++ b/turbopack/crates/turbo-tasks-fs/src/watcher.rs @@ -0,0 +1,443 @@ +use std::{ + collections::{HashMap, HashSet}, + mem::take, + path::{Path, PathBuf}, + sync::{ + mpsc::{channel, Receiver, TryRecvError}, + Arc, Mutex, + }, + time::Duration, +}; + +use anyhow::Result; +use notify::{ + event::{MetadataKind, ModifyKind, RenameMode}, + Config, EventKind, RecommendedWatcher, RecursiveMode, Watcher, +}; +use serde::{Deserialize, Serialize}; +use tokio::sync::RwLock; +use tracing::instrument; +use turbo_tasks::{spawn_thread, Invalidator, RcStr}; + +use crate::{ + format_absolute_fs_path, + invalidation::{WatchChange, WatchStart}, + invalidator_map::InvalidatorMap, + path_to_key, +}; + +#[derive(Default, Serialize, Deserialize)] +pub(crate) struct DiskWatcher { + #[serde(skip)] + watcher: Mutex>, + + /// Array of paths that should not notify invalidations. + /// `notify` currently doesn't support unwatching subpaths from the root, + /// so underlying we still watches filesystem event but only skips to + /// invalidate. + ignored_subpaths: Vec, + + /// Keeps track of which directories are currently watched. This is only + /// used on OSs that doesn't support recursive watching. + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + #[serde(skip)] + watching: dashmap::DashSet, +} + +impl DiskWatcher { + pub(crate) fn new(ignored_subpaths: Vec) -> Self { + Self { + ignored_subpaths, + ..Default::default() + } + } + + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + pub(crate) fn restore_if_watching(&self, dir_path: &Path, root_path: &Path) -> Result<()> { + if self.watching.contains(dir_path) { + let mut watcher = self.watcher.lock().unwrap(); + self.start_watching_dir(&mut watcher, dir_path, root_path)?; + } + Ok(()) + } + + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + pub(crate) fn ensure_watching(&self, dir_path: &Path, root_path: &Path) -> Result<()> { + if self.watching.contains(dir_path) { + return Ok(()); + } + let mut watcher = self.watcher.lock().unwrap(); + if self.watching.insert(dir_path.to_path_buf()) { + self.start_watching_dir(&mut watcher, dir_path, root_path)?; + } + Ok(()) + } + + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + fn start_watching_dir( + &self, + watcher: &mut std::sync::MutexGuard>, + dir_path: &Path, + root_path: &Path, + ) -> Result<()> { + use anyhow::Context; + + if let Some(watcher) = watcher.as_mut() { + let mut path = dir_path; + while let Err(err) = watcher.watch(path, RecursiveMode::NonRecursive) { + if path == root_path { + return Err(err).context(format!( + "Unable to watch {} (tried up to {})", + dir_path.display(), + path.display() + )); + } + let Some(parent_path) = path.parent() else { + return Err(err).context(format!( + "Unable to watch {} (tried up to {})", + dir_path.display(), + path.display() + )); + }; + path = parent_path; + } + } + Ok(()) + } + + /// Create a watcher and start watching by creating `debounced` watcher + /// via `full debouncer` + /// + /// `notify` provides 2 different debouncer implementations, `-full` + /// provides below differences for the easy of use: + /// + /// - Only emits a single Rename event if the rename From and To events can + /// be matched + /// - Merges multiple Rename events + /// - Takes Rename events into account and updates paths for events that + /// occurred before the rename event, but which haven't been emitted, yet + /// - Optionally keeps track of the file system IDs all files and stitches + /// rename events together (FSevents, Windows) + /// - Emits only one Remove event when deleting a directory (inotify) + /// - Doesn't emit duplicate create events + /// - Doesn't emit Modify events after a Create event + pub(crate) fn start_watching( + self: Arc, + name: RcStr, + root_path: PathBuf, + report_invalidation_reason: Option<(RcStr, PathBuf)>, + invalidation_lock: Arc>, + invalidator_map: Arc, + dir_invalidator_map: Arc, + ) -> Result<()> { + let mut watcher_guard = self.watcher.lock().unwrap(); + if watcher_guard.is_some() { + return Ok(()); + } + + // Create a channel to receive the events. + let (tx, rx) = channel(); + // Create a watcher object, delivering debounced events. + // The notification back-end is selected based on the platform. + let mut watcher = RecommendedWatcher::new(tx, Config::default())?; + // Add a path to be watched. All files and directories at that path and + // below will be monitored for changes. + #[cfg(any(target_os = "macos", target_os = "windows"))] + { + watcher.watch(&root_path, RecursiveMode::Recursive)?; + } + + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + for dir_path in self.watching.iter() { + watcher.watch(&dir_path, RecursiveMode::NonRecursive)?; + } + + // We need to invalidate all reads that happened before watching + // Best is to start_watching before starting to read + for invalidator in take(&mut *invalidator_map.lock().unwrap()) + .into_iter() + .chain(take(&mut *dir_invalidator_map.lock().unwrap()).into_iter()) + .flat_map(|(_, invalidators)| invalidators.into_iter()) + { + if report_invalidation_reason.is_some() { + invalidator.invalidate_with_reason(WatchStart { name: name.clone() }) + } else { + invalidator.invalidate(); + } + } + + watcher_guard.replace(watcher); + drop(watcher_guard); + + spawn_thread(move || { + self.watch_thread( + rx, + root_path, + report_invalidation_reason, + invalidation_lock, + invalidator_map, + dir_invalidator_map, + ) + }); + + Ok(()) + } + + pub(crate) fn stop_watching(&self) { + if let Some(watcher) = self.watcher.lock().unwrap().take() { + drop(watcher); + // thread will detect the stop because the channel is disconnected + } + } + + /// Internal thread that processes the events from the watcher + /// and invalidates the cache. + /// + /// Should only be called once from `start_watching`. + fn watch_thread( + &self, + rx: Receiver>, + root_path: PathBuf, + report_invalidation_reason: Option<(RcStr, PathBuf)>, + invalidation_lock: Arc>, + invalidator_map: Arc, + dir_invalidator_map: Arc, + ) { + let mut batched_invalidate_path = HashSet::new(); + let mut batched_invalidate_path_dir = HashSet::new(); + let mut batched_invalidate_path_and_children = HashSet::new(); + let mut batched_invalidate_path_and_children_dir = HashSet::new(); + + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + let mut batched_new_paths = HashSet::new(); + + 'outer: loop { + let mut event = rx.recv().or(Err(TryRecvError::Disconnected)); + loop { + match event { + Ok(Ok(notify::Event { kind, paths, .. })) => { + let paths: Vec = paths + .iter() + .filter(|p| { + !self + .ignored_subpaths + .iter() + .any(|ignored| p.starts_with(ignored)) + }) + .cloned() + .collect(); + + if paths.is_empty() { + return; + } + + // [NOTE] there is attrs in the `Event` struct, which contains few + // more metadata like process_id who triggered the event, + // or the source we may able to utilize later. + match kind { + // [NOTE] Observing `ModifyKind::Metadata(MetadataKind::Any)` is + // not a mistake, fix for PACK-2437. + // In here explicitly subscribes to the `ModifyKind::Data` which + // indicates file content changes - in case of fsevents backend, + // this is `kFSEventStreamEventFlagItemModified`. + // Also meanwhile we subscribe to ModifyKind::Metadata as well. + // This is due to in some cases fsevents does not emit explicit + // kFSEventStreamEventFlagItemModified kernel events, + // but only emits kFSEventStreamEventFlagItemInodeMetaMod. While + // this could cause redundant invalidation, + // it's the way to reliably detect file content changes. + // ref other implementation, i.e libuv does same thing to + // trigger UV_CHANEGS https://github.com/libuv/libuv/commit/73cf3600d75a5884b890a1a94048b8f3f9c66876#diff-e12fdb1f404f1c97bbdcc0956ac90d7db0d811d9fa9ca83a3deef90c937a486cR95-R99 + EventKind::Modify( + ModifyKind::Data(_) | ModifyKind::Metadata(MetadataKind::Any), + ) => { + batched_invalidate_path.extend(paths.clone()); + } + EventKind::Create(_) => { + batched_invalidate_path_and_children.extend(paths.clone()); + batched_invalidate_path_and_children_dir.extend(paths.clone()); + paths.iter().for_each(|path| { + if let Some(parent) = path.parent() { + batched_invalidate_path_dir.insert(PathBuf::from(parent)); + } + }); + + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + batched_new_paths.extend(paths.clone()); + } + EventKind::Remove(_) => { + batched_invalidate_path_and_children.extend(paths.clone()); + batched_invalidate_path_and_children_dir.extend(paths.clone()); + paths.iter().for_each(|path| { + if let Some(parent) = path.parent() { + batched_invalidate_path_dir.insert(PathBuf::from(parent)); + } + }); + } + // A single event emitted with both the `From` and `To` paths. + EventKind::Modify(ModifyKind::Name(RenameMode::Both)) => { + // For the rename::both, notify provides an array of paths + // in given order + if let [source, destination, ..] = &paths[..] { + batched_invalidate_path_and_children.insert(source.clone()); + if let Some(parent) = source.parent() { + batched_invalidate_path_dir.insert(PathBuf::from(parent)); + } + batched_invalidate_path_and_children + .insert(destination.clone()); + if let Some(parent) = destination.parent() { + batched_invalidate_path_dir.insert(PathBuf::from(parent)); + } + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + batched_new_paths.insert(destination.clone()); + } else { + // If we hit here, we expect this as a bug either in + // notify or system weirdness. + panic!( + "Rename event does not contain source and destination \ + paths {:#?}", + paths + ); + } + } + // We expect `RenameMode::Both` to cover most of the cases we + // need to invalidate, + // but we also check other RenameModes + // to cover cases where notify couldn't match the two rename + // events. + EventKind::Any + | EventKind::Modify(ModifyKind::Any | ModifyKind::Name(..)) => { + batched_invalidate_path.extend(paths.clone()); + batched_invalidate_path_and_children.extend(paths.clone()); + batched_invalidate_path_and_children_dir.extend(paths.clone()); + for parent in paths.iter().filter_map(|path| path.parent()) { + batched_invalidate_path_dir.insert(PathBuf::from(parent)); + } + } + EventKind::Modify(ModifyKind::Metadata(..) | ModifyKind::Other) + | EventKind::Access(_) + | EventKind::Other => { + // ignored + } + } + } + // Error raised by notify watcher itself + Ok(Err(notify::Error { kind, paths })) => { + println!("watch error ({:?}): {:?} ", paths, kind); + + if paths.is_empty() { + batched_invalidate_path_and_children.insert(root_path.clone()); + batched_invalidate_path_and_children_dir.insert(root_path.clone()); + } else { + batched_invalidate_path_and_children.extend(paths.clone()); + batched_invalidate_path_and_children_dir.extend(paths.clone()); + } + } + Err(TryRecvError::Disconnected) => { + // Sender has been disconnected + // which means DiskFileSystem has been dropped + // exit thread + break 'outer; + } + Err(TryRecvError::Empty) => { + // Linux watching is too fast, so we need to throttle it a bit to avoid + // reading wip files + #[cfg(target_os = "linux")] + let delay = Duration::from_millis(10); + #[cfg(not(target_os = "linux"))] + let delay = Duration::from_millis(1); + match rx.recv_timeout(delay) { + Ok(result) => { + event = Ok(result); + continue; + } + Err(_) => break, + } + } + } + event = rx.try_recv(); + } + + // We need to start watching first before invalidating the changed paths + #[cfg(not(any(target_os = "macos", target_os = "windows")))] + { + for path in batched_new_paths.drain() { + let _ = self.restore_if_watching(&path, &root_path); + } + } + + let _lock = invalidation_lock.blocking_write(); + { + let mut invalidator_map = invalidator_map.lock().unwrap(); + invalidate_path( + &report_invalidation_reason, + &mut invalidator_map, + batched_invalidate_path.drain(), + ); + invalidate_path_and_children_execute( + &report_invalidation_reason, + &mut invalidator_map, + batched_invalidate_path_and_children.drain(), + ); + } + { + let mut dir_invalidator_map = dir_invalidator_map.lock().unwrap(); + invalidate_path( + &report_invalidation_reason, + &mut dir_invalidator_map, + batched_invalidate_path_dir.drain(), + ); + invalidate_path_and_children_execute( + &report_invalidation_reason, + &mut dir_invalidator_map, + batched_invalidate_path_and_children_dir.drain(), + ); + } + } + } +} + +#[instrument(parent = None, level = "info", name = "DiskFileSystem file change", skip_all, fields(name = display(path.display())))] +fn invalidate( + report_invalidation_reason: &Option<(RcStr, PathBuf)>, + path: &Path, + invalidator: Invalidator, +) { + if let Some((name, root_path)) = report_invalidation_reason { + if let Some(path) = format_absolute_fs_path(path, name, root_path) { + invalidator.invalidate_with_reason(WatchChange { path }); + return; + } + } + invalidator.invalidate(); +} + +fn invalidate_path( + report_invalidation_reason: &Option<(RcStr, PathBuf)>, + invalidator_map: &mut HashMap>, + paths: impl Iterator, +) { + for path in paths { + let key = path_to_key(&path); + if let Some(invalidators) = invalidator_map.remove(&key) { + invalidators + .into_iter() + .for_each(|i| invalidate(report_invalidation_reason, &path, i)); + } + } +} + +fn invalidate_path_and_children_execute( + report_invalidation_reason: &Option<(RcStr, PathBuf)>, + invalidator_map: &mut HashMap>, + paths: impl Iterator, +) { + for path in paths { + let path_key = path_to_key(&path); + for (_, invalidators) in invalidator_map.extract_if(|key, _| key.starts_with(&path_key)) { + invalidators + .into_iter() + .for_each(|i| invalidate(report_invalidation_reason, &path, i)); + } + } +} diff --git a/turbopack/crates/turbo-tasks-hash/Cargo.toml b/turbopack/crates/turbo-tasks-hash/Cargo.toml new file mode 100644 index 0000000000000..05dcad51392ff --- /dev/null +++ b/turbopack/crates/turbo-tasks-hash/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "turbo-tasks-hash" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +md4 = "0.10.1" +turbo-tasks-macros = { workspace = true } +twox-hash = "1.6.3" diff --git a/turbopack/crates/turbo-tasks-hash/src/deterministic_hash.rs b/turbopack/crates/turbo-tasks-hash/src/deterministic_hash.rs new file mode 100644 index 0000000000000..7d378108eeaea --- /dev/null +++ b/turbopack/crates/turbo-tasks-hash/src/deterministic_hash.rs @@ -0,0 +1,200 @@ +use std::mem::Discriminant; + +pub use turbo_tasks_macros::DeterministicHash; + +macro_rules! deterministic_hash_number { + ($(($ty:ident, $meth:ident),)*) => {$( + impl DeterministicHash for $ty { + fn deterministic_hash(&self, state: &mut H) { + state.$meth(*self); + } + } + )*} +} + +macro_rules! impl_write_number { + ($(($ty:ident, $meth:ident),)*) => {$( + /// Writes a single `$ty` to this hasher + #[inline] + fn $meth(&mut self, i: $ty) { + // Apple silicon and Intel chips both use little endian, so this should be fast. + let little_endian = i.to_le_bytes(); + self.write_bytes(&little_endian); + } + )*} +} + +/// DeterministicHash is a custom trait that signals the implementor can safely +/// be hashed in a replicatable way across platforms and process runs. Note that +/// the default Hash trait used by Rust is not deterministic for our purposes. +/// +/// It's very important that Vcs never implement this, since they cannot be +/// deterministic. The value that they wrap, however, can implement the trait. +pub trait DeterministicHash { + /// Adds self's bytes to the [Hasher] state, in a way that is replicatable + /// on any platform or process run. + fn deterministic_hash(&self, state: &mut H); +} + +/// DeterministicHasher is a custom trait that signals the implementor can +/// safely hash in a replicatable way across platforms and process runs. Note +/// that the default Hasher trait used by Rust allows for non-deterministic +/// hashing, so it is not suitable for our purposes. +pub trait DeterministicHasher { + fn finish(&self) -> u64; + fn write_bytes(&mut self, bytes: &[u8]); + + /// Writes a single `u8` to this hasher + #[inline] + fn write_u8(&mut self, i: u8) { + self.write_bytes(&[i]); + } + + /// Writes a single `usize` to this hasher + #[inline] + fn write_usize(&mut self, i: usize) { + // usize can be 4 or 8 bytes, standardize on the larger. + // As long as the original value is smaller than 4 bytes, the two will hash + // equivalently. + self.write_u64(i as u64); + } + + /// Writes a single `isize` to this hasher + #[inline] + fn write_isize(&mut self, i: isize) { + // isize can be 4 or 8 bytes, standardize on the larger. + // As long as the original value is smaller than 4 bytes, the two will hash + // equivalently. + self.write_i64(i as i64); + } + + impl_write_number! { + (u16, write_u16), + (u32, write_u32), + (u64, write_u64), + (i8, write_i8), + (i16, write_i16), + (i32, write_i32), + (i64, write_i64), + (u128, write_u128), + (i128, write_i128), + } +} + +deterministic_hash_number! { + (u8, write_u8), + (u16, write_u16), + (u32, write_u32), + (u64, write_u64), + (usize, write_usize), + (i8, write_i8), + (i16, write_i16), + (i32, write_i32), + (i64, write_i64), + (isize, write_isize), + (u128, write_u128), + (i128, write_i128), +} + +impl DeterministicHash for &T { + fn deterministic_hash(&self, state: &mut H) { + (**self).deterministic_hash(state); + } +} + +impl DeterministicHash for [u8] { + fn deterministic_hash(&self, state: &mut H) { + state.write_usize(self.len()); + state.write_bytes(self); + } +} + +impl DeterministicHash for String { + fn deterministic_hash(&self, state: &mut H) { + state.write_usize(self.len()); + state.write_bytes(self.as_bytes()); + } +} + +impl DeterministicHash for &str { + fn deterministic_hash(&self, state: &mut H) { + state.write_usize(self.len()); + state.write_bytes(self.as_bytes()); + } +} + +impl DeterministicHash for bool { + fn deterministic_hash(&self, state: &mut H) { + state.write_u8(*self as u8); + } +} + +impl DeterministicHash for Option { + fn deterministic_hash(&self, state: &mut H) { + match self { + None => state.write_u8(0), + Some(v) => { + state.write_u8(1); + v.deterministic_hash(state); + } + } + } +} + +impl DeterministicHash for Vec { + fn deterministic_hash(&self, state: &mut H) { + state.write_usize(self.len()); + for v in self { + v.deterministic_hash(state); + } + } +} + +macro_rules! tuple_impls { + ( $( $name:ident )+ ) => { + impl<$($name: DeterministicHash),+> DeterministicHash for ($($name,)+) + { + #[allow(non_snake_case)] + fn deterministic_hash(&self, state: &mut Hasher) { + let ($(ref $name,)+) = *self; + $($name.deterministic_hash(state);)+ + } + } + }; +} + +// Implement `DeterministicHash` for all tuples of 1 to 12 elements. +tuple_impls! { A } +tuple_impls! { A B } +tuple_impls! { A B C } +tuple_impls! { A B C D } +tuple_impls! { A B C D E } +tuple_impls! { A B C D E F } +tuple_impls! { A B C D E F G } +tuple_impls! { A B C D E F G H } +tuple_impls! { A B C D E F G H I } +tuple_impls! { A B C D E F G H I J } +tuple_impls! { A B C D E F G H I J K } +tuple_impls! { A B C D E F G H I J K L } + +/// HasherWrapper allows the DeterministicHasher to be used as a Hasher, for +/// standard types that do not allow us to directly access their internals. +struct HasherWrapper<'a, D: DeterministicHasher>(&'a mut D); +impl<'a, D: DeterministicHasher> std::hash::Hasher for HasherWrapper<'a, D> { + fn write(&mut self, bytes: &[u8]) { + self.0.write_bytes(bytes); + } + + fn finish(&self) -> u64 { + unimplemented!(); + } +} + +impl DeterministicHash for Discriminant { + fn deterministic_hash(&self, state: &mut H) { + // The Discriminant does not allow us to access its internal state, but does + // allow us to Hash it. + let mut wrapper = HasherWrapper(state); + std::hash::Hash::hash(self, &mut wrapper); + } +} diff --git a/turbopack/crates/turbo-tasks-hash/src/hex.rs b/turbopack/crates/turbo-tasks-hash/src/hex.rs new file mode 100644 index 0000000000000..9fd35fa975f22 --- /dev/null +++ b/turbopack/crates/turbo-tasks-hash/src/hex.rs @@ -0,0 +1,4 @@ +/// Encodes a 64-bit unsigned integer into a hex string. +pub fn encode_hex(n: u64) -> String { + format!("{:01$x}", n, std::mem::size_of::() * 2) +} diff --git a/turbopack/crates/turbo-tasks-hash/src/lib.rs b/turbopack/crates/turbo-tasks-hash/src/lib.rs new file mode 100644 index 0000000000000..d6ab4c13e44f8 --- /dev/null +++ b/turbopack/crates/turbo-tasks-hash/src/lib.rs @@ -0,0 +1,17 @@ +//! Hashing and encoding functions for turbopack. +//! +//! An example use of this module is hashing a file's content for cache +//! invalidation, and encoding the hash to an hexadecimal string for use in a +//! file name. + +mod deterministic_hash; +mod hex; +mod md4; +mod xxh3_hash64; + +pub use crate::{ + deterministic_hash::{DeterministicHash, DeterministicHasher}, + hex::encode_hex, + md4::hash_md4, + xxh3_hash64::{hash_xxh3_hash64, Xxh3Hash64Hasher}, +}; diff --git a/turbopack/crates/turbo-tasks-hash/src/md4.rs b/turbopack/crates/turbo-tasks-hash/src/md4.rs new file mode 100644 index 0000000000000..1087cfc587504 --- /dev/null +++ b/turbopack/crates/turbo-tasks-hash/src/md4.rs @@ -0,0 +1,8 @@ +use md4::Digest; + +/// Hash some content with the MD4 cryptographic hash function. +/// +/// Returns a 16-byte hash digest. +pub fn hash_md4(content: &[u8]) -> [u8; 16] { + md4::Md4::digest(content).into() +} diff --git a/turbopack/crates/turbo-tasks-hash/src/xxh3_hash64.rs b/turbopack/crates/turbo-tasks-hash/src/xxh3_hash64.rs new file mode 100644 index 0000000000000..e5dec287e4b30 --- /dev/null +++ b/turbopack/crates/turbo-tasks-hash/src/xxh3_hash64.rs @@ -0,0 +1,55 @@ +use std::hash::Hasher; + +use twox_hash::xxh3; + +use crate::{DeterministicHash, DeterministicHasher}; + +/// Hash some content with the Xxh3Hash64 non-cryptographic hash function. +pub fn hash_xxh3_hash64(input: T) -> u64 { + let mut hasher = Xxh3Hash64Hasher::new(); + input.deterministic_hash(&mut hasher); + hasher.finish() +} + +/// Xxh3Hash64 hasher. +pub struct Xxh3Hash64Hasher(xxh3::Hash64); + +impl Xxh3Hash64Hasher { + /// Create a new hasher. + pub fn new() -> Self { + Self(xxh3::Hash64::with_seed(0)) + } + + /// Uses the DeterministicHash trait to hash the input in a + /// cross-platform way. + pub fn write_value(&mut self, input: T) { + input.deterministic_hash(self); + } + + /// Uses the DeterministicHash trait to hash the input in a + /// cross-platform way. + pub fn write_ref(&mut self, input: &T) { + input.deterministic_hash(self); + } + + /// Finish the hash computation and return the digest. + pub fn finish(&self) -> u64 { + self.0.finish() + } +} + +impl DeterministicHasher for Xxh3Hash64Hasher { + fn finish(&self) -> u64 { + self.0.finish() + } + + fn write_bytes(&mut self, bytes: &[u8]) { + self.0.write(bytes); + } +} + +impl Default for Xxh3Hash64Hasher { + fn default() -> Self { + Self::new() + } +} diff --git a/turbopack/crates/turbo-tasks-macros-shared/Cargo.toml b/turbopack/crates/turbo-tasks-macros-shared/Cargo.toml new file mode 100644 index 0000000000000..b8ce941c8b99f --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-shared/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "turbo-tasks-macros-shared" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +proc-macro2 = { workspace = true } +quote = { workspace = true } +syn = { workspace = true, features = ["full", "extra-traits"] } diff --git a/turbopack/crates/turbo-tasks-macros-shared/readme.md b/turbopack/crates/turbo-tasks-macros-shared/readme.md new file mode 100644 index 0000000000000..ab4de49a59dd4 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-shared/readme.md @@ -0,0 +1,3 @@ +# turbo-tasks-macros-shared + +Shared utilities between `turbo-tasks-macros` and `turbo-tasks-build`. diff --git a/turbopack/crates/turbo-tasks-macros-shared/src/expand.rs b/turbopack/crates/turbo-tasks-macros-shared/src/expand.rs new file mode 100644 index 0000000000000..dfcb4108a8255 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-shared/src/expand.rs @@ -0,0 +1,191 @@ +use proc_macro2::{Ident, TokenStream}; +use quote::quote; +use syn::{ + spanned::Spanned, Data, DataEnum, DataStruct, DeriveInput, Field, Fields, FieldsNamed, + FieldsUnnamed, +}; + +/// Handles the expansion of a struct/enum into a match statement that accesses +/// every field for procedural code generation. +/// +/// Requires several Fn helpers which perform expand different structures: +/// +/// - [expand_named] handles the expansion of a struct or enum variant with +/// named fields (e.g. `struct Foo { bar: u32 }`, `Foo::Bar { baz: u32 }`). +/// - [expand_unnamed] handles the expansion of a struct or enum variant with +/// unnamed fields (e.g. `struct Foo(u32)`, `Foo::Bar(u32)`). +/// - [expand_unit] handles the expansion of a unit struct or enum (e.g. `struct +/// Foo;`, `Foo::Bar`). +/// +/// These helpers should themselves call [generate_destructuring] to generate +/// the destructure necessary to access the fields of the value. +pub fn match_expansion< + EN: Fn(TokenStream, &FieldsNamed) -> (TokenStream, TokenStream), + EU: Fn(TokenStream, &FieldsUnnamed) -> (TokenStream, TokenStream), + U: Fn(TokenStream) -> TokenStream, +>( + derive_input: &DeriveInput, + expand_named: &EN, + expand_unnamed: &EU, + expand_unit: &U, +) -> TokenStream { + let ident = &derive_input.ident; + let expand_unit = move |ident| (TokenStream::new(), expand_unit(ident)); + match &derive_input.data { + Data::Enum(DataEnum { variants, .. }) => { + let (idents, (variants_fields_capture, expansion)): (Vec<_>, (Vec<_>, Vec<_>)) = + variants + .iter() + .map(|variant| { + let variants_idents = &variant.ident; + let ident = quote! { #ident::#variants_idents }; + ( + ident.clone(), + expand_fields( + ident, + &variant.fields, + expand_named, + expand_unnamed, + expand_unit, + ), + ) + }) + .unzip(); + + if idents.is_empty() { + let (_, expansion) = expand_unit(quote! { #ident }); + quote! { + #expansion + } + } else { + quote! { + match self { + #( + #idents #variants_fields_capture => #expansion, + )* + } + } + } + } + Data::Struct(DataStruct { fields, .. }) => { + let (captures, expansion) = expand_fields( + quote! { #ident }, + fields, + expand_named, + expand_unnamed, + expand_unit, + ); + + if fields.is_empty() { + assert!(captures.is_empty()); + // a match expression here doesn't make sense as there's no fields to capture, + // just pass through the inner expression. + expansion + } else { + match fields { + Fields::Named(_) | Fields::Unnamed(_) => quote! { + match self { + #ident #captures => #expansion + } + }, + Fields::Unit => unreachable!(), + } + } + } + _ => { + derive_input + .span() + .unwrap() + .error("unsupported syntax") + .emit(); + + quote! {} + } + } +} + +/// Formats the fields of any structure or enum variant. +/// +/// Empty lists of named or unnamed fields are treated as unit structs, as they +/// are semantically identical, and the `expand_unit` codepath can usually +/// generate better code. +pub fn expand_fields< + 'ident, + 'fields, + EN: Fn(TokenStream, &'fields FieldsNamed) -> R, + EU: Fn(TokenStream, &'fields FieldsUnnamed) -> R, + U: Fn(TokenStream) -> R, + R, +>( + ident: TokenStream, + fields: &'fields Fields, + expand_named: EN, + expand_unnamed: EU, + expand_unit: U, +) -> R { + if fields.is_empty() { + // any empty struct (regardless of the syntax used during declaration) is + // equivalent to a unit struct + return expand_unit(ident); + } + match fields { + Fields::Named(named) => expand_named(ident, named), + Fields::Unnamed(unnamed) => expand_unnamed(ident, unnamed), + Fields::Unit => unreachable!(), + } +} + +/// Generates a match arm destructuring pattern for the given fields. +/// +/// If no `filter_field` function is provided, all fields are included in the +/// pattern. If a `filter_field` function is provided, only fields for which +/// the function returns `true` are included in the pattern. If any field is +/// ignored, a wildcard pattern is added to the end of the pattern, making it +/// non-exhaustive. +/// +/// Returns both the capture pattern token stream and the name of the bound +/// identifiers corresponding to the input fields. +pub fn generate_destructuring<'a, I: Fn(&Field) -> bool>( + fields: impl ExactSizeIterator, + filter_field: &I, +) -> (TokenStream, Vec) { + let fields_len = fields.len(); + let (captures, fields_idents): (Vec<_>, Vec<_>) = fields + // We need to enumerate first to capture the indexes of the fields before filtering has + // changed them. + .enumerate() + .filter(|(_i, field)| filter_field(field)) + .map(|(i, field)| match &field.ident { + Some(ident) => (quote! { #ident }, quote! { #ident }), + None => { + let ident = Ident::new(&format!("field_{}", i), field.span()); + let index = syn::Index::from(i); + (quote! { #index: #ident }, quote! { #ident }) + } + }) + .unzip(); + // Only add the wildcard pattern if we're ignoring some fields. + let wildcard = if fields_idents.len() != fields_len { + quote! { .. } + } else { + quote! {} + }; + ( + quote! { + { #(#captures,)* #wildcard } + }, + fields_idents, + ) +} + +/// Generates an exhaustive match arm destructuring pattern for the given +/// fields. This is equivalent to calling [`generate_destructuring`] with a +/// `filter_field` function that always returns `true`. +/// +/// Returns both the capture pattern token stream and the name of the bound +/// identifiers corresponding to the input fields. +pub fn generate_exhaustive_destructuring<'a>( + fields: impl ExactSizeIterator, +) -> (TokenStream, Vec) { + generate_destructuring(fields, &|_| true) +} diff --git a/turbopack/crates/turbo-tasks-macros-shared/src/generic_type_input.rs b/turbopack/crates/turbo-tasks-macros-shared/src/generic_type_input.rs new file mode 100644 index 0000000000000..2c9e08375f99a --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-shared/src/generic_type_input.rs @@ -0,0 +1,21 @@ +use syn::{ + parse::{Parse, ParseStream}, + Generics, Result, Token, Type, +}; + +/// The input of the `generic_type` macro. +#[derive(Debug)] +pub struct GenericTypeInput { + pub generics: Generics, + pub ty: Type, +} + +impl Parse for GenericTypeInput { + fn parse(input: ParseStream) -> Result { + let generics: Generics = input.parse()?; + let _comma: Token![,] = input.parse()?; + let ty: Type = input.parse()?; + + Ok(GenericTypeInput { generics, ty }) + } +} diff --git a/turbopack/crates/turbo-tasks-macros-shared/src/ident.rs b/turbopack/crates/turbo-tasks-macros-shared/src/ident.rs new file mode 100644 index 0000000000000..332a4812c456b --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-shared/src/ident.rs @@ -0,0 +1,246 @@ +use quote::ToTokens; +use syn::{spanned::Spanned, GenericArgument, Ident, Path, PathArguments, Type, TypeParamBound}; + +pub fn get_register_value_type_ident(struct_ident: &Ident) -> Ident { + Ident::new( + &format!("__register_{struct_ident}_value_type"), + struct_ident.span(), + ) +} + +pub fn get_register_trait_methods_ident(trait_ident: &Ident, struct_ident: &Ident) -> Ident { + Ident::new( + &format!("__register_{struct_ident}_{trait_ident}_trait_methods"), + trait_ident.span(), + ) +} + +pub fn get_native_function_ident(ident: &Ident) -> Ident { + Ident::new( + &format!("{}_FUNCTION", ident.to_string().to_uppercase()), + ident.span(), + ) +} + +pub fn get_native_function_id_ident(ident: &Ident) -> Ident { + Ident::new( + &format!("{}_FUNCTION_ID", ident.to_string().to_uppercase()), + ident.span(), + ) +} + +pub fn get_trait_type_ident(ident: &Ident) -> Ident { + Ident::new( + &format!("{}_TRAIT_TYPE", ident.to_string().to_uppercase()), + ident.span(), + ) +} + +pub fn get_impl_function_ident(struct_ident: &Ident, ident: &Ident) -> Ident { + Ident::new( + &format!( + "{}_IMPL_{}_FUNCTION", + struct_ident.to_string().to_uppercase(), + ident.to_string().to_uppercase() + ), + ident.span(), + ) +} + +pub fn get_inherent_impl_function_ident(ty_ident: &Ident, fn_ident: &Ident) -> Ident { + Ident::new( + &format!( + "{}_IMPL_{}_FUNCTION", + ty_ident.to_string().to_uppercase(), + fn_ident.to_string().to_uppercase() + ), + fn_ident.span(), + ) +} + +pub fn get_inherent_impl_function_id_ident(ty_ident: &Ident, fn_ident: &Ident) -> Ident { + Ident::new( + &format!( + "{}_IMPL_{}_FUNCTION_ID", + ty_ident.to_string().to_uppercase(), + fn_ident.to_string().to_uppercase() + ), + fn_ident.span(), + ) +} + +pub fn get_trait_impl_function_ident( + struct_ident: &Ident, + trait_ident: &Ident, + ident: &Ident, +) -> Ident { + Ident::new( + &format!( + "{}_IMPL_TRAIT_{}_{}_FUNCTION", + struct_ident.to_string().to_uppercase(), + trait_ident.to_string().to_uppercase(), + ident.to_string().to_uppercase() + ), + ident.span(), + ) +} + +pub fn get_trait_impl_function_id_ident( + struct_ident: &Ident, + trait_ident: &Ident, + ident: &Ident, +) -> Ident { + Ident::new( + &format!( + "{}_IMPL_TRAIT_{}_{}_FUNCTION_ID", + struct_ident.to_string().to_uppercase(), + trait_ident.to_string().to_uppercase(), + ident.to_string().to_uppercase() + ), + ident.span(), + ) +} + +pub fn get_internal_trait_impl_function_ident(trait_ident: &Ident, ident: &Ident) -> Ident { + Ident::new( + &format!("__trait_call_{trait_ident}_{ident}"), + trait_ident.span(), + ) +} + +pub fn get_path_ident(path: &Path) -> Ident { + let mut result = String::new(); + + for (i, segment) in path.segments.iter().enumerate() { + let ident = segment.ident.to_string(); + + if i > 0 { + result.push('_'); + } + + result.push_str(&ident); + + match &segment.arguments { + PathArguments::AngleBracketed(args) => { + for arg in &args.args { + match arg { + GenericArgument::Type(ty) => { + if let Type::Path(type_path) = ty { + let type_ident = get_path_ident(&type_path.path); + result.push('_'); + result.push_str(&type_ident.to_string()); + } else if let Type::TraitObject(trait_obj) = ty { + for bound in &trait_obj.bounds { + if let TypeParamBound::Trait(bound_trait) = bound { + let bound_ident = get_path_ident(&bound_trait.path); + result.push_str("_dyn_"); + result.push_str(&bound_ident.to_string()); + } + } + } else { + arg.span() + .unwrap() + .error( + "#[turbo_tasks::value_impl] does not support this type \ + argument", + ) + .emit(); + } + } + _ => arg + .span() + .unwrap() + .error("#[turbo_tasks::value_impl] does not support this type argument") + .emit(), + } + } + } + PathArguments::None => {} + _ => { + segment + .span() + .unwrap() + .error("#[turbo_tasks::value_impl] does not support this type argument") + .emit(); + } + } + } + + Ident::new(&result, path.span()) +} + +pub fn get_type_ident(ty: &Type) -> Option { + match ty { + Type::Path(path) => Some(get_path_ident(&path.path)), + Type::Tuple(tuple) => Some(Ident::new("unit", tuple.span())), + _ => { + ty.span() + .unwrap() + .error(format!( + "#[turbo_tasks::value_impl] does not support the type {}, expected T or \ + Box", + ty.to_token_stream() + )) + .emit(); + None + } + } +} + +pub fn get_read_ref_ident(ident: &Ident) -> Ident { + Ident::new(&(ident.to_string() + "ReadRef"), ident.span()) +} + +pub fn get_trait_ref_ident(ident: &Ident) -> Ident { + Ident::new(&(ident.to_string() + "TraitRef"), ident.span()) +} + +pub fn get_trait_default_impl_function_ident(trait_ident: &Ident, ident: &Ident) -> Ident { + Ident::new( + &format!( + "{}_DEFAULT_IMPL_{}_FUNCTION", + trait_ident.to_string().to_uppercase(), + ident.to_string().to_uppercase() + ), + ident.span(), + ) +} + +pub fn get_trait_type_id_ident(ident: &Ident) -> Ident { + Ident::new( + &format!("{}_TRAIT_TYPE_ID", ident.to_string().to_uppercase()), + ident.span(), + ) +} + +pub fn get_trait_default_impl_function_id_ident(trait_ident: &Ident, ident: &Ident) -> Ident { + Ident::new( + &format!( + "{}_DEFAULT_IMPL_{}_FUNCTION_ID", + trait_ident.to_string().to_uppercase(), + ident.to_string().to_uppercase() + ), + ident.span(), + ) +} + +pub fn get_value_type_ident(ident: &Ident) -> Ident { + Ident::new( + &format!("{}_VALUE_TYPE", ident.to_string().to_uppercase()), + ident.span(), + ) +} + +pub fn get_value_type_id_ident(ident: &Ident) -> Ident { + Ident::new( + &format!("{}_VALUE_TYPE_ID", ident.to_string().to_uppercase()), + ident.span(), + ) +} + +pub fn get_value_type_init_ident(ident: &Ident) -> Ident { + Ident::new( + &format!("{}_VALUE_TYPE_INIT", ident.to_string().to_uppercase()), + ident.span(), + ) +} diff --git a/turbopack/crates/turbo-tasks-macros-shared/src/lib.rs b/turbopack/crates/turbo-tasks-macros-shared/src/lib.rs new file mode 100644 index 0000000000000..cbeb9aa2d3399 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-shared/src/lib.rs @@ -0,0 +1,14 @@ +#![feature(proc_macro_diagnostic)] +#![feature(box_patterns)] + +mod expand; +mod generic_type_input; +mod ident; +mod primitive_input; +mod value_trait_arguments; + +pub use expand::*; +pub use generic_type_input::GenericTypeInput; +pub use ident::*; +pub use primitive_input::PrimitiveInput; +pub use value_trait_arguments::ValueTraitArguments; diff --git a/turbopack/crates/turbo-tasks-macros-shared/src/primitive_input.rs b/turbopack/crates/turbo-tasks-macros-shared/src/primitive_input.rs new file mode 100644 index 0000000000000..de4eb53398642 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-shared/src/primitive_input.rs @@ -0,0 +1,16 @@ +use syn::{ + parse::{Parse, ParseStream}, + Result, Type, +}; + +#[derive(Debug)] +pub struct PrimitiveInput { + pub ty: Type, +} + +impl Parse for PrimitiveInput { + fn parse(input: ParseStream) -> Result { + let ty: Type = input.parse()?; + Ok(PrimitiveInput { ty }) + } +} diff --git a/turbopack/crates/turbo-tasks-macros-shared/src/value_trait_arguments.rs b/turbopack/crates/turbo-tasks-macros-shared/src/value_trait_arguments.rs new file mode 100644 index 0000000000000..a28b4e45d81fc --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-shared/src/value_trait_arguments.rs @@ -0,0 +1,54 @@ +use proc_macro2::Span; +use syn::{ + parse::{Parse, ParseStream}, + punctuated::Punctuated, + spanned::Spanned, + Meta, Token, +}; + +/// Arguments to the `#[turbo_tasks::value_trait]` attribute macro. +#[derive(Debug)] +pub struct ValueTraitArguments { + /// Whether the macro should generate a `ValueDebug`-like `dbg()` + /// implementation on the trait's `Vc`. + pub debug: bool, + /// Should the trait have a `turbo_tasks::ResolvedValue` constraint? + /// + /// `Some(...)` if enabled, containing the span that enabled the constraint. + pub resolved: Option, +} + +impl Default for ValueTraitArguments { + fn default() -> Self { + Self { + debug: true, + resolved: None, + } + } +} + +impl Parse for ValueTraitArguments { + fn parse(input: ParseStream) -> syn::Result { + let mut result = Self::default(); + if input.is_empty() { + return Ok(result); + } + + let punctuated: Punctuated = input.parse_terminated(Meta::parse)?; + for meta in punctuated { + match meta.path().get_ident().map(ToString::to_string).as_deref() { + Some("no_debug") => { + result.debug = false; + } + Some("resolved") => { + result.resolved = Some(meta.span()); + } + _ => { + return Err(syn::Error::new_spanned(meta, "unknown parameter")); + } + } + } + + Ok(result) + } +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/Cargo.toml b/turbopack/crates/turbo-tasks-macros-tests/Cargo.toml new file mode 100644 index 0000000000000..d52804b5d68d1 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "turbo-tasks-macros-tests" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[dev-dependencies] +anyhow = { workspace = true } +serde = { workspace = true } +tokio = { workspace = true } +trybuild = { version = "1.0.97" } +turbo-tasks = { workspace = true } +turbo-tasks-testing = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-macros-tests/build.rs b/turbopack/crates/turbo-tasks-macros-tests/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_only_vc.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_only_vc.rs new file mode 100644 index 0000000000000..f091233b4f018 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_only_vc.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +use turbo_tasks::{ResolvedValue, Vc}; + +#[derive(ResolvedValue)] +struct ContainsOnlyVc { + a: Vc, +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_only_vc.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_only_vc.stderr new file mode 100644 index 0000000000000..32b9d09452a35 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_only_vc.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `Vc: ResolvedValue` is not satisfied + --> tests/derive_resolved_value/fail_contains_only_vc.rs:7:8 + | +7 | a: Vc, + | ^^^^^^^ the trait `ResolvedValue` is not implemented for `Vc` + | + = help: the following other types implement trait `ResolvedValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others +note: required by a bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + --> tests/derive_resolved_value/fail_contains_only_vc.rs:5:10 + | +5 | #[derive(ResolvedValue)] + | ^^^^^^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + = note: this error originates in the derive macro `ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_resolved_vc_and_vc.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_resolved_vc_and_vc.rs new file mode 100644 index 0000000000000..46f2db572d90d --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_resolved_vc_and_vc.rs @@ -0,0 +1,11 @@ +#![allow(dead_code)] + +use turbo_tasks::{ResolvedValue, ResolvedVc, Vc}; + +#[derive(ResolvedValue)] +struct ContainsResolvedVcAndVc { + a: ResolvedVc, + b: Vc, +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_resolved_vc_and_vc.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_resolved_vc_and_vc.stderr new file mode 100644 index 0000000000000..3c6098cdc5fed --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_resolved_vc_and_vc.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `Vc: ResolvedValue` is not satisfied + --> tests/derive_resolved_value/fail_contains_resolved_vc_and_vc.rs:8:8 + | +8 | b: Vc, + | ^^^^^^^ the trait `ResolvedValue` is not implemented for `Vc` + | + = help: the following other types implement trait `ResolvedValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others +note: required by a bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + --> tests/derive_resolved_value/fail_contains_resolved_vc_and_vc.rs:5:10 + | +5 | #[derive(ResolvedValue)] + | ^^^^^^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + = note: this error originates in the derive macro `ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_vc_inside_generic.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_vc_inside_generic.rs new file mode 100644 index 0000000000000..52e7e833e1ea9 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_vc_inside_generic.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +use turbo_tasks::{ResolvedValue, Vc}; + +#[derive(ResolvedValue)] +struct ContainsVcInsideGeneric { + a: Option; 4]>>, +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_vc_inside_generic.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_vc_inside_generic.stderr new file mode 100644 index 0000000000000..5851763aa4698 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_contains_vc_inside_generic.stderr @@ -0,0 +1,25 @@ +error[E0277]: the trait bound `Vc: ResolvedValue` is not satisfied + --> tests/derive_resolved_value/fail_contains_vc_inside_generic.rs:7:8 + | +7 | a: Option; 4]>>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ResolvedValue` is not implemented for `Vc`, which is required by `std::option::Option; 4]>>: ResolvedValue` + | + = help: the following other types implement trait `ResolvedValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others + = note: required for `[Vc; 4]` to implement `ResolvedValue` + = note: 2 redundant requirements hidden + = note: required for `std::option::Option; 4]>>` to implement `ResolvedValue` +note: required by a bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + --> tests/derive_resolved_value/fail_contains_vc_inside_generic.rs:5:10 + | +5 | #[derive(ResolvedValue)] + | ^^^^^^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + = note: this error originates in the derive macro `ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_enum.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_enum.rs new file mode 100644 index 0000000000000..931043a001111 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_enum.rs @@ -0,0 +1,14 @@ +#![allow(dead_code)] + +use turbo_tasks::ResolvedValue; + +struct UnresolvedValue; + +#[derive(ResolvedValue)] +enum ContainsUnresolvedValue { + Unit, + Unnamed(UnresolvedValue), + Named { a: UnresolvedValue }, +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_enum.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_enum.stderr new file mode 100644 index 0000000000000..31871c211e49f --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_enum.stderr @@ -0,0 +1,45 @@ +error[E0277]: the trait bound `UnresolvedValue: ResolvedValue` is not satisfied + --> tests/derive_resolved_value/fail_simple_enum.rs:10:13 + | +10 | Unnamed(UnresolvedValue), + | ^^^^^^^^^^^^^^^ the trait `ResolvedValue` is not implemented for `UnresolvedValue` + | + = help: the following other types implement trait `ResolvedValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others +note: required by a bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + --> tests/derive_resolved_value/fail_simple_enum.rs:7:10 + | +7 | #[derive(ResolvedValue)] + | ^^^^^^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + = note: this error originates in the derive macro `ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `UnresolvedValue: ResolvedValue` is not satisfied + --> tests/derive_resolved_value/fail_simple_enum.rs:11:16 + | +11 | Named { a: UnresolvedValue }, + | ^^^^^^^^^^^^^^^ the trait `ResolvedValue` is not implemented for `UnresolvedValue` + | + = help: the following other types implement trait `ResolvedValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others +note: required by a bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + --> tests/derive_resolved_value/fail_simple_enum.rs:7:10 + | +7 | #[derive(ResolvedValue)] + | ^^^^^^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + = note: this error originates in the derive macro `ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_named_struct.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_named_struct.rs new file mode 100644 index 0000000000000..bd138baba00b2 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_named_struct.rs @@ -0,0 +1,12 @@ +#![allow(dead_code)] + +use turbo_tasks::ResolvedValue; + +struct UnresolvedValue; + +#[derive(ResolvedValue)] +struct ContainsUnresolvedValueNamed { + a: UnresolvedValue, +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_named_struct.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_named_struct.stderr new file mode 100644 index 0000000000000..57e0b2cae6ce2 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_named_struct.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `UnresolvedValue: ResolvedValue` is not satisfied + --> tests/derive_resolved_value/fail_simple_named_struct.rs:9:8 + | +9 | a: UnresolvedValue, + | ^^^^^^^^^^^^^^^ the trait `ResolvedValue` is not implemented for `UnresolvedValue` + | + = help: the following other types implement trait `ResolvedValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others +note: required by a bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + --> tests/derive_resolved_value/fail_simple_named_struct.rs:7:10 + | +7 | #[derive(ResolvedValue)] + | ^^^^^^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + = note: this error originates in the derive macro `ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_unnamed_struct.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_unnamed_struct.rs new file mode 100644 index 0000000000000..5549af87f1f86 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_unnamed_struct.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +use turbo_tasks::ResolvedValue; + +struct UnresolvedValue; + +#[derive(ResolvedValue)] +struct ContainsUnresolvedValueUnnamed(UnresolvedValue); + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_unnamed_struct.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_unnamed_struct.stderr new file mode 100644 index 0000000000000..6052e7151c56e --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_simple_unnamed_struct.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `UnresolvedValue: ResolvedValue` is not satisfied + --> tests/derive_resolved_value/fail_simple_unnamed_struct.rs:8:39 + | +8 | struct ContainsUnresolvedValueUnnamed(UnresolvedValue); + | ^^^^^^^^^^^^^^^ the trait `ResolvedValue` is not implemented for `UnresolvedValue` + | + = help: the following other types implement trait `ResolvedValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others +note: required by a bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + --> tests/derive_resolved_value/fail_simple_unnamed_struct.rs:7:10 + | +7 | #[derive(ResolvedValue)] + | ^^^^^^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + = note: this error originates in the derive macro `ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_underconstrained_generic.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_underconstrained_generic.rs new file mode 100644 index 0000000000000..1ccb4149ff1e8 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_underconstrained_generic.rs @@ -0,0 +1,10 @@ +#![allow(dead_code)] + +use turbo_tasks::ResolvedValue; + +#[derive(ResolvedValue)] +struct ContainsUnderconstrainedGeneric { + value: T, +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_underconstrained_generic.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_underconstrained_generic.stderr new file mode 100644 index 0000000000000..985703ae8f3fc --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/fail_underconstrained_generic.stderr @@ -0,0 +1,16 @@ +error[E0277]: the trait bound `T: ResolvedValue` is not satisfied + --> tests/derive_resolved_value/fail_underconstrained_generic.rs:7:12 + | +7 | value: T, + | ^ the trait `ResolvedValue` is not implemented for `T` + | +note: required by a bound in `DeriveResolvedValueAssertion::::assert_impl_resolved_value` + --> tests/derive_resolved_value/fail_underconstrained_generic.rs:5:10 + | +5 | #[derive(ResolvedValue)] + | ^^^^^^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::::assert_impl_resolved_value` + = note: this error originates in the derive macro `ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) +help: consider restricting type parameter `T` + | +6 | struct ContainsUnderconstrainedGeneric { + | ++++++++++++++++++++++++++++ diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_contains_resolved_vc.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_contains_resolved_vc.rs new file mode 100644 index 0000000000000..5c80368183097 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_contains_resolved_vc.rs @@ -0,0 +1,27 @@ +#![allow(dead_code)] + +use turbo_tasks::{ResolvedValue, ResolvedVc}; + +#[derive(ResolvedValue)] +struct ContainsResolvedVcNamedStruct { + a: ResolvedVc, +} + +#[derive(ResolvedValue)] +struct ContainsResolvedVcUnnamedStruct(ResolvedVc); + +#[derive(ResolvedValue)] +enum ContainsResolvedVcEnum { + Unit, + Unnamed(ResolvedVc), + Named { a: ResolvedVc }, +} + +#[derive(ResolvedValue)] +struct ContainsResolvedAlongWithOtherValues { + a: i32, + b: ResolvedVc, + c: (), +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_lifetimes.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_lifetimes.rs new file mode 100644 index 0000000000000..58bad80f3cc2b --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_lifetimes.rs @@ -0,0 +1,13 @@ +use turbo_tasks::ResolvedValue; + +#[derive(ResolvedValue)] +struct ContainsBorrowedData<'a> { + borrowed: &'a Option<&'a [&'a str]>, +} + +fn main() { + let a = ContainsBorrowedData { + borrowed: &Some(["value"].as_slice()), + }; + let _ = a.borrowed; +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_linked_list.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_linked_list.rs new file mode 100644 index 0000000000000..f57c0e06225cb --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_linked_list.rs @@ -0,0 +1,31 @@ +use turbo_tasks::ResolvedValue; + +#[derive(ResolvedValue)] +// use an inline type constraint here +struct LinkedList { + // LinkedListNode is also a ResolvedValue + head: Option>>, +} + +#[derive(ResolvedValue)] +struct LinkedListNode +where + T: ResolvedValue, // use a where type constraint here +{ + current: T, + // A self-recursive type + next: Option>>, +} + +fn main() { + let ll = LinkedList { + head: Some(Box::new(LinkedListNode { + current: 1, + next: Some(Box::new(LinkedListNode { + current: 2, + next: None, + })), + })), + }; + let _last = ll.head.unwrap().next.unwrap().current; +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_phantom_data.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_phantom_data.rs new file mode 100644 index 0000000000000..b6e540a5efb59 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_phantom_data.rs @@ -0,0 +1,16 @@ +#![allow(dead_code)] + +use std::marker::PhantomData; + +use turbo_tasks::{ResolvedValue, Vc}; + +struct Unresolved; + +#[derive(ResolvedValue)] +struct PhantomDataCanContainAnything( + PhantomData>, + PhantomData, + PhantomData>, +); + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_simple_enums.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_simple_enums.rs new file mode 100644 index 0000000000000..46c1ce3d9d75e --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_simple_enums.rs @@ -0,0 +1,19 @@ +#![allow(dead_code)] + +use turbo_tasks::{ResolvedValue, ResolvedVc}; + +#[derive(ResolvedValue)] +enum EnumI32 { + Unit, + Unnamed(i32), + Named { a: i32 }, +} + +#[derive(ResolvedValue)] +enum EnumResolvedVc { + Unit, + Unnamed(ResolvedVc), + Named { a: ResolvedVc }, +} + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_simple_structs.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_simple_structs.rs new file mode 100644 index 0000000000000..1d7420d65a072 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/derive_resolved_value/pass_simple_structs.rs @@ -0,0 +1,23 @@ +#![allow(dead_code)] + +use std::marker::PhantomData; + +use turbo_tasks::ResolvedValue; + +#[derive(ResolvedValue)] +struct UnitStruct; + +#[derive(ResolvedValue)] +struct ContainsSimpleValuesNamed { + a: i32, + b: String, + c: (), + d: (u8, u8, (u8, u8, u8)), + e: [u8; 8], + f: PhantomData, +} + +#[derive(ResolvedValue)] +struct ContainsSimpleValuesUnnamed(i32, String, ()); + +fn main() {} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/task_input.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/task_input.rs new file mode 100644 index 0000000000000..143592a2514d3 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/task_input.rs @@ -0,0 +1,29 @@ +//! Tests for the `#[derive(TaskInput)]` macro are in `turbo_tasks` itself. +//! However, we keep one test here as an integration test between the derive +//! macro and the `#[turbo_tasks::function]` macro. + +use serde::{Deserialize, Serialize}; +use turbo_tasks::{Completion, ReadRef, TaskInput, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[derive(Clone, TaskInput, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +struct OneUnnamedField(u32); + +#[turbo_tasks::function] +async fn one_unnamed_field(input: OneUnnamedField) -> Vc { + assert_eq!(input.0, 42); + Completion::immutable() +} + +#[tokio::test] +async fn tests() { + run(®ISTRATION, async { + assert!(ReadRef::ptr_eq( + &one_unnamed_field(OneUnnamedField(42)).await.unwrap(), + &Completion::immutable().await.unwrap(), + )) + }) + .await +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/trybuild.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/trybuild.rs new file mode 100644 index 0000000000000..8620bbd901638 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/trybuild.rs @@ -0,0 +1,20 @@ +#[test] +fn derive_resolved_value() { + let t = trybuild::TestCases::new(); + t.pass("tests/derive_resolved_value/pass_*.rs"); + t.compile_fail("tests/derive_resolved_value/fail_*.rs"); +} + +#[test] +fn value() { + let t = trybuild::TestCases::new(); + t.pass("tests/value/pass_*.rs"); + t.compile_fail("tests/value/fail_*.rs"); +} + +#[test] +fn value_trait() { + let t = trybuild::TestCases::new(); + t.pass("tests/value_trait/pass_*.rs"); + t.compile_fail("tests/value_trait/fail_*.rs"); +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/value/fail_resolved.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/value/fail_resolved.rs new file mode 100644 index 0000000000000..0280713b8722c --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/value/fail_resolved.rs @@ -0,0 +1,13 @@ +#![feature(arbitrary_self_types)] + +use turbo_tasks::Vc; + +#[turbo_tasks::value(resolved)] +struct MyValue { + value: Vc, +} + +fn main() { + let v = MyValue { value: Vc::cell(0) }; + let _ = v.value; +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/value/fail_resolved.stderr b/turbopack/crates/turbo-tasks-macros-tests/tests/value/fail_resolved.stderr new file mode 100644 index 0000000000000..d100c44fdc5b0 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/value/fail_resolved.stderr @@ -0,0 +1,22 @@ +error[E0277]: the trait bound `Vc: ResolvedValue` is not satisfied + --> tests/value/fail_resolved.rs:7:12 + | +7 | value: Vc, + | ^^^^^^^ the trait `ResolvedValue` is not implemented for `Vc` + | + = help: the following other types implement trait `ResolvedValue`: + &T + &mut T + () + (A, Z, Y, X, W, V, U, T) + (B, A, Z, Y, X, W, V, U, T) + (C, B, A, Z, Y, X, W, V, U, T) + (D, C, B, A, Z, Y, X, W, V, U, T) + (E, D, C, B, A, Z, Y, X, W, V, U, T) + and $N others +note: required by a bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + --> tests/value/fail_resolved.rs:5:22 + | +5 | #[turbo_tasks::value(resolved)] + | ^^^^^^^^ required by this bound in `DeriveResolvedValueAssertion::assert_impl_resolved_value` + = note: this error originates in the derive macro `turbo_tasks::ResolvedValue` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/value/pass_resolved.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/value/pass_resolved.rs new file mode 100644 index 0000000000000..5fd5ea50638e8 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/value/pass_resolved.rs @@ -0,0 +1,14 @@ +#![feature(arbitrary_self_types)] + +#[turbo_tasks::value(resolved)] +struct MyValue { + value: i32, +} + +fn expects_resolved(value: T) {} + +fn main() { + let v = MyValue { value: 0 }; + expects_resolved(v); + let _ = v.value; +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/value_debug.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/value_debug.rs new file mode 100644 index 0000000000000..317912a60e075 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/value_debug.rs @@ -0,0 +1,32 @@ +use turbo_tasks::debug::ValueDebugFormat; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn ignored_indexes() { + #[allow(dead_code)] + #[derive(ValueDebugFormat)] + struct IgnoredIndexes( + #[allow(dead_code)] + #[turbo_tasks(debug_ignore)] + i32, + i32, + #[allow(dead_code)] + #[turbo_tasks(debug_ignore)] + i32, + ); + + run(®ISTRATION, async { + let input = IgnoredIndexes(-1, 2, -3); + let debug = input + .value_debug_format(usize::MAX) + .try_to_string() + .await + .unwrap(); + assert!(!debug.contains("-1")); + assert!(debug.contains('2')); + assert!(!debug.contains("-3")); + }) + .await; +} diff --git a/turbopack/crates/turbo-tasks-macros-tests/tests/value_trait/pass_resolved.rs b/turbopack/crates/turbo-tasks-macros-tests/tests/value_trait/pass_resolved.rs new file mode 100644 index 0000000000000..dbdca31fb5add --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros-tests/tests/value_trait/pass_resolved.rs @@ -0,0 +1,10 @@ +#![feature(arbitrary_self_types)] + +#[turbo_tasks::value_trait(resolved)] +trait MyTrait {} + +fn expects_resolved() {} + +fn main() { + expects_resolved::<&dyn MyTrait>(); +} diff --git a/turbopack/crates/turbo-tasks-macros/Cargo.toml b/turbopack/crates/turbo-tasks-macros/Cargo.toml new file mode 100644 index 0000000000000..0200335e03ce2 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "turbo-tasks-macros" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lib] +proc-macro = true +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +either = { workspace = true } +proc-macro-error = "1.0.4" +proc-macro2 = { workspace = true } +quote = { workspace = true } +regex = { workspace = true } +syn = { workspace = true, features = ["full", "extra-traits", "visit-mut"] } +turbo-tasks-macros-shared = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/deterministic_hash_macro.rs b/turbopack/crates/turbo-tasks-macros/src/derive/deterministic_hash_macro.rs new file mode 100644 index 0000000000000..33774a1c90602 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/derive/deterministic_hash_macro.rs @@ -0,0 +1,67 @@ +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use syn::{parse_macro_input, Data, DeriveInput, FieldsNamed, FieldsUnnamed}; +use turbo_tasks_macros_shared::{generate_exhaustive_destructuring, match_expansion}; + +/// This macro generates the implementation of the `DeterministicHash` trait for +/// a given type. +/// +/// This requires that every contained value also implement `DeterministicHash`. +pub fn derive_deterministic_hash(input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(input as DeriveInput); + + let ident = &derive_input.ident; + let match_hash = match_expansion(&derive_input, &hash_named, &hash_unnamed, &hash_unit); + let discriminant = match derive_input.data { + Data::Enum(_) => { + quote! { + turbo_tasks_hash::DeterministicHash::deterministic_hash(&std::mem::discriminant(self), __state__); + } + } + _ => quote! {}, + }; + + quote! { + impl turbo_tasks_hash::DeterministicHash for #ident { + fn deterministic_hash(&self, __state__: &mut H) { + #discriminant + #match_hash + } + } + } + .into() +} + +/// Hashes a struct or enum variant with named fields (e.g. `struct Foo { +/// bar: u32 }`, `Foo::Bar { baz: u32 }`). +fn hash_named(_ident: TokenStream2, fields: &FieldsNamed) -> (TokenStream2, TokenStream2) { + let (captures, fields_idents) = generate_exhaustive_destructuring(fields.named.iter()); + ( + captures, + quote! { + {#( + #fields_idents.deterministic_hash(__state__); + )*} + }, + ) +} + +/// Hashes a struct or enum variant with unnamed fields (e.g. `struct +/// Foo(u32)`, `Foo::Bar(u32)`). +fn hash_unnamed(_ident: TokenStream2, fields: &FieldsUnnamed) -> (TokenStream2, TokenStream2) { + let (captures, fields_idents) = generate_exhaustive_destructuring(fields.unnamed.iter()); + ( + captures, + quote! { + {#( + #fields_idents.deterministic_hash(__state__); + )*} + }, + ) +} + +/// Hashes a unit struct or enum variant (e.g. `struct Foo;`, `Foo::Bar`). +fn hash_unit(_ident: TokenStream2) -> TokenStream2 { + quote! { { } } +} diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/mod.rs b/turbopack/crates/turbo-tasks-macros/src/derive/mod.rs new file mode 100644 index 0000000000000..d48323309096e --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/derive/mod.rs @@ -0,0 +1,64 @@ +mod deterministic_hash_macro; +mod resolved_value_macro; +mod task_input_macro; +mod trace_raw_vcs_macro; +mod value_debug_format_macro; +mod value_debug_macro; + +pub use deterministic_hash_macro::derive_deterministic_hash; +pub use resolved_value_macro::derive_resolved_value; +use syn::{spanned::Spanned, Attribute, Meta, MetaList, NestedMeta}; +pub use task_input_macro::derive_task_input; +pub use trace_raw_vcs_macro::derive_trace_raw_vcs; +pub use value_debug_format_macro::derive_value_debug_format; +pub use value_debug_macro::derive_value_debug; + +struct FieldAttributes { + trace_ignore: bool, + debug_ignore: bool, +} + +impl From<&[Attribute]> for FieldAttributes { + fn from(attrs: &[Attribute]) -> Self { + let mut result = Self { + trace_ignore: false, + debug_ignore: false, + }; + + for attr in attrs { + if !attr + .path + .get_ident() + .map(|ident| *ident == "turbo_tasks") + .unwrap_or_default() + { + continue; + } + if let Ok(Meta::List(MetaList { nested, .. })) = attr + .parse_meta() + .map_err(|err| err.span().unwrap().error(err.to_string()).emit()) + { + for meta in nested { + if let NestedMeta::Meta(Meta::Path(path)) = &meta { + match path.get_ident().map(|ident| ident.to_string()).as_deref() { + Some("trace_ignore") => result.trace_ignore = true, + Some("debug_ignore") => result.debug_ignore = true, + _ => path + .span() + .unwrap() + .error("expected `trace_ignore` or `debug_ignore`") + .emit(), + } + } else { + meta.span() + .unwrap() + .error("expected `trace_ignore` or `debug_ignore`") + .emit(); + } + } + } + } + + result + } +} diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/resolved_value_macro.rs b/turbopack/crates/turbo-tasks-macros/src/derive/resolved_value_macro.rs new file mode 100644 index 0000000000000..de703384b00b8 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/derive/resolved_value_macro.rs @@ -0,0 +1,59 @@ +use either::Either; +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use quote::{quote, quote_spanned}; +use syn::{parse_macro_input, spanned::Spanned, Data, DeriveInput, Generics}; + +pub fn derive_resolved_value(input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(input as DeriveInput); + let ident = &derive_input.ident; + + let assertions = assert_fields_impl_resolved_value(&derive_input.generics, &derive_input.data); + + let (impl_generics, ty_generics, where_clause) = derive_input.generics.split_for_impl(); + quote! { + unsafe impl #impl_generics turbo_tasks::ResolvedValue + for #ident #ty_generics #where_clause {} + #assertions + } + .into() +} + +fn iter_data_fields(data: &Data) -> impl Iterator { + match data { + Data::Struct(ds) => Either::Left(ds.fields.iter()), + Data::Enum(de) => Either::Right(Either::Left(de.variants.iter().flat_map(|v| &v.fields))), + Data::Union(du) => Either::Right(Either::Right(du.fields.named.iter())), + } +} + +fn assert_fields_impl_resolved_value(generics: &Generics, data: &Data) -> TokenStream2 { + // this technique is based on the trick used by + // `static_assertions::assert_impl_all`, but extended to support generics. + let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); + let field_types: Vec<_> = iter_data_fields(data).map(|field| &field.ty).collect(); + let assertion_calls = field_types.iter().map(|ty| { + quote_spanned! { + // attribute type assertion errors to the line where the field is defined + ty.span() => + // this call is only valid if ty is a ResolvedValue + Self::assert_impl_resolved_value::<#ty>(); + } + }); + quote! { + const _: fn() = || { + // create this struct just to hold onto our generics... + // we reproduce the field types here to ensure any generics get used + struct DeriveResolvedValueAssertion #impl_generics (#(#field_types),*) #where_clause; + + impl #impl_generics DeriveResolvedValueAssertion #ty_generics #where_clause { + fn assert_impl_resolved_value< + ExpectedResolvedValue: turbo_tasks::ResolvedValue + ?Sized + >() {} + fn field_types() { + #(#assertion_calls)* + } + } + }; + } +} diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/task_input_macro.rs b/turbopack/crates/turbo-tasks-macros/src/derive/task_input_macro.rs new file mode 100644 index 0000000000000..7a96916784d59 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/derive/task_input_macro.rs @@ -0,0 +1,177 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, spanned::Spanned, DeriveInput}; +use turbo_tasks_macros_shared::{generate_exhaustive_destructuring, match_expansion}; + +pub fn derive_task_input(input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(input as DeriveInput); + let ident = &derive_input.ident; + let generics = &derive_input.generics; + + if let Some(where_clause) = &generics.where_clause { + // NOTE(alexkirsz) We could support where clauses and generic parameters bounds + // in the future, but for simplicity's sake, we don't support them yet. + where_clause + .span() + .unwrap() + .error("the TaskInput derive macro does not support where clauses yet") + .emit(); + } + + for param in &generics.params { + match param { + syn::GenericParam::Type(param) => { + if !param.bounds.is_empty() { + // NOTE(alexkirsz) See where clause above. + param + .span() + .unwrap() + .error( + "the TaskInput derive macro does not support generic parameters \ + bounds yet", + ) + .emit(); + } + } + syn::GenericParam::Lifetime(param) => { + param + .span() + .unwrap() + .error("the TaskInput derive macro does not support generic lifetimes") + .emit(); + } + syn::GenericParam::Const(param) => { + // NOTE(alexkirsz) Ditto: not supported yet for simplicity's sake. + param + .span() + .unwrap() + .error("the TaskInput derive macro does not support const generics yet") + .emit(); + } + } + } + + let is_resolved_impl = match_expansion( + &derive_input, + &|_ident, fields| { + let (capture, fields) = generate_exhaustive_destructuring(fields.named.iter()); + ( + capture, + quote! { + {#( + #fields.is_resolved() && + )* true} + }, + ) + }, + &|_ident, fields| { + let (capture, fields) = generate_exhaustive_destructuring(fields.unnamed.iter()); + ( + capture, + quote! { + {#( + #fields.is_resolved() && + )* true} + }, + ) + }, + &|_ident| quote! {true}, + ); + let is_transient_impl = match_expansion( + &derive_input, + &|_ident, fields| { + let (capture, fields) = generate_exhaustive_destructuring(fields.named.iter()); + ( + capture, + quote! { + {#( + #fields.is_transient() || + )* false} + }, + ) + }, + &|_ident, fields| { + let (capture, fields) = generate_exhaustive_destructuring(fields.unnamed.iter()); + ( + capture, + quote! { + {#( + #fields.is_transient() || + )* false} + }, + ) + }, + &|_ident| quote! {false}, + ); + let resolve_impl = match_expansion( + &derive_input, + &|ident, fields| { + let (capture, fields) = generate_exhaustive_destructuring(fields.named.iter()); + ( + capture, + quote! { + { + #( + let #fields = #fields.resolve().await?; + )* + Ok(#ident { #(#fields),* }) + } + }, + ) + }, + &|ident, fields| { + let (capture, fields) = generate_exhaustive_destructuring(fields.unnamed.iter()); + ( + capture, + quote! { + { + #( + let #fields = #fields.resolve().await?; + )* + Ok(#ident(#(#fields),*)) + } + }, + ) + }, + &|ident| quote! {Ok(#ident)}, + ); + + let generic_params: Vec<_> = generics + .params + .iter() + .filter_map(|param| match param { + syn::GenericParam::Type(param) => Some(param), + _ => { + // We already report an error for this above. + None + } + }) + .collect(); + + quote! { + #[turbo_tasks::macro_helpers::async_trait] + impl #generics turbo_tasks::TaskInput for #ident #generics + where + #(#generic_params: turbo_tasks::TaskInput,)* + { + #[allow(non_snake_case)] + #[allow(unreachable_code)] // This can occur for enums with no variants. + fn is_resolved(&self) -> bool { + #is_resolved_impl + } + + #[allow(non_snake_case)] + #[allow(unreachable_code)] // This can occur for enums with no variants. + fn is_transient(&self) -> bool { + #is_transient_impl + } + + #[allow(non_snake_case)] + #[allow(unreachable_code)] // This can occur for enums with no variants. + async fn resolve(&self) -> turbo_tasks::Result { + #resolve_impl + } + } + } + .into() +} diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/trace_raw_vcs_macro.rs b/turbopack/crates/turbo-tasks-macros/src/derive/trace_raw_vcs_macro.rs new file mode 100644 index 0000000000000..f735624997d2b --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/derive/trace_raw_vcs_macro.rs @@ -0,0 +1,61 @@ +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use syn::{parse_macro_input, DeriveInput, Field, FieldsNamed, FieldsUnnamed}; +use turbo_tasks_macros_shared::{generate_destructuring, match_expansion}; + +use super::FieldAttributes; + +fn filter_field(field: &Field) -> bool { + !FieldAttributes::from(field.attrs.as_slice()).trace_ignore +} + +pub fn derive_trace_raw_vcs(input: TokenStream) -> TokenStream { + let mut derive_input = parse_macro_input!(input as DeriveInput); + let ident = &derive_input.ident; + + for type_param in derive_input.generics.type_params_mut() { + type_param + .bounds + .push(syn::parse_quote!(turbo_tasks::trace::TraceRawVcs)); + } + let (impl_generics, ty_generics, where_clause) = derive_input.generics.split_for_impl(); + + let trace_items = match_expansion(&derive_input, &trace_named, &trace_unnamed, &trace_unit); + quote! { + impl #impl_generics turbo_tasks::trace::TraceRawVcs for #ident #ty_generics #where_clause { + fn trace_raw_vcs(&self, __context__: &mut turbo_tasks::trace::TraceRawVcsContext) { + #trace_items + } + } + } + .into() +} + +fn trace_named(_ident: TokenStream2, fields: &FieldsNamed) -> (TokenStream2, TokenStream2) { + let (captures, fields_idents) = generate_destructuring(fields.named.iter(), &filter_field); + ( + captures, + quote! { + {#( + turbo_tasks::trace::TraceRawVcs::trace_raw_vcs(#fields_idents, __context__); + )*} + }, + ) +} + +fn trace_unnamed(_ident: TokenStream2, fields: &FieldsUnnamed) -> (TokenStream2, TokenStream2) { + let (captures, fields_idents) = generate_destructuring(fields.unnamed.iter(), &filter_field); + ( + captures, + quote! { + {#( + turbo_tasks::trace::TraceRawVcs::trace_raw_vcs(#fields_idents, __context__); + )*} + }, + ) +} + +fn trace_unit(_ident: TokenStream2) -> TokenStream2 { + quote! { { } } +} diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/value_debug_format_macro.rs b/turbopack/crates/turbo-tasks-macros/src/derive/value_debug_format_macro.rs new file mode 100644 index 0000000000000..5f721893c5f19 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/derive/value_debug_format_macro.rs @@ -0,0 +1,126 @@ +use proc_macro::TokenStream; +use proc_macro2::TokenStream as TokenStream2; +use quote::quote; +use syn::{parse_macro_input, DeriveInput, Field, FieldsNamed, FieldsUnnamed}; +use turbo_tasks_macros_shared::{generate_destructuring, match_expansion}; + +use super::FieldAttributes; + +fn filter_field(field: &Field) -> bool { + !FieldAttributes::from(field.attrs.as_slice()).debug_ignore +} + +/// This macro generates the implementation of the `ValueDebugFormat` trait for +/// a given type. +/// +/// Fields annotated with `#[debug_ignore]` will not appear in the +/// `ValueDebugFormat` representation of the type. +pub fn derive_value_debug_format(input: TokenStream) -> TokenStream { + let mut derive_input = parse_macro_input!(input as DeriveInput); + + let ident = &derive_input.ident; + + for type_param in derive_input.generics.type_params_mut() { + type_param + .bounds + .push(syn::parse_quote!(turbo_tasks::debug::ValueDebugFormat)); + type_param.bounds.push(syn::parse_quote!(std::fmt::Debug)); + type_param.bounds.push(syn::parse_quote!(std::marker::Send)); + type_param.bounds.push(syn::parse_quote!(std::marker::Sync)); + } + let (impl_generics, ty_generics, where_clause) = derive_input.generics.split_for_impl(); + + let formatting_logic = + match_expansion(&derive_input, &format_named, &format_unnamed, &format_unit); + + quote! { + impl #impl_generics turbo_tasks::debug::ValueDebugFormat for #ident #ty_generics #where_clause { + fn value_debug_format<'a>(&'a self, depth: usize) -> turbo_tasks::debug::ValueDebugFormatString<'a> { + turbo_tasks::debug::ValueDebugFormatString::Async( + Box::pin(async move { + if depth == 0 { + return Ok(stringify!(#ident).to_string()); + } + + use turbo_tasks::debug::internal::*; + use turbo_tasks::debug::ValueDebugFormat; + Ok(format!("{:#?}", #formatting_logic)) + }) + ) + } + } + } + .into() +} + +/// Formats a single field nested inside named or unnamed fields. +fn format_field(value: TokenStream2) -> TokenStream2 { + quote! { + turbo_tasks::macro_helpers::value_debug_format_field(#value.value_debug_format(depth.saturating_sub(1))) + } +} + +/// Formats a struct or enum variant with named fields (e.g. `struct Foo { +/// bar: u32 }`, `Foo::Bar { baz: u32 }`). +fn format_named(ident: TokenStream2, fields: &FieldsNamed) -> (TokenStream2, TokenStream2) { + let (captures, fields_idents) = generate_destructuring(fields.named.iter(), &filter_field); + ( + captures, + if fields_idents.is_empty() { + // this can happen if all fields are ignored, we must special-case this to avoid + // rustc being unable to infer the type of an empty vec of futures + quote! { + FormattingStruct::new_named(turbo_tasks::stringify_path!(#ident), vec![]) + } + } else { + let fields_values = fields_idents.iter().cloned().map(format_field); + quote! { + FormattingStruct::new_named_async( + turbo_tasks::stringify_path!(#ident), + vec![#( + AsyncFormattingField::new( + stringify!(#fields_idents), + #fields_values, + ), + )*], + ).await + } + }, + ) +} + +/// Formats a struct or enum variant with unnamed fields (e.g. `struct +/// Foo(u32)`, `Foo::Bar(u32)`). +fn format_unnamed(ident: TokenStream2, fields: &FieldsUnnamed) -> (TokenStream2, TokenStream2) { + let (captures, fields_idents) = generate_destructuring(fields.unnamed.iter(), &filter_field); + ( + captures, + if fields_idents.is_empty() { + // this can happen if all fields are ignored, we must special-case this to avoid + // rustc being unable to infer the type of an empty vec of futures + quote! { + FormattingStruct::new_unnamed(turbo_tasks::stringify_path!(#ident), vec![]) + } + } else { + let fields_values = fields_idents.into_iter().map(format_field); + quote! { + FormattingStruct::new_unnamed_async( + turbo_tasks::stringify_path!(#ident), + vec![#( + #fields_values, + )*], + ).await + } + }, + ) +} + +/// Formats a unit struct or enum variant (e.g. `struct Foo;`, `Foo::Bar`). +fn format_unit(ident: TokenStream2) -> TokenStream2 { + quote! { + FormattingStruct::new_unnamed( + turbo_tasks::stringify_path!(#ident), + vec![], + ) + } +} diff --git a/turbopack/crates/turbo-tasks-macros/src/derive/value_debug_macro.rs b/turbopack/crates/turbo-tasks-macros/src/derive/value_debug_macro.rs new file mode 100644 index 0000000000000..4bf8fe445dd32 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/derive/value_debug_macro.rs @@ -0,0 +1,27 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +/// This macro generates the implementation of the `ValueDebug` trait for a +/// given type. +/// +/// This requires the type to implement the `ValueDebugFormat` trait. +pub fn derive_value_debug(input: TokenStream) -> TokenStream { + let derive_input = parse_macro_input!(input as DeriveInput); + let ident = &derive_input.ident; + quote! { + #[turbo_tasks::value_impl] + impl turbo_tasks::debug::ValueDebug for #ident { + #[turbo_tasks::function] + async fn dbg(&self) -> anyhow::Result> { + turbo_tasks::debug::ValueDebugFormat::value_debug_format(self, usize::MAX).try_to_value_debug_string().await + } + + #[turbo_tasks::function] + async fn dbg_depth(&self, depth: usize) -> anyhow::Result> { + turbo_tasks::debug::ValueDebugFormat::value_debug_format(self, depth).try_to_value_debug_string().await + } + } + } + .into() +} diff --git a/turbopack/crates/turbo-tasks-macros/src/func.rs b/turbopack/crates/turbo-tasks-macros/src/func.rs new file mode 100644 index 0000000000000..d6840ded4fe59 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/func.rs @@ -0,0 +1,557 @@ +use proc_macro2::Ident; +use syn::{ + parse_quote, + punctuated::{Pair, Punctuated}, + spanned::Spanned, + AngleBracketedGenericArguments, Block, Expr, ExprPath, FnArg, GenericArgument, Pat, PatIdent, + PatType, Path, PathArguments, PathSegment, Receiver, ReturnType, Signature, Token, Type, + TypeGroup, TypePath, TypeTuple, +}; + +#[derive(Debug)] +pub struct TurboFn { + // signature: Signature, + // block: Block, + ident: Ident, + output: Type, + this: Option, + inputs: Vec, +} + +#[derive(Debug)] +pub struct Input { + pub ident: Ident, + pub ty: Type, +} + +impl TurboFn { + pub fn new( + original_signature: &Signature, + definition_context: DefinitionContext, + ) -> Option { + if !original_signature.generics.params.is_empty() { + original_signature + .generics + .span() + .unwrap() + .error(format!( + "{} do not support generic parameters", + definition_context.function_type(), + )) + .emit(); + return None; + } + + if original_signature.generics.where_clause.is_some() { + original_signature + .generics + .where_clause + .span() + .unwrap() + .error(format!( + "{} do not support where clauses", + definition_context.function_type(), + )) + .emit(); + return None; + } + + let mut raw_inputs = original_signature.inputs.iter(); + let mut this = None; + let mut inputs = Vec::with_capacity(raw_inputs.len()); + + if let Some(possibly_receiver) = raw_inputs.next() { + match possibly_receiver { + FnArg::Receiver( + receiver @ Receiver { + attrs, + self_token, + reference, + mutability, + }, + ) => { + if !attrs.is_empty() { + receiver + .span() + .unwrap() + .error(format!( + "{} do not support attributes on arguments", + definition_context.function_type(), + )) + .emit(); + return None; + } + + // tt::functions in tt::value_impl can either take self as a typed `self: + // Vc`, or as immutable references `&self`. We must validate against any + // other forms of self. + + let definition_context = match &definition_context { + DefinitionContext::NakedFn { .. } => return None, + _ => &definition_context, + }; + + if !attrs.is_empty() { + receiver + .span() + .unwrap() + .error(format!( + "{} do not support attributes on self", + definition_context.function_type(), + )) + .emit(); + return None; + } + + if mutability.is_some() { + receiver + .span() + .unwrap() + .error(format!( + "{} cannot take self by mutable reference, use &self or self: \ + Vc instead", + definition_context.function_type(), + )) + .emit(); + return None; + } + + match &reference { + None => { + receiver + .span() + .unwrap() + .error(format!( + "{} cannot take self by value, use &self or self: Vc \ + instead", + definition_context.function_type(), + )) + .emit(); + return None; + } + Some((_, Some(lifetime))) => { + lifetime + .span() + .unwrap() + .error(format!( + "{} cannot take self by reference with a custom lifetime, use \ + &self or self: Vc instead", + definition_context.function_type(), + )) + .emit(); + return None; + } + _ => {} + } + + this = Some(Input { + ident: Ident::new("self", self_token.span()), + ty: parse_quote! { turbo_tasks::Vc }, + }); + } + FnArg::Typed(typed) => { + if !typed.attrs.is_empty() { + typed + .span() + .unwrap() + .error(format!( + "{} does not support attributes on arguments", + definition_context.function_type(), + )) + .emit(); + return None; + } + + if let Pat::Ident(ident) = &*typed.pat { + if ident.ident == "self" { + if let DefinitionContext::NakedFn { .. } = definition_context { + // The function is not associated. The compiler will emit an error + // on its own. + return None; + }; + + // We don't validate that the user provided a valid + // `turbo_tasks::Vc` here. + // We'll rely on the compiler to emit an error + // if the user provided an invalid receiver type + + let ident = ident.ident.clone(); + + this = Some(Input { + ident, + ty: parse_quote! { turbo_tasks::Vc }, + }); + } else { + match definition_context { + DefinitionContext::NakedFn { .. } + | DefinitionContext::ValueInherentImpl { .. } => {} + DefinitionContext::ValueTraitImpl { .. } + | DefinitionContext::ValueTrait { .. } => { + typed + .span() + .unwrap() + .error(format!( + "{} must accept &self or self: Vc as the first \ + argument", + definition_context.function_type(), + )) + .emit(); + return None; + } + } + let ident = ident.ident.clone(); + + inputs.push(Input { + ident, + ty: (*typed.ty).clone(), + }); + } + } else { + // We can't support destructuring patterns (or other kinds of patterns). + let ident = Ident::new("arg1", typed.pat.span()); + + inputs.push(Input { + ident, + ty: (*typed.ty).clone(), + }); + } + } + } + } + + for (i, input) in raw_inputs.enumerate() { + match input { + FnArg::Receiver(_) => { + // The compiler will emit an error on its own. + return None; + } + FnArg::Typed(typed) => { + let ident = if let Pat::Ident(ident) = &*typed.pat { + ident.ident.clone() + } else { + Ident::new(&format!("arg{}", i + 2), typed.pat.span()) + }; + + inputs.push(Input { + ident, + ty: (*typed.ty).clone(), + }); + } + } + } + + let output = return_type_to_type(&original_signature.output); + + Some(TurboFn { + ident: original_signature.ident.clone(), + output, + this, + inputs, + }) + } + + /// The signature of the exposed function. This is the original signature + /// converted to a standard turbo_tasks function signature. + pub fn signature(&self) -> Signature { + let exposed_inputs: Punctuated<_, Token![,]> = self + .this + .as_ref() + .into_iter() + .chain(self.inputs.iter()) + .map(|input| { + FnArg::Typed(PatType { + attrs: Default::default(), + ty: Box::new(input.ty.clone()), + pat: Box::new(Pat::Ident(PatIdent { + attrs: Default::default(), + by_ref: None, + mutability: None, + ident: input.ident.clone(), + subpat: None, + })), + colon_token: Default::default(), + }) + }) + .collect(); + + let ident = &self.ident; + let orig_output = &self.output; + let new_output = expand_vc_return_type(orig_output); + + parse_quote! { + fn #ident(#exposed_inputs) -> #new_output + } + } + + pub fn trait_signature(&self) -> Signature { + let signature = self.signature(); + + parse_quote! { + #signature where Self: Sized + } + } + + fn inputs(&self) -> Vec<&Ident> { + self.inputs + .iter() + .map(|Input { ident, .. }| ident) + .collect() + } + + pub fn input_types(&self) -> Vec<&Type> { + self.inputs.iter().map(|Input { ty, .. }| ty).collect() + } + + fn converted_this(&self) -> Option { + self.this.as_ref().map(|Input { ty: _, ident }| { + parse_quote! { + turbo_tasks::Vc::into_raw(#ident) + } + }) + } + + /// The block of the exposed function for a dynamic dispatch call to the + /// given trait. + pub fn dynamic_block(&self, trait_type_id_ident: &Ident) -> Block { + let ident = &self.ident; + let output = &self.output; + if let Some(converted_this) = self.converted_this() { + let inputs = self.inputs(); + parse_quote! { + { + <#output as turbo_tasks::task::TaskOutput>::try_from_raw_vc( + turbo_tasks::trait_call( + *#trait_type_id_ident, + std::borrow::Cow::Borrowed(stringify!(#ident)), + #converted_this, + Box::new((#(#inputs,)*)) as Box, + ) + ) + } + } + } else { + parse_quote! { + { + unimplemented!("trait methods without self are not yet supported") + } + } + } + } + + /// The block of the exposed function for a static dispatch call to the + /// given native function. + pub fn static_block(&self, native_function_id_ident: &Ident) -> Block { + let output = &self.output; + let inputs = self.inputs(); + if let Some(converted_this) = self.converted_this() { + parse_quote! { + { + <#output as turbo_tasks::task::TaskOutput>::try_from_raw_vc( + turbo_tasks::dynamic_this_call( + *#native_function_id_ident, + #converted_this, + Box::new((#(#inputs,)*)) as Box, + ) + ) + } + } + } else { + parse_quote! { + { + <#output as turbo_tasks::task::TaskOutput>::try_from_raw_vc( + turbo_tasks::dynamic_call( + *#native_function_id_ident, + Box::new((#(#inputs,)*)) as Box, + ) + ) + } + } + } + } + + pub(crate) fn is_method(&self) -> bool { + self.this.is_some() + } +} + +fn return_type_to_type(return_type: &ReturnType) -> Type { + match return_type { + ReturnType::Default => parse_quote! { () }, + ReturnType::Type(_, ref return_type) => (**return_type).clone(), + } +} + +fn expand_vc_return_type(orig_output: &Type) -> Type { + // HACK: Approximate the expansion that we'd otherwise get from + // `::Return`, so that the return type shown in the rustdocs + // is as simple as possible. Break out as soon as we see something we don't + // recognize. + let mut new_output = orig_output.clone(); + let mut found_vc = false; + loop { + new_output = match new_output { + Type::Group(TypeGroup { elem, .. }) => *elem, + Type::Tuple(TypeTuple { elems, .. }) if elems.is_empty() => { + Type::Path(parse_quote!(turbo_tasks::Vc<()>)) + } + Type::Path(TypePath { + qself: None, + path: + Path { + leading_colon, + ref segments, + }, + }) => { + let mut pairs = segments.pairs(); + let mut cur_pair = pairs.next(); + + enum PathPrefix { + Anyhow, + TurboTasks, + } + + // try to strip a `turbo_tasks::` or `anyhow::` prefix + let prefix = if let Some(first) = cur_pair.as_ref().map(|p| p.value()) { + if first.arguments.is_none() { + if first.ident == "turbo_tasks" { + Some(PathPrefix::TurboTasks) + } else if first.ident == "anyhow" { + Some(PathPrefix::Anyhow) + } else { + None + } + } else { + None + } + } else { + None + }; + + if prefix.is_some() { + cur_pair = pairs.next(); // strip the matched prefix + } else if leading_colon.is_some() { + break; // something like `::Vc` isn't valid + } + + // Look for a `Vc<...>` or `Result<...>` generic + let Some(Pair::End(PathSegment { + ident, + arguments: + PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }), + })) = cur_pair + else { + break; + }; + if ident == "Vc" { + found_vc = true; + break; // Vc is the bottom-most level + } + if ident == "Result" && args.len() == 1 { + let GenericArgument::Type(ty) = + args.first().expect("Result<...> type has an argument") + else { + break; + }; + ty.clone() + } else { + break; // we only support expanding Result<...> + } + } + _ => break, + } + } + + if !found_vc { + orig_output + .span() + .unwrap() + .error( + "Expected return type to be `turbo_tasks::Vc` or `anyhow::Result>`. \ + Unable to process type.", + ) + .emit(); + } + + new_output +} + +/// The context in which the function is being defined. +#[derive(Debug, Clone, Eq, PartialEq)] +pub enum DefinitionContext { + // The function is defined as a naked #[turbo_tasks::function]. + NakedFn, + // The function is defined as a #[turbo_tasks::value_impl] inherent implementation method. + ValueInherentImpl, + // The function is defined as a #[turbo_tasks::value_impl] trait implementation method. + ValueTraitImpl, + // The function is defined as a #[turbo_tasks::value_trait] default method. + ValueTrait, +} + +impl DefinitionContext { + pub fn function_type(&self) -> &'static str { + match self { + DefinitionContext::NakedFn => "#[turbo_tasks::function] naked functions", + DefinitionContext::ValueInherentImpl => "#[turbo_tasks::value_impl] inherent methods", + DefinitionContext::ValueTraitImpl => "#[turbo_tasks::value_impl] trait methods", + DefinitionContext::ValueTrait => "#[turbo_tasks::value_trait] methods", + } + } +} + +#[derive(Debug)] +pub struct NativeFn { + function_path_string: String, + function_path: ExprPath, + is_method: bool, +} + +impl NativeFn { + pub fn new(function_path_string: &str, function_path: &ExprPath, is_method: bool) -> NativeFn { + NativeFn { + function_path_string: function_path_string.to_owned(), + function_path: function_path.clone(), + is_method, + } + } + + pub fn ty(&self) -> Type { + parse_quote! { turbo_tasks::macro_helpers::Lazy } + } + + pub fn definition(&self) -> Expr { + let Self { + function_path_string, + function_path, + is_method, + } = self; + + if *is_method { + parse_quote! { + turbo_tasks::macro_helpers::Lazy::new(|| { + #[allow(deprecated)] + turbo_tasks::NativeFunction::new_method(#function_path_string.to_owned(), #function_path) + }) + } + } else { + parse_quote! { + turbo_tasks::macro_helpers::Lazy::new(|| { + #[allow(deprecated)] + turbo_tasks::NativeFunction::new_function(#function_path_string.to_owned(), #function_path) + }) + } + } + } + + pub fn id_ty(&self) -> Type { + parse_quote! { turbo_tasks::macro_helpers::Lazy } + } + + pub fn id_definition(&self, native_function_id_path: &Path) -> Expr { + parse_quote! { + turbo_tasks::macro_helpers::Lazy::new(|| { + turbo_tasks::registry::get_function_id(&*#native_function_id_path) + }) + } + } +} diff --git a/turbopack/crates/turbo-tasks-macros/src/function_macro.rs b/turbopack/crates/turbo-tasks-macros/src/function_macro.rs new file mode 100644 index 0000000000000..519abdb8f4ebe --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/function_macro.rs @@ -0,0 +1,83 @@ +use proc_macro::TokenStream; +use proc_macro2::Ident; +use quote::quote; +use syn::{parse_macro_input, parse_quote, ExprPath, ItemFn}; +use turbo_tasks_macros_shared::{get_native_function_id_ident, get_native_function_ident}; + +use crate::func::{DefinitionContext, NativeFn, TurboFn}; + +/// This macro generates the virtual function that powers turbo tasks. +/// An annotated task is replaced with a stub function that returns a +/// lazy completion (Vc), and stamps out the concrete implementation +/// of the task alongside that the Vc uses to resolve itself. +/// +/// Functions support being tagged for informational purposes. This +/// is currently only used in turbo-static for doing static analysis +/// of tasks. +/// +/// # Examples +/// +/// ```rust +/// use turbo_tasks::{Vc}; +/// +/// #[turbo_tasks::function(fs)] +/// async fn my_task() -> Vc { +/// // access filesystem +/// } +/// ``` +pub fn function(_args: TokenStream, input: TokenStream) -> TokenStream { + let item = parse_macro_input!(input as ItemFn); + + let ItemFn { + attrs, + vis, + sig, + block, + } = &item; + + let Some(turbo_fn) = TurboFn::new(sig, DefinitionContext::NakedFn) else { + return quote! { + // An error occurred while parsing the function signature. + } + .into(); + }; + + let ident = &sig.ident; + + let inline_function_ident = Ident::new(&format!("{ident}_inline_function"), ident.span()); + let inline_function_path: ExprPath = parse_quote! { #inline_function_ident }; + let mut inline_signature = sig.clone(); + inline_signature.ident = inline_function_ident; + + let native_fn = NativeFn::new( + &ident.to_string(), + &inline_function_path, + turbo_fn.is_method(), + ); + let native_function_ident = get_native_function_ident(ident); + let native_function_ty = native_fn.ty(); + let native_function_def = native_fn.definition(); + + let native_function_id_ident = get_native_function_id_ident(ident); + let native_function_id_ty = native_fn.id_ty(); + let native_function_id_def = native_fn.id_definition(&native_function_ident.clone().into()); + + let exposed_signature = turbo_fn.signature(); + let exposed_block = turbo_fn.static_block(&native_function_id_ident); + + quote! { + #(#attrs)* + #vis #exposed_signature #exposed_block + + #(#attrs)* + #[doc(hidden)] + #inline_signature #block + + #[doc(hidden)] + pub(crate) static #native_function_ident: #native_function_ty = #native_function_def; + + #[doc(hidden)] + pub(crate) static #native_function_id_ident: #native_function_id_ty = #native_function_id_def; + } + .into() +} diff --git a/turbopack/crates/turbo-tasks-macros/src/generic_type_macro.rs b/turbopack/crates/turbo-tasks-macros/src/generic_type_macro.rs new file mode 100644 index 0000000000000..29ca8ab32f727 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/generic_type_macro.rs @@ -0,0 +1,156 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::{parse_macro_input, spanned::Spanned, visit_mut::VisitMut, GenericParam, Lifetime, Type}; +use turbo_tasks_macros_shared::{get_type_ident, GenericTypeInput}; + +use crate::value_macro::value_type_and_register; + +pub fn generic_type(input: TokenStream) -> TokenStream { + let mut input = parse_macro_input!(input as GenericTypeInput); + + for param in &input.generics.params { + match param { + syn::GenericParam::Type(ty) => { + if ty.ident == "Vc" { + ty.span() + .unwrap() + .error("Vc is a reserved name in generic_type") + .emit(); + } + } + syn::GenericParam::Lifetime(lt) => { + lt.span() + .unwrap() + .error("lifetime parameters are not supported in generic_type") + .emit(); + } + syn::GenericParam::Const(c) => { + c.span() + .unwrap() + .error("const parameters are not supported in generic_type") + .emit(); + } + } + } + + // Add Send bound to input generics. + + for param in &mut input.generics.params { + if let GenericParam::Type(param) = param { + param.bounds.push(syn::parse_quote! { std::marker::Send }); + } + } + + let (impl_generics, _, where_clause) = input.generics.split_for_impl(); + + let repr = replace_generics_with_unit(input.generics.params.iter(), &input.ty); + + let ty = input.ty; + let Some(ident) = get_type_ident(&ty) else { + return quote! { + // An error occurred while parsing the ident. + } + .into(); + }; + + let mut generics_with_static = input.generics.clone(); + for param in &mut generics_with_static.params { + if let GenericParam::Type(param) = param { + param.bounds.push(syn::TypeParamBound::Lifetime(Lifetime { + ident: syn::Ident::new("static", param.ident.span()), + apostrophe: param.ident.span(), + })) + } + } + + let value_type_and_register = value_type_and_register( + &ident, + quote! { #ty }, + Some(&generics_with_static), + quote! { + turbo_tasks::VcTransparentRead<#ty, #ty, #repr> + }, + quote! { + turbo_tasks::VcCellSharedMode<#ty> + }, + quote! { + turbo_tasks::ValueType::new_with_any_serialization::<#repr>() + }, + ); + + quote! { + #value_type_and_register + + impl #impl_generics Vc<#ty> #where_clause { + /// Converts this `Vc` to a generic representation. + fn to_repr(vc: Self) -> Vc<#repr> { + unsafe { + turbo_tasks::Vc::from_raw(Vc::into_raw(vc)) + } + } + + /// Converts a generic representation of this `Vc` to the proper `Vc` type. + /// + /// # Safety + /// + /// The caller must ensure that the `repr` is a valid representation of this `Vc`. + unsafe fn from_repr(vc: Vc<#repr>) -> Self { + unsafe { + turbo_tasks::Vc::from_raw(Vc::into_raw(vc)) + } + } + } + } + .into() +} + +struct ReplaceGenericsVisitor<'a> { + generics: &'a std::collections::HashSet, +} + +impl<'a> VisitMut for ReplaceGenericsVisitor<'a> { + fn visit_type_mut(&mut self, node: &mut Type) { + if let Type::Path(type_path) = node { + if type_path.qself.is_none() + && type_path.path.segments.len() == 1 + && type_path.path.segments[0].arguments.is_none() + && self + .generics + .contains(&type_path.path.segments[0].ident.to_string()) + { + // Replace the whole path with () + *node = syn::parse_quote! { () }; + return; + } + } + + syn::visit_mut::visit_type_mut(self, node); + } +} + +/// Replaces all instances of `params` generic types in `ty` with the unit type +/// `()`. +fn replace_generics_with_unit<'a, P>(params: P, ty: &Type) -> Type +where + P: IntoIterator, +{ + let generics_set: std::collections::HashSet<_> = params + .into_iter() + .filter_map(|param| { + if let GenericParam::Type(type_param) = param { + Some(type_param.ident.to_string()) + } else { + None + } + }) + .collect(); + + let mut new_ty = ty.clone(); + let mut visitor = ReplaceGenericsVisitor { + generics: &generics_set, + }; + + syn::visit_mut::visit_type_mut(&mut visitor, &mut new_ty); + + new_ty +} diff --git a/turbopack/crates/turbo-tasks-macros/src/lib.rs b/turbopack/crates/turbo-tasks-macros/src/lib.rs new file mode 100644 index 0000000000000..092eeb151b552 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/lib.rs @@ -0,0 +1,213 @@ +#![allow(internal_features)] +#![feature(proc_macro_diagnostic)] +#![feature(allow_internal_unstable)] +#![feature(box_patterns)] + +mod derive; +mod func; +mod function_macro; +mod generic_type_macro; +mod primitive_macro; +mod value_impl_macro; +mod value_macro; +mod value_trait_macro; + +extern crate proc_macro; + +use proc_macro::TokenStream; +use proc_macro_error::proc_macro_error; + +#[proc_macro_derive(TraceRawVcs, attributes(turbo_tasks))] +pub fn derive_trace_raw_vcs_attr(input: TokenStream) -> TokenStream { + derive::derive_trace_raw_vcs(input) +} + +#[proc_macro_derive(ResolvedValue, attributes(turbo_tasks))] +pub fn derive_resolved_value_attr(input: TokenStream) -> TokenStream { + derive::derive_resolved_value(input) +} + +#[proc_macro_derive(ValueDebug, attributes(turbo_tasks))] +pub fn derive_value_debug_attr(input: TokenStream) -> TokenStream { + derive::derive_value_debug(input) +} + +#[proc_macro_derive(ValueDebugFormat, attributes(turbo_tasks))] +pub fn derive_value_debug_format_attr(input: TokenStream) -> TokenStream { + derive::derive_value_debug_format(input) +} + +#[proc_macro_derive(DeterministicHash, attributes(turbo_tasks))] +pub fn derive_deterministic_hash(input: TokenStream) -> TokenStream { + derive::derive_deterministic_hash(input) +} + +#[proc_macro_derive(TaskInput, attributes(turbo_tasks))] +pub fn derive_task_input(input: TokenStream) -> TokenStream { + derive::derive_task_input(input) +} + +/// Creates a Vc struct for a `struct` or `enum` that represent +/// that type placed into a cell in a Task. +/// +/// That Vc object can be `await`ed to get a readonly reference +/// to the value contained in the cell. +/// +/// ## Arguments +/// +/// Example: `#[turbo_tasks::value(into = "new", eq = "manual")]` +/// +/// ### `cell` +/// +/// Possible values: +/// +/// - "new": Always overrides the value in the cell. Invalidating all +/// dependent tasks. +/// - "shared" (default): Compares with the existing value in the cell, before +/// overriding it. Requires Value to implement [Eq]. +/// +/// ### `eq` +/// +/// Possible values: +/// +/// - "manual": Prevents deriving [Eq] so you can do it manually. +/// +/// ### `into` +/// +/// When provided the Vc implement `From` to allow to convert +/// a Value to a Vc by placing it into a cell in a Task. +/// +/// Possible values: +/// +/// - "new": Always overrides the value in the cell. Invalidating all +/// dependent tasks. +/// - "shared": Compares with the existing value in the cell, before +/// overriding it. Requires Value to implement [Eq]. +/// - "none" (default): Prevents implementing `From`. +/// +/// ### `serialization` +/// +/// Affects serialization via [serde::Serialize] and [serde::Deserialize]. +/// +/// Possible values: +/// +/// - "auto" (default): Derives the serialization traits and enabled +/// serialization. +/// - "auto_for_input": Same as "auto", but also adds the marker trait +/// [turbo_tasks::TypedForInput]. +/// - "custom": Prevents deriving the serialization traits, but still enables +/// serialization (you need to manually implement [serde::Serialize] and +/// [serde::Deserialize]). +/// - "custom_for_input":Same as "auto", but also adds the marker trait +/// [turbo_tasks::TypedForInput]. +/// - "none": Disables serialization and prevents deriving the traits. +/// +/// ### `shared` +/// +/// Sets both `cell = "shared"` and `into = "shared"` +/// +/// No value. +/// +/// Example: `#[turbo_tasks::value(shared)]` +/// +/// ### `transparent` +/// +/// If applied to a unit struct (e.g. `struct Wrapper(Value)`) the outer struct +/// is skipped for all operations (cell, into, reading). +/// +/// No value. +/// +/// Example: `#[turbo_tasks::value(transparent)]` +/// +/// ### `resolved` +/// +/// A shorthand syntax for +/// [`#[derive(turbo_tasks::ResolvedValue)]`][macro@turbo_tasks::ResolvedValue] +/// +/// Example: `#[turbo_tasks::value(resolved)]` +/// +/// TODO: add more documentation: presets, traits +#[allow_internal_unstable(min_specialization, into_future, trivial_bounds)] +#[proc_macro_error] +#[proc_macro_attribute] +pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { + value_macro::value(args, input) +} + +/// Allows this trait to be used as part of a trait object inside of a value +/// cell, in the form of `Vc`. +/// +/// ## Arguments +/// +/// Example: `#[turbo_tasks::value_trait(no_debug, resolved)]` +/// +/// ### 'no_debug` +/// +/// Disables the automatic implementation of [`turbo_tasks::debug::ValueDebug`]. +/// +/// Example: `#[turbo_tasks::value_trait(no_debug)]` +/// +/// ### 'resolved` +/// +/// Adds [`turbo_tasks::ResolvedValue`] as a supertrait of this trait. +/// +/// Example: `#[turbo_tasks::value_trait(resolved)]` +#[allow_internal_unstable(min_specialization, into_future, trivial_bounds)] +#[proc_macro_error] +#[proc_macro_attribute] +pub fn value_trait(args: TokenStream, input: TokenStream) -> TokenStream { + value_trait_macro::value_trait(args, input) +} + +#[allow_internal_unstable(min_specialization, into_future, trivial_bounds)] +#[proc_macro_error] +#[proc_macro_attribute] +pub fn function(args: TokenStream, input: TokenStream) -> TokenStream { + function_macro::function(args, input) +} + +#[allow_internal_unstable(min_specialization, into_future, trivial_bounds)] +#[proc_macro_error] +#[proc_macro_attribute] +pub fn test_tt(_args: TokenStream, input: TokenStream) -> TokenStream { + derive::derive_value_debug(input) +} + +#[allow_internal_unstable(min_specialization, into_future, trivial_bounds)] +#[proc_macro_error] +#[proc_macro_attribute] +pub fn value_impl(args: TokenStream, input: TokenStream) -> TokenStream { + value_impl_macro::value_impl(args, input) +} + +#[allow_internal_unstable(min_specialization, into_future, trivial_bounds)] +#[proc_macro_error] +#[proc_macro] +pub fn primitive(input: TokenStream) -> TokenStream { + primitive_macro::primitive(input) +} + +/// Registers a value type that is generic over the `Vc` it contains. +/// +/// # Example +/// +/// ``` +/// use crate::generic_type as __turbo_tasks_internal_generic_type; +/// +/// __turbo_tasks_internal_generic_type!(, GenericType, Vc>); +/// +/// // Now you can do the following, for any `A` and `B` value types: +/// +/// let vc: Vc, Vc>> = Vc::cell( +/// GenericType::new( +/// Vc::cell(42), +/// Vc::cell("hello".to_string()) +/// ) +/// ); +/// ``` +#[allow_internal_unstable(min_specialization, into_future, trivial_bounds)] +#[proc_macro_error] +#[proc_macro] +pub fn generic_type(input: TokenStream) -> TokenStream { + generic_type_macro::generic_type(input) +} diff --git a/turbopack/crates/turbo-tasks-macros/src/primitive_macro.rs b/turbopack/crates/turbo-tasks-macros/src/primitive_macro.rs new file mode 100644 index 0000000000000..2d0b99e857ae6 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/primitive_macro.rs @@ -0,0 +1,69 @@ +use proc_macro::TokenStream; +use quote::quote; +use syn::parse_macro_input; +use turbo_tasks_macros_shared::{get_type_ident, PrimitiveInput}; + +use crate::value_macro::value_type_and_register; + +pub fn primitive(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as PrimitiveInput); + + let ty = input.ty; + let Some(ident) = get_type_ident(&ty) else { + return quote! { + // An error occurred while parsing the ident. + } + .into(); + }; + + let value_debug_impl = quote! { + #[turbo_tasks::value_impl] + impl turbo_tasks::debug::ValueDebug for #ty { + #[turbo_tasks::function] + async fn dbg(&self) -> anyhow::Result> { + use turbo_tasks::debug::ValueDebugFormat; + self.value_debug_format(usize::MAX).try_to_value_debug_string().await + } + + #[turbo_tasks::function] + async fn dbg_depth(&self, depth: usize) -> anyhow::Result> { + use turbo_tasks::debug::ValueDebugFormat; + self.value_debug_format(depth).try_to_value_debug_string().await + } + } + }; + + let value_type_and_register = value_type_and_register( + &ident, + quote! { #ty }, + None, + quote! { + turbo_tasks::VcTransparentRead<#ty, #ty, #ty> + }, + quote! { + turbo_tasks::VcCellSharedMode<#ty> + }, + quote! { + turbo_tasks::ValueType::new_with_any_serialization::<#ty>() + }, + ); + + let value_default_impl = quote! { + #[turbo_tasks::value_impl] + impl turbo_tasks::ValueDefault for #ty { + #[turbo_tasks::function] + fn value_default() -> Vc { + Vc::cell(Default::default()) + } + } + }; + + quote! { + #value_type_and_register + + #value_debug_impl + + #value_default_impl + } + .into() +} diff --git a/turbopack/crates/turbo-tasks-macros/src/value_impl_macro.rs b/turbopack/crates/turbo-tasks-macros/src/value_impl_macro.rs new file mode 100644 index 0000000000000..93eff9cdece0f --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/value_impl_macro.rs @@ -0,0 +1,339 @@ +use proc_macro::TokenStream; +use proc_macro2::{Ident, TokenStream as TokenStream2}; +use quote::{quote, ToTokens}; +use syn::{ + parse::{Parse, ParseStream}, + parse_macro_input, parse_quote, + punctuated::Punctuated, + spanned::Spanned, + Attribute, Error, ExprPath, Generics, ImplItem, ImplItemMethod, ItemImpl, Lit, LitStr, Meta, + MetaNameValue, Path, Result, Token, Type, +}; +use turbo_tasks_macros_shared::{ + get_inherent_impl_function_id_ident, get_inherent_impl_function_ident, get_path_ident, + get_register_trait_methods_ident, get_trait_impl_function_id_ident, + get_trait_impl_function_ident, get_type_ident, +}; + +use crate::func::{DefinitionContext, NativeFn, TurboFn}; + +fn is_attribute(attr: &Attribute, name: &str) -> bool { + let path = &attr.path; + if path.leading_colon.is_some() { + return false; + } + let mut iter = path.segments.iter(); + match iter.next() { + Some(seg) if seg.arguments.is_empty() && seg.ident == "turbo_tasks" => match iter.next() { + Some(seg) if seg.arguments.is_empty() && seg.ident == name => iter.next().is_none(), + _ => false, + }, + _ => false, + } +} + +fn strip_function_attribute<'a>(item: &'a ImplItem, attrs: &'a [Attribute]) -> Vec<&'a Attribute> { + let (function_attrs, attrs): (Vec<_>, Vec<_>) = attrs + .iter() + // TODO(alexkirsz) Replace this with function + .partition(|attr| is_attribute(attr, "function")); + if function_attrs.is_empty() { + item.span() + .unwrap() + .error("#[turbo_tasks::function] attribute missing") + .emit(); + } + attrs +} + +struct ValueImplArguments { + ident: Option, +} + +impl Parse for ValueImplArguments { + fn parse(input: ParseStream) -> Result { + let mut result = ValueImplArguments { ident: None }; + let punctuated: Punctuated = input.parse_terminated(Meta::parse)?; + for meta in punctuated { + match ( + meta.path() + .get_ident() + .map(ToString::to_string) + .as_deref() + .unwrap_or_default(), + meta, + ) { + ( + "ident", + Meta::NameValue(MetaNameValue { + lit: Lit::Str(lit), .. + }), + ) => { + result.ident = Some(lit); + } + (_, meta) => { + return Err(Error::new_spanned( + &meta, + format!("unexpected {:?}, expected \"ident\"", meta), + )) + } + } + } + + Ok(result) + } +} + +pub fn value_impl(args: TokenStream, input: TokenStream) -> TokenStream { + let ValueImplArguments { ident } = parse_macro_input!(args as ValueImplArguments); + + fn inherent_value_impl(ty: &Type, ty_ident: &Ident, items: &[ImplItem]) -> TokenStream2 { + let mut all_definitions = Vec::new(); + let mut exposed_impl_items = Vec::new(); + + for item in items.iter() { + if let ImplItem::Method(ImplItemMethod { + attrs, + vis, + defaultness: _, + sig, + block, + }) = item + { + let attrs = strip_function_attribute(item, attrs); + + let ident = &sig.ident; + + // TODO(alexkirsz) These should go into their own utilities. + let inline_function_ident: Ident = + Ident::new(&format!("{}_inline", ident), ident.span()); + let inline_function_path: ExprPath = parse_quote! { <#ty>::#inline_function_ident }; + let mut inline_signature = sig.clone(); + inline_signature.ident = inline_function_ident; + + let Some(turbo_fn) = TurboFn::new(sig, DefinitionContext::ValueInherentImpl) else { + return quote! { + // An error occurred while parsing the function signature. + }; + }; + + let native_fn = NativeFn::new( + &format!("{ty}::{ident}", ty = ty.to_token_stream()), + &inline_function_path, + turbo_fn.is_method(), + ); + + let native_function_ident = get_inherent_impl_function_ident(ty_ident, ident); + let native_function_ty = native_fn.ty(); + let native_function_def = native_fn.definition(); + let native_function_id_ident = get_inherent_impl_function_id_ident(ty_ident, ident); + let native_function_id_ty = native_fn.id_ty(); + let native_function_id_def = native_fn.id_definition(&parse_quote! { + #native_function_ident + }); + + let turbo_signature = turbo_fn.signature(); + let turbo_block = turbo_fn.static_block(&native_function_id_ident); + exposed_impl_items.push(quote! { + #(#attrs)* + #vis #turbo_signature #turbo_block + }); + + all_definitions.push(quote! { + #[doc(hidden)] + impl #ty { + // By declaring the native function's body within an `impl` block, we ensure that `Self` refers + // to `#ty`. This is necessary because the function's body is originally declared within an + // `impl` block already. + #[allow(declare_interior_mutable_const)] + #[doc(hidden)] + const #native_function_ident: #native_function_ty = #native_function_def; + #[allow(declare_interior_mutable_const)] + #[doc(hidden)] + const #native_function_id_ident: #native_function_id_ty = #native_function_id_def; + + #(#attrs)* + #[doc(hidden)] + #[deprecated(note = "This function is only exposed for use in macros. Do not call it directly.")] + pub(self) #inline_signature #block + } + + #[doc(hidden)] + pub(crate) static #native_function_ident: #native_function_ty = <#ty>::#native_function_ident; + #[doc(hidden)] + pub(crate) static #native_function_id_ident: #native_function_id_ty = <#ty>::#native_function_id_ident; + }) + } + } + + quote! { + impl #ty { + #(#exposed_impl_items)* + } + + #(#all_definitions)* + } + } + + fn trait_value_impl( + ty: &Type, + generics: &Generics, + ty_ident: &Ident, + trait_path: &Path, + items: &[ImplItem], + ) -> TokenStream2 { + let trait_ident = get_path_ident(trait_path); + + let (impl_generics, _, where_clause) = generics.split_for_impl(); + + let register = get_register_trait_methods_ident(&trait_ident, ty_ident); + + let mut trait_registers = Vec::new(); + let mut trait_functions = Vec::with_capacity(items.len()); + let mut all_definitions = Vec::with_capacity(items.len()); + + for item in items.iter() { + if let ImplItem::Method(ImplItemMethod { + sig, attrs, block, .. + }) = item + { + let ident = &sig.ident; + + let Some(turbo_fn) = TurboFn::new(sig, DefinitionContext::ValueTraitImpl) else { + return quote! { + // An error occurred while parsing the function signature. + }; + }; + + let attrs = strip_function_attribute(item, attrs); + + // TODO(alexkirsz) These should go into their own utilities. + let inline_function_ident: Ident = + Ident::new(&format!("{}_inline", ident), ident.span()); + let inline_extension_trait_ident = Ident::new( + &format!("{}_{}_{}_inline", ty_ident, trait_ident, ident), + ident.span(), + ); + let inline_function_path: ExprPath = + parse_quote! { <#ty as #inline_extension_trait_ident>::#inline_function_ident }; + let mut inline_signature = sig.clone(); + inline_signature.ident = inline_function_ident; + + let native_fn = NativeFn::new( + &format!( + "<{ty} as {trait_path}>::{ident}", + ty = ty.to_token_stream(), + trait_path = trait_path.to_token_stream() + ), + &inline_function_path, + turbo_fn.is_method(), + ); + + let native_function_ident = + get_trait_impl_function_ident(ty_ident, &trait_ident, ident); + + let native_function_ty = native_fn.ty(); + let native_function_def = native_fn.definition(); + let native_function_id_ident = + get_trait_impl_function_id_ident(ty_ident, &trait_ident, ident); + let native_function_id_ty = native_fn.id_ty(); + let native_function_id_def = native_fn.id_definition(&parse_quote! { + #native_function_ident + }); + + let turbo_signature = turbo_fn.signature(); + let turbo_block = turbo_fn.static_block(&native_function_id_ident); + + trait_functions.push(quote! { + #(#attrs)* + #turbo_signature #turbo_block + }); + + all_definitions.push(quote! { + #[doc(hidden)] + #[allow(non_camel_case_types)] + trait #inline_extension_trait_ident: std::marker::Send { + #[allow(declare_interior_mutable_const)] + #[doc(hidden)] + const #native_function_ident: #native_function_ty; + #[allow(declare_interior_mutable_const)] + #[doc(hidden)] + const #native_function_id_ident: #native_function_id_ty; + + #(#attrs)* + #[doc(hidden)] + #inline_signature; + } + + #[doc(hidden)] + impl #impl_generics #inline_extension_trait_ident for #ty #where_clause { + #[allow(declare_interior_mutable_const)] + #[doc(hidden)] + const #native_function_ident: #native_function_ty = #native_function_def; + #[allow(declare_interior_mutable_const)] + #[doc(hidden)] + const #native_function_id_ident: #native_function_id_ty = #native_function_id_def; + + #(#attrs)* + #[doc(hidden)] + #[deprecated(note = "This function is only exposed for use in macros. Do not call it directly.")] + #inline_signature #block + } + + #[doc(hidden)] + pub(crate) static #native_function_ident: #native_function_ty = <#ty as #inline_extension_trait_ident>::#native_function_ident; + #[doc(hidden)] + pub(crate) static #native_function_id_ident: #native_function_id_ty = <#ty as #inline_extension_trait_ident>::#native_function_id_ident; + }); + + trait_registers.push(quote! { + value.register_trait_method( as turbo_tasks::VcValueTrait>::get_trait_type_id(), stringify!(#ident).into(), *#native_function_id_ident); + }); + } + } + + quote! { + #[doc(hidden)] + #[allow(non_snake_case)] + pub(crate) fn #register(value: &mut turbo_tasks::ValueType) { + value.register_trait( as turbo_tasks::VcValueTrait>::get_trait_type_id()); + #(#trait_registers)* + } + + // NOTE(alexkirsz) We can't have a general `turbo_tasks::Upcast> for T where T: Trait` because + // rustc complains: error[E0210]: type parameter `T` must be covered by another type when it appears before + // the first local type (`dyn Trait`). + unsafe impl #impl_generics turbo_tasks::Upcast> for #ty #where_clause {} + + impl #impl_generics #trait_path for #ty #where_clause { + #(#trait_functions)* + } + + #(#all_definitions)* + } + } + + let item = parse_macro_input!(input as ItemImpl); + + let Some(ty_ident) = ident + .map(|ident| Ident::new(&ident.value(), ident.span())) + .or_else(|| get_type_ident(&item.self_ty)) + else { + return quote! { + // An error occurred while parsing the type. + } + .into(); + }; + + match &item.trait_ { + None => inherent_value_impl(&item.self_ty, &ty_ident, &item.items).into(), + Some((_, trait_path, _)) => trait_value_impl( + &item.self_ty, + &item.generics, + &ty_ident, + trait_path, + &item.items, + ) + .into(), + } +} diff --git a/turbopack/crates/turbo-tasks-macros/src/value_macro.rs b/turbopack/crates/turbo-tasks-macros/src/value_macro.rs new file mode 100644 index 0000000000000..9e79117540894 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/value_macro.rs @@ -0,0 +1,521 @@ +use std::sync::OnceLock; + +use proc_macro::TokenStream; +use proc_macro2::{Ident, Span}; +use quote::{quote, quote_spanned, ToTokens}; +use regex::Regex; +use syn::{ + parse::{Parse, ParseStream}, + parse_macro_input, parse_quote, + punctuated::Punctuated, + spanned::Spanned, + Error, Fields, FieldsUnnamed, Generics, Item, ItemEnum, ItemStruct, Lit, LitStr, Meta, + MetaNameValue, Result, Token, +}; +use turbo_tasks_macros_shared::{ + get_register_value_type_ident, get_value_type_id_ident, get_value_type_ident, + get_value_type_init_ident, +}; + +enum IntoMode { + None, + New, + Shared, +} + +impl Parse for IntoMode { + fn parse(input: ParseStream) -> Result { + let ident = input.parse::()?; + Self::try_from(ident) + } +} + +impl TryFrom for IntoMode { + type Error = Error; + + fn try_from(lit: LitStr) -> std::result::Result { + match lit.value().as_str() { + "none" => Ok(IntoMode::None), + "new" => Ok(IntoMode::New), + "shared" => Ok(IntoMode::Shared), + _ => Err(Error::new_spanned( + &lit, + "expected \"none\", \"new\" or \"shared\"", + )), + } + } +} + +enum CellMode { + New, + Shared, +} + +impl Parse for CellMode { + fn parse(input: ParseStream) -> Result { + let ident = input.parse::()?; + Self::try_from(ident) + } +} + +impl TryFrom for CellMode { + type Error = Error; + + fn try_from(lit: LitStr) -> std::result::Result { + match lit.value().as_str() { + "new" => Ok(CellMode::New), + "shared" => Ok(CellMode::Shared), + _ => Err(Error::new_spanned(&lit, "expected \"new\" or \"shared\"")), + } + } +} + +enum SerializationMode { + None, + Auto, + AutoForInput, + Custom, + CustomForInput, +} + +impl Parse for SerializationMode { + fn parse(input: ParseStream) -> Result { + let ident = input.parse::()?; + Self::try_from(ident) + } +} + +impl TryFrom for SerializationMode { + type Error = Error; + + fn try_from(lit: LitStr) -> std::result::Result { + match lit.value().as_str() { + "none" => Ok(SerializationMode::None), + "auto" => Ok(SerializationMode::Auto), + "auto_for_input" => Ok(SerializationMode::AutoForInput), + "custom" => Ok(SerializationMode::Custom), + "custom_for_input" => Ok(SerializationMode::CustomForInput), + _ => Err(Error::new_spanned( + &lit, + "expected \"none\", \"auto\", \"auto_for_input\", \"custom\" or \ + \"custom_for_input\"", + )), + } + } +} + +struct ValueArguments { + serialization_mode: SerializationMode, + into_mode: IntoMode, + cell_mode: CellMode, + manual_eq: bool, + transparent: bool, + /// Should we `#[derive(turbo_tasks::ResolvedValue)]`? + /// + /// `Some(...)` if enabled, containing the span that enabled the derive. + resolved: Option, +} + +impl Parse for ValueArguments { + fn parse(input: ParseStream) -> Result { + let mut result = ValueArguments { + serialization_mode: SerializationMode::Auto, + into_mode: IntoMode::None, + cell_mode: CellMode::Shared, + manual_eq: false, + resolved: None, + transparent: false, + }; + let punctuated: Punctuated = input.parse_terminated(Meta::parse)?; + for meta in punctuated { + match ( + meta.path() + .get_ident() + .map(ToString::to_string) + .as_deref() + .unwrap_or_default(), + meta, + ) { + ("shared", Meta::Path(_)) => { + result.into_mode = IntoMode::Shared; + result.cell_mode = CellMode::Shared; + } + ( + "into", + Meta::NameValue(MetaNameValue { + lit: Lit::Str(str), .. + }), + ) => { + result.into_mode = IntoMode::try_from(str)?; + } + ( + "serialization", + Meta::NameValue(MetaNameValue { + lit: Lit::Str(str), .. + }), + ) => { + result.serialization_mode = SerializationMode::try_from(str)?; + } + ( + "cell", + Meta::NameValue(MetaNameValue { + lit: Lit::Str(str), .. + }), + ) => { + result.cell_mode = CellMode::try_from(str)?; + } + ( + "eq", + Meta::NameValue(MetaNameValue { + lit: Lit::Str(str), .. + }), + ) => { + result.manual_eq = if str.value() == "manual" { + true + } else { + return Err(Error::new_spanned(&str, "expected \"manual\"")); + }; + } + ("transparent", Meta::Path(_)) => { + result.transparent = true; + } + ("resolved", Meta::Path(path)) => { + result.resolved = Some(path.span()); + } + (_, meta) => { + return Err(Error::new_spanned( + &meta, + format!( + "unexpected {:?}, expected \"shared\", \"into\", \"serialization\", \ + \"cell\", \"eq\", \"transparent\"", + meta + ), + )) + } + } + } + + Ok(result) + } +} + +pub fn value(args: TokenStream, input: TokenStream) -> TokenStream { + let mut item = parse_macro_input!(input as Item); + let ValueArguments { + serialization_mode, + into_mode, + cell_mode, + manual_eq, + transparent, + resolved, + } = parse_macro_input!(args as ValueArguments); + + let mut inner_type = None; + if transparent { + if let Item::Struct(ItemStruct { + attrs, + fields: Fields::Unnamed(FieldsUnnamed { unnamed, .. }), + .. + }) = &mut item + { + if unnamed.len() == 1 { + let field = unnamed.iter().next().unwrap(); + inner_type = Some(field.ty.clone()); + + // generate a type string to add to the docs + let inner_type_string = inner_type.to_token_stream().to_string(); + + // HACK: proc_macro2 inserts whitespace between every token. It's ugly, so + // remove it, assuming these whitespace aren't syntatically important. Using + // prettyplease (or similar) would be more correct, but slower and add another + // dependency. + static WHITESPACE_RE: OnceLock = OnceLock::new(); + // Remove whitespace, as long as there is a non-word character (e.g. `>` or `,`) + // on either side. Try not to remove whitespace between `dyn Trait`. + let whitespace_re = WHITESPACE_RE.get_or_init(|| { + Regex::new(r"\b \B|\B \b|\B \B").expect("WHITESPACE_RE is valid") + }); + let inner_type_string = whitespace_re.replace_all(&inner_type_string, ""); + + // Add a couple blank lines in case there's already a doc comment we're + // effectively appending to. If there's not, rustdoc will strip + // the leading whitespace. + let doc_str = format!( + "\n\nThis is a [transparent value type][turbo_tasks::value#transparent] \ + wrapping [`{}`].", + inner_type_string, + ); + + attrs.push(parse_quote! { + #[doc = #doc_str] + }); + } + } + if inner_type.is_none() { + item.span() + .unwrap() + .error( + "#[turbo_tasks::value(transparent)] is only valid with single-item unit \ + structs", + ) + .emit(); + } + } + + let ident = match &item { + Item::Enum(ItemEnum { ident, .. }) => ident, + Item::Struct(ItemStruct { ident, .. }) => ident, + _ => { + item.span().unwrap().error("unsupported syntax").emit(); + + return quote! { + #item + } + .into(); + } + }; + + let cell_mode = match cell_mode { + CellMode::New => quote! { + turbo_tasks::VcCellNewMode<#ident> + }, + CellMode::Shared => quote! { + turbo_tasks::VcCellSharedMode<#ident> + }, + }; + + let (cell_prefix, cell_access_content, read) = if let Some(inner_type) = &inner_type { + ( + quote! { pub }, + quote! { + content.0 + }, + quote! { + turbo_tasks::VcTransparentRead::<#ident, #inner_type, #ident> + }, + ) + } else { + ( + if let IntoMode::New | IntoMode::Shared = into_mode { + quote! { pub } + } else { + quote! {} + }, + quote! { content }, + quote! { + turbo_tasks::VcDefaultRead::<#ident> + }, + ) + }; + + let cell_struct = quote! { + /// Places a value in a cell of the current task. + /// + /// Cell is selected based on the value type and call order of `cell`. + #cell_prefix fn cell(self) -> turbo_tasks::Vc { + let content = self; + turbo_tasks::Vc::cell_private(#cell_access_content) + } + }; + + let into = if let IntoMode::New | IntoMode::Shared = into_mode { + quote! { + impl Into> for #ident { + fn into(self) -> turbo_tasks::Vc<#ident> { + self.cell() + } + } + } + } else { + quote! {} + }; + + let derive = match serialization_mode { + SerializationMode::None | SerializationMode::Custom | SerializationMode::CustomForInput => { + quote! { + #[derive(turbo_tasks::trace::TraceRawVcs)] + } + } + SerializationMode::Auto | SerializationMode::AutoForInput => quote! { + #[derive( + turbo_tasks::trace::TraceRawVcs, + turbo_tasks::macro_helpers::serde::Serialize, + turbo_tasks::macro_helpers::serde::Deserialize, + )] + #[serde(crate = "turbo_tasks::macro_helpers::serde")] + }, + }; + let debug_derive = if inner_type.is_some() { + // Transparent structs have their own manual `ValueDebug` implementation. + quote! { + #[repr(transparent)] + } + } else { + quote! { + #[derive( + turbo_tasks::debug::ValueDebugFormat, + turbo_tasks::debug::internal::ValueDebug, + )] + } + }; + let eq_derive = if manual_eq { + quote!() + } else { + quote!( + #[derive(PartialEq, Eq)] + ) + }; + let resolved_derive = if let Some(span) = resolved { + quote_spanned!( + span => + #[derive(turbo_tasks::ResolvedValue)] + ) + } else { + quote!() + }; + + let new_value_type = match serialization_mode { + SerializationMode::None => quote! { + turbo_tasks::ValueType::new::<#ident>() + }, + SerializationMode::Auto | SerializationMode::Custom => { + quote! { + turbo_tasks::ValueType::new_with_any_serialization::<#ident>() + } + } + SerializationMode::AutoForInput | SerializationMode::CustomForInput => { + quote! { + turbo_tasks::ValueType::new_with_magic_serialization::<#ident>() + } + } + }; + + let for_input_marker = match serialization_mode { + SerializationMode::None | SerializationMode::Auto | SerializationMode::Custom => quote! {}, + SerializationMode::AutoForInput | SerializationMode::CustomForInput => quote! { + impl turbo_tasks::TypedForInput for #ident {} + }, + }; + + let value_debug_impl = if inner_type.is_some() { + // For transparent values, we defer directly to the inner type's `ValueDebug` + // implementation. + quote! { + #[turbo_tasks::value_impl] + impl turbo_tasks::debug::ValueDebug for #ident { + #[turbo_tasks::function] + async fn dbg(&self) -> anyhow::Result> { + use turbo_tasks::debug::ValueDebugFormat; + (&self.0).value_debug_format(usize::MAX).try_to_value_debug_string().await + } + + #[turbo_tasks::function] + async fn dbg_depth(&self, depth: usize) -> anyhow::Result> { + use turbo_tasks::debug::ValueDebugFormat; + (&self.0).value_debug_format(depth).try_to_value_debug_string().await + } + } + } + } else { + quote! {} + }; + + let value_type_and_register_code = value_type_and_register( + ident, + quote! { #ident }, + None, + read, + cell_mode, + new_value_type, + ); + + let expanded = quote! { + #derive + #debug_derive + #eq_derive + #resolved_derive + #item + + impl #ident { + #cell_struct + } + + #into + + #value_type_and_register_code + + #for_input_marker + + #value_debug_impl + }; + + expanded.into() +} + +pub fn value_type_and_register( + ident: &Ident, + ty: proc_macro2::TokenStream, + generics: Option<&Generics>, + read: proc_macro2::TokenStream, + cell_mode: proc_macro2::TokenStream, + new_value_type: proc_macro2::TokenStream, +) -> proc_macro2::TokenStream { + let value_type_init_ident = get_value_type_init_ident(ident); + let value_type_ident = get_value_type_ident(ident); + let value_type_id_ident = get_value_type_id_ident(ident); + let register_value_type_ident = get_register_value_type_ident(ident); + + let (impl_generics, where_clause) = if let Some(generics) = generics { + let (impl_generics, _, where_clause) = generics.split_for_impl(); + (quote! { #impl_generics }, quote! { #where_clause }) + } else { + (quote!(), quote!()) + }; + + quote! { + #[doc(hidden)] + static #value_type_init_ident: turbo_tasks::macro_helpers::OnceCell< + turbo_tasks::ValueType, + > = turbo_tasks::macro_helpers::OnceCell::new(); + #[doc(hidden)] + pub(crate) static #value_type_ident: turbo_tasks::macro_helpers::Lazy<&turbo_tasks::ValueType> = + turbo_tasks::macro_helpers::Lazy::new(|| { + #value_type_init_ident.get_or_init(|| { + panic!( + concat!( + stringify!(#value_type_ident), + " has not been initialized (this should happen via the generated register function)" + ) + ) + }) + }); + #[doc(hidden)] + static #value_type_id_ident: turbo_tasks::macro_helpers::Lazy = + turbo_tasks::macro_helpers::Lazy::new(|| { + turbo_tasks::registry::get_value_type_id(*#value_type_ident) + }); + + + #[doc(hidden)] + #[allow(non_snake_case)] + pub(crate) fn #register_value_type_ident( + global_name: &'static str, + f: impl FnOnce(&mut turbo_tasks::ValueType), + ) { + #value_type_init_ident.get_or_init(|| { + let mut value = #new_value_type; + f(&mut value); + value + }).register(global_name); + } + + unsafe impl #impl_generics turbo_tasks::VcValueType for #ty #where_clause { + type Read = #read; + type CellMode = #cell_mode; + + fn get_value_type_id() -> turbo_tasks::ValueTypeId { + *#value_type_id_ident + } + } + } +} diff --git a/turbopack/crates/turbo-tasks-macros/src/value_trait_macro.rs b/turbopack/crates/turbo-tasks-macros/src/value_trait_macro.rs new file mode 100644 index 0000000000000..5eabf273b7851 --- /dev/null +++ b/turbopack/crates/turbo-tasks-macros/src/value_trait_macro.rs @@ -0,0 +1,250 @@ +use proc_macro::TokenStream; +use proc_macro2::{Ident, TokenStream as TokenStream2}; +use quote::{quote, quote_spanned}; +use syn::{ + parse_macro_input, parse_quote, spanned::Spanned, ExprPath, ItemTrait, TraitItem, + TraitItemMethod, +}; +use turbo_tasks_macros_shared::{ + get_trait_default_impl_function_id_ident, get_trait_default_impl_function_ident, + get_trait_type_id_ident, get_trait_type_ident, ValueTraitArguments, +}; + +use crate::func::{DefinitionContext, NativeFn, TurboFn}; + +pub fn value_trait(args: TokenStream, input: TokenStream) -> TokenStream { + let ValueTraitArguments { debug, resolved } = parse_macro_input!(args as ValueTraitArguments); + + let item = parse_macro_input!(input as ItemTrait); + + let ItemTrait { + vis, + ident: trait_ident, + items: raw_items, + supertraits, + attrs, + trait_token, + colon_token: _, + unsafety, + auto_token, + generics, + brace_token: _, + } = &item; + + if unsafety.is_some() { + item.span() + .unwrap() + .error("unsafe traits are not supported in #[turbo_tasks::value_trait]") + .emit(); + } + + if auto_token.is_some() { + item.span() + .unwrap() + .error("auto traits are not supported in #[turbo_tasks::value_trait]") + .emit(); + } + + if !generics.params.is_empty() { + item.span() + .unwrap() + .error("generic traits are not supported in #[turbo_tasks::value_trait]") + .emit(); + } + + if generics.where_clause.is_some() { + item.span() + .unwrap() + .error("where clauses are not supported in #[turbo_tasks::value_trait]") + .emit(); + } + + let supertraits = supertraits.iter().collect::>(); + + let trait_type_ident = get_trait_type_ident(trait_ident); + let trait_type_id_ident = get_trait_type_id_ident(trait_ident); + let mut dynamic_trait_fns = Vec::new(); + let mut trait_methods: Vec = Vec::new(); + let mut native_functions = Vec::new(); + let mut items = Vec::with_capacity(raw_items.len()); + + for item in raw_items.iter() { + let TraitItem::Method(TraitItemMethod { + sig, + default, + attrs, + semi_token: _, + }) = item + else { + item.span() + .unwrap() + .error("only methods are allowed in a #[turbo_tasks::value_trait] trait") + .emit(); + continue; + }; + + let ident = &sig.ident; + + let Some(turbo_fn) = TurboFn::new(sig, DefinitionContext::ValueTrait) else { + return quote! { + // An error occurred while parsing the function signature. + } + .into(); + }; + + let turbo_signature = turbo_fn.signature(); + let arg_types = turbo_fn.input_types(); + let dynamic_block = turbo_fn.dynamic_block(&trait_type_id_ident); + dynamic_trait_fns.push(quote! { + #turbo_signature #dynamic_block + }); + + let default = if let Some(block) = default { + // TODO(alexkirsz) These should go into their own utilities. + let inline_function_ident: Ident = + Ident::new(&format!("{}_inline", ident), ident.span()); + let inline_extension_trait_ident = + Ident::new(&format!("{}_{}_inline", trait_ident, ident), ident.span()); + let inline_function_path: ExprPath = parse_quote! { as #inline_extension_trait_ident>::#inline_function_ident }; + let mut inline_signature = sig.clone(); + inline_signature.ident = inline_function_ident; + + let native_function = NativeFn::new( + &format!("{trait_ident}::{ident}"), + &inline_function_path, + turbo_fn.is_method(), + ); + + let native_function_ident = get_trait_default_impl_function_ident(trait_ident, ident); + let native_function_ty = native_function.ty(); + let native_function_def = native_function.definition(); + let native_function_id_ident = + get_trait_default_impl_function_id_ident(trait_ident, ident); + let native_function_id_ty = native_function.id_ty(); + let native_function_id_def = native_function.id_definition(&parse_quote! { + #native_function_ident + }); + + trait_methods.push(quote! { + trait_type.register_default_trait_method::<(#(#arg_types),*)>(stringify!(#ident).into(), *#native_function_id_ident); + }); + + native_functions.push(quote! { + #[doc(hidden)] + #[allow(non_camel_case_types)] + trait #inline_extension_trait_ident: std::marker::Send { + #[allow(declare_interior_mutable_const)] + const #native_function_ident: #native_function_ty; + #[allow(declare_interior_mutable_const)] + const #native_function_id_ident: #native_function_id_ty; + + #(#attrs)* + #inline_signature; + } + + #[doc(hidden)] + // Needs to be explicit 'static here, otherwise we can get a lifetime error + // in the inline signature. + impl #inline_extension_trait_ident for Box { + #[allow(declare_interior_mutable_const)] + const #native_function_ident: #native_function_ty = #native_function_def; + #[allow(declare_interior_mutable_const)] + const #native_function_id_ident: #native_function_id_ty = #native_function_id_def; + + #(#attrs)* + #inline_signature #block + } + + #[doc(hidden)] + pub(crate) static #native_function_ident: #native_function_ty = as #inline_extension_trait_ident>::#native_function_ident; + #[doc(hidden)] + pub(crate) static #native_function_id_ident: #native_function_id_ty = as #inline_extension_trait_ident>::#native_function_id_ident; + }); + + Some(turbo_fn.static_block(&native_function_id_ident)) + } else { + trait_methods.push(quote! { + trait_type.register_trait_method::<(#(#arg_types),*)>(stringify!(#ident).into()); + }); + None + }; + + items.push(TraitItem::Method(TraitItemMethod { + sig: turbo_fn.trait_signature(), + default, + attrs: attrs.clone(), + semi_token: Default::default(), + })); + } + + let value_debug_impl = if debug { + quote! { + unsafe impl turbo_tasks::Dynamic> for Box {} + unsafe impl turbo_tasks::Upcast> for Box {} + } + } else { + quote! {} + }; + + let mut extended_supertraits = Vec::new(); + if let Some(span) = resolved { + extended_supertraits.push(quote_spanned! { + span => turbo_tasks::ResolvedValue + }); + } + extended_supertraits.push(quote!(::std::marker::Send)); + extended_supertraits.push(quote!(::std::marker::Sync)); + if debug { + extended_supertraits.push(quote!(turbo_tasks::debug::ValueDebug)); + } + + let expanded = quote! { + #[must_use] + #(#attrs)* + #vis #trait_token #trait_ident: #(#supertraits +)* #(#extended_supertraits +)* + { + #(#items)* + } + + #(#native_functions)* + + #[doc(hidden)] + pub(crate) static #trait_type_ident: turbo_tasks::macro_helpers::Lazy = + turbo_tasks::macro_helpers::Lazy::new(|| { + let mut trait_type = turbo_tasks::TraitType::new(stringify!(#trait_ident).to_string());; + #(#trait_methods)* + trait_type + }); + #[doc(hidden)] + static #trait_type_id_ident: turbo_tasks::macro_helpers::Lazy = + turbo_tasks::macro_helpers::Lazy::new(|| { + turbo_tasks::registry::get_trait_type_id(&#trait_type_ident) + }); + + impl turbo_tasks::VcValueTrait for Box { + fn get_trait_type_id() -> turbo_tasks::TraitTypeId { + *#trait_type_id_ident + } + } + + unsafe impl turbo_tasks::Dynamic> for Box {} + // TODO(alexkirsz) It would be great to have the following identity. However, I run into an ICE when I attempt this, + // so tabling it for now. + unsafe impl turbo_tasks::Upcast> for Box {} + + impl #trait_ident for T + where + T: turbo_tasks::Dynamic> + #(#supertraits +)* #(#extended_supertraits +)*, + { + #(#dynamic_trait_fns)* + } + + #( + unsafe impl turbo_tasks::Dynamic> for Box {} + unsafe impl turbo_tasks::Upcast> for Box {} + )* + + #value_debug_impl + }; + expanded.into() +} diff --git a/turbopack/crates/turbo-tasks-malloc/Cargo.toml b/turbopack/crates/turbo-tasks-malloc/Cargo.toml new file mode 100644 index 0000000000000..78b29a88759b1 --- /dev/null +++ b/turbopack/crates/turbo-tasks-malloc/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "turbo-tasks-malloc" +version = "0.1.0" +description = "A wrapper around mimalloc or the system allocator that tracks allocations" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[target.'cfg(not(any(target_os = "linux", target_family = "wasm", target_env = "musl")))'.dependencies] +mimalloc = { version = "0.1.42", features = [], optional = true } + +[target.'cfg(all(target_os = "linux", not(any(target_family = "wasm", target_env = "musl"))))'.dependencies] +mimalloc = { version = "0.1.42", features = [ + "local_dynamic_tls", +], optional = true } + +[features] +custom_allocator = ["dep:mimalloc"] +default = ["custom_allocator"] diff --git a/turbopack/crates/turbo-tasks-malloc/src/counter.rs b/turbopack/crates/turbo-tasks-malloc/src/counter.rs new file mode 100644 index 0000000000000..b3cc5b07219f9 --- /dev/null +++ b/turbopack/crates/turbo-tasks-malloc/src/counter.rs @@ -0,0 +1,166 @@ +use std::{ + cell::UnsafeCell, + ptr::NonNull, + sync::atomic::{AtomicUsize, Ordering}, +}; + +use crate::AllocationCounters; + +static ALLOCATED: AtomicUsize = AtomicUsize::new(0); +const KB: usize = 1024; +/// When global counter is updates we will keep a thread-local buffer of this +/// size. +const TARGET_BUFFER: usize = 100 * KB; +/// When the thread-local buffer would exceed this size, we will update the +/// global counter. +const MAX_BUFFER: usize = 200 * KB; + +#[derive(Default)] +struct ThreadLocalCounter { + /// Thread-local buffer of allocated bytes that have been added to the + /// global counter desprite not being allocated yet. It is unsigned so that + /// means the global counter is always equal or greater than the real + /// value. + buffer: usize, + allocation_counters: AllocationCounters, +} + +impl ThreadLocalCounter { + fn add(&mut self, size: usize) { + self.allocation_counters.allocations += size; + self.allocation_counters.allocation_count += 1; + if self.buffer >= size { + self.buffer -= size; + } else { + let offset = size - self.buffer + TARGET_BUFFER; + self.buffer = TARGET_BUFFER; + ALLOCATED.fetch_add(offset, Ordering::Relaxed); + } + } + + fn remove(&mut self, size: usize) { + self.allocation_counters.deallocations += size; + self.allocation_counters.deallocation_count += 1; + self.buffer += size; + if self.buffer > MAX_BUFFER { + let offset = self.buffer - TARGET_BUFFER; + self.buffer = TARGET_BUFFER; + ALLOCATED.fetch_sub(offset, Ordering::Relaxed); + } + } + + fn update(&mut self, old_size: usize, new_size: usize) { + self.allocation_counters.deallocations += old_size; + self.allocation_counters.deallocation_count += 1; + self.allocation_counters.allocations += new_size; + self.allocation_counters.allocation_count += 1; + match old_size.cmp(&new_size) { + std::cmp::Ordering::Equal => {} + std::cmp::Ordering::Less => { + let size = new_size - old_size; + if self.buffer >= size { + self.buffer -= size; + } else { + let offset = size - self.buffer + TARGET_BUFFER; + self.buffer = TARGET_BUFFER; + ALLOCATED.fetch_add(offset, Ordering::Relaxed); + } + } + std::cmp::Ordering::Greater => { + let size = old_size - new_size; + self.buffer += size; + if self.buffer > MAX_BUFFER { + let offset = self.buffer - TARGET_BUFFER; + self.buffer = TARGET_BUFFER; + ALLOCATED.fetch_sub(offset, Ordering::Relaxed); + } + } + } + } + + fn unload(&mut self) { + if self.buffer > 0 { + ALLOCATED.fetch_sub(self.buffer, Ordering::Relaxed); + self.buffer = 0; + } + self.allocation_counters = AllocationCounters::default(); + } +} + +thread_local! { + static LOCAL_COUNTER: UnsafeCell = UnsafeCell::new(ThreadLocalCounter::default()); +} + +pub fn get() -> usize { + ALLOCATED.load(Ordering::Relaxed) +} + +pub fn allocation_counters() -> AllocationCounters { + with_local_counter(|local| local.allocation_counters.clone()) +} + +pub fn reset_allocation_counters(start: AllocationCounters) { + with_local_counter(|local| local.allocation_counters = start); +} + +fn with_local_counter(f: impl FnOnce(&mut ThreadLocalCounter) -> T) -> T { + LOCAL_COUNTER.with(|local| { + let ptr = local.get(); + // SAFETY: This is a thread local. + let mut local = unsafe { NonNull::new_unchecked(ptr) }; + f(unsafe { local.as_mut() }) + }) +} + +/// Adds some `size` to the global counter in a thread-local buffered way. +pub fn add(size: usize) { + with_local_counter(|local| local.add(size)); +} + +/// Removes some `size` to the global counter in a thread-local buffered way. +pub fn remove(size: usize) { + with_local_counter(|local| local.remove(size)); +} + +/// Adds some `size` to the global counter in a thread-local buffered way. +pub fn update(old_size: usize, new_size: usize) { + with_local_counter(|local| local.update(old_size, new_size)); +} + +/// Flushes the thread-local buffer to the global counter. This should be called +/// e. g. when a thread is stopped or goes to sleep for a long time. +pub fn flush() { + with_local_counter(|local| local.unload()); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn counting() { + let mut expected = get(); + add(100); + // Initial change should fill up the buffer + expected += TARGET_BUFFER + 100; + assert_eq!(get(), expected); + add(100); + // Further changes should use the buffer + assert_eq!(get(), expected); + add(MAX_BUFFER); + // Large changes should require more buffer space + expected += 100 + MAX_BUFFER; + assert_eq!(get(), expected); + remove(100); + // Small changes should use the buffer + // buffer size is now TARGET_BUFFER + 100 + assert_eq!(get(), expected); + remove(MAX_BUFFER); + // The buffer should not grow over MAX_BUFFER + // buffer size would be TARGET_BUFFER + 100 + MAX_BUFFER + // but it will be reduce to TARGET_BUFFER + // this means the global counter should reduce by 100 + MAX_BUFFER + expected -= MAX_BUFFER + 100; + assert_eq!(get(), expected); + } +} diff --git a/turbopack/crates/turbo-tasks-malloc/src/lib.rs b/turbopack/crates/turbo-tasks-malloc/src/lib.rs new file mode 100644 index 0000000000000..3eb6acf24e046 --- /dev/null +++ b/turbopack/crates/turbo-tasks-malloc/src/lib.rs @@ -0,0 +1,115 @@ +mod counter; + +use std::{ + alloc::{GlobalAlloc, Layout}, + marker::PhantomData, +}; + +use self::counter::{add, flush, get, remove, update}; + +#[derive(Default, Clone, Debug)] +pub struct AllocationInfo { + pub allocations: usize, + pub deallocations: usize, + pub allocation_count: usize, + pub deallocation_count: usize, +} + +impl AllocationInfo { + pub fn is_empty(&self) -> bool { + self.allocations == 0 + && self.deallocations == 0 + && self.allocation_count == 0 + && self.deallocation_count == 0 + } +} + +#[derive(Default, Clone, Debug)] +pub struct AllocationCounters { + pub allocations: usize, + pub deallocations: usize, + pub allocation_count: usize, + pub deallocation_count: usize, + _not_send: PhantomData<*mut ()>, +} + +impl AllocationCounters { + pub fn until_now(&self) -> AllocationInfo { + let new = TurboMalloc::allocation_counters(); + AllocationInfo { + allocations: new.allocations - self.allocations, + deallocations: new.deallocations - self.deallocations, + allocation_count: new.allocation_count - self.allocation_count, + deallocation_count: new.deallocation_count - self.deallocation_count, + } + } +} + +/// Turbo's preferred global allocator. This is a new type instead of a type +/// alias because you can't use type aliases to instantiate unit types (E0423). +pub struct TurboMalloc; + +impl TurboMalloc { + pub fn memory_usage() -> usize { + get() + } + + pub fn thread_stop() { + flush(); + } + + pub fn allocation_counters() -> AllocationCounters { + self::counter::allocation_counters() + } + + pub fn reset_allocation_counters(start: AllocationCounters) { + self::counter::reset_allocation_counters(start); + } +} + +/// Get the allocator for this platform that we should wrap with TurboMalloc. +#[inline] +fn base_alloc() -> &'static impl GlobalAlloc { + #[cfg(all( + feature = "custom_allocator", + not(any(target_family = "wasm", target_env = "musl")) + ))] + return &mimalloc::MiMalloc; + #[cfg(any( + not(feature = "custom_allocator"), + any(target_family = "wasm", target_env = "musl") + ))] + return &std::alloc::System; +} + +unsafe impl GlobalAlloc for TurboMalloc { + unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + let ret = base_alloc().alloc(layout); + if !ret.is_null() { + add(layout.size()); + } + ret + } + + unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + base_alloc().dealloc(ptr, layout); + remove(layout.size()); + } + + unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + let ret = base_alloc().alloc_zeroed(layout); + if !ret.is_null() { + add(layout.size()); + } + ret + } + + unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + let ret = base_alloc().realloc(ptr, layout, new_size); + if !ret.is_null() { + let old_size = layout.size(); + update(old_size, new_size); + } + ret + } +} diff --git a/turbopack/crates/turbo-tasks-memory/Cargo.toml b/turbopack/crates/turbo-tasks-memory/Cargo.toml new file mode 100644 index 0000000000000..37be735ce7de6 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/Cargo.toml @@ -0,0 +1,67 @@ +[package] +name = "turbo-tasks-memory" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +auto-hash-map = { workspace = true } +concurrent-queue = { workspace = true } +dashmap = { workspace = true } +either = { workspace = true } +indexmap = { workspace = true } +num_cpus = "1.13.1" +once_cell = { workspace = true } +parking_lot = { workspace = true } +priority-queue = "1.3.0" +ref-cast = "1.0.20" +rustc-hash = { workspace = true } +serde = { workspace = true } +smallvec = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } +turbo-prehash = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-hash = { workspace = true } +turbo-tasks-malloc = { workspace = true, default-features = false } + +[dev-dependencies] +criterion = { workspace = true, features = ["async_tokio"] } +loom = "0.7.2" +rand = { workspace = true, features = ["small_rng"] } +regex = { workspace = true } +rstest = { workspace = true } +serde_json = { workspace = true } +tokio = { workspace = true, features = ["full"] } +turbo-tasks-testing = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } + +[features] +track_unfinished = [] +track_wait_dependencies = [] +unsafe_once_map = [] +log_running_tasks = [] +log_scheduled_tasks = [] +log_activate_tasks = [] +log_connect_tasks = [] +report_expensive = [] +print_scope_updates = [] +print_task_invalidation = [] +inline_add_to_scope = [] +inline_remove_from_scope = [] +default = [] + +[[bench]] +name = "mod" +harness = false diff --git a/turbopack/crates/turbo-tasks-memory/benches/mod.rs b/turbopack/crates/turbo-tasks-memory/benches/mod.rs new file mode 100644 index 0000000000000..6bbaf50152aa7 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/benches/mod.rs @@ -0,0 +1,18 @@ +#![feature(arbitrary_self_types)] + +use criterion::{criterion_group, criterion_main, Criterion}; + +pub(crate) mod scope_stress; +pub(crate) mod stress; + +criterion_group!( + name = turbo_tasks_memory_stress; + config = Criterion::default(); + targets = stress::fibonacci, scope_stress::scope_stress +); +criterion_main!(turbo_tasks_memory_stress); + +pub fn register() { + turbo_tasks::register(); + include!(concat!(env!("OUT_DIR"), "/register_benches.rs")); +} diff --git a/turbopack/crates/turbo-tasks-memory/benches/scope_stress.rs b/turbopack/crates/turbo-tasks-memory/benches/scope_stress.rs new file mode 100644 index 0000000000000..3c8d47338bff4 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/benches/scope_stress.rs @@ -0,0 +1,78 @@ +use anyhow::Result; +use criterion::{BenchmarkId, Criterion}; +use turbo_tasks::{Completion, TryJoinIterExt, TurboTasks, Vc}; +use turbo_tasks_memory::MemoryBackend; + +use super::register; + +pub fn scope_stress(c: &mut Criterion) { + if matches!( + std::env::var("TURBOPACK_BENCH_STRESS").ok().as_deref(), + None | Some("") | Some("no") | Some("false") + ) { + return; + } + + register(); + + let mut group = c.benchmark_group("turbo_tasks_memory_scope_stress"); + group.sample_size(20); + + for size in [5, 10, 15, 20, 25, 30, 100, 200, 300] { + group.throughput(criterion::Throughput::Elements( + /* tasks for fib from 0 to size - 1 = */ + (size as u64) * (size as u64) + + /* root tasks = */ + (2 * size as u64) + - 1, + )); + group.bench_with_input( + BenchmarkId::new("rectangle", format_args!("{size} x {size}")), + &size, + |b, size| { + let rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + let size = *size; + + b.to_async(rt).iter_with_large_drop(move || { + let tt = TurboTasks::new(MemoryBackend::default()); + async move { + (0..size) + .map(|a| (a, size - 1)) + .chain((0..size - 1).map(|b| (size - 1, b))) + .map(|(a, b)| { + let tt = &tt; + async move { + let task = tt.spawn_once_task(async move { + rectangle(a, b).strongly_consistent().await?; + Ok::, _>(Default::default()) + }); + tt.wait_task_completion(task, false).await + } + }) + .try_join() + .await + .unwrap(); + + tt + } + }) + }, + ); + } +} + +/// This fills a rectagle from (0, 0) to (a, b) by +/// first filling (0, 0) to (a - 1, b) and then (0, 0) to (a, b - 1) recursively +#[turbo_tasks::function] +async fn rectangle(a: u32, b: u32) -> Result> { + if a > 0 { + rectangle(a - 1, b).await?; + } + if b > 0 { + rectangle(a, b - 1).await?; + } + Ok(Completion::new()) +} diff --git a/turbopack/crates/turbo-tasks-memory/benches/stress.rs b/turbopack/crates/turbo-tasks-memory/benches/stress.rs new file mode 100644 index 0000000000000..f0482ab83e0d7 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/benches/stress.rs @@ -0,0 +1,78 @@ +use anyhow::Result; +use criterion::{BenchmarkId, Criterion}; +use turbo_tasks::{TryJoinIterExt, TurboTasks, Vc}; +use turbo_tasks_memory::MemoryBackend; + +use super::register; + +pub fn fibonacci(c: &mut Criterion) { + if matches!( + std::env::var("TURBOPACK_BENCH_STRESS").ok().as_deref(), + None | Some("") | Some("no") | Some("false") + ) { + return; + } + + register(); + + let mut group = c.benchmark_group("turbo_tasks_memory_stress"); + group.sample_size(20); + + for size in [100, 200, 500, 1000, 1414] { + group.throughput(criterion::Throughput::Elements( + /* tasks for fib from 0 to size - 1 = */ + size as u64 * (size as u64 + 1) / 2 + + /* root task = */ + 1, + )); + group.bench_with_input(BenchmarkId::new("fibonacci", size), &size, |b, size| { + let rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + let size = *size; + + b.to_async(rt).iter_with_large_drop(move || { + let tt = TurboTasks::new(MemoryBackend::default()); + async move { + let task = tt.spawn_once_task(async move { + // Number of tasks: + // 1 root task + // size >= 1 => + fib(0) = 1 + // size >= 2 => + fib(1) = 2 + (0..size).map(|i| fib(i, i)).try_join().await?; + Ok::, _>(Default::default()) + }); + tt.wait_task_completion(task, false).await.unwrap(); + tt + } + }) + }); + } +} + +#[turbo_tasks::value(transparent)] +struct FibResult(u64); + +// Number of tasks: +// fib(0) = 1 tasks +// fib(1) = 2 tasks +// fib(n) = n + 1 tasks + +/// Computes a fibonacci number in a recursive matter. Due to turbo-tasks this +/// will result in a lot of cached tasks, so its performance is only O(n) +/// (compared to non-turbo-tasks O(1.6^N)). +/// This function also has a `key` parameter to allow forcing it to separate +/// cache entries by using different keys. +#[turbo_tasks::function] +async fn fib(i: u32, key: u32) -> Result> { + Ok(match i { + 0 => FibResult(1).cell(), + 1 => fib(0, key), + _ => { + let a = fib(i - 1, key); + let b = fib(i - 2, key); + FibResult(a.await?.wrapping_add(*b.await?)).cell() + } + }) +} diff --git a/turbopack/crates/turbo-tasks-memory/build.rs b/turbopack/crates/turbo-tasks-memory/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/aggregation_data.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/aggregation_data.rs new file mode 100644 index 0000000000000..fd95e982094a3 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/aggregation_data.rs @@ -0,0 +1,83 @@ +use std::ops::{Deref, DerefMut}; + +use super::{ + increase_aggregation_number_internal, AggregationContext, AggregationNode, AggregationNodeGuard, +}; +use crate::aggregation::{balance_queue::BalanceQueue, increase::IncreaseReason}; + +/// Gives an reference to the aggregated data for a given item. This will +/// convert the item to a fully aggregated node. +pub fn aggregation_data<'l, C>( + ctx: &'l C, + node_id: &C::NodeRef, +) -> AggregationDataGuard> +where + C: AggregationContext + 'l, +{ + let guard = ctx.node(node_id); + if guard.aggregation_number() == u32::MAX { + AggregationDataGuard { guard } + } else { + let mut balance_queue = BalanceQueue::new(); + increase_aggregation_number_internal( + ctx, + &mut balance_queue, + guard, + node_id, + u32::MAX, + u32::MAX, + IncreaseReason::AggregationData, + ); + balance_queue.process(ctx); + let guard = ctx.node(node_id); + debug_assert!(guard.aggregation_number() == u32::MAX); + AggregationDataGuard { guard } + } +} + +/// Converted the given node to a fully aggregated node. To make the next call +/// to `aggregation_data` instant. +pub fn prepare_aggregation_data(ctx: &C, node_id: &C::NodeRef) { + let mut balance_queue = BalanceQueue::new(); + increase_aggregation_number_internal( + ctx, + &mut balance_queue, + ctx.node(node_id), + node_id, + u32::MAX, + u32::MAX, + IncreaseReason::AggregationData, + ); + balance_queue.process(ctx); +} + +/// A reference to the aggregated data of a node. This holds a lock to the node. +pub struct AggregationDataGuard { + guard: G, +} + +impl AggregationDataGuard { + pub fn into_inner(self) -> G { + self.guard + } +} + +impl Deref for AggregationDataGuard { + type Target = G::Data; + + fn deref(&self) -> &Self::Target { + match &*self.guard { + AggregationNode::Leaf { .. } => unreachable!(), + AggregationNode::Aggegating(aggregating) => &aggregating.data, + } + } +} + +impl DerefMut for AggregationDataGuard { + fn deref_mut(&mut self) -> &mut Self::Target { + match &mut *self.guard { + AggregationNode::Leaf { .. } => unreachable!(), + AggregationNode::Aggegating(aggregating) => &mut aggregating.data, + } + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/balance_edge.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/balance_edge.rs new file mode 100644 index 0000000000000..ee968cd3228d6 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/balance_edge.rs @@ -0,0 +1,208 @@ +use std::cmp::Ordering; + +use super::{ + balance_queue::BalanceQueue, + followers::{ + add_follower_count, remove_follower_count, remove_positive_follower_count, + RemovePositveFollowerCountResult, + }, + in_progress::is_in_progress, + increase::IncreaseReason, + increase_aggregation_number_internal, + uppers::{ + add_upper_count, remove_positive_upper_count, remove_upper_count, + RemovePositiveUpperCountResult, + }, + AggregationContext, AggregationNode, +}; + +// Migrated followers to uppers or uppers to followers depending on the +// aggregation numbers of the nodes involved in the edge. Might increase targets +// aggregation number if they are equal. +pub(super) fn balance_edge( + ctx: &C, + balance_queue: &mut BalanceQueue, + upper_id: &C::NodeRef, + mut upper_aggregation_number: u32, + target_id: &C::NodeRef, + mut target_aggregation_number: u32, +) -> (u32, u32) { + // too many uppers on target + let mut extra_uppers = 0; + // too many followers on upper + let mut extra_followers = 0; + // The last info about uppers + let mut uppers_count: Option = None; + // The last info about followers + let mut followers_count = None; + + loop { + let root = upper_aggregation_number == u32::MAX || target_aggregation_number == u32::MAX; + let order = if root { + Ordering::Greater + } else { + upper_aggregation_number.cmp(&target_aggregation_number) + }; + match order { + Ordering::Equal => { + // we probably want to increase the aggregation number of target + let upper = ctx.node(upper_id); + upper_aggregation_number = upper.aggregation_number(); + drop(upper); + if upper_aggregation_number != u32::MAX + && upper_aggregation_number == target_aggregation_number + { + let target = ctx.node(target_id); + target_aggregation_number = target.aggregation_number(); + if upper_aggregation_number == target_aggregation_number { + // increase target aggregation number + increase_aggregation_number_internal( + ctx, + balance_queue, + target, + target_id, + target_aggregation_number + 1, + target_aggregation_number + 1, + IncreaseReason::EqualAggregationNumberOnBalance, + ); + } + } + } + Ordering::Less => { + // target should probably be a follower of upper + if uppers_count.map_or(false, |count| count <= 0) { + // We already removed all uppers, maybe too many + break; + } else if extra_followers == 0 { + let upper = ctx.node(upper_id); + upper_aggregation_number = upper.aggregation_number(); + if upper_aggregation_number < target_aggregation_number { + // target should be a follower of upper + // add some extra followers + let count = uppers_count.unwrap_or(1) as usize; + extra_followers += count; + followers_count = Some(add_follower_count( + ctx, + balance_queue, + upper, + upper_id, + target_id, + count, + true, + )); + } + } else { + // we already have extra followers, remove some uppers to balance + let count = extra_followers + extra_uppers; + let target = ctx.node(target_id); + if is_in_progress(ctx, upper_id) { + drop(target); + let mut upper = ctx.node(upper_id); + if is_in_progress(ctx, upper_id) { + let AggregationNode::Aggegating(aggregating) = &mut *upper else { + unreachable!(); + }; + aggregating.enqueued_balancing.push(( + upper_id.clone(), + upper_aggregation_number, + target_id.clone(), + target_aggregation_number, + )); + drop(upper); + // Somebody else will balance this edge + return (upper_aggregation_number, target_aggregation_number); + } + } else { + let RemovePositiveUpperCountResult { + removed_count, + remaining_count, + } = remove_positive_upper_count( + ctx, + balance_queue, + target, + upper_id, + count, + ); + decrease_numbers(removed_count, &mut extra_uppers, &mut extra_followers); + uppers_count = Some(remaining_count); + } + } + } + Ordering::Greater => { + // target should probably be an inner node of upper + if followers_count.map_or(false, |count| count <= 0) { + // We already removed all followers, maybe too many + break; + } else if extra_uppers == 0 { + let target = ctx.node(target_id); + target_aggregation_number = target.aggregation_number(); + if root || target_aggregation_number < upper_aggregation_number { + // target should be a inner node of upper + if is_in_progress(ctx, upper_id) { + drop(target); + let mut upper = ctx.node(upper_id); + if is_in_progress(ctx, upper_id) { + let AggregationNode::Aggegating(aggregating) = &mut *upper else { + unreachable!(); + }; + aggregating.enqueued_balancing.push(( + upper_id.clone(), + upper_aggregation_number, + target_id.clone(), + target_aggregation_number, + )); + drop(upper); + // Somebody else will balance this edge + return (upper_aggregation_number, target_aggregation_number); + } + } else { + // add some extra uppers + let count = followers_count.unwrap_or(1) as usize; + extra_uppers += count; + uppers_count = Some( + add_upper_count( + ctx, + balance_queue, + target, + target_id, + upper_id, + count, + true, + ) + .new_count, + ); + } + } + } else { + // we already have extra uppers, try to remove some followers to balance + let count = extra_followers + extra_uppers; + let upper = ctx.node(upper_id); + let RemovePositveFollowerCountResult { + removed_count, + remaining_count, + } = remove_positive_follower_count(ctx, balance_queue, upper, target_id, count); + decrease_numbers(removed_count, &mut extra_followers, &mut extra_uppers); + followers_count = Some(remaining_count); + } + } + } + } + if extra_followers > 0 { + let upper = ctx.node(upper_id); + remove_follower_count(ctx, balance_queue, upper, target_id, extra_followers); + } + if extra_uppers > 0 { + let target = ctx.node(target_id); + remove_upper_count(ctx, balance_queue, target, upper_id, extra_uppers); + } + (upper_aggregation_number, target_aggregation_number) +} + +fn decrease_numbers(amount: usize, a: &mut usize, b: &mut usize) { + if *a >= amount { + *a -= amount; + } else { + *b -= amount - *a; + *a = 0; + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/balance_queue.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/balance_queue.rs new file mode 100644 index 0000000000000..1f11d4dd9a98d --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/balance_queue.rs @@ -0,0 +1,90 @@ +use std::{cmp::max, collections::HashMap, hash::Hash, mem::take}; + +use indexmap::IndexSet; + +use super::{balance_edge, AggregationContext}; + +/// Enqueued edges that need to be balanced. Deduplicates edges and keeps track +/// of aggregation numbers read during balancing. +pub struct BalanceQueue { + queue: IndexSet<(I, I)>, + aggregation_numbers: HashMap, +} + +impl BalanceQueue { + pub fn new() -> Self { + Self { + queue: IndexSet::default(), + aggregation_numbers: HashMap::default(), + } + } + + fn add_number(&mut self, id: I, number: u32) { + self.aggregation_numbers + .entry(id) + .and_modify(|n| *n = max(*n, number)) + .or_insert(number); + } + + /// Add an edge to the queue. The edge will be balanced during the next + /// call. + pub fn balance( + &mut self, + upper_id: I, + upper_aggregation_number: u32, + target_id: I, + target_aggregation_number: u32, + ) { + debug_assert!(upper_id != target_id); + self.add_number(upper_id.clone(), upper_aggregation_number); + self.add_number(target_id.clone(), target_aggregation_number); + self.queue.insert((upper_id.clone(), target_id.clone())); + } + + /// Add multiple edges to the queue. The edges will be balanced during the + /// next call. + pub fn balance_all(&mut self, edges: Vec<(I, u32, I, u32)>) { + for (upper_id, upper_aggregation_number, target_id, target_aggregation_number) in edges { + self.balance( + upper_id, + upper_aggregation_number, + target_id, + target_aggregation_number, + ); + } + } + + /// Process the queue and balance all enqueued edges. + pub fn process>(mut self, ctx: &C) { + while !self.queue.is_empty() { + let queue = take(&mut self.queue); + for (upper_id, target_id) in queue { + let upper_aggregation_number = self + .aggregation_numbers + .get(&upper_id) + .copied() + .unwrap_or_default(); + let target_aggregation_number = self + .aggregation_numbers + .get(&target_id) + .copied() + .unwrap_or_default(); + + let (u, t) = balance_edge( + ctx, + &mut self, + &upper_id, + upper_aggregation_number, + &target_id, + target_aggregation_number, + ); + if u != upper_aggregation_number { + self.add_number(upper_id, u); + } + if t != target_aggregation_number { + self.add_number(target_id, t); + } + } + } + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/change.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/change.rs new file mode 100644 index 0000000000000..a0ff1eb605692 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/change.rs @@ -0,0 +1,108 @@ +use std::hash::Hash; + +use super::{AggegatingNode, AggregationContext, AggregationNode, PreparedOperation, StackVec}; + +impl AggregationNode { + /// Prepares to apply a change to a node. Changes will be propagated to all + /// upper nodes. + #[must_use] + pub fn apply_change>( + &mut self, + ctx: &C, + change: C::DataChange, + ) -> Option> { + match self { + AggregationNode::Leaf { uppers, .. } => (!uppers.is_empty()).then(|| PreparedChange { + uppers: uppers.iter().cloned().collect::>(), + change, + }), + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { data, uppers, .. } = &mut **aggegating; + let change = ctx.apply_change(data, &change); + if uppers.is_empty() { + None + } else { + change.map(|change| PreparedChange { + uppers: uppers.iter().cloned().collect::>(), + change, + }) + } + } + } + } + + /// Prepares to apply a change to a node. Changes will be propagated to all + /// upper nodes. + #[must_use] + pub fn apply_change_ref<'l, C: AggregationContext>( + &mut self, + ctx: &C, + change: &'l C::DataChange, + ) -> Option> { + match self { + AggregationNode::Leaf { uppers, .. } => { + (!uppers.is_empty()).then(|| PreparedChangeRef::Borrowed { + uppers: uppers.iter().cloned().collect::>(), + change, + }) + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { data, uppers, .. } = &mut **aggegating; + let change = ctx.apply_change(data, change); + if uppers.is_empty() { + None + } else { + change.map(|change| PreparedChangeRef::Owned { + uppers: uppers.iter().cloned().collect::>(), + change, + }) + } + } + } + } +} + +/// A prepared `apply_change` operation. +pub struct PreparedChange { + uppers: StackVec, + change: C::DataChange, +} + +impl PreparedOperation for PreparedChange { + type Result = (); + fn apply(self, ctx: &C) { + let prepared = self + .uppers + .into_iter() + .filter_map(|upper_id| ctx.node(&upper_id).apply_change_ref(ctx, &self.change)) + .collect::>(); + prepared.apply(ctx); + } +} + +/// A prepared `apply_change_ref` operation. +pub enum PreparedChangeRef<'l, C: AggregationContext> { + Borrowed { + uppers: StackVec, + change: &'l C::DataChange, + }, + Owned { + uppers: StackVec, + change: C::DataChange, + }, +} + +impl<'l, C: AggregationContext> PreparedOperation for PreparedChangeRef<'l, C> { + type Result = (); + fn apply(self, ctx: &C) { + let (uppers, change) = match self { + PreparedChangeRef::Borrowed { uppers, change } => (uppers, change), + PreparedChangeRef::Owned { uppers, ref change } => (uppers, change), + }; + let prepared = uppers + .into_iter() + .filter_map(|upper_id| ctx.node(&upper_id).apply_change_ref(ctx, change)) + .collect::>(); + prepared.apply(ctx); + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/followers.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/followers.rs new file mode 100644 index 0000000000000..e69d374f3a63b --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/followers.rs @@ -0,0 +1,201 @@ +use super::{ + balance_queue::BalanceQueue, + in_progress::start_in_progress_all, + notify_lost_follower, notify_new_follower, + optimize::{optimize_aggregation_number_for_followers, MAX_FOLLOWERS}, + AggregationContext, AggregationNode, StackVec, +}; +use crate::count_hash_set::RemovePositiveCountResult; + +/// Add a follower to a node. Followers will be propagated to the uppers of the +/// node. +pub fn add_follower( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + follower_id: &C::NodeRef, + already_optimizing_for_node: bool, +) -> usize { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + if aggregating.followers.add_clonable(follower_id) { + on_added( + ctx, + balance_queue, + node, + node_id, + follower_id, + already_optimizing_for_node, + ) + } else { + 0 + } +} + +/// Handle the addition of a follower to a node. This function is called after +/// the follower has been added to the node. +pub fn on_added( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + follower_id: &C::NodeRef, + already_optimizing_for_node: bool, +) -> usize { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + let followers_len = aggregating.followers.len(); + let optimize = (!already_optimizing_for_node + && followers_len >= MAX_FOLLOWERS + && followers_len.count_ones() == 1) + .then(|| { + aggregating + .followers + .iter() + .cloned() + .collect::>() + }); + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + drop(node); + + let mut optimizing = false; + + if let Some(followers) = optimize { + optimizing = optimize_aggregation_number_for_followers( + ctx, + balance_queue, + node_id, + followers, + false, + ); + } + + let mut affected_nodes = uppers.len(); + for upper_id in uppers { + affected_nodes += notify_new_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + follower_id, + optimizing, + ); + } + affected_nodes +} + +/// Add a follower to a node with a count. Followers will be propagated to the +/// uppers of the node. +pub fn add_follower_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + follower_id: &C::NodeRef, + follower_count: usize, + already_optimizing_for_node: bool, +) -> isize { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + if aggregating + .followers + .add_clonable_count(follower_id, follower_count) + { + let count = aggregating.followers.get_count(follower_id); + on_added( + ctx, + balance_queue, + node, + node_id, + follower_id, + already_optimizing_for_node, + ); + count + } else { + aggregating.followers.get_count(follower_id) + } +} + +/// Remove a follower from a node. Followers will be propagated to the uppers of +/// the node. +pub fn remove_follower_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + follower_id: &C::NodeRef, + follower_count: usize, +) { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + if aggregating + .followers + .remove_clonable_count(follower_id, follower_count) + { + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + drop(node); + for upper_id in uppers { + notify_lost_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + follower_id, + ); + } + } +} + +pub struct RemovePositveFollowerCountResult { + /// The amount of followers that have been removed. + pub removed_count: usize, + /// The amount of followers that are remaining. Might be negative. + pub remaining_count: isize, +} + +/// Remove a positive count of a follower from a node. Negative counts will not +/// be increased. The function returns how much of the count has been removed +/// and whats remaining. Followers will be propagated to the uppers of the node. +pub fn remove_positive_follower_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + follower_id: &C::NodeRef, + follower_count: usize, +) -> RemovePositveFollowerCountResult { + let AggregationNode::Aggegating(aggregating) = &mut *node else { + unreachable!(); + }; + let RemovePositiveCountResult { + removed, + removed_count, + count, + } = aggregating + .followers + .remove_positive_clonable_count(follower_id, follower_count); + + if removed { + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + drop(node); + for upper_id in uppers { + notify_lost_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + follower_id, + ); + } + } + RemovePositveFollowerCountResult { + removed_count, + remaining_count: count, + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/in_progress.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/in_progress.rs new file mode 100644 index 0000000000000..1dbb080630c3e --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/in_progress.rs @@ -0,0 +1,75 @@ +use std::{hash::Hash, mem::take}; + +use super::{balance_queue::BalanceQueue, AggregationContext, AggregationNode, StackVec}; + +impl AggregationNode { + /// Finishes an in progress operation. This might enqueue balancing + /// operations when they weren't possible due to the in progress operation. + pub(super) fn finish_in_progress>( + &mut self, + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &I, + ) { + let value = ctx + .atomic_in_progress_counter(node_id) + .fetch_sub(1, std::sync::atomic::Ordering::AcqRel); + debug_assert!(value > 0); + if value == 1 { + if let AggregationNode::Aggegating(aggegating) = &mut *self { + balance_queue.balance_all(take(&mut aggegating.enqueued_balancing)) + } + } + } +} + +/// Finishes an in progress operation. This might enqueue balancing +/// operations when they weren't possible due to the in progress operation. +/// This version doesn't require a node guard. +pub fn finish_in_progress_without_node( + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &C::NodeRef, +) { + let value = ctx + .atomic_in_progress_counter(node_id) + .fetch_sub(1, std::sync::atomic::Ordering::AcqRel); + debug_assert!(value > 0); + if value == 1 { + let mut node = ctx.node(node_id); + if let AggregationNode::Aggegating(aggegating) = &mut *node { + balance_queue.balance_all(take(&mut aggegating.enqueued_balancing)) + } + } +} + +/// Starts an in progress operation for all nodes in the list. +pub fn start_in_progress_all(ctx: &C, node_ids: &StackVec) { + for node_id in node_ids { + start_in_progress(ctx, node_id); + } +} + +/// Starts an in progress operation for a node. +pub fn start_in_progress(ctx: &C, node_id: &C::NodeRef) { + start_in_progress_count(ctx, node_id, 1); +} + +/// Starts multiple in progress operations for a node. +pub fn start_in_progress_count(ctx: &C, node_id: &C::NodeRef, count: u32) { + if count == 0 { + return; + } + ctx.atomic_in_progress_counter(node_id) + .fetch_add(count, std::sync::atomic::Ordering::Release); +} + +/// Checks if there is an in progress operation for a node. +/// It doesn't require a lock, but should run under a lock of the node or a +/// follower/inner node. +pub fn is_in_progress(ctx: &C, node_id: &C::NodeRef) -> bool { + let counter = ctx + .atomic_in_progress_counter(node_id) + .load(std::sync::atomic::Ordering::Acquire); + counter > 0 +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/increase.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/increase.rs new file mode 100644 index 0000000000000..37ad79d2f45a2 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/increase.rs @@ -0,0 +1,346 @@ +use std::{hash::Hash, mem::take}; + +use super::{ + balance_queue::BalanceQueue, AggegatingNode, AggregationContext, AggregationNode, + AggregationNodeGuard, PreparedInternalOperation, PreparedOperation, StackVec, +}; +pub(super) const LEAF_NUMBER: u32 = 16; + +#[derive(Debug)] +pub enum IncreaseReason { + Upgraded, + AggregationData, + EqualAggregationNumberOnBalance, + EqualAggregationNumberOnNewFollower, + OptimizeForUppers, + OptimizeForFollowers, + LeafEdge, + LeafEdgeAfterIncrease, + #[cfg(test)] + Test, +} + +impl AggregationNode { + /// Increase the aggregation number of a node. This might temporarily + /// violate the graph invariants between uppers and followers of that node. + /// Therefore a balancing operation is enqueued to restore the invariants. + /// The actual change to the aggregation number is applied in the prepared + /// operation after checking all upper nodes aggregation numbers. + #[must_use] + pub(super) fn increase_aggregation_number_internal< + C: AggregationContext, + >( + &mut self, + _ctx: &C, + node_id: &C::NodeRef, + min_aggregation_number: u32, + target_aggregation_number: u32, + reason: IncreaseReason, + ) -> Option> { + if self.aggregation_number() >= min_aggregation_number { + return None; + } + Some(PreparedInternalIncreaseAggregationNumber::Lazy { + node_id: node_id.clone(), + uppers: self.uppers_mut().iter().cloned().collect(), + min_aggregation_number, + target_aggregation_number, + reason, + }) + } + + /// Increase the aggregation number of a node. This is only for testing + /// proposes. + #[cfg(test)] + pub fn increase_aggregation_number>( + &mut self, + _ctx: &C, + node_id: &C::NodeRef, + new_aggregation_number: u32, + ) -> Option> { + self.increase_aggregation_number_internal( + _ctx, + node_id, + new_aggregation_number, + new_aggregation_number, + IncreaseReason::Test, + ) + .map(PreparedIncreaseAggregationNumber) + } +} + +/// Increase the aggregation number of a node directly. This might temporarily +/// violate the graph invariants between uppers and followers of that node. +/// Therefore a balancing operation is enqueued to restore the invariants. +/// The actual change to the aggregation number is applied directly without +/// checking the upper nodes. +#[must_use] +pub(super) fn increase_aggregation_number_immediately( + _ctx: &C, + node: &mut C::Guard<'_>, + node_id: C::NodeRef, + min_aggregation_number: u32, + target_aggregation_number: u32, + reason: IncreaseReason, +) -> Option> { + if node.aggregation_number() >= min_aggregation_number { + return None; + } + + let _span = tracing::trace_span!( + "increase_aggregation_number_immediately", + reason = debug(&reason) + ) + .entered(); + let children = matches!(**node, AggregationNode::Leaf { .. }) + .then(|| node.children().collect::>()); + match &mut **node { + AggregationNode::Leaf { + aggregation_number, + uppers, + } => { + let children = children.unwrap(); + if target_aggregation_number < LEAF_NUMBER { + *aggregation_number = target_aggregation_number as u8; + Some(PreparedInternalIncreaseAggregationNumber::Leaf { + target_aggregation_number, + children, + }) + } else { + let uppers_copy = uppers.iter().cloned().collect::>(); + // Convert to Aggregating + **node = AggregationNode::Aggegating(Box::new(AggegatingNode { + aggregation_number: target_aggregation_number, + uppers: take(uppers), + followers: children.iter().cloned().collect(), + data: node.get_initial_data(), + enqueued_balancing: Vec::new(), + })); + let followers = children; + Some(PreparedInternalIncreaseAggregationNumber::Aggregating { + node_id, + uppers: uppers_copy, + followers, + target_aggregation_number, + }) + } + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { + followers, + uppers, + aggregation_number, + .. + } = &mut **aggegating; + let uppers = uppers.iter().cloned().collect::>(); + let followers = followers.iter().cloned().collect(); + *aggregation_number = target_aggregation_number; + Some(PreparedInternalIncreaseAggregationNumber::Aggregating { + node_id, + uppers, + followers, + target_aggregation_number, + }) + } + } +} + +/// A prepared `increase_aggregation_number` operation. +pub enum PreparedInternalIncreaseAggregationNumber { + Lazy { + node_id: C::NodeRef, + uppers: StackVec, + min_aggregation_number: u32, + target_aggregation_number: u32, + reason: IncreaseReason, + }, + Leaf { + children: StackVec, + target_aggregation_number: u32, + }, + Aggregating { + node_id: C::NodeRef, + uppers: StackVec, + followers: StackVec, + target_aggregation_number: u32, + }, +} + +impl PreparedInternalOperation + for PreparedInternalIncreaseAggregationNumber +{ + type Result = (); + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) { + match self { + PreparedInternalIncreaseAggregationNumber::Lazy { + min_aggregation_number, + mut target_aggregation_number, + node_id, + uppers, + reason, + } => { + if target_aggregation_number >= LEAF_NUMBER { + let mut need_to_run = true; + while need_to_run { + need_to_run = false; + let mut max = 0; + for upper_id in &uppers { + let upper = ctx.node(upper_id); + let aggregation_number = upper.aggregation_number(); + if aggregation_number != u32::MAX { + if aggregation_number > max { + max = aggregation_number; + } + if aggregation_number == target_aggregation_number { + target_aggregation_number += 1; + if max >= target_aggregation_number { + need_to_run = true; + } + } + } + } + } + } + drop(uppers); + let mut node = ctx.node(&node_id); + if node.aggregation_number() >= min_aggregation_number { + return; + } + let _span = + tracing::trace_span!("increase_aggregation_number", reason = debug(&reason)) + .entered(); + let children = matches!(*node, AggregationNode::Leaf { .. }) + .then(|| node.children().collect::>()); + let (uppers, followers) = match &mut *node { + AggregationNode::Leaf { + aggregation_number, + uppers, + } => { + let children = children.unwrap(); + if target_aggregation_number < LEAF_NUMBER { + *aggregation_number = target_aggregation_number as u8; + drop(node); + for child_id in children { + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(&child_id), + &child_id, + target_aggregation_number + 1, + target_aggregation_number + 1, + IncreaseReason::LeafEdgeAfterIncrease, + ); + } + return; + } else { + let uppers_copy = uppers.iter().cloned().collect::>(); + // Convert to Aggregating + *node = AggregationNode::Aggegating(Box::new(AggegatingNode { + aggregation_number: target_aggregation_number, + uppers: take(uppers), + followers: children.iter().cloned().collect(), + data: node.get_initial_data(), + enqueued_balancing: Vec::new(), + })); + let followers = children; + drop(node); + (uppers_copy, followers) + } + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { + followers, + uppers, + aggregation_number, + .. + } = &mut **aggegating; + let uppers = uppers.iter().cloned().collect::>(); + let followers = followers.iter().cloned().collect(); + *aggregation_number = target_aggregation_number; + drop(node); + (uppers, followers) + } + }; + for follower_id in followers { + balance_queue.balance( + node_id.clone(), + target_aggregation_number, + follower_id, + 0, + ); + } + for upper_id in uppers { + balance_queue.balance(upper_id, 0, node_id.clone(), target_aggregation_number); + } + } + PreparedInternalIncreaseAggregationNumber::Leaf { + children, + target_aggregation_number, + } => { + for child_id in children { + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(&child_id), + &child_id, + target_aggregation_number + 1, + target_aggregation_number + 1, + IncreaseReason::LeafEdgeAfterIncrease, + ); + } + } + PreparedInternalIncreaseAggregationNumber::Aggregating { + node_id, + uppers, + followers, + target_aggregation_number, + } => { + for follower_id in followers { + balance_queue.balance( + node_id.clone(), + target_aggregation_number, + follower_id, + 0, + ); + } + for upper_id in uppers { + balance_queue.balance(upper_id, 0, node_id.clone(), target_aggregation_number); + } + } + } + } +} + +pub fn increase_aggregation_number_internal( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + min_aggregation_number: u32, + target_aggregation_number: u32, + reason: IncreaseReason, +) { + let prepared = node.increase_aggregation_number_internal( + ctx, + node_id, + min_aggregation_number, + target_aggregation_number, + reason, + ); + drop(node); + prepared.apply(ctx, balance_queue); +} + +/// A prepared `increase_aggregation_number` operation. +pub struct PreparedIncreaseAggregationNumber( + PreparedInternalIncreaseAggregationNumber, +); + +impl PreparedOperation for PreparedIncreaseAggregationNumber { + type Result = (); + fn apply(self, ctx: &C) { + let mut balance_queue = BalanceQueue::new(); + self.0.apply(ctx, &mut balance_queue); + balance_queue.process(ctx); + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/loom_tests.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/loom_tests.rs new file mode 100644 index 0000000000000..f5750e3c27aab --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/loom_tests.rs @@ -0,0 +1,265 @@ +use std::{ + fmt::Debug, + hash::Hash, + ops::{Deref, DerefMut}, + sync::{atomic::AtomicU32, Arc}, +}; + +use loom::{ + sync::{Mutex, MutexGuard}, + thread, +}; +use rand::{rngs::SmallRng, Rng, SeedableRng}; +use ref_cast::RefCast; +use rstest::*; + +use super::{ + aggregation_data, handle_new_edge, AggregationContext, AggregationNode, AggregationNodeGuard, + PreparedOperation, +}; + +struct Node { + atomic: AtomicU32, + inner: Mutex, +} + +impl Node { + fn new(value: u32) -> Arc { + Arc::new(Node { + atomic: AtomicU32::new(0), + inner: Mutex::new(NodeInner { + children: Vec::new(), + aggregation_node: AggregationNode::new(), + value, + }), + }) + } + + fn add_child(self: &Arc, aggregation_context: &NodeAggregationContext, child: Arc) { + let mut guard = self.inner.lock().unwrap(); + guard.children.push(child.clone()); + let number_of_children = guard.children.len(); + let mut guard = unsafe { NodeGuard::new(guard, self.clone()) }; + let prepared = handle_new_edge( + aggregation_context, + &mut guard, + &NodeRef(self.clone()), + &NodeRef(child), + number_of_children, + ); + drop(guard); + prepared.apply(aggregation_context); + } +} + +#[derive(Copy, Clone)] +struct Change {} + +struct NodeInner { + children: Vec>, + aggregation_node: AggregationNode, + value: u32, +} + +struct NodeAggregationContext {} + +#[derive(Clone, RefCast)] +#[repr(transparent)] +struct NodeRef(Arc); + +impl Debug for NodeRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "NodeRef({})", self.0.inner.lock().unwrap().value) + } +} + +impl Hash for NodeRef { + fn hash(&self, state: &mut H) { + Arc::as_ptr(&self.0).hash(state); + } +} + +impl PartialEq for NodeRef { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} + +impl Eq for NodeRef {} + +struct NodeGuard { + guard: MutexGuard<'static, NodeInner>, + // This field is important to keep the node alive + #[allow(dead_code)] + node: Arc, +} + +impl NodeGuard { + unsafe fn new(guard: MutexGuard<'_, NodeInner>, node: Arc) -> Self { + NodeGuard { + guard: unsafe { std::mem::transmute(guard) }, + node, + } + } +} + +impl Deref for NodeGuard { + type Target = AggregationNode; + + fn deref(&self) -> &Self::Target { + &self.guard.aggregation_node + } +} + +impl DerefMut for NodeGuard { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.guard.aggregation_node + } +} + +impl AggregationNodeGuard for NodeGuard { + type Data = Aggregated; + type NodeRef = NodeRef; + type DataChange = Change; + type ChildrenIter<'a> = impl Iterator + 'a; + + fn children(&self) -> Self::ChildrenIter<'_> { + self.guard + .children + .iter() + .map(|child| NodeRef(child.clone())) + } + + fn get_remove_change(&self) -> Option { + None + } + + fn get_add_change(&self) -> Option { + None + } + + fn get_initial_data(&self) -> Self::Data { + Aggregated {} + } +} + +impl AggregationContext for NodeAggregationContext { + type Guard<'l> = NodeGuard where Self: 'l; + type Data = Aggregated; + type NodeRef = NodeRef; + type DataChange = Change; + + fn node<'b>(&'b self, reference: &Self::NodeRef) -> Self::Guard<'b> { + let r = reference.0.clone(); + let guard = reference.0.inner.lock().unwrap(); + unsafe { NodeGuard::new(guard, r) } + } + + fn atomic_in_progress_counter<'l>(&self, id: &'l NodeRef) -> &'l AtomicU32 + where + Self: 'l, + { + &id.0.atomic + } + + fn apply_change(&self, _data: &mut Aggregated, _change: &Change) -> Option { + None + } + + fn data_to_add_change(&self, _data: &Self::Data) -> Option { + None + } + + fn data_to_remove_change(&self, _data: &Self::Data) -> Option { + None + } +} + +#[derive(Default)] +struct Aggregated {} + +// #[test] +#[allow(dead_code)] +fn fuzzy_loom_new() { + for size in [10, 20] { + for _ in 0..1000 { + let seed = rand::random(); + println!("Seed {} Size {}", seed, size); + fuzzy_loom(seed, size); + } + } +} + +#[rstest] +#[case::a(3302552607, 10)] +// #[case::b(3629477471, 50)] +// #[case::c(1006976052, 20)] +// #[case::d(2174645157, 10)] +fn fuzzy_loom(#[case] seed: u32, #[case] count: u32) { + let mut builder = loom::model::Builder::new(); + builder.max_branches = 100000; + builder.check(move || { + loom::stop_exploring(); + thread::Builder::new() + .stack_size(80000) + .spawn(move || { + let ctx = NodeAggregationContext {}; + + let mut seed_buffer = [0; 32]; + seed_buffer[0..4].copy_from_slice(&seed.to_be_bytes()); + let mut r = SmallRng::from_seed(seed_buffer); + let mut nodes = Vec::new(); + for i in 0..count { + nodes.push(Node::new(i)); + } + aggregation_data(&ctx, &NodeRef(nodes[0].clone())); + aggregation_data(&ctx, &NodeRef(nodes[1].clone())); + + // setup graph + for _ in 0..20 { + let parent = r.gen_range(0..nodes.len() - 1); + let child = r.gen_range(parent + 1..nodes.len()); + let parent_node = nodes[parent].clone(); + let child_node = nodes[child].clone(); + parent_node.add_child(&ctx, child_node); + } + + let mut edges = Vec::new(); + for _ in 0..2 { + let parent = r.gen_range(0..nodes.len() - 1); + let child = r.gen_range(parent + 1..nodes.len()); + let parent_node = nodes[parent].clone(); + let child_node = nodes[child].clone(); + edges.push((parent_node, child_node)); + } + + let ctx = Arc::new(ctx); + + loom::explore(); + + let mut threads = Vec::new(); + + // Fancy testing + for (parent_node, child_node) in edges.iter() { + let parent_node = parent_node.clone(); + let child_node = child_node.clone(); + let ctx = ctx.clone(); + threads.push( + thread::Builder::new() + .stack_size(80000) + .spawn(move || { + parent_node.add_child(&ctx, child_node); + }) + .unwrap(), + ); + } + + for thread in threads { + thread.join().unwrap(); + } + }) + .unwrap() + .join() + .unwrap(); + }); +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/lost_edge.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/lost_edge.rs new file mode 100644 index 0000000000000..7c95e3cbb461c --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/lost_edge.rs @@ -0,0 +1,115 @@ +use std::hash::Hash; + +use super::{ + balance_queue::BalanceQueue, in_progress::start_in_progress_count, + notify_lost_follower::PreparedNotifyLostFollower, AggregationContext, AggregationNode, + PreparedInternalOperation, PreparedOperation, StackVec, +}; + +impl AggregationNode { + /// Handles the loss of edges to a node. This will notify all upper nodes + /// about the new follower or add the new node as inner node. + #[must_use] + pub fn handle_lost_edges>( + &mut self, + ctx: &C, + origin_id: &C::NodeRef, + target_ids: impl IntoIterator, + ) -> Option> { + match self { + AggregationNode::Leaf { uppers, .. } => { + let uppers = uppers.iter().cloned().collect::>(); + let target_ids: StackVec<_> = target_ids.into_iter().collect(); + for upper_id in &uppers { + start_in_progress_count(ctx, upper_id, target_ids.len() as u32); + } + Some(PreparedLostEdgesInner::Leaf { uppers, target_ids }.into()) + } + AggregationNode::Aggegating(_) => { + let notify = target_ids + .into_iter() + .filter_map(|target_id| { + self.notify_lost_follower_not_in_progress(ctx, origin_id, &target_id) + }) + .collect::>(); + (!notify.is_empty()).then(|| notify.into()) + } + } + } +} + +/// A prepared `handle_lost_edges` operation. +pub struct PreparedLostEdges { + inner: PreparedLostEdgesInner, +} + +impl From> for PreparedLostEdges { + fn from(inner: PreparedLostEdgesInner) -> Self { + Self { inner } + } +} + +impl From>> for PreparedLostEdges { + fn from(notify: StackVec>) -> Self { + Self { + inner: PreparedLostEdgesInner::Aggregating { notify }, + } + } +} + +#[allow(clippy::large_enum_variant)] +enum PreparedLostEdgesInner { + Leaf { + uppers: StackVec, + target_ids: StackVec, + }, + Aggregating { + notify: StackVec>, + }, +} + +impl PreparedOperation for PreparedLostEdges { + type Result = (); + fn apply(self, ctx: &C) { + let mut balance_queue = BalanceQueue::new(); + match self.inner { + PreparedLostEdgesInner::Leaf { uppers, target_ids } => { + // TODO This could be more efficient + for upper_id in uppers { + let mut upper = ctx.node(&upper_id); + let prepared = target_ids + .iter() + .filter_map(|target_id| { + upper.notify_lost_follower( + ctx, + &mut balance_queue, + &upper_id, + target_id, + ) + }) + .collect::>(); + drop(upper); + prepared.apply(ctx, &mut balance_queue); + } + } + PreparedLostEdgesInner::Aggregating { notify } => { + notify.apply(ctx, &mut balance_queue); + } + } + balance_queue.process(ctx); + } +} + +/// Handles the loss of edges to a node. This will notify all upper nodes +/// about the new follower or add the new node as inner node. +#[cfg(test)] +pub fn handle_lost_edges( + ctx: &C, + mut origin: C::Guard<'_>, + origin_id: &C::NodeRef, + target_ids: impl IntoIterator, +) { + let p = origin.handle_lost_edges(ctx, origin_id, target_ids); + drop(origin); + p.apply(ctx); +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/mod.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/mod.rs new file mode 100644 index 0000000000000..bfbd8da7b657f --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/mod.rs @@ -0,0 +1,246 @@ +use std::{fmt::Debug, hash::Hash, ops::DerefMut, sync::atomic::AtomicU32}; + +use smallvec::SmallVec; + +use crate::count_hash_set::CountHashSet; + +mod aggregation_data; +mod balance_edge; +mod balance_queue; +mod change; +mod followers; +mod in_progress; +mod increase; +#[cfg(test)] +mod loom_tests; +mod lost_edge; +mod new_edge; +mod notify_lost_follower; +mod notify_new_follower; +mod optimize; +mod root_query; +#[cfg(test)] +mod tests; +mod uppers; + +pub use aggregation_data::{aggregation_data, prepare_aggregation_data, AggregationDataGuard}; +use balance_edge::balance_edge; +use increase::increase_aggregation_number_internal; +pub use new_edge::handle_new_edge; +use notify_lost_follower::notify_lost_follower; +use notify_new_follower::notify_new_follower; +pub use root_query::{query_root_info, RootQuery}; + +use self::balance_queue::BalanceQueue; + +type StackVec = SmallVec<[I; 16]>; + +/// The aggregation node structure. This stores the aggregation number, the +/// aggregation edges to uppers and followers and the aggregated data. +pub enum AggregationNode { + Leaf { + aggregation_number: u8, + uppers: CountHashSet, + }, + Aggegating(Box>), +} + +/// The aggregation node structure for aggregating nodes. +pub struct AggegatingNode { + aggregation_number: u32, + uppers: CountHashSet, + followers: CountHashSet, + data: D, + enqueued_balancing: Vec<(I, u32, I, u32)>, +} + +impl AggregationNode { + pub fn new() -> Self { + Self::Leaf { + aggregation_number: 0, + uppers: CountHashSet::new(), + } + } + + pub fn shrink_to_fit(&mut self) + where + I: Hash + Eq, + { + match self { + AggregationNode::Leaf { uppers, .. } => uppers.shrink_to_fit(), + AggregationNode::Aggegating(aggregating) => { + aggregating.uppers.shrink_to_fit(); + aggregating.followers.shrink_to_fit(); + } + } + } + + /// Returns the aggregation number of the node. + pub fn aggregation_number(&self) -> u32 { + match self { + AggregationNode::Leaf { + aggregation_number, .. + } => *aggregation_number as u32, + AggregationNode::Aggegating(aggregating) => aggregating.aggregation_number, + } + } + + fn is_leaf(&self) -> bool { + matches!(self, AggregationNode::Leaf { .. }) + } + + fn uppers(&self) -> &CountHashSet { + match self { + AggregationNode::Leaf { uppers, .. } => uppers, + AggregationNode::Aggegating(aggregating) => &aggregating.uppers, + } + } + + fn uppers_mut(&mut self) -> &mut CountHashSet { + match self { + AggregationNode::Leaf { uppers, .. } => uppers, + AggregationNode::Aggegating(aggregating) => &mut aggregating.uppers, + } + } + + fn followers(&self) -> Option<&CountHashSet> { + match self { + AggregationNode::Leaf { .. } => None, + AggregationNode::Aggegating(aggregating) => Some(&aggregating.followers), + } + } +} + +/// A prepared operation. Must be applied outside of node locks. +#[must_use] +pub trait PreparedOperation { + type Result; + fn apply(self, ctx: &C) -> Self::Result; +} + +impl> PreparedOperation for Option { + type Result = Option; + fn apply(self, ctx: &C) -> Self::Result { + self.map(|prepared| prepared.apply(ctx)) + } +} + +impl> PreparedOperation for Vec { + type Result = (); + fn apply(self, ctx: &C) -> Self::Result { + for prepared in self { + prepared.apply(ctx); + } + } +} + +impl, const N: usize> PreparedOperation + for SmallVec<[T; N]> +{ + type Result = (); + fn apply(self, ctx: &C) -> Self::Result { + for prepared in self { + prepared.apply(ctx); + } + } +} + +/// A prepared internal operation. Must be applied inside of node locks and with +/// a balance queue. +#[must_use] +trait PreparedInternalOperation { + type Result; + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result; +} + +impl> PreparedInternalOperation + for Option +{ + type Result = Option; + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result { + self.map(|prepared| prepared.apply(ctx, balance_queue)) + } +} + +impl> PreparedInternalOperation + for Vec +{ + type Result = (); + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result { + for prepared in self { + prepared.apply(ctx, balance_queue); + } + } +} + +impl, const N: usize> + PreparedInternalOperation for SmallVec<[T; N]> +{ + type Result = (); + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result { + for prepared in self { + prepared.apply(ctx, balance_queue); + } + } +} + +/// Context for aggregation operations. +pub trait AggregationContext { + type NodeRef: Clone + Eq + Hash + Debug; + type Guard<'l>: AggregationNodeGuard< + NodeRef = Self::NodeRef, + Data = Self::Data, + DataChange = Self::DataChange, + > + where + Self: 'l; + type Data; + type DataChange; + + /// Gets mutable access to an item. + fn node<'l>(&'l self, id: &Self::NodeRef) -> Self::Guard<'l>; + + /// Get the atomic in progress counter for a node. + fn atomic_in_progress_counter<'l>(&self, id: &'l Self::NodeRef) -> &'l AtomicU32 + where + Self: 'l; + + /// Apply a changeset to an aggregated data object. Returns a new changeset + /// that should be applied to the next aggregation level. Might return None, + /// if no change should be applied to the next level. + fn apply_change( + &self, + data: &mut Self::Data, + change: &Self::DataChange, + ) -> Option; + + /// Creates a changeset from an aggregated data object, that represents + /// adding the aggregated node to an aggregated node of the next level. + fn data_to_add_change(&self, data: &Self::Data) -> Option; + /// Creates a changeset from an aggregated data object, that represents + /// removing the aggregated node from an aggregated node of the next level. + fn data_to_remove_change(&self, data: &Self::Data) -> Option; +} + +/// A guard for a node that allows to access the aggregation node, children and +/// data. +pub trait AggregationNodeGuard: + DerefMut> +{ + type NodeRef: Clone + Eq + Hash; + type Data; + type DataChange; + + type ChildrenIter<'a>: Iterator + 'a + where + Self: 'a; + + /// Returns an iterator over the children. + fn children(&self) -> Self::ChildrenIter<'_>; + /// Returns a changeset that represents the addition of the node. + fn get_add_change(&self) -> Option; + /// Returns a changeset that represents the removal of the node. + fn get_remove_change(&self) -> Option; + /// Returns the aggregated data which contains only that node + fn get_initial_data(&self) -> Self::Data; +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/new_edge.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/new_edge.rs new file mode 100644 index 0000000000000..306fb47a63f08 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/new_edge.rs @@ -0,0 +1,173 @@ +use super::{ + balance_queue::BalanceQueue, + in_progress::start_in_progress_all, + increase::{ + increase_aggregation_number_immediately, IncreaseReason, + PreparedInternalIncreaseAggregationNumber, LEAF_NUMBER, + }, + increase_aggregation_number_internal, notify_new_follower, + notify_new_follower::PreparedNotifyNewFollower, + optimize::optimize_aggregation_number_for_uppers, + AggregationContext, AggregationNode, PreparedInternalOperation, PreparedOperation, StackVec, +}; + +const BUFFER_SPACE: u32 = 2; + +const MAX_UPPERS_TIMES_CHILDREN: usize = 32; + +const MAX_AFFECTED_NODES: usize = 4096; + +/// Handle the addition of a new edge to a node. The the edge is propagated to +/// the uppers of that node or added a inner node. +pub fn handle_new_edge( + ctx: &C, + origin: &mut C::Guard<'_>, + origin_id: &C::NodeRef, + target_id: &C::NodeRef, + number_of_children: usize, +) -> impl PreparedOperation { + match **origin { + AggregationNode::Leaf { + ref mut aggregation_number, + ref uppers, + } => { + if number_of_children.count_ones() == 1 + && (uppers.len() + 1) * number_of_children >= MAX_UPPERS_TIMES_CHILDREN + { + let uppers = uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + let increase = increase_aggregation_number_immediately( + ctx, + origin, + origin_id.clone(), + LEAF_NUMBER, + LEAF_NUMBER, + IncreaseReason::Upgraded, + ) + .unwrap(); + Some(PreparedNewEdge::Upgraded { + uppers, + target_id: target_id.clone(), + increase, + }) + } else { + let min_aggregation_number = *aggregation_number as u32 + 1; + let target_aggregation_number = *aggregation_number as u32 + 1 + BUFFER_SPACE; + let uppers = uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + Some(PreparedNewEdge::Leaf { + min_aggregation_number, + target_aggregation_number, + uppers, + target_id: target_id.clone(), + }) + } + } + AggregationNode::Aggegating(_) => origin + .notify_new_follower_not_in_progress(ctx, origin_id, target_id) + .map(|notify| PreparedNewEdge::Aggegating { + target_id: target_id.clone(), + notify, + }), + } +} + +/// A prepared `handle_new_edge` operation. +enum PreparedNewEdge { + Leaf { + min_aggregation_number: u32, + target_aggregation_number: u32, + uppers: StackVec, + target_id: C::NodeRef, + }, + Upgraded { + uppers: StackVec, + target_id: C::NodeRef, + increase: PreparedInternalIncreaseAggregationNumber, + }, + Aggegating { + notify: PreparedNotifyNewFollower, + target_id: C::NodeRef, + }, +} + +impl PreparedOperation for PreparedNewEdge { + type Result = (); + fn apply(self, ctx: &C) { + let mut balance_queue = BalanceQueue::new(); + match self { + PreparedNewEdge::Leaf { + min_aggregation_number, + target_aggregation_number, + uppers, + target_id, + } => { + increase_aggregation_number_internal( + ctx, + &mut balance_queue, + ctx.node(&target_id), + &target_id, + min_aggregation_number, + target_aggregation_number, + IncreaseReason::LeafEdge, + ); + let mut affected_nodes = 0; + for upper_id in uppers { + affected_nodes += notify_new_follower( + ctx, + &mut balance_queue, + ctx.node(&upper_id), + &upper_id, + &target_id, + false, + ); + if affected_nodes > MAX_AFFECTED_NODES { + handle_expensive_node(ctx, &mut balance_queue, &target_id); + } + } + } + PreparedNewEdge::Upgraded { + uppers, + target_id, + increase, + } => { + // Since it was added to a leaf node, we would add it to the uppers + for upper_id in uppers { + notify_new_follower( + ctx, + &mut balance_queue, + ctx.node(&upper_id), + &upper_id, + &target_id, + true, + ); + } + // The balancing will attach it to the aggregated node later + increase.apply(ctx, &mut balance_queue); + } + PreparedNewEdge::Aggegating { target_id, notify } => { + let affected_nodes = notify.apply(ctx, &mut balance_queue); + if affected_nodes > MAX_AFFECTED_NODES { + handle_expensive_node(ctx, &mut balance_queue, &target_id); + } + } + } + balance_queue.process(ctx); + } +} + +/// Called in the case when we detect that adding this node was expensive. It +/// optimizes the aggregation number of the node so it can be cheaper on the +/// next call. +fn handle_expensive_node( + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &C::NodeRef, +) { + let _span = tracing::trace_span!("handle_expensive_node").entered(); + let node = ctx.node(node_id); + let uppers = node.uppers().iter().cloned().collect::>(); + let leaf = matches!(*node, AggregationNode::Leaf { .. }); + drop(node); + optimize_aggregation_number_for_uppers(ctx, balance_queue, node_id, leaf, uppers); +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/notify_lost_follower.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/notify_lost_follower.rs new file mode 100644 index 0000000000000..136dc4209671c --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/notify_lost_follower.rs @@ -0,0 +1,220 @@ +use std::{hash::Hash, thread::yield_now}; + +use super::{ + balance_queue::BalanceQueue, + in_progress::{finish_in_progress_without_node, start_in_progress, start_in_progress_all}, + AggegatingNode, AggregationContext, AggregationNode, AggregationNodeGuard, + PreparedInternalOperation, PreparedOperation, StackVec, +}; +use crate::count_hash_set::RemoveIfEntryResult; + +impl AggregationNode { + /// Called when a inner node of the upper node has lost a follower + /// It's expected that the upper node is flagged as "in progress". + pub(super) fn notify_lost_follower>( + &mut self, + ctx: &C, + balance_queue: &mut BalanceQueue, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + ) -> Option> { + let AggregationNode::Aggegating(aggregating) = self else { + unreachable!(); + }; + match aggregating.followers.remove_if_entry(follower_id) { + RemoveIfEntryResult::PartiallyRemoved => { + self.finish_in_progress(ctx, balance_queue, upper_id); + None + } + RemoveIfEntryResult::Removed => { + aggregating.followers.shrink_amortized(); + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + self.finish_in_progress(ctx, balance_queue, upper_id); + Some(PreparedNotifyLostFollower::RemovedFollower { + uppers, + follower_id: follower_id.clone(), + }) + } + RemoveIfEntryResult::NotPresent => Some(PreparedNotifyLostFollower::NotFollower { + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + }), + } + } + + /// Called when a inner node of the upper node has lost a follower. + /// It's expected that the upper node is NOT flagged as "in progress". + pub(super) fn notify_lost_follower_not_in_progress< + C: AggregationContext, + >( + &mut self, + ctx: &C, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + ) -> Option> { + let AggregationNode::Aggegating(aggregating) = self else { + unreachable!(); + }; + match aggregating.followers.remove_if_entry(follower_id) { + RemoveIfEntryResult::PartiallyRemoved => None, + RemoveIfEntryResult::Removed => { + aggregating.followers.shrink_amortized(); + let uppers = aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + Some(PreparedNotifyLostFollower::RemovedFollower { + uppers, + follower_id: follower_id.clone(), + }) + } + RemoveIfEntryResult::NotPresent => { + start_in_progress(ctx, upper_id); + Some(PreparedNotifyLostFollower::NotFollower { + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + }) + } + } + } +} + +/// A prepared `notify_lost_follower` operation. +pub(super) enum PreparedNotifyLostFollower { + RemovedFollower { + uppers: StackVec, + follower_id: C::NodeRef, + }, + NotFollower { + upper_id: C::NodeRef, + follower_id: C::NodeRef, + }, +} + +impl PreparedInternalOperation for PreparedNotifyLostFollower { + type Result = (); + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) { + match self { + PreparedNotifyLostFollower::RemovedFollower { + uppers, + follower_id, + } => { + for upper_id in uppers { + notify_lost_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + &follower_id, + ); + } + } + PreparedNotifyLostFollower::NotFollower { + upper_id, + follower_id, + } => { + loop { + let mut follower = ctx.node(&follower_id); + match follower.uppers_mut().remove_if_entry(&upper_id) { + RemoveIfEntryResult::PartiallyRemoved => { + finish_in_progress_without_node(ctx, balance_queue, &upper_id); + drop(follower); + return; + } + RemoveIfEntryResult::Removed => { + let remove_change = get_aggregated_remove_change(ctx, &follower); + let followers = match &*follower { + AggregationNode::Leaf { .. } => { + follower.children().collect::>() + } + AggregationNode::Aggegating(aggregating) => { + let AggegatingNode { ref followers, .. } = **aggregating; + followers.iter().cloned().collect::>() + } + }; + drop(follower); + + let mut upper = ctx.node(&upper_id); + let remove_change = remove_change + .map(|remove_change| upper.apply_change(ctx, remove_change)); + let prepared = followers + .into_iter() + .filter_map(|follower_id| { + upper.notify_lost_follower_not_in_progress( + ctx, + &upper_id, + &follower_id, + ) + }) + .collect::>(); + upper.finish_in_progress(ctx, balance_queue, &upper_id); + drop(upper); + prepared.apply(ctx, balance_queue); + remove_change.apply(ctx); + return; + } + RemoveIfEntryResult::NotPresent => { + drop(follower); + let mut upper = ctx.node(&upper_id); + let AggregationNode::Aggegating(aggregating) = &mut *upper else { + unreachable!(); + }; + match aggregating.followers.remove_if_entry(&follower_id) { + RemoveIfEntryResult::PartiallyRemoved => { + upper.finish_in_progress(ctx, balance_queue, &upper_id); + return; + } + RemoveIfEntryResult::Removed => { + aggregating.followers.shrink_amortized(); + let uppers = + aggregating.uppers.iter().cloned().collect::>(); + start_in_progress_all(ctx, &uppers); + upper.finish_in_progress(ctx, balance_queue, &upper_id); + drop(upper); + for upper_id in uppers { + notify_lost_follower( + ctx, + balance_queue, + ctx.node(&upper_id), + &upper_id, + &follower_id, + ); + } + return; + } + RemoveIfEntryResult::NotPresent => { + drop(upper); + yield_now() + // Retry, concurrency + } + } + } + } + } + } + } + } +} + +/// Notifies the upper node that a follower has been lost. +/// It's expected that the upper node is flagged as "in progress". +pub fn notify_lost_follower( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut upper: C::Guard<'_>, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, +) { + let p = upper.notify_lost_follower(ctx, balance_queue, upper_id, follower_id); + drop(upper); + p.apply(ctx, balance_queue); +} + +fn get_aggregated_remove_change( + ctx: &C, + guard: &C::Guard<'_>, +) -> Option { + match &**guard { + AggregationNode::Leaf { .. } => guard.get_remove_change(), + AggregationNode::Aggegating(aggegating) => ctx.data_to_remove_change(&aggegating.data), + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/notify_new_follower.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/notify_new_follower.rs new file mode 100644 index 0000000000000..573b62b92c5c7 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/notify_new_follower.rs @@ -0,0 +1,245 @@ +use std::{cmp::Ordering, hash::Hash}; + +use super::{ + balance_queue::BalanceQueue, + followers::add_follower, + in_progress::{finish_in_progress_without_node, start_in_progress}, + increase::IncreaseReason, + increase_aggregation_number_internal, + optimize::optimize_aggregation_number_for_uppers, + uppers::add_upper, + AggregationContext, AggregationNode, PreparedInternalOperation, StackVec, +}; + +const MAX_AFFECTED_NODES: usize = 4096; + +impl AggregationNode { + // Called when a inner node of the upper node has a new follower. + // It's expected that the upper node is flagged as "in progress". + pub(super) fn notify_new_follower>( + &mut self, + ctx: &C, + balance_queue: &mut BalanceQueue, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + already_optimizing_for_upper: bool, + ) -> Option> { + let AggregationNode::Aggegating(aggregating) = self else { + unreachable!(); + }; + if aggregating.followers.add_if_entry(follower_id) { + self.finish_in_progress(ctx, balance_queue, upper_id); + None + } else { + let upper_aggregation_number = aggregating.aggregation_number; + if upper_aggregation_number == u32::MAX { + Some(PreparedNotifyNewFollower::Inner { + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + already_optimizing_for_upper, + }) + } else { + Some(PreparedNotifyNewFollower::FollowerOrInner { + upper_aggregation_number, + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + already_optimizing_for_upper, + }) + } + } + } + + // Called when a inner node of the upper node has a new follower. + // It's expected that the upper node is NOT flagged as "in progress". + pub(super) fn notify_new_follower_not_in_progress< + C: AggregationContext, + >( + &mut self, + ctx: &C, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + ) -> Option> { + let AggregationNode::Aggegating(aggregating) = self else { + unreachable!(); + }; + if aggregating.followers.add_if_entry(follower_id) { + None + } else { + start_in_progress(ctx, upper_id); + let upper_aggregation_number = aggregating.aggregation_number; + if upper_aggregation_number == u32::MAX { + Some(PreparedNotifyNewFollower::Inner { + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + already_optimizing_for_upper: false, + }) + } else { + Some(PreparedNotifyNewFollower::FollowerOrInner { + upper_aggregation_number, + upper_id: upper_id.clone(), + follower_id: follower_id.clone(), + already_optimizing_for_upper: false, + }) + } + } + } +} + +/// A prepared `notify_new_follower` operation. +pub(super) enum PreparedNotifyNewFollower { + Inner { + upper_id: C::NodeRef, + follower_id: C::NodeRef, + already_optimizing_for_upper: bool, + }, + FollowerOrInner { + upper_aggregation_number: u32, + upper_id: C::NodeRef, + follower_id: C::NodeRef, + already_optimizing_for_upper: bool, + }, +} + +impl PreparedInternalOperation for PreparedNotifyNewFollower { + type Result = usize; + fn apply(self, ctx: &C, balance_queue: &mut BalanceQueue) -> Self::Result { + match self { + PreparedNotifyNewFollower::Inner { + upper_id, + follower_id, + already_optimizing_for_upper, + } => { + let follower = ctx.node(&follower_id); + let affected_nodes = add_upper( + ctx, + balance_queue, + follower, + &follower_id, + &upper_id, + already_optimizing_for_upper, + ); + finish_in_progress_without_node(ctx, balance_queue, &upper_id); + if !already_optimizing_for_upper && affected_nodes > MAX_AFFECTED_NODES { + let follower = ctx.node(&follower_id); + let uppers = follower.uppers().iter().cloned().collect::>(); + let leaf: bool = follower.is_leaf(); + drop(follower); + if optimize_aggregation_number_for_uppers( + ctx, + balance_queue, + &follower_id, + leaf, + uppers, + ) { + return 1; + } + } + affected_nodes + } + PreparedNotifyNewFollower::FollowerOrInner { + mut upper_aggregation_number, + upper_id, + follower_id, + already_optimizing_for_upper, + } => loop { + let follower = ctx.node(&follower_id); + let follower_aggregation_number = follower.aggregation_number(); + if follower_aggregation_number < upper_aggregation_number { + let affected_nodes = add_upper( + ctx, + balance_queue, + follower, + &follower_id, + &upper_id, + already_optimizing_for_upper, + ); + finish_in_progress_without_node(ctx, balance_queue, &upper_id); + if !already_optimizing_for_upper && affected_nodes > MAX_AFFECTED_NODES { + let follower = ctx.node(&follower_id); + let uppers = follower.uppers().iter().cloned().collect::>(); + let leaf = follower.is_leaf(); + drop(follower); + if optimize_aggregation_number_for_uppers( + ctx, + balance_queue, + &follower_id, + leaf, + uppers, + ) { + return 1; + } + } + return affected_nodes; + } else { + drop(follower); + let mut upper = ctx.node(&upper_id); + let AggregationNode::Aggegating(aggregating) = &mut *upper else { + unreachable!(); + }; + upper_aggregation_number = aggregating.aggregation_number; + if upper_aggregation_number == u32::MAX { + // retry, concurrency + } else { + match follower_aggregation_number.cmp(&upper_aggregation_number) { + Ordering::Less => { + // retry, concurrency + } + Ordering::Equal => { + drop(upper); + let follower = ctx.node(&follower_id); + let follower_aggregation_number = follower.aggregation_number(); + if follower_aggregation_number == upper_aggregation_number { + increase_aggregation_number_internal( + ctx, + balance_queue, + follower, + &follower_id, + upper_aggregation_number + 1, + upper_aggregation_number + 1, + IncreaseReason::EqualAggregationNumberOnNewFollower, + ); + // retry + } else { + // retry, concurrency + } + } + Ordering::Greater => { + upper.finish_in_progress(ctx, balance_queue, &upper_id); + return add_follower( + ctx, + balance_queue, + upper, + &upper_id, + &follower_id, + already_optimizing_for_upper, + ); + } + } + } + } + }, + } + } +} + +/// Notifies the upper node that it has a new follower. +/// Returns the number of affected nodes. +/// The upper node is expected to be flagged as "in progress". +pub fn notify_new_follower( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut upper: C::Guard<'_>, + upper_id: &C::NodeRef, + follower_id: &C::NodeRef, + already_optimizing_for_upper: bool, +) -> usize { + let p = upper.notify_new_follower( + ctx, + balance_queue, + upper_id, + follower_id, + already_optimizing_for_upper, + ); + drop(upper); + p.apply(ctx, balance_queue).unwrap_or_default() +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/optimize.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/optimize.rs new file mode 100644 index 0000000000000..8ca45a882a35d --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/optimize.rs @@ -0,0 +1,146 @@ +use tracing::Level; + +use super::{ + balance_queue::BalanceQueue, + increase::{increase_aggregation_number_internal, IncreaseReason, LEAF_NUMBER}, + AggregationContext, StackVec, +}; + +pub const MAX_UPPERS: usize = 512; + +pub const MAX_FOLLOWERS: usize = 128; + +/// Optimize the aggregation number for a node based on a list of upper nodes. +/// The goal is to reduce the number of upper nodes, so we try to find a +/// aggregation number that is higher than some of the upper nodes. +/// Returns true if the aggregation number was increased. +#[tracing::instrument(level = Level::TRACE, skip(ctx, balance_queue, node_id, uppers))] +pub fn optimize_aggregation_number_for_uppers( + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &C::NodeRef, + leaf: bool, + uppers: StackVec, +) -> bool { + let count = uppers.len(); + let mut root_count = 0; + let mut min = u32::MAX; + let mut max = 0; + let mut uppers_uppers = 0; + for upper_id in uppers.into_iter() { + let upper = ctx.node(&upper_id); + let aggregation_number = upper.aggregation_number(); + if aggregation_number == u32::MAX { + root_count += 1; + } else { + let upper_uppers = upper.uppers().len(); + uppers_uppers += upper_uppers; + if aggregation_number < min { + min = aggregation_number; + } + if aggregation_number > max { + max = aggregation_number; + } + } + } + if min == u32::MAX { + min = LEAF_NUMBER - 1; + } + if max < LEAF_NUMBER { + max = LEAF_NUMBER - 1; + } + let aggregation_number = (min + max) / 2 + 1; + if leaf { + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(node_id), + node_id, + aggregation_number, + aggregation_number, + IncreaseReason::OptimizeForUppers, + ); + return true; + } else { + let normal_count = count - root_count; + if normal_count > 0 { + let avg_uppers_uppers = uppers_uppers / normal_count; + if count > avg_uppers_uppers && root_count * 2 < count { + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(node_id), + node_id, + aggregation_number, + aggregation_number, + IncreaseReason::OptimizeForUppers, + ); + return true; + } + } + } + false +} + +/// Optimize the aggregation number for a node based on a list of followers. +/// The goal is to reduce the number of followers, so we try to find a +/// aggregation number that is higher than some of the followers. +/// Returns true if the aggregation number was increased. +#[tracing::instrument(level = Level::TRACE, skip(ctx, balance_queue, node_id, followers))] +pub fn optimize_aggregation_number_for_followers( + ctx: &C, + balance_queue: &mut BalanceQueue, + node_id: &C::NodeRef, + followers: StackVec, + force: bool, +) -> bool { + let count = followers.len(); + let mut root_count = 0; + let mut min = u32::MAX; + let mut max = 0; + let mut followers_followers = 0; + for follower_id in followers.into_iter() { + let follower = ctx.node(&follower_id); + let aggregation_number = follower.aggregation_number(); + if aggregation_number == u32::MAX { + root_count += 1; + } else { + let follower_followers = follower.followers().map_or(0, |f| f.len()); + followers_followers += follower_followers; + if aggregation_number < min { + min = aggregation_number; + } + if aggregation_number > max { + max = aggregation_number; + } + } + } + if min == u32::MAX { + min = LEAF_NUMBER - 1; + } + if min < LEAF_NUMBER { + min = LEAF_NUMBER - 1; + } + if max < min { + max = min; + } + let normal_count = count - root_count; + if normal_count > 0 { + let avg_followers_followers = followers_followers / normal_count; + let makes_sense = count > avg_followers_followers || force; + if makes_sense && root_count * 2 < count { + let aggregation_number = (min + max) / 2 + 1; + increase_aggregation_number_internal( + ctx, + balance_queue, + ctx.node(node_id), + node_id, + aggregation_number, + aggregation_number, + IncreaseReason::OptimizeForFollowers, + ); + return true; + } + } + false +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/root_query.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/root_query.rs new file mode 100644 index 0000000000000..74cacffb6961a --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/root_query.rs @@ -0,0 +1,51 @@ +use std::ops::ControlFlow; + +use auto_hash_map::AutoSet; + +use super::{AggregationContext, AggregationNode, StackVec}; + +/// A query about aggregation data in a root node. +pub trait RootQuery { + type Data; + type Result; + + /// Processes the aggregated data of a root node. Can decide to stop the + /// query. + fn query(&mut self, data: &Self::Data) -> ControlFlow<()>; + /// Returns the result of the query. + fn result(self) -> Self::Result; +} + +/// Queries the root node of an aggregation tree. +pub fn query_root_info>( + ctx: &C, + mut query: Q, + node_id: C::NodeRef, +) -> Q::Result { + let mut queue = StackVec::new(); + queue.push(node_id); + let mut visited = AutoSet::new(); + while let Some(node_id) = queue.pop() { + let node = ctx.node(&node_id); + match &*node { + AggregationNode::Leaf { uppers, .. } => { + for upper_id in uppers.iter() { + if visited.insert(upper_id.clone()) { + queue.push(upper_id.clone()); + } + } + } + AggregationNode::Aggegating(aggegrating) => { + if let ControlFlow::Break(_) = query.query(&aggegrating.data) { + return query.result(); + } + for upper_id in aggegrating.uppers.iter() { + if visited.insert(upper_id.clone()) { + queue.push(upper_id.clone()); + } + } + } + } + } + query.result() +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/tests.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/tests.rs new file mode 100644 index 0000000000000..4cdcbd38e41df --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/tests.rs @@ -0,0 +1,1070 @@ +use std::{ + collections::HashSet, + fmt::Debug, + hash::Hash, + iter::once, + ops::{ControlFlow, Deref, DerefMut}, + sync::{ + atomic::{AtomicU32, Ordering}, + Arc, + }, + time::Instant, +}; + +use indexmap::IndexSet; +use parking_lot::{Mutex, MutexGuard}; +use rand::{rngs::SmallRng, Rng, SeedableRng}; +use ref_cast::RefCast; +use rstest::*; + +use self::aggregation_data::prepare_aggregation_data; +use super::{ + aggregation_data, handle_new_edge, lost_edge::handle_lost_edges, AggregationContext, + AggregationNode, AggregationNodeGuard, RootQuery, +}; +use crate::aggregation::{query_root_info, PreparedOperation, StackVec}; + +fn find_root(mut node: NodeRef) -> NodeRef { + loop { + let lock = node.0.inner.lock(); + let uppers = lock.aggregation_node.uppers(); + if uppers.is_empty() { + drop(lock); + return node; + } + let upper = uppers.iter().next().unwrap().clone(); + drop(lock); + node = upper; + } +} + +fn check_invariants<'a>( + ctx: &NodeAggregationContext<'a>, + node_ids: impl IntoIterator, +) { + let mut queue = node_ids.into_iter().collect::>(); + // print(ctx, &queue[0], true); + let mut visited = HashSet::new(); + while let Some(node_id) = queue.pop() { + assert_eq!(node_id.0.atomic.load(Ordering::SeqCst), 0); + let node = ctx.node(&node_id); + for child_id in node.children() { + if visited.insert(child_id.clone()) { + queue.push(child_id.clone()); + } + } + + let aggregation_number = node.aggregation_number(); + let node_value = node.guard.value; + let uppers = match &*node { + AggregationNode::Leaf { uppers, .. } => { + let uppers = uppers.iter().cloned().collect::>(); + drop(node); + uppers + } + AggregationNode::Aggegating(aggegrating) => { + let uppers = aggegrating.uppers.iter().cloned().collect::>(); + let followers = aggegrating + .followers + .iter() + .cloned() + .collect::>(); + drop(node); + for follower_id in followers { + let follower_aggregation_number; + let follower_uppers; + let follower_value; + { + let follower = ctx.node(&follower_id); + + follower_aggregation_number = follower.aggregation_number(); + follower_uppers = + follower.uppers().iter().cloned().collect::>(); + follower_value = follower.guard.value; + } + + // A follower should have a bigger aggregation number + let condition = follower_aggregation_number > aggregation_number + || aggregation_number == u32::MAX; + if !condition { + let msg = format!( + "follower #{} {} -> #{} {}", + node_value, + aggregation_number, + follower_value, + follower_aggregation_number + ); + print(ctx, &find_root(node_id.clone()), true); + panic!("{msg}"); + } + + // All followers should also be connected to all uppers + let missing_uppers = uppers.iter().filter(|&upper_id| { + if follower_uppers + .iter() + .any(|follower_upper_id| follower_upper_id == upper_id) + { + return false; + } + let upper = ctx.node(upper_id); + if let Some(followers) = upper.followers() { + !followers + .iter() + .any(|follower_upper_id| follower_upper_id == &follower_id) + } else { + false + } + }); + #[allow(clippy::never_loop)] + for missing_upper in missing_uppers { + let upper_value = { + let upper = ctx.node(missing_upper); + upper.guard.value + }; + let msg = format!( + "follower #{} -> #{} is not connected to upper #{}", + node_value, follower_value, upper_value, + ); + print(ctx, &find_root(node_id.clone()), true); + panic!("{msg}"); + } + + // And visit them too + if visited.insert(follower_id.clone()) { + queue.push(follower_id); + } + } + uppers + } + }; + for upper_id in uppers { + { + let upper = ctx.node(&upper_id); + let upper_aggregation_number = upper.aggregation_number(); + let condition = + upper_aggregation_number > aggregation_number || aggregation_number == u32::MAX; + if !condition { + let msg = format!( + "upper #{} {} -> #{} {}", + node_value, aggregation_number, upper.guard.value, upper_aggregation_number + ); + drop(upper); + print(ctx, &find_root(upper_id.clone()), true); + panic!("{msg}"); + } + } + if visited.insert(upper_id.clone()) { + queue.push(upper_id); + } + } + } +} + +fn print_graph( + ctx: &C, + entries: impl IntoIterator, + show_internal: bool, + name_fn: impl Fn(&C::NodeRef) -> String, +) { + let mut queue = entries.into_iter().collect::>(); + let mut visited = queue.iter().cloned().collect::>(); + while let Some(node_id) = queue.pop() { + let name = name_fn(&node_id); + let node = ctx.node(&node_id); + let n = node.aggregation_number(); + let n = if n == u32::MAX { + "♾".to_string() + } else { + n.to_string() + }; + let color = if matches!(*node, AggregationNode::Leaf { .. }) { + "gray" + } else { + "#99ff99" + }; + let children = node.children().collect::>(); + let uppers = node.uppers().iter().cloned().collect::>(); + let followers = match &*node { + AggregationNode::Aggegating(aggegrating) => aggegrating + .followers + .iter() + .cloned() + .collect::>(), + AggregationNode::Leaf { .. } => StackVec::new(), + }; + drop(node); + + if show_internal { + println!( + "\"{}\" [label=\"{}\\n{}\", style=filled, fillcolor=\"{}\"];", + name, name, n, color + ); + } else { + println!( + "\"{}\" [label=\"{}\\n{}\\n{}U {}F\", style=filled, fillcolor=\"{}\"];", + name, + name, + n, + uppers.len(), + followers.len(), + color, + ); + } + + for child_id in children { + let child_name = name_fn(&child_id); + println!("\"{}\" -> \"{}\";", name, child_name); + if visited.insert(child_id.clone()) { + queue.push(child_id); + } + } + if show_internal { + for upper_id in uppers { + let upper_name = name_fn(&upper_id); + println!( + "\"{}\" -> \"{}\" [style=dashed, color=green];", + name, upper_name + ); + if visited.insert(upper_id.clone()) { + queue.push(upper_id); + } + } + for follower_id in followers { + let follower_name = name_fn(&follower_id); + println!( + "\"{}\" -> \"{}\" [style=dashed, color=red];", + name, follower_name + ); + if visited.insert(follower_id.clone()) { + queue.push(follower_id); + } + } + } + } +} + +struct Node { + atomic: AtomicU32, + inner: Mutex, +} + +impl Node { + fn new(value: u32) -> Arc { + Arc::new(Node { + atomic: AtomicU32::new(0), + inner: Mutex::new(NodeInner { + children: Vec::new(), + aggregation_node: AggregationNode::new(), + value, + }), + }) + } + + fn new_with_children( + aggregation_context: &NodeAggregationContext, + value: u32, + children: Vec>, + ) -> Arc { + let node = Self::new(value); + for child in children { + node.add_child(aggregation_context, child); + } + node + } + + fn add_child(self: &Arc, aggregation_context: &NodeAggregationContext, child: Arc) { + self.add_child_unchecked(aggregation_context, child); + check_invariants(aggregation_context, once(find_root(NodeRef(self.clone())))); + } + + fn add_child_unchecked( + self: &Arc, + aggregation_context: &NodeAggregationContext, + child: Arc, + ) { + let mut guard = self.inner.lock(); + guard.children.push(child.clone()); + let number_of_children = guard.children.len(); + let mut guard = unsafe { NodeGuard::new(guard, self.clone()) }; + let prepared = handle_new_edge( + aggregation_context, + &mut guard, + &NodeRef(self.clone()), + &NodeRef(child), + number_of_children, + ); + drop(guard); + prepared.apply(aggregation_context); + } + + fn prepare_add_child<'c>( + self: &Arc, + aggregation_context: &'c NodeAggregationContext<'c>, + child: Arc, + ) -> impl PreparedOperation> { + let mut guard = self.inner.lock(); + guard.children.push(child.clone()); + let number_of_children = guard.children.len(); + let mut guard = unsafe { NodeGuard::new(guard, self.clone()) }; + handle_new_edge( + aggregation_context, + &mut guard, + &NodeRef(self.clone()), + &NodeRef(child), + number_of_children, + ) + } + + fn prepare_aggregation_number<'c>( + self: &Arc, + aggregation_context: &'c NodeAggregationContext<'c>, + aggregation_number: u32, + ) -> impl PreparedOperation> { + let mut guard = self.inner.lock(); + guard.aggregation_node.increase_aggregation_number( + aggregation_context, + &NodeRef(self.clone()), + aggregation_number, + ) + } + + fn remove_child( + self: &Arc, + aggregation_context: &NodeAggregationContext, + child: &Arc, + ) { + self.remove_child_unchecked(aggregation_context, child); + check_invariants(aggregation_context, once(NodeRef(self.clone()))); + } + + fn remove_child_unchecked( + self: &Arc, + aggregation_context: &NodeAggregationContext, + child: &Arc, + ) { + let mut guard = self.inner.lock(); + if let Some(idx) = guard + .children + .iter() + .position(|item| Arc::ptr_eq(item, child)) + { + guard.children.swap_remove(idx); + handle_lost_edges( + aggregation_context, + unsafe { NodeGuard::new(guard, self.clone()) }, + &NodeRef(self.clone()), + [NodeRef(child.clone())], + ); + } + } + + fn incr(self: &Arc, aggregation_context: &NodeAggregationContext) { + let mut guard = self.inner.lock(); + guard.value += 10000; + let prepared = guard + .aggregation_node + .apply_change(aggregation_context, Change { value: 10000 }); + drop(guard); + prepared.apply(aggregation_context); + check_invariants(aggregation_context, once(NodeRef(self.clone()))); + } +} + +#[derive(Copy, Clone)] +struct Change { + value: i32, +} + +impl Change { + fn is_empty(&self) -> bool { + self.value == 0 + } +} + +struct NodeInner { + children: Vec>, + aggregation_node: AggregationNode, + value: u32, +} + +struct NodeAggregationContext<'a> { + additions: AtomicU32, + #[allow(dead_code)] + something_with_lifetime: &'a u32, + add_value: bool, +} + +#[derive(Clone, RefCast)] +#[repr(transparent)] +struct NodeRef(Arc); + +impl Debug for NodeRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "NodeRef({})", self.0.inner.lock().value) + } +} + +impl Hash for NodeRef { + fn hash(&self, state: &mut H) { + Arc::as_ptr(&self.0).hash(state); + } +} + +impl PartialEq for NodeRef { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.0, &other.0) + } +} + +impl Eq for NodeRef {} + +struct NodeGuard { + guard: MutexGuard<'static, NodeInner>, + // This field is important to keep the node alive + #[allow(dead_code)] + node: Arc, +} + +impl NodeGuard { + unsafe fn new(guard: MutexGuard<'_, NodeInner>, node: Arc) -> Self { + NodeGuard { + guard: unsafe { std::mem::transmute(guard) }, + node, + } + } +} + +impl Deref for NodeGuard { + type Target = AggregationNode; + + fn deref(&self) -> &Self::Target { + &self.guard.aggregation_node + } +} + +impl DerefMut for NodeGuard { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.guard.aggregation_node + } +} + +impl AggregationNodeGuard for NodeGuard { + type Data = Aggregated; + type NodeRef = NodeRef; + type DataChange = Change; + type ChildrenIter<'a> = impl Iterator + 'a; + + fn children(&self) -> Self::ChildrenIter<'_> { + self.guard + .children + .iter() + .map(|child| NodeRef(child.clone())) + } + + fn get_remove_change(&self) -> Option { + let change = Change { + value: -(self.guard.value as i32), + }; + if change.is_empty() { + None + } else { + Some(change) + } + } + + fn get_add_change(&self) -> Option { + let change = Change { + value: self.guard.value as i32, + }; + if change.is_empty() { + None + } else { + Some(change) + } + } + + fn get_initial_data(&self) -> Self::Data { + Aggregated { + value: self.guard.value as i32, + active: false, + } + } +} + +impl<'a> AggregationContext for NodeAggregationContext<'a> { + type Guard<'l> = NodeGuard where Self: 'l; + type Data = Aggregated; + type NodeRef = NodeRef; + type DataChange = Change; + + fn node<'b>(&'b self, reference: &Self::NodeRef) -> Self::Guard<'b> { + let r = reference.0.clone(); + let guard = reference.0.inner.lock(); + unsafe { NodeGuard::new(guard, r) } + } + + fn atomic_in_progress_counter<'l>(&self, id: &'l Self::NodeRef) -> &'l AtomicU32 + where + Self: 'l, + { + &id.0.atomic + } + + fn apply_change(&self, data: &mut Aggregated, change: &Change) -> Option { + if data.value != 0 { + self.additions.fetch_add(1, Ordering::SeqCst); + } + if self.add_value { + data.value += change.value; + Some(*change) + } else { + None + } + } + + fn data_to_add_change(&self, data: &Self::Data) -> Option { + let change = Change { value: data.value }; + if change.is_empty() { + None + } else { + Some(change) + } + } + + fn data_to_remove_change(&self, data: &Self::Data) -> Option { + let change = Change { value: -data.value }; + if change.is_empty() { + None + } else { + Some(change) + } + } +} + +#[derive(Default)] +struct ActiveQuery { + active: bool, +} + +impl RootQuery for ActiveQuery { + type Data = Aggregated; + type Result = bool; + + fn query(&mut self, data: &Self::Data) -> ControlFlow<()> { + if data.active { + self.active = true; + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + } + + fn result(self) -> Self::Result { + self.active + } +} + +#[derive(Default)] +struct Aggregated { + value: i32, + active: bool, +} + +#[test] +fn chain() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: true, + }; + let root = Node::new(1); + let mut current = root.clone(); + for i in 2..=100 { + let node = Node::new(i); + current.add_child(&ctx, node.clone()); + current = node; + } + let leaf = Node::new(10000); + current.add_child(&ctx, leaf.clone()); + let current = NodeRef(root); + + { + let root_info = query_root_info(&ctx, ActiveQuery::default(), NodeRef(leaf.clone())); + assert!(!root_info); + } + + { + let aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 15050); + } + assert_eq!(ctx.additions.load(Ordering::SeqCst), 182); + ctx.additions.store(0, Ordering::SeqCst); + check_invariants(&ctx, once(current.clone())); + + { + let root_info = query_root_info(&ctx, ActiveQuery::default(), NodeRef(leaf.clone())); + assert!(!root_info); + } + check_invariants(&ctx, once(current.clone())); + + leaf.incr(&ctx); + // The change need to propagate through 4 aggregated nodes + assert_eq!(ctx.additions.load(Ordering::SeqCst), 4); + ctx.additions.store(0, Ordering::SeqCst); + + { + let mut aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 25050); + aggregated.active = true; + } + assert_eq!(ctx.additions.load(Ordering::SeqCst), 0); + ctx.additions.store(0, Ordering::SeqCst); + + { + let root_info = query_root_info(&ctx, ActiveQuery::default(), NodeRef(leaf.clone())); + assert!(root_info); + } + + let i = 101; + let current = Node::new_with_children(&ctx, i, vec![current.0]); + let current = NodeRef(current); + + { + let aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 25151); + } + // This should be way less the 100 to prove that we are reusing trees + assert_eq!(ctx.additions.load(Ordering::SeqCst), 1); + ctx.additions.store(0, Ordering::SeqCst); + + leaf.incr(&ctx); + // This should be less the 20 to prove that we are reusing trees + assert_eq!(ctx.additions.load(Ordering::SeqCst), 5); + ctx.additions.store(0, Ordering::SeqCst); + + { + let root_info = query_root_info(&ctx, ActiveQuery::default(), NodeRef(leaf.clone())); + assert!(root_info); + } + + print(&ctx, ¤t, true); + check_invariants(&ctx, once(current.clone())); +} + +#[test] +fn chain_double_connected() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: true, + }; + let root = Node::new(1); + let mut nodes = vec![root.clone()]; + let mut current = root.clone(); + let mut current2 = Node::new(2); + current.add_child(&ctx, current2.clone()); + nodes.push(current2.clone()); + for i in 3..=100 { + let node = Node::new(i); + nodes.push(node.clone()); + current.add_child(&ctx, node.clone()); + current2.add_child(&ctx, node.clone()); + current = current2; + current2 = node; + } + let current = NodeRef(root); + + { + let aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 20017); + } + check_invariants(&ctx, once(current.clone())); + assert_eq!(ctx.additions.load(Ordering::SeqCst), 643); + ctx.additions.store(0, Ordering::SeqCst); + + print(&ctx, ¤t, true); + + for i in 2..nodes.len() { + nodes[i - 2].remove_child(&ctx, &nodes[i]); + nodes[i - 1].remove_child(&ctx, &nodes[i]); + } + nodes[0].remove_child(&ctx, &nodes[1]); + + { + let aggregated = aggregation_data(&ctx, ¤t); + assert_eq!(aggregated.value, 1); + } +} + +const RECT_SIZE: usize = 30; +const RECT_MULT: usize = 100; + +#[test] +fn rectangle_tree() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: false, + }; + let mut nodes: Vec>> = Vec::new(); + let mut extra_nodes = Vec::new(); + for y in 0..RECT_SIZE { + let mut line: Vec> = Vec::new(); + for x in 0..RECT_SIZE { + let mut parents = Vec::new(); + if x > 0 { + parents.push(line[x - 1].clone()); + } + if y > 0 { + parents.push(nodes[y - 1][x].clone()); + } + let value = (x + y * RECT_MULT) as u32; + let node = Node::new(value); + if x == 0 || y == 0 { + let extra_node = Node::new(value + 100000); + prepare_aggregation_data(&ctx, &NodeRef(extra_node.clone())); + extra_node.add_child(&ctx, node.clone()); + extra_nodes.push(extra_node); + prepare_aggregation_data(&ctx, &NodeRef(node.clone())); + } + for parent in parents { + parent.add_child_unchecked(&ctx, node.clone()); + } + if x == 0 || y == 0 { + prepare_aggregation_data(&ctx, &NodeRef(node.clone())); + } + line.push(node); + } + nodes.push(line); + } + + check_invariants(&ctx, extra_nodes.iter().cloned().map(NodeRef)); + + let root = NodeRef(extra_nodes[0].clone()); + print(&ctx, &root, false); +} + +#[rstest] +#[case::many_roots_initial(100000, 0, 2, 1)] +#[case::many_roots_later(1, 100000, 2, 1)] +#[case::many_roots_later2(0, 100000, 2, 1)] +#[case::many_roots(50000, 50000, 2, 1)] +#[case::many_children(2, 0, 100000, 1)] +#[case::many_roots_and_children(5000, 5000, 10000, 1)] +#[case::many_roots_and_subgraph(5000, 5000, 100, 2)] +#[case::large_subgraph_a(9, 1, 10, 5)] +#[case::large_subgraph_b(5, 5, 10, 5)] +#[case::large_subgraph_c(1, 9, 10, 5)] +#[case::large_subgraph_d(6, 0, 10, 5)] +#[case::large_subgraph_e(0, 10, 10, 5)] +#[case::many_roots_large_subgraph(5000, 5000, 10, 5)] +fn performance( + #[case] initial_root_count: u32, + #[case] additional_root_count: u32, + #[case] children_count: u32, + #[case] children_layers_count: u32, +) { + fn print_aggregation_numbers(node: Arc) { + print!("Aggregation numbers "); + let mut current = node.clone(); + loop { + let guard = current.inner.lock(); + let n = guard.aggregation_node.aggregation_number(); + let f = guard.aggregation_node.followers().map_or(0, |f| f.len()); + let u = guard.aggregation_node.uppers().len(); + print!(" -> {} [{}U {}F]", n, u, f); + if guard.children.is_empty() { + break; + } + let child = guard.children[guard.children.len() / 2].clone(); + drop(guard); + current = child; + } + println!(); + } + + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: false, + }; + let mut roots: Vec> = Vec::new(); + let inner_node = Node::new(0); + // Setup + for i in 0..initial_root_count { + let node = Node::new(2 + i); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + let start = Instant::now(); + let mut children = vec![inner_node.clone()]; + for j in 0..children_layers_count { + let mut new_children = Vec::new(); + for child in children { + for i in 0..children_count { + let node = Node::new(1000000 * (j + 1) + i); + new_children.push(node.clone()); + child.add_child_unchecked(&ctx, node.clone()); + } + } + children = new_children; + } + println!("Setup children: {:?}", start.elapsed()); + + print_aggregation_numbers(inner_node.clone()); + + let start = Instant::now(); + for i in 0..additional_root_count { + let node = Node::new(2 + i); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + println!("Setup additional roots: {:?}", start.elapsed()); + + print_aggregation_numbers(inner_node.clone()); + + // Add another root + let start = Instant::now(); + { + let node = Node::new(1); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + let root_duration = start.elapsed(); + println!("Root: {:?}", root_duration); + + // Add another child + let start = Instant::now(); + { + let node = Node::new(999999); + inner_node.add_child_unchecked(&ctx, node.clone()); + } + let child_duration = start.elapsed(); + println!("Child: {:?}", child_duration); + + print_aggregation_numbers(inner_node.clone()); + + assert!(root_duration.as_micros() < 10000); + assert!(child_duration.as_micros() < 10000); + + // check_invariants(&ctx, roots.iter().cloned().map(NodeRef)); +} + +#[test] +fn many_children() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: false, + }; + let mut roots: Vec> = Vec::new(); + let mut children: Vec> = Vec::new(); + const CHILDREN: u32 = 100000; + const ROOTS: u32 = 3; + let inner_node = Node::new(0); + let start = Instant::now(); + for i in 0..ROOTS { + let node = Node::new(10000 + i); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + println!("Roots: {:?}", start.elapsed()); + let start = Instant::now(); + for i in 0..CHILDREN { + let node = Node::new(20000 + i); + children.push(node.clone()); + inner_node.add_child_unchecked(&ctx, node.clone()); + } + println!("Children: {:?}", start.elapsed()); + let start = Instant::now(); + for i in 0..CHILDREN { + let node = Node::new(40000 + i); + children.push(node.clone()); + inner_node.add_child_unchecked(&ctx, node.clone()); + } + let children_duration = start.elapsed(); + println!("Children: {:?}", children_duration); + for j in 0.. { + let start = Instant::now(); + for i in 0..CHILDREN { + let node = Node::new(50000 + j * 10000 + i); + children.push(node.clone()); + inner_node.add_child_unchecked(&ctx, node.clone()); + } + let dur = start.elapsed(); + println!("Children: {:?}", dur); + let is_slow = dur > children_duration * 2; + if j > 10 && !is_slow { + break; + } + if j > 20 { + panic!("Adding children has become slower over time"); + } + } + + let start = Instant::now(); + for i in 0..ROOTS { + let node = Node::new(30000 + i); + roots.push(node.clone()); + aggregation_data(&ctx, &NodeRef(node.clone())).active = true; + node.add_child_unchecked(&ctx, inner_node.clone()); + } + println!("Roots: {:?}", start.elapsed()); + + check_invariants(&ctx, roots.iter().cloned().map(NodeRef)); + + // let root = NodeRef(roots[0].clone()); + // print(&ctx, &root, false); +} + +#[test] +fn concurrent_modification() { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: true, + }; + let root1 = Node::new(1); + let root2 = Node::new(2); + let helper = Node::new(3); + let inner_node = Node::new(10); + let outer_node1 = Node::new(11); + let outer_node2 = Node::new(12); + let outer_node3 = Node::new(13); + let outer_node4 = Node::new(14); + inner_node.add_child(&ctx, outer_node1.clone()); + inner_node.add_child(&ctx, outer_node2.clone()); + root2.add_child(&ctx, helper.clone()); + outer_node1.prepare_aggregation_number(&ctx, 7).apply(&ctx); + outer_node3.prepare_aggregation_number(&ctx, 7).apply(&ctx); + root1.prepare_aggregation_number(&ctx, 8).apply(&ctx); + root2.prepare_aggregation_number(&ctx, 4).apply(&ctx); + helper.prepare_aggregation_number(&ctx, 3).apply(&ctx); + + let add_job1 = root1.prepare_add_child(&ctx, inner_node.clone()); + let add_job2 = inner_node.prepare_add_child(&ctx, outer_node3.clone()); + let add_job3 = inner_node.prepare_add_child(&ctx, outer_node4.clone()); + let add_job4 = helper.prepare_add_child(&ctx, inner_node.clone()); + + add_job4.apply(&ctx); + print_all(&ctx, [root1.clone(), root2.clone()].map(NodeRef), true); + add_job3.apply(&ctx); + print_all(&ctx, [root1.clone(), root2.clone()].map(NodeRef), true); + add_job2.apply(&ctx); + print_all(&ctx, [root1.clone(), root2.clone()].map(NodeRef), true); + add_job1.apply(&ctx); + + print_all(&ctx, [root1.clone(), root2.clone()].map(NodeRef), true); + + check_invariants(&ctx, [root1, root2].map(NodeRef)); +} + +#[test] +fn fuzzy_new() { + for size in [10, 50, 100, 200, 1000] { + for _ in 0..100 { + let seed = rand::random(); + println!("Seed {} Size {}", seed, size); + fuzzy(seed, size); + } + } +} + +#[rstest] +#[case::a(4059591975, 10)] +#[case::b(603692396, 100)] +#[case::c(3317876847, 10)] +#[case::d(4012518846, 50)] +fn fuzzy(#[case] seed: u32, #[case] count: u32) { + let something_with_lifetime = 0; + let ctx = NodeAggregationContext { + additions: AtomicU32::new(0), + something_with_lifetime: &something_with_lifetime, + add_value: true, + }; + + let mut seed_buffer = [0; 32]; + seed_buffer[0..4].copy_from_slice(&seed.to_be_bytes()); + let mut r = SmallRng::from_seed(seed_buffer); + let mut nodes = Vec::new(); + for i in 0..count { + nodes.push(Node::new(i)); + } + prepare_aggregation_data(&ctx, &NodeRef(nodes[0].clone())); + + let mut edges = IndexSet::new(); + + for _ in 0..1000 { + match r.gen_range(0..=2) { + 0 | 1 => { + // if x == 47 { + // print_all(&ctx, nodes.iter().cloned().map(NodeRef), true); + // } + // add edge + let parent = r.gen_range(0..nodes.len() - 1); + let child = r.gen_range(parent + 1..nodes.len()); + // println!("add edge {} -> {}", parent, child); + if edges.insert((parent, child)) { + nodes[parent].add_child(&ctx, nodes[child].clone()); + } + } + 2 => { + // remove edge + if edges.is_empty() { + continue; + } + let i = r.gen_range(0..edges.len()); + let (parent, child) = edges.swap_remove_index(i).unwrap(); + // println!("remove edge {} -> {}", parent, child); + nodes[parent].remove_child(&ctx, &nodes[child]); + } + _ => unreachable!(), + } + } + + for (parent, child) in edges { + nodes[parent].remove_child(&ctx, &nodes[child]); + } + + assert_eq!(aggregation_data(&ctx, &NodeRef(nodes[0].clone())).value, 0); + + check_invariants(&ctx, nodes.iter().cloned().map(NodeRef)); + + for node in nodes { + let lock = node.inner.lock(); + if let AggregationNode::Aggegating(a) = &lock.aggregation_node { + assert_eq!(a.data.value, lock.value as i32); + } + } +} + +fn print(aggregation_context: &NodeAggregationContext<'_>, root: &NodeRef, show_internal: bool) { + print_all(aggregation_context, once(root.clone()), show_internal); +} + +fn print_all( + aggregation_context: &NodeAggregationContext<'_>, + nodes: impl IntoIterator, + show_internal: bool, +) { + println!("digraph {{"); + print_graph(aggregation_context, nodes, show_internal, |item| { + let lock = item.0.inner.lock(); + if let AggregationNode::Aggegating(a) = &lock.aggregation_node { + format!("#{} [{}]", lock.value, a.data.value) + } else { + format!("#{}", lock.value) + } + }); + println!("\n}}"); +} diff --git a/turbopack/crates/turbo-tasks-memory/src/aggregation/uppers.rs b/turbopack/crates/turbo-tasks-memory/src/aggregation/uppers.rs new file mode 100644 index 0000000000000..581341b0f1630 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/aggregation/uppers.rs @@ -0,0 +1,257 @@ +use super::{ + balance_queue::BalanceQueue, + in_progress::start_in_progress_count, + optimize::{optimize_aggregation_number_for_uppers, MAX_UPPERS}, + AggegatingNode, AggregationContext, AggregationNode, AggregationNodeGuard, + PreparedInternalOperation, PreparedOperation, StackVec, +}; +use crate::count_hash_set::RemovePositiveCountResult; + +/// Adds an upper node to a node. Returns the number of affected nodes by this +/// operation. This will also propagate the followers to the new upper node. +pub fn add_upper( + ctx: &C, + balance_queue: &mut BalanceQueue, + node: C::Guard<'_>, + node_id: &C::NodeRef, + upper_id: &C::NodeRef, + already_optimizing_for_upper: bool, +) -> usize { + add_upper_count( + ctx, + balance_queue, + node, + node_id, + upper_id, + 1, + already_optimizing_for_upper, + ) + .affected_nodes +} + +pub struct AddUpperCountResult { + pub new_count: isize, + pub affected_nodes: usize, +} + +/// Adds an upper node to a node with a given count. Returns the new count of +/// the upper node and the number of affected nodes by this operation. This will +/// also propagate the followers to the new upper node. +pub fn add_upper_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + upper_id: &C::NodeRef, + count: usize, + already_optimizing_for_upper: bool, +) -> AddUpperCountResult { + // TODO add_clonable_count could return the current count for better performance + let (added, count) = match &mut *node { + AggregationNode::Leaf { uppers, .. } => { + if uppers.add_clonable_count(upper_id, count) { + let count = uppers.get_count(upper_id); + (true, count) + } else { + (false, uppers.get_count(upper_id)) + } + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { ref mut uppers, .. } = **aggegating; + if uppers.add_clonable_count(upper_id, count) { + let count = uppers.get_count(upper_id); + (true, count) + } else { + (false, uppers.get_count(upper_id)) + } + } + }; + let mut affected_nodes = 0; + if added { + affected_nodes = on_added( + ctx, + balance_queue, + node, + node_id, + upper_id, + already_optimizing_for_upper, + ); + } else { + drop(node); + } + AddUpperCountResult { + new_count: count, + affected_nodes, + } +} + +/// Called when an upper node was added to a node. This will propagate the +/// followers to the new upper node. +pub fn on_added( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + node_id: &C::NodeRef, + upper_id: &C::NodeRef, + already_optimizing_for_upper: bool, +) -> usize { + let uppers = node.uppers(); + let uppers_len = uppers.len(); + let optimize = + (!already_optimizing_for_upper && uppers_len >= MAX_UPPERS && uppers_len.count_ones() == 1) + .then(|| (true, uppers.iter().cloned().collect::>())); + let (add_change, followers) = match &mut *node { + AggregationNode::Leaf { .. } => { + let add_change = node.get_add_change(); + let children = node.children().collect::>(); + start_in_progress_count(ctx, upper_id, children.len() as u32); + drop(node); + (add_change, children) + } + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { ref followers, .. } = **aggegating; + let add_change = ctx.data_to_add_change(&aggegating.data); + let followers = followers.iter().cloned().collect::>(); + start_in_progress_count(ctx, upper_id, followers.len() as u32); + drop(node); + + (add_change, followers) + } + }; + + let mut optimizing = false; + + // This heuristic ensures that we don’t have too many upper edges, which would + // degrade update performance + if let Some((leaf, uppers)) = optimize { + optimizing = + optimize_aggregation_number_for_uppers(ctx, balance_queue, node_id, leaf, uppers); + } + + let mut affected_nodes = 0; + + // Make sure to propagate the change to the upper node + let mut upper = ctx.node(upper_id); + let add_prepared = add_change.and_then(|add_change| upper.apply_change(ctx, add_change)); + affected_nodes += followers.len(); + let prepared = followers + .into_iter() + .filter_map(|child_id| { + upper.notify_new_follower(ctx, balance_queue, upper_id, &child_id, optimizing) + }) + .collect::>(); + drop(upper); + add_prepared.apply(ctx); + for prepared in prepared { + affected_nodes += prepared.apply(ctx, balance_queue); + } + + affected_nodes +} + +/// Removes an upper node from a node with a count. +pub fn remove_upper_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + upper_id: &C::NodeRef, + count: usize, +) { + let uppers = match &mut *node { + AggregationNode::Leaf { uppers, .. } => uppers, + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { ref mut uppers, .. } = **aggegating; + uppers + } + }; + let removed = uppers.remove_clonable_count(upper_id, count); + if removed { + uppers.shrink_amortized(); + on_removed(ctx, balance_queue, node, upper_id); + } +} + +pub struct RemovePositiveUpperCountResult { + pub removed_count: usize, + pub remaining_count: isize, +} + +/// Removes a positive count of an upper node from a node. +/// Returns the removed count and the remaining count of the upper node. +/// This will also propagate the followers to the removed upper node. +pub fn remove_positive_upper_count( + ctx: &C, + balance_queue: &mut BalanceQueue, + mut node: C::Guard<'_>, + upper_id: &C::NodeRef, + count: usize, +) -> RemovePositiveUpperCountResult { + let uppers = match &mut *node { + AggregationNode::Leaf { uppers, .. } => uppers, + AggregationNode::Aggegating(aggegating) => { + let AggegatingNode { ref mut uppers, .. } = **aggegating; + uppers + } + }; + let RemovePositiveCountResult { + removed, + removed_count, + count, + } = uppers.remove_positive_clonable_count(upper_id, count); + if removed { + uppers.shrink_amortized(); + on_removed(ctx, balance_queue, node, upper_id); + } + RemovePositiveUpperCountResult { + removed_count, + remaining_count: count, + } +} + +/// Called when an upper node was removed from a node. This will propagate the +/// followers to the removed upper node. +pub fn on_removed( + ctx: &C, + balance_queue: &mut BalanceQueue, + node: C::Guard<'_>, + upper_id: &C::NodeRef, +) { + match &*node { + AggregationNode::Leaf { .. } => { + let remove_change = node.get_remove_change(); + let children = node.children().collect::>(); + drop(node); + let mut upper = ctx.node(upper_id); + let remove_prepared = + remove_change.and_then(|remove_change| upper.apply_change(ctx, remove_change)); + start_in_progress_count(ctx, upper_id, children.len() as u32); + let prepared = children + .into_iter() + .map(|child_id| upper.notify_lost_follower(ctx, balance_queue, upper_id, &child_id)) + .collect::>(); + drop(upper); + remove_prepared.apply(ctx); + prepared.apply(ctx, balance_queue); + } + AggregationNode::Aggegating(aggegating) => { + let remove_change = ctx.data_to_remove_change(&aggegating.data); + let followers = aggegating + .followers + .iter() + .cloned() + .collect::>(); + drop(node); + let mut upper = ctx.node(upper_id); + let remove_prepared = + remove_change.and_then(|remove_change| upper.apply_change(ctx, remove_change)); + start_in_progress_count(ctx, upper_id, followers.len() as u32); + let prepared = followers + .into_iter() + .map(|child_id| upper.notify_lost_follower(ctx, balance_queue, upper_id, &child_id)) + .collect::>(); + drop(upper); + remove_prepared.apply(ctx); + prepared.apply(ctx, balance_queue); + } + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/cell.rs b/turbopack/crates/turbo-tasks-memory/src/cell.rs new file mode 100644 index 0000000000000..1f82d32dc3661 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/cell.rs @@ -0,0 +1,272 @@ +use std::{fmt::Debug, mem::replace}; + +use turbo_tasks::{ + backend::CellContent, + event::{Event, EventListener}, + TaskId, TaskIdSet, TurboTasksBackendApi, +}; + +use crate::MemoryBackend; + +#[derive(Default, Debug)] +pub(crate) struct Cell { + dependent_tasks: TaskIdSet, + state: CellState, +} + +#[derive(Default, Debug)] +pub(crate) enum CellState { + /// No content has been set yet, or + /// it was removed for memory pressure reasons, or + /// cell is no longer used (It was assigned once and then no longer used + /// after recomputation). + /// + /// Assigning a value will transition to the Value state. + /// Reading this cell will, + /// - transition to the Computing state if the task is is progress + /// - return an error if the task is already done. + #[default] + Empty, + /// The content has been removed for memory pressure reasons, but the + /// tracking is still active. Any update will invalidate dependent tasks. + /// Assigning a value will transition to the Value state. + /// Reading this cell will transition to the Computing state. + TrackedValueless, + /// Someone wanted to read the content and it was not available. The content + /// is now being computed. + /// Assigning a value will transition to the Value state. + /// When the task ends this transitions to the Empty state if not assigned. + Computing { + /// The event that will be triggered when transitioning to another + /// state. + event: Event, + }, + /// The content was set only once and is tracked. + /// GC operation will transition to the TrackedValueless state. + Value { content: CellContent }, +} + +pub enum ReadContentError { + Computing { + listener: EventListener, + schedule: bool, + }, + Unused, +} + +impl Cell { + /// Removes a task from the list of dependent tasks. + pub fn remove_dependent_task(&mut self, task: TaskId) { + self.dependent_tasks.remove(&task); + } + + /// Switch the cell to recomputing state. + fn compute( + &mut self, + description: impl Fn() -> String + Sync + Send + 'static, + note: impl Fn() -> String + Sync + Send + 'static, + ) -> EventListener { + let event = Event::new(move || (description)() + " -> CellState::Computing::event"); + let listener = event.listen_with_note(note); + self.state = CellState::Computing { event }; + listener + } + + /// Read the content of the cell when avaiable. Registers the reader as + /// dependent task. Will trigger recomputation is no content is + /// available. + pub fn read_content( + &mut self, + reader: TaskId, + task_done: bool, + description: impl Fn() -> String + Sync + Send + 'static, + note: impl Fn() -> String + Sync + Send + 'static, + ) -> Result { + match &self.state { + CellState::Value { content } => { + self.dependent_tasks.insert(reader); + Ok(content.clone()) + } + CellState::Empty if task_done => { + self.dependent_tasks.insert(reader); + Err(ReadContentError::Unused) + } + _ => { + // Same behavior for all other states, so we reuse the same code. + self.read_content_untracked(task_done, description, note) + } + } + } + + /// Read the content of the cell when avaiable. Does not register the reader + /// as dependent task. Will trigger recomputation is no content is + /// available. + /// + /// INVALIDATION: Be careful with this, it will not + /// track dependencies, so using it could break cache invalidation. + pub fn read_content_untracked( + &mut self, + task_done: bool, + description: impl Fn() -> String + Sync + Send + 'static, + note: impl Fn() -> String + Sync + Send + 'static, + ) -> Result { + match &self.state { + CellState::Value { content } => Ok(content.clone()), + CellState::Empty => { + if task_done { + Err(ReadContentError::Unused) + } else { + let listener = self.compute(description, note); + Err(ReadContentError::Computing { + listener, + schedule: true, + }) + } + } + CellState::Computing { event } => { + let listener = event.listen_with_note(note); + Err(ReadContentError::Computing { + listener, + schedule: false, + }) + } + CellState::TrackedValueless => { + let listener = self.compute(description, note); + Err(ReadContentError::Computing { + listener, + schedule: true, + }) + } + } + } + + /// Read the content of the cell when avaiable. Does not register the reader + /// as dependent task. Will not start recomputing when content is not + /// available. + /// + /// INVALIDATION: Be careful with this, it will not track + /// dependencies, so using it could break cache invalidation. + pub fn read_own_content_untracked(&self) -> CellContent { + match &self.state { + CellState::Empty | CellState::Computing { .. } | CellState::TrackedValueless => { + CellContent(None) + } + CellState::Value { content } => content.to_owned(), + } + } + + /// Assigns a new content to the cell. Will notify dependent tasks if the + /// content has changed. + /// If clean = true, the task inputs weren't changes since the last + /// execution and can be assumed to produce the same content again. + /// + /// Safety: This funtion does not check if the type of the content is the + /// same as the type of the cell. It is the caller's responsibility to + /// ensure that the content is of the correct type. + pub fn assign( + &mut self, + content: CellContent, + clean: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + match &self.state { + CellState::Empty => {} + CellState::Computing { event } => { + event.notify(usize::MAX); + if clean { + // We can assume that the task is deterministic and produces the same content + // again. No need to notify dependent tasks. + self.state = CellState::Value { content }; + return; + } + } + CellState::TrackedValueless => { + if clean { + // We can assume that the task is deterministic and produces the same content + // again. No need to notify dependent tasks. + self.state = CellState::Value { content }; + return; + } + } + CellState::Value { + content: cell_content, + } => { + if content == *cell_content { + return; + } + } + } + self.state = CellState::Value { content }; + // Assigning to a cell will invalidate all dependent tasks as the content might + // have changed. + if !self.dependent_tasks.is_empty() { + turbo_tasks.schedule_notify_tasks_set(&self.dependent_tasks); + self.dependent_tasks.clear(); + } + } + + pub fn empty( + &mut self, + clean: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Option { + let content = match replace(&mut self.state, CellState::Empty) { + CellState::TrackedValueless | CellState::Empty => None, + CellState::Computing { event } => { + event.notify(usize::MAX); + if clean { + // We can assume that the task is deterministic and produces the same content + // again. No need to notify dependent tasks. + return None; + } + None + } + CellState::Value { content } => Some(content), + }; + // Assigning to a cell will invalidate all dependent tasks as the content might + // have changed. + if !self.dependent_tasks.is_empty() { + turbo_tasks.schedule_notify_tasks_set(&self.dependent_tasks); + self.dependent_tasks.clear(); + } + content + } + + /// Reduces memory needs to the minimum. + pub fn shrink_to_fit(&mut self) { + self.dependent_tasks.shrink_to_fit(); + } + + /// Returns true if the cell is current not used and could be dropped from + /// the array. + pub fn is_unused(&self) -> bool { + self.dependent_tasks.is_empty() && matches!(self.state, CellState::Empty) + } + + /// Takes the content out of the cell. Make sure to drop the content outside + /// of the task state lock. + #[must_use] + pub fn gc_content(&mut self) -> Option { + match self.state { + CellState::Empty | CellState::Computing { .. } | CellState::TrackedValueless => None, + CellState::Value { .. } => { + let CellState::Value { content, .. } = + replace(&mut self.state, CellState::TrackedValueless) + else { + unreachable!() + }; + Some(content) + } + } + } + + /// Drops the cell after GC. Will notify all dependent tasks and events. + pub fn gc_drop(self, turbo_tasks: &dyn TurboTasksBackendApi) { + if !self.dependent_tasks.is_empty() { + turbo_tasks.schedule_notify_tasks_set(&self.dependent_tasks); + } + if let CellState::Computing { event } = self.state { + event.notify(usize::MAX); + } + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/count_hash_set.rs b/turbopack/crates/turbo-tasks-memory/src/count_hash_set.rs new file mode 100644 index 0000000000000..d872a614c5df1 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/count_hash_set.rs @@ -0,0 +1,522 @@ +use std::{ + borrow::Borrow, + cmp::Ordering, + collections::hash_map::RandomState, + fmt::{Debug, Formatter}, + hash::{BuildHasher, Hash}, + iter::FilterMap, +}; + +use auto_hash_map::{ + map::{Entry, Iter, RawEntry}, + AutoMap, +}; + +#[derive(Clone)] +pub struct CountHashSet { + inner: AutoMap, + negative_entries: usize, +} + +impl Debug for CountHashSet { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("CountHashSet") + .field("inner", &self.inner) + .field("negative_entries", &self.negative_entries) + .finish() + } +} + +impl From<[T; N]> for CountHashSet { + fn from(list: [T; N]) -> Self { + let mut set = CountHashSet::default(); + for item in list { + set.add(item); + } + set + } +} + +impl Default for CountHashSet { + fn default() -> Self { + Self { + inner: Default::default(), + negative_entries: 0, + } + } +} + +impl FromIterator for CountHashSet { + fn from_iter>(iter: I) -> Self { + let mut set = CountHashSet::default(); + for item in iter { + set.add(item); + } + set + } +} + +impl CountHashSet { + pub fn new() -> Self { + Self::default() + } +} + +impl CountHashSet { + /// Get the number of positive entries + pub fn len(&self) -> usize { + self.inner.len() - self.negative_entries + } + + /// Checks if the set looks empty from outside. It might still have negative + /// entries, but they should be treated as not existing. + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +#[derive(Debug, PartialEq, Eq)] +pub enum RemoveIfEntryResult { + PartiallyRemoved, + Removed, + NotPresent, +} + +pub struct RemovePositiveCountResult { + pub removed: bool, + pub removed_count: usize, + pub count: isize, +} + +impl CountHashSet { + /// Returns true, when the value has become visible from outside + pub fn add_count(&mut self, item: T, count: usize) -> bool { + if count == 0 { + return false; + } + match self.inner.entry(item) { + Entry::Occupied(mut e) => { + let value = e.get_mut(); + let old = *value; + *value += count as isize; + if old > 0 { + // it was positive before + false + } else if *value > 0 { + // it was negative and has become positive + self.negative_entries -= 1; + true + } else if *value == 0 { + // it was negative and has become zero + self.negative_entries -= 1; + e.remove(); + false + } else { + // it was and still is negative + false + } + } + Entry::Vacant(e) => { + // it was zero and is now positive + e.insert(count as isize); + true + } + } + } + + /// Returns true when the value has become visible from outside + pub fn add(&mut self, item: T) -> bool { + self.add_count(item, 1) + } + + /// Returns true, when the value has been added. Returns false, when the + /// value was not part of the set before (positive or negative). The + /// visibility from outside will never change due to this method. + pub fn add_if_entry(&mut self, item: &Q) -> bool + where + T: Borrow, + Q: Hash + Eq + ?Sized, + { + match self.inner.raw_entry_mut(item) { + RawEntry::Occupied(mut e) => { + let value = e.get_mut(); + *value += 1; + if *value == 0 { + // it was negative and has become zero + self.negative_entries -= 1; + e.remove(); + } + true + } + RawEntry::Vacant(_) => false, + } + } + + /// Removes an item if it is present. + pub fn remove_if_entry(&mut self, item: &T) -> RemoveIfEntryResult { + match self.inner.raw_entry_mut(item) { + RawEntry::Occupied(mut e) => { + let value = e.get_mut(); + if *value < 0 { + return RemoveIfEntryResult::NotPresent; + } + *value -= 1; + if *value == 0 { + // It was positive and has become zero + e.remove(); + RemoveIfEntryResult::Removed + } else { + RemoveIfEntryResult::PartiallyRemoved + } + } + RawEntry::Vacant(_) => RemoveIfEntryResult::NotPresent, + } + } + + pub fn iter(&self) -> CountHashSetIter<'_, T> { + CountHashSetIter { + inner: self.inner.iter().filter_map(filter), + count: self.inner.len() - self.negative_entries, + } + } + + pub fn get_count(&self, item: &T) -> isize { + match self.inner.get(item) { + Some(value) => *value, + None => 0, + } + } + + /// Frees unused memory + pub fn shrink_to_fit(&mut self) { + self.inner.shrink_to_fit(); + } + + /// Frees unused memory in an amortized way + pub fn shrink_amortized(&mut self) { + self.inner.shrink_amortized() + } +} + +impl CountHashSet { + /// Returns true, when the value has become visible from outside + pub fn add_clonable_count(&mut self, item: &T, count: usize) -> bool { + if count == 0 { + return false; + } + match self.inner.raw_entry_mut(item) { + RawEntry::Occupied(mut e) => { + let value = e.get_mut(); + let old = *value; + *value += count as isize; + if old > 0 { + // it was positive before + false + } else if *value > 0 { + // it was negative and has become positive + self.negative_entries -= 1; + true + } else if *value == 0 { + // it was negative and has become zero + self.negative_entries -= 1; + e.remove(); + false + } else { + // it was and still is negative + false + } + } + RawEntry::Vacant(e) => { + // it was zero and is now positive + e.insert(item.clone(), count as isize); + true + } + } + } + + /// Returns true when the value has become visible from outside + pub fn add_clonable(&mut self, item: &T) -> bool { + self.add_clonable_count(item, 1) + } + + /// Returns true when the value is no longer visible from outside + pub fn remove_clonable_count(&mut self, item: &T, count: usize) -> bool { + if count == 0 { + return false; + } + match self.inner.raw_entry_mut(item) { + RawEntry::Occupied(mut e) => { + let value = e.get_mut(); + let old = *value; + *value -= count as isize; + if *value > 0 { + // It was and still is positive + false + } else if *value == 0 { + // It was positive and has become zero + e.remove(); + true + } else if old > 0 { + // It was positive and is negative now + self.negative_entries += 1; + true + } else { + // It was and still is negative + false + } + } + RawEntry::Vacant(e) => { + // It was zero and is negative now + e.insert(item.clone(), -(count as isize)); + self.negative_entries += 1; + false + } + } + } + + /// Returns true when the value is no longer visible from outside + pub fn remove_positive_clonable_count( + &mut self, + item: &T, + count: usize, + ) -> RemovePositiveCountResult { + if count == 0 { + return RemovePositiveCountResult { + removed: false, + removed_count: 0, + count: self.inner.get(item).copied().unwrap_or(0), + }; + } + match self.inner.raw_entry_mut(item) { + RawEntry::Occupied(mut e) => { + let value = e.get_mut(); + let old = *value; + match old.cmp(&(count as isize)) { + Ordering::Less => { + if old < 0 { + // It's already negative, can't remove anything + RemovePositiveCountResult { + removed: false, + removed_count: 0, + count: old, + } + } else { + // It's removed completely with count remaining + e.remove(); + RemovePositiveCountResult { + removed: true, + removed_count: old as usize, + count: 0, + } + } + } + Ordering::Equal => { + // It's perfectly removed + e.remove(); + RemovePositiveCountResult { + removed: true, + removed_count: count, + count: 0, + } + } + Ordering::Greater => { + // It's partially removed + *value -= count as isize; + RemovePositiveCountResult { + removed: false, + removed_count: count, + count: *value, + } + } + } + } + RawEntry::Vacant(_) => { + // It's not present + RemovePositiveCountResult { + removed: false, + removed_count: 0, + count: 0, + } + } + } + } +} + +fn filter<'a, T>((k, v): (&'a T, &'a isize)) -> Option<&'a T> { + if *v > 0 { + Some(k) + } else { + None + } +} + +type InnerIter<'a, T> = + FilterMap, for<'b> fn((&'b T, &'b isize)) -> Option<&'b T>>; + +pub struct CountHashSetIter<'a, T> { + inner: InnerIter<'a, T>, + count: usize, +} + +impl<'a, T> Iterator for CountHashSetIter<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + self.count = self.count.saturating_sub(1); + self.inner.next() + } + + fn size_hint(&self) -> (usize, Option) { + (self.count, Some(self.count)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_add_remove() { + let mut set: CountHashSet = CountHashSet::new(); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(set.add(1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(!set.add(1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(set.add(2)); + assert_eq!(set.len(), 2); + assert!(!set.is_empty()); + + assert!(set.remove_clonable_count(&2, 2)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(!set.remove_clonable_count(&2, 1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(!set.remove_clonable_count(&1, 1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(set.remove_clonable_count(&1, 1)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(!set.add_count(2, 2)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert_eq!( + format!("{:?}", set), + "CountHashSet { inner: {}, negative_entries: 0 }" + ); + } + + #[test] + fn test_add_remove_cloneable() { + let mut set: CountHashSet = CountHashSet::new(); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(set.add_clonable_count(&1, 1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(!set.add_clonable_count(&1, 1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(set.add_clonable_count(&2, 1)); + assert_eq!(set.len(), 2); + assert!(!set.is_empty()); + + assert!(set.remove_clonable_count(&2, 2)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(!set.remove_clonable_count(&2, 1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(!set.remove_clonable_count(&1, 1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert!(set.remove_clonable_count(&1, 1)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(!set.add_clonable_count(&2, 2)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert_eq!( + format!("{:?}", set), + "CountHashSet { inner: {}, negative_entries: 0 }" + ); + } + + #[test] + fn test_add_remove_if_entry() { + let mut set: CountHashSet = CountHashSet::new(); + + assert!(!set.add_if_entry(&1)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(set.add(1)); + + assert!(set.add_if_entry(&1)); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert_eq!( + set.remove_if_entry(&1), + RemoveIfEntryResult::PartiallyRemoved + ); + assert_eq!(set.len(), 1); + assert!(!set.is_empty()); + + assert_eq!(set.remove_if_entry(&1), RemoveIfEntryResult::Removed); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert_eq!(set.remove_if_entry(&1), RemoveIfEntryResult::NotPresent); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + } + + #[test] + fn test_zero() { + let mut set: CountHashSet = CountHashSet::new(); + + assert!(!set.add_count(1, 0)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(!set.remove_clonable_count(&1, 0)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(!set.add_clonable_count(&1, 0)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(!set.remove_clonable_count(&1, 0)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert!(!set.remove_clonable_count(&1, 1)); + assert_eq!(set.len(), 0); + assert!(set.is_empty()); + + assert_eq!(set.remove_if_entry(&1), RemoveIfEntryResult::NotPresent); + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/edges_set.rs b/turbopack/crates/turbo-tasks-memory/src/edges_set.rs new file mode 100644 index 0000000000000..648841200db90 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/edges_set.rs @@ -0,0 +1,585 @@ +use std::{hash::BuildHasherDefault, mem::replace}; + +use auto_hash_map::{map::Entry, AutoMap, AutoSet}; +use either::Either; +use rustc_hash::FxHasher; +use smallvec::SmallVec; +use turbo_tasks::{CellId, TaskId, TraitTypeId, ValueTypeId}; + +#[derive(Hash, Copy, Clone, PartialEq, Eq)] +pub enum TaskEdge { + Output(TaskId), + Cell(TaskId, CellId), + Collectibles(TaskId, TraitTypeId), + Child(TaskId), +} + +impl TaskEdge { + fn task_and_edge_entry(self) -> (TaskId, EdgeEntry) { + match self { + TaskEdge::Output(task) => (task, EdgeEntry::Output), + TaskEdge::Cell(task, cell_id) => (task, EdgeEntry::Cell(cell_id)), + TaskEdge::Collectibles(task, trait_type_id) => { + (task, EdgeEntry::Collectibles(trait_type_id)) + } + TaskEdge::Child(task) => (task, EdgeEntry::Child), + } + } +} + +#[derive(Hash, Copy, Clone, PartialEq, Eq, Debug)] +enum EdgeEntry { + Output, + Child, + Cell(CellId), + Collectibles(TraitTypeId), +} + +impl EdgeEntry { + fn into_dependency(self, task: TaskId) -> TaskEdge { + match self { + EdgeEntry::Output => TaskEdge::Output(task), + EdgeEntry::Cell(cell_id) => TaskEdge::Cell(task, cell_id), + EdgeEntry::Collectibles(trait_type_id) => TaskEdge::Collectibles(task, trait_type_id), + EdgeEntry::Child => TaskEdge::Child(task), + } + } +} + +type ComplexSet = AutoSet, 9>; + +/// Represents a set of [`EdgeEntry`]s for an individual task, where common +/// cases are stored using compact representations. +#[derive(Debug)] +enum EdgesDataEntry { + Empty, + Output, + Child, + ChildAndOutput, + Cell0(ValueTypeId), + ChildAndCell0(ValueTypeId), + OutputAndCell0(ValueTypeId), + ChildOutputAndCell0(ValueTypeId), + Complex(Box), +} + +impl EdgesDataEntry { + fn from(entry: EdgeEntry) -> Self { + match entry { + EdgeEntry::Output => EdgesDataEntry::Output, + EdgeEntry::Child => EdgesDataEntry::Child, + EdgeEntry::Cell(CellId { type_id, index }) => { + if index == 0 { + EdgesDataEntry::Cell0(type_id) + } else { + let mut set = AutoSet::default(); + set.insert(EdgeEntry::Cell(CellId { type_id, index })); + EdgesDataEntry::Complex(Box::new(set)) + } + } + EdgeEntry::Collectibles(trait_type_id) => { + let mut set = AutoSet::default(); + set.insert(EdgeEntry::Collectibles(trait_type_id)); + EdgesDataEntry::Complex(Box::new(set)) + } + } + } + + fn into_iter(self) -> impl Iterator { + match self { + EdgesDataEntry::Empty => unreachable!(), + EdgesDataEntry::Output => Either::Left(Either::Left([EdgeEntry::Output].into_iter())), + EdgesDataEntry::Child => Either::Left(Either::Left([EdgeEntry::Child].into_iter())), + EdgesDataEntry::Cell0(type_id) => Either::Left(Either::Left( + [EdgeEntry::Cell(CellId { type_id, index: 0 })].into_iter(), + )), + EdgesDataEntry::ChildAndOutput => Either::Left(Either::Right( + [EdgeEntry::Child, EdgeEntry::Output].into_iter(), + )), + EdgesDataEntry::ChildAndCell0(type_id) => Either::Left(Either::Right( + [ + EdgeEntry::Child, + EdgeEntry::Cell(CellId { type_id, index: 0 }), + ] + .into_iter(), + )), + EdgesDataEntry::OutputAndCell0(type_id) => Either::Left(Either::Right( + [ + EdgeEntry::Output, + EdgeEntry::Cell(CellId { type_id, index: 0 }), + ] + .into_iter(), + )), + EdgesDataEntry::ChildOutputAndCell0(type_id) => Either::Right(Either::Left( + [ + EdgeEntry::Child, + EdgeEntry::Output, + EdgeEntry::Cell(CellId { type_id, index: 0 }), + ] + .into_iter(), + )), + EdgesDataEntry::Complex(set) => Either::Right(Either::Right(set.into_iter())), + } + } + + fn iter(&self) -> impl Iterator + '_ { + match self { + EdgesDataEntry::Empty => unreachable!(), + EdgesDataEntry::Output => Either::Left(Either::Left([EdgeEntry::Output].into_iter())), + EdgesDataEntry::Child => Either::Left(Either::Left([EdgeEntry::Child].into_iter())), + EdgesDataEntry::Cell0(type_id) => Either::Left(Either::Left( + [EdgeEntry::Cell(CellId { + type_id: *type_id, + index: 0, + })] + .into_iter(), + )), + EdgesDataEntry::ChildAndOutput => Either::Left(Either::Right( + [EdgeEntry::Child, EdgeEntry::Output].into_iter(), + )), + EdgesDataEntry::ChildAndCell0(type_id) => Either::Left(Either::Right( + [ + EdgeEntry::Child, + EdgeEntry::Cell(CellId { + type_id: *type_id, + index: 0, + }), + ] + .into_iter(), + )), + EdgesDataEntry::OutputAndCell0(type_id) => Either::Left(Either::Right( + [ + EdgeEntry::Output, + EdgeEntry::Cell(CellId { + type_id: *type_id, + index: 0, + }), + ] + .into_iter(), + )), + EdgesDataEntry::ChildOutputAndCell0(type_id) => Either::Right(Either::Left( + [ + EdgeEntry::Child, + EdgeEntry::Output, + EdgeEntry::Cell(CellId { + type_id: *type_id, + index: 0, + }), + ] + .into_iter(), + )), + EdgesDataEntry::Complex(set) => Either::Right(Either::Right(set.iter().copied())), + } + } + + fn has(&self, entry: EdgeEntry) -> bool { + match (entry, self) { + ( + EdgeEntry::Output, + EdgesDataEntry::Output + | EdgesDataEntry::OutputAndCell0(_) + | EdgesDataEntry::ChildAndOutput + | EdgesDataEntry::ChildOutputAndCell0(_), + ) => true, + ( + EdgeEntry::Child, + EdgesDataEntry::Child + | EdgesDataEntry::ChildAndOutput + | EdgesDataEntry::ChildAndCell0(_) + | EdgesDataEntry::ChildOutputAndCell0(_), + ) => true, + ( + EdgeEntry::Cell(cell_id), + EdgesDataEntry::Cell0(type_id) + | EdgesDataEntry::OutputAndCell0(type_id) + | EdgesDataEntry::ChildAndCell0(type_id) + | EdgesDataEntry::ChildOutputAndCell0(type_id), + ) => *type_id == cell_id.type_id, + (entry, EdgesDataEntry::Complex(set)) => set.contains(&entry), + _ => false, + } + } + + fn as_complex(&mut self) -> &mut ComplexSet { + match self { + EdgesDataEntry::Complex(set) => set, + _ => { + let items = replace(self, EdgesDataEntry::Output).into_iter().collect(); + *self = EdgesDataEntry::Complex(Box::new(items)); + let EdgesDataEntry::Complex(set) = self else { + unreachable!(); + }; + set + } + } + } + + fn try_insert_without_complex(&mut self, entry: EdgeEntry) -> Result { + if self.has(entry) { + return Ok(false); + } + match entry { + EdgeEntry::Output => match self { + EdgesDataEntry::Child => { + *self = EdgesDataEntry::ChildAndOutput; + return Ok(true); + } + EdgesDataEntry::Cell0(type_id) => { + *self = EdgesDataEntry::OutputAndCell0(*type_id); + return Ok(true); + } + EdgesDataEntry::ChildAndCell0(type_id) => { + *self = EdgesDataEntry::ChildOutputAndCell0(*type_id); + return Ok(true); + } + _ => {} + }, + EdgeEntry::Child => match self { + EdgesDataEntry::Output => { + *self = EdgesDataEntry::ChildAndOutput; + return Ok(true); + } + EdgesDataEntry::Cell0(type_id) => { + *self = EdgesDataEntry::ChildAndCell0(*type_id); + return Ok(true); + } + EdgesDataEntry::OutputAndCell0(type_id) => { + *self = EdgesDataEntry::ChildOutputAndCell0(*type_id); + return Ok(true); + } + _ => {} + }, + EdgeEntry::Cell(type_id) => { + let CellId { type_id, index } = type_id; + if index == 0 { + match self { + EdgesDataEntry::Output => { + *self = EdgesDataEntry::OutputAndCell0(type_id); + return Ok(true); + } + EdgesDataEntry::Child => { + *self = EdgesDataEntry::ChildAndCell0(type_id); + return Ok(true); + } + EdgesDataEntry::ChildAndOutput => { + *self = EdgesDataEntry::ChildOutputAndCell0(type_id); + return Ok(true); + } + _ => {} + } + } + } + EdgeEntry::Collectibles(_) => {} + } + Err(()) + } + + fn insert(&mut self, entry: EdgeEntry) -> bool { + match self.try_insert_without_complex(entry) { + Ok(true) => true, + Ok(false) => false, + Err(()) => self.as_complex().insert(entry), + } + } + + /// Removes the entry from the set, returning `true` if the entry was + /// present. When the entry was removed, `self` might become `Empty` and + /// must be removed. + fn remove(&mut self, entry: EdgeEntry) -> bool { + if !self.has(entry) { + return false; + } + // We verified that the entry is present, so any non-complex case is easier to + // handle + match entry { + EdgeEntry::Output => match self { + EdgesDataEntry::Output => { + *self = EdgesDataEntry::Empty; + return true; + } + EdgesDataEntry::ChildAndOutput => { + *self = EdgesDataEntry::Child; + return true; + } + EdgesDataEntry::OutputAndCell0(type_id) => { + *self = EdgesDataEntry::Cell0(*type_id); + return true; + } + EdgesDataEntry::ChildOutputAndCell0(type_id) => { + *self = EdgesDataEntry::ChildAndCell0(*type_id); + return true; + } + _ => {} + }, + EdgeEntry::Child => match self { + EdgesDataEntry::Child => { + *self = EdgesDataEntry::Empty; + return true; + } + EdgesDataEntry::ChildAndOutput => { + *self = EdgesDataEntry::Output; + return true; + } + EdgesDataEntry::ChildAndCell0(type_id) => { + *self = EdgesDataEntry::Cell0(*type_id); + return true; + } + EdgesDataEntry::ChildOutputAndCell0(type_id) => { + *self = EdgesDataEntry::OutputAndCell0(*type_id); + return true; + } + _ => {} + }, + EdgeEntry::Cell(_) => match self { + EdgesDataEntry::Cell0(_) => { + *self = EdgesDataEntry::Empty; + return true; + } + EdgesDataEntry::OutputAndCell0(_) => { + *self = EdgesDataEntry::Output; + return true; + } + EdgesDataEntry::ChildAndCell0(_) => { + *self = EdgesDataEntry::Child; + return true; + } + EdgesDataEntry::ChildOutputAndCell0(_) => { + *self = EdgesDataEntry::ChildAndOutput; + return true; + } + _ => {} + }, + EdgeEntry::Collectibles(_) => {} + } + if let EdgesDataEntry::Complex(set) = self { + if set.remove(&entry) { + self.simplify(); + return true; + } + } + false + } + + fn shrink_to_fit(&mut self) { + if let EdgesDataEntry::Complex(set) = self { + set.shrink_to_fit(); + } + } + + /// Simplifies the set by converting it to a more compact representation. + /// When `self` becomes `Empty`, it must be removed. + fn simplify(&mut self) { + if let EdgesDataEntry::Complex(set) = self { + match set.len() { + 0 => { + *self = EdgesDataEntry::Empty; + } + 1..=3 => { + let mut iter = set.iter(); + let first = iter.next().unwrap(); + if matches!( + first, + EdgeEntry::Output + | EdgeEntry::Child + | EdgeEntry::Cell(CellId { index: 0, .. }) + ) { + let mut new = EdgesDataEntry::from(*first); + for entry in iter { + if new.try_insert_without_complex(*entry).is_err() { + return; + } + } + *self = new; + } + } + _ => (), + } + } + } +} + +#[derive(Default, Debug)] +pub struct TaskEdgesSet { + edges: AutoMap>, +} + +impl TaskEdgesSet { + pub fn new() -> Self { + Self { + edges: Default::default(), + } + } + + pub fn insert(&mut self, edge: TaskEdge) -> bool { + let (task, edge) = edge.task_and_edge_entry(); + match self.edges.entry(task) { + Entry::Occupied(mut entry) => { + let entry = entry.get_mut(); + entry.insert(edge) + } + Entry::Vacant(entry) => { + entry.insert(EdgesDataEntry::from(edge)); + true + } + } + } + + pub fn shrink_to_fit(&mut self) { + for entry in self.edges.values_mut() { + entry.shrink_to_fit(); + } + self.edges.shrink_to_fit(); + } + + pub fn is_empty(&self) -> bool { + self.edges.is_empty() + } + + pub fn into_list(self) -> TaskEdgesList { + let mut edges = Vec::with_capacity(self.edges.len()); + self.edges.into_iter().for_each(|edge| edges.push(edge)); + TaskEdgesList { + edges: edges.into_boxed_slice(), + } + } + + pub(crate) fn drain_children(&mut self) -> SmallVec<[TaskId; 6]> { + let mut children = SmallVec::new(); + self.edges.retain(|&task, entry| match entry { + EdgesDataEntry::Child => { + children.push(task); + false + } + EdgesDataEntry::ChildAndOutput => { + children.push(task); + *entry = EdgesDataEntry::Output; + true + } + EdgesDataEntry::ChildAndCell0(type_id) => { + children.push(task); + *entry = EdgesDataEntry::Cell0(*type_id); + true + } + EdgesDataEntry::ChildOutputAndCell0(type_id) => { + children.push(task); + *entry = EdgesDataEntry::OutputAndCell0(*type_id); + true + } + EdgesDataEntry::Complex(set) => { + if set.remove(&EdgeEntry::Child) { + children.push(task); + entry.simplify(); + !matches!(entry, EdgesDataEntry::Empty) + } else { + true + } + } + _ => true, + }); + children + } + + /// Removes all dependencies from the passed `dependencies` argument + pub(crate) fn remove_all(&mut self, dependencies: &TaskEdgesSet) { + self.edges.retain(|task, entry| { + if let Some(other) = dependencies.edges.get(task) { + for item in other.iter() { + entry.remove(item); + } + !matches!(entry, EdgesDataEntry::Empty) + } else { + true + } + }); + } + + pub(crate) fn remove(&mut self, child_id: TaskEdge) -> bool { + let (task, edge) = child_id.task_and_edge_entry(); + let Entry::Occupied(mut entry) = self.edges.entry(task) else { + return false; + }; + let edge_entry = entry.get_mut(); + if edge_entry.remove(edge) { + if matches!(edge_entry, EdgesDataEntry::Empty) { + entry.remove(); + } + true + } else { + false + } + } + + pub fn children(&self) -> impl Iterator + '_ { + self.edges.iter().filter_map(|(task, entry)| match entry { + EdgesDataEntry::Child => Some(*task), + EdgesDataEntry::ChildAndOutput => Some(*task), + EdgesDataEntry::ChildAndCell0(_) => Some(*task), + EdgesDataEntry::ChildOutputAndCell0(_) => Some(*task), + EdgesDataEntry::Complex(set) => { + if set.contains(&EdgeEntry::Child) { + Some(*task) + } else { + None + } + } + _ => None, + }) + } +} + +impl IntoIterator for TaskEdgesSet { + type Item = TaskEdge; + type IntoIter = impl Iterator; + + fn into_iter(self) -> Self::IntoIter { + self.edges + .into_iter() + .flat_map(|(task, entry)| entry.into_iter().map(move |e| e.into_dependency(task))) + } +} + +#[derive(Default)] +pub struct TaskEdgesList { + edges: Box<[(TaskId, EdgesDataEntry)]>, +} + +impl TaskEdgesList { + pub fn into_set(self) -> TaskEdgesSet { + TaskEdgesSet { + edges: self.edges.into_vec().into_iter().collect(), + } + } + + pub fn is_empty(&self) -> bool { + self.edges.is_empty() + } + + pub fn children(&self) -> impl Iterator + '_ { + self.edges.iter().filter_map(|(task, entry)| match entry { + EdgesDataEntry::Child => Some(*task), + EdgesDataEntry::ChildAndOutput => Some(*task), + EdgesDataEntry::ChildAndCell0(_) => Some(*task), + EdgesDataEntry::ChildOutputAndCell0(_) => Some(*task), + EdgesDataEntry::Complex(set) => { + if set.contains(&EdgeEntry::Child) { + Some(*task) + } else { + None + } + } + _ => None, + }) + } +} + +impl IntoIterator for TaskEdgesList { + type Item = TaskEdge; + type IntoIter = impl Iterator; + + fn into_iter(self) -> Self::IntoIter { + self.edges + .into_vec() + .into_iter() + .flat_map(|(task, entry)| entry.into_iter().map(move |e| e.into_dependency(task))) + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/gc.rs b/turbopack/crates/turbo-tasks-memory/src/gc.rs new file mode 100644 index 0000000000000..fe3e70e82b34a --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/gc.rs @@ -0,0 +1,396 @@ +use std::{ + cmp::{max, Reverse}, + collections::VecDeque, + fmt::Debug, + mem::take, + num::NonZeroU32, + sync::atomic::{AtomicU32, AtomicUsize, Ordering}, + time::Duration, +}; + +use concurrent_queue::ConcurrentQueue; +use dashmap::DashSet; +use parking_lot::Mutex; +use tracing::field::{debug, Empty}; +use turbo_tasks::{TaskId, TurboTasksBackendApi}; + +use crate::{task::GcResult, MemoryBackend}; + +/// The priority of a task for garbage collection. +/// Any action will shrink the internal memory structures of the task in a +/// transparent way. +#[derive(Debug, Default, PartialEq, Eq, PartialOrd, Ord, Copy, Clone)] +pub struct GcPriority { + // Memory usage divided by compute duration. Specifies how efficient garbage collection would + // be with this task. Higher memory usage and lower compute duration makes it more likely to be + // garbage collected. + memory_per_time: u16, +} + +/// State about garbage collection for a task. +#[derive(Clone, Copy, Debug, Default)] +pub struct GcTaskState { + pub priority: GcPriority, + /// The generation where the task was last accessed. + pub generation: Option, +} + +impl GcTaskState { + pub(crate) fn execution_completed( + &mut self, + duration: Duration, + memory_usage: usize, + generation: NonZeroU32, + ) { + self.generation = Some(generation); + self.priority = GcPriority { + memory_per_time: ((memory_usage + TASK_BASE_MEMORY_USAGE) as u64 + / (duration.as_micros() as u64 + TASK_BASE_COMPUTE_DURATION_IN_MICROS)) + .try_into() + .unwrap_or(u16::MAX), + }; + } + + pub(crate) fn on_read(&mut self, generation: NonZeroU32) -> bool { + if let Some(old_generation) = self.generation { + if old_generation < generation { + self.generation = Some(generation); + true + } else { + false + } + } else { + self.generation = Some(generation); + true + } + } +} + +const MAX_DEACTIVATIONS: usize = 100_000; +const TASKS_PER_NEW_GENERATION: usize = 100_000; +const MAX_TASKS_PER_OLD_GENERATION: usize = 200_000; +const PERCENTAGE_TO_COLLECT: usize = 30; +const TASK_BASE_MEMORY_USAGE: usize = 1_000; +const TASK_BASE_COMPUTE_DURATION_IN_MICROS: u64 = 1_000; +pub const PERCENTAGE_MIN_TARGET_MEMORY: usize = 70; +pub const PERCENTAGE_MAX_TARGET_MEMORY: usize = 75; +pub const PERCENTAGE_MIN_IDLE_TARGET_MEMORY: usize = 55; +pub const PERCENTAGE_MAX_IDLE_TARGET_MEMORY: usize = 60; +pub const MAX_GC_STEPS: usize = 100; + +struct OldGeneration { + tasks: Vec, + generation: NonZeroU32, +} + +#[derive(Default)] +struct ProcessGenerationResult { + old_generations: usize, + priority: Option, + content_dropped_count: usize, + unloaded_count: usize, + already_unloaded_count: usize, +} + +struct ProcessDeactivationsResult { + count: usize, +} + +/// The queue of actions that garbage collection should perform. +pub struct GcQueue { + /// The current generation number. + generation: AtomicU32, + /// Fresh or read tasks that should added to the queue. + incoming_tasks: ConcurrentQueue, + /// Number of tasks in `incoming_tasks`. + incoming_tasks_count: AtomicUsize, + /// Tasks from old generations. The oldest generation will be garbage + /// collected next. + generations: Mutex>, + /// Tasks that have become inactive. Processing them should ensure them for + /// GC, if they are not already ensured and put all child tasks into the + /// activation_queue + deactivation_queue: ConcurrentQueue, + /// Tasks that are active and not enqueued in the deactivation queue. + // TODO Could be a bit field with locks, an array of atomics or an AMQF. + active_tasks: DashSet, +} + +impl GcQueue { + pub fn new() -> Self { + Self { + // SAFETY: Starting at 1 to produce NonZeroU32s + generation: AtomicU32::new(1), + incoming_tasks: ConcurrentQueue::unbounded(), + incoming_tasks_count: AtomicUsize::new(0), + generations: Mutex::new(VecDeque::with_capacity(128)), + deactivation_queue: ConcurrentQueue::unbounded(), + active_tasks: DashSet::new(), + } + } + + /// Get the current generation number. + pub fn generation(&self) -> NonZeroU32 { + // SAFETY: We are sure that the generation is not 0, since we start at 1. + unsafe { NonZeroU32::new_unchecked(self.generation.load(Ordering::Relaxed)) } + } + + /// Notify the GC queue that a task has been executed. + #[must_use] + pub fn task_executed(&self, task: TaskId) -> NonZeroU32 { + self.add_task(task) + } + + /// Notify the GC queue that a task has been accessed. + #[must_use] + pub fn task_accessed(&self, task: TaskId) -> NonZeroU32 { + self.add_task(task) + } + + /// Notify the GC queue that a task should be enqueue for GC because it is + /// inactive. + #[must_use] + pub fn task_inactive(&self, task: TaskId) -> NonZeroU32 { + self.add_task(task) + } + + /// Notify the GC queue that a task was active during GC + pub fn task_gc_active(&self, task: TaskId) { + self.active_tasks.insert(task); + } + + /// Notify the GC queue that a task might be inactive now. + pub fn task_potentially_no_longer_active(&self, task: TaskId) { + if self.active_tasks.remove(&task).is_some() { + let _ = self.deactivation_queue.push(task); + } + } + + fn add_task(&self, task: TaskId) -> NonZeroU32 { + let _ = self.incoming_tasks.push(task); + if self.incoming_tasks_count.fetch_add(1, Ordering::Acquire) % TASKS_PER_NEW_GENERATION + == TASKS_PER_NEW_GENERATION - 1 + { + self.incoming_tasks_count + .fetch_sub(TASKS_PER_NEW_GENERATION, Ordering::Release); + // We are selected to move TASKS_PER_NEW_GENERATION tasks into a generation + let gen = unsafe { + // SAFETY: We are sure that the generation is not 0, since we start at 1. + NonZeroU32::new_unchecked(self.generation.fetch_add(1, Ordering::Relaxed)) + }; + let mut tasks = Vec::with_capacity(TASKS_PER_NEW_GENERATION); + for _ in 0..TASKS_PER_NEW_GENERATION { + match self.incoming_tasks.pop() { + Ok(task) => { + tasks.push(task); + } + Err(_) => { + // That will not happen, since we only pop the same amount as we have + // pushed. + unreachable!(); + } + } + } + self.generations.lock().push_front(OldGeneration { + tasks, + generation: gen, + }); + gen + } else { + self.generation() + } + } + + fn process_deactivations( + &self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> ProcessDeactivationsResult { + let mut i = 0; + loop { + let Ok(id) = self.deactivation_queue.pop() else { + break; + }; + backend.with_task(id, |task| { + if !task.potentially_become_inactive(self, backend, turbo_tasks) { + self.active_tasks.insert(id); + } + }); + i += 1; + if i > MAX_DEACTIVATIONS { + break; + } + } + ProcessDeactivationsResult { count: i } + } + + fn process_old_generation( + &self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Option { + let old_generation_info = { + let guard = &mut self.generations.lock(); + let len = guard.len(); + guard.pop_back().map(|g| (g, len)) + }; + let Some(( + OldGeneration { + mut tasks, + generation, + }, + old_generations, + )) = old_generation_info + else { + // No old generation to process + return None; + }; + // Check all tasks for the correct generation + let mut indices = Vec::with_capacity(tasks.len()); + assert!(tasks.len() <= MAX_TASKS_PER_OLD_GENERATION); + for (i, task) in tasks.iter().enumerate() { + backend.with_task(*task, |task| { + if let Some(state) = task.gc_state() { + if let Some(gen) = state.generation { + if gen <= generation { + indices.push((Reverse(state.priority), i as u32)); + } + } + } + }); + } + + if indices.is_empty() { + // No valid tasks in old generation to process + return Some(ProcessGenerationResult { + old_generations, + ..ProcessGenerationResult::default() + }); + } + + // Sorting based on sort_by_cached_key from std lib + indices.sort_unstable(); + for i in 0..indices.len() { + let mut index = indices[i].1; + while (index as usize) < i { + index = indices[index as usize].1; + } + indices[i].1 = index; + tasks.swap(i, index as usize); + } + tasks.truncate(indices.len()); + + let tasks_to_collect = max(1, tasks.len() * PERCENTAGE_TO_COLLECT / 100); + let (Reverse(max_priority), _) = indices[0]; + drop(indices); + + // Put back remaining tasks into the queue + let remaining_tasks = &tasks[tasks_to_collect..]; + { + let mut guard = self.generations.lock(); + if !remaining_tasks.is_empty() { + if let Some(first) = guard.front_mut() { + first.tasks.extend(remaining_tasks); + if first.tasks.len() > MAX_TASKS_PER_OLD_GENERATION { + // Need to split the tasks into two generations + let mut gen_b = Vec::with_capacity(first.tasks.len() / 2); + let mut gen_a = Vec::with_capacity(first.tasks.len() - gen_b.capacity()); + for (i, task) in take(&mut first.tasks).into_iter().enumerate() { + if i % 2 == 0 { + gen_a.push(task); + } else { + gen_b.push(task); + } + } + let generation = first.generation; + first.tasks = gen_a; + guard.push_front(OldGeneration { + tasks: gen_b, + generation, + }); + } + } else { + guard.push_front(OldGeneration { + tasks: remaining_tasks.to_vec(), + generation, + }); + } + } + } + + // GC the tasks + let mut content_dropped_count = 0; + let mut unloaded_count = 0; + let mut already_unloaded_count = 0; + for task in tasks[..tasks_to_collect].iter() { + backend.with_task(*task, |task| { + match task.run_gc(generation, self, backend, turbo_tasks) { + GcResult::NotPossible => {} + GcResult::Stale => {} + GcResult::ContentDropped => { + content_dropped_count += 1; + } + GcResult::Unloaded => { + unloaded_count += 1; + } + GcResult::AlreadyUnloaded => { + already_unloaded_count += 1; + } + } + }); + } + + Some(ProcessGenerationResult { + old_generations, + priority: Some(max_priority), + content_dropped_count, + unloaded_count, + already_unloaded_count, + }) + } + + /// Run garbage collection on the queue. Returns true, if some progress has + /// been made. Returns the number of old generations. + pub fn run_gc( + &self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Option { + let span = tracing::trace_span!( + "garbage collection step", + priority = Empty, + deactivations_count = Empty, + content_dropped_count = Empty, + unloaded_count = Empty, + already_unloaded_count = Empty + ) + .entered(); + + let ProcessDeactivationsResult { + count: deactivations_count, + } = self.process_deactivations(backend, turbo_tasks); + + if let Some(ProcessGenerationResult { + old_generations, + priority, + content_dropped_count, + unloaded_count, + already_unloaded_count, + }) = self.process_old_generation(backend, turbo_tasks) + { + span.record("deactivations_count", deactivations_count); + span.record("content_dropped_count", content_dropped_count); + span.record("unloaded_count", unloaded_count); + span.record("already_unloaded_count", already_unloaded_count); + if let Some(priority) = &priority { + span.record("priority", debug(priority)); + } else { + span.record("priority", ""); + } + + Some(old_generations) + } else { + (deactivations_count > 0).then_some(0) + } + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/lib.rs b/turbopack/crates/turbo-tasks-memory/src/lib.rs new file mode 100644 index 0000000000000..b699dbaa71a70 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/lib.rs @@ -0,0 +1,22 @@ +#![feature(hash_extract_if)] +#![feature(option_get_or_insert_default)] +#![feature(type_alias_impl_trait)] +#![feature(lint_reasons)] +#![feature(box_patterns)] +#![feature(int_roundings)] +#![feature(impl_trait_in_assoc_type)] +#![deny(unsafe_op_in_unsafe_fn)] + +mod aggregation; +mod cell; +mod count_hash_set; +mod edges_set; +mod gc; +mod map_guard; +mod memory_backend; +mod output; +mod task; +mod task_statistics; + +pub use memory_backend::MemoryBackend; +pub use task_statistics::{TaskStatistics, TaskStatisticsApi}; diff --git a/turbopack/crates/turbo-tasks-memory/src/map_guard.rs b/turbopack/crates/turbo-tasks-memory/src/map_guard.rs new file mode 100644 index 0000000000000..c0d324d2d8546 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/map_guard.rs @@ -0,0 +1,68 @@ +use std::ops::{Deref, DerefMut}; + +use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; + +pub struct ReadGuard<'a, T: 'a, U: 'a, M: 'a + Fn(&T) -> Option<&U>> { + inner: RwLockReadGuard<'a, T>, + map: M, +} + +impl<'a, T: 'a, U: 'a, M: 'a + Fn(&T) -> Option<&U>> ReadGuard<'a, T, U, M> { + pub fn new(guard: RwLockReadGuard<'a, T>, map: M) -> Self { + Self { inner: guard, map } + } +} + +impl<'a, T: 'a, U: 'a, M: 'a + Fn(&T) -> Option<&U>> Deref for ReadGuard<'a, T, U, M> { + type Target = U; + + fn deref(&self) -> &Self::Target { + (self.map)(&self.inner).unwrap() + } +} + +pub struct WriteGuard< + 'a, + T: 'a, + U: 'a, + M: 'a + Fn(&T) -> Option<&U>, + MM: 'a + Fn(&mut T) -> Option<&mut U>, +> { + inner: RwLockWriteGuard<'a, T>, + map: M, + map_mut: MM, +} + +impl<'a, T: 'a, U: 'a, M: 'a + Fn(&T) -> Option<&U>, MM: 'a + Fn(&mut T) -> Option<&mut U>> + WriteGuard<'a, T, U, M, MM> +{ + pub fn new(guard: RwLockWriteGuard<'a, T>, map: M, map_mut: MM) -> Self { + Self { + inner: guard, + map, + map_mut, + } + } + + pub fn into_inner(self) -> RwLockWriteGuard<'a, T> { + self.inner + } +} + +impl<'a, T: 'a, U: 'a, M: 'a + Fn(&T) -> Option<&U>, MM: 'a + Fn(&mut T) -> Option<&mut U>> Deref + for WriteGuard<'a, T, U, M, MM> +{ + type Target = U; + + fn deref(&self) -> &Self::Target { + (self.map)(&self.inner).unwrap() + } +} + +impl<'a, T: 'a, U: 'a, M: 'a + Fn(&T) -> Option<&U>, MM: 'a + Fn(&mut T) -> Option<&mut U>> DerefMut + for WriteGuard<'a, T, U, M, MM> +{ + fn deref_mut(&mut self) -> &mut Self::Target { + (self.map_mut)(&mut self.inner).unwrap() + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/memory_backend.rs b/turbopack/crates/turbo-tasks-memory/src/memory_backend.rs new file mode 100644 index 0000000000000..6992f861044ea --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/memory_backend.rs @@ -0,0 +1,761 @@ +use std::{ + borrow::{Borrow, Cow}, + cell::RefCell, + future::Future, + hash::{BuildHasher, BuildHasherDefault, Hash}, + num::NonZeroU32, + pin::Pin, + sync::{ + atomic::{AtomicBool, AtomicUsize, Ordering}, + Arc, + }, + time::Duration, +}; + +use anyhow::{anyhow, bail, Result}; +use auto_hash_map::AutoMap; +use dashmap::{mapref::entry::Entry, DashMap}; +use rustc_hash::FxHasher; +use tokio::task::futures::TaskLocalFuture; +use tracing::trace_span; +use turbo_prehash::{BuildHasherExt, PassThroughHash, PreHashed}; +use turbo_tasks::{ + backend::{ + Backend, BackendJobId, CellContent, PersistentTaskType, TaskCollectiblesMap, + TaskExecutionSpec, TransientTaskType, TypedCellContent, + }, + event::EventListener, + util::{IdFactoryWithReuse, NoMoveVec}, + CellId, RawVc, TaskId, TaskIdSet, TraitTypeId, TurboTasksBackendApi, Unused, ValueTypeId, +}; + +use crate::{ + edges_set::{TaskEdge, TaskEdgesSet}, + gc::{ + GcQueue, MAX_GC_STEPS, PERCENTAGE_MAX_IDLE_TARGET_MEMORY, PERCENTAGE_MAX_TARGET_MEMORY, + PERCENTAGE_MIN_IDLE_TARGET_MEMORY, PERCENTAGE_MIN_TARGET_MEMORY, + }, + output::Output, + task::{ReadCellError, Task, DEPENDENCIES_TO_TRACK}, + task_statistics::TaskStatisticsApi, +}; + +fn prehash_task_type(task_type: PersistentTaskType) -> PreHashed { + BuildHasherDefault::::prehash(&Default::default(), task_type) +} + +pub struct MemoryBackend { + memory_tasks: NoMoveVec, + backend_jobs: NoMoveVec, + backend_job_id_factory: IdFactoryWithReuse, + task_cache: + DashMap>, TaskId, BuildHasherDefault>, + memory_limit: AtomicUsize, + gc_queue: Option, + idle_gc_active: AtomicBool, + task_statistics: TaskStatisticsApi, +} + +impl Default for MemoryBackend { + fn default() -> Self { + Self::new(usize::MAX) + } +} + +impl MemoryBackend { + pub fn new(memory_limit: usize) -> Self { + Self { + memory_tasks: NoMoveVec::new(), + backend_jobs: NoMoveVec::new(), + backend_job_id_factory: IdFactoryWithReuse::new(), + task_cache: DashMap::with_hasher_and_shard_amount( + Default::default(), + (std::thread::available_parallelism().map_or(1, usize::from) * 32) + .next_power_of_two(), + ), + memory_limit: AtomicUsize::new(memory_limit), + gc_queue: (memory_limit != usize::MAX).then(GcQueue::new), + idle_gc_active: AtomicBool::new(false), + task_statistics: TaskStatisticsApi::default(), + } + } + + fn connect_task_child( + &self, + parent: TaskId, + child: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.with_task(parent, |parent| { + parent.connect_child(child, self, turbo_tasks) + }); + } + + pub(crate) fn create_backend_job(&self, job: Job) -> BackendJobId { + job.before_schedule(self); + let id = self.backend_job_id_factory.get(); + // SAFETY: This is a fresh id + unsafe { + self.backend_jobs.insert(*id as usize, job); + } + id + } + + pub(crate) fn has_gc(&self) -> bool { + self.gc_queue.is_some() + } + + fn try_get_output Result>( + &self, + id: TaskId, + strongly_consistent: bool, + note: impl Fn() -> String + Sync + Send + 'static, + turbo_tasks: &dyn TurboTasksBackendApi, + func: F, + ) -> Result> { + self.with_task(id, |task| { + task.get_or_wait_output(strongly_consistent, func, note, self, turbo_tasks) + }) + } + + pub fn with_all_cached_tasks(&self, mut func: impl FnMut(TaskId)) { + for id in self.task_cache.clone().into_read_only().values() { + func(*id); + } + } + + #[inline(always)] + pub fn with_task(&self, id: TaskId, func: impl FnOnce(&Task) -> T) -> T { + func(self.memory_tasks.get(*id as usize).unwrap()) + } + + #[inline(always)] + pub fn task(&self, id: TaskId) -> &Task { + self.memory_tasks.get(*id as usize).unwrap() + } + + /// Runs the garbage collection until reaching the target memory. An `idle` + /// garbage collection has a lower target memory. Returns true, when + /// memory was collected. + pub fn run_gc( + &self, + idle: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> bool { + if let Some(gc_queue) = &self.gc_queue { + let mut did_something = false; + let mut remaining_generations = 0; + let mut mem_limit = self.memory_limit.load(Ordering::Relaxed); + let mut span = None; + 'outer: loop { + let mut collected_generations = 0; + let (min, max) = if idle { + ( + mem_limit * PERCENTAGE_MIN_IDLE_TARGET_MEMORY / 100, + mem_limit * PERCENTAGE_MAX_IDLE_TARGET_MEMORY / 100, + ) + } else { + ( + mem_limit * PERCENTAGE_MIN_TARGET_MEMORY / 100, + mem_limit * PERCENTAGE_MAX_TARGET_MEMORY / 100, + ) + }; + let mut target = max; + let mut counter = 0; + loop { + let usage = turbo_tasks_malloc::TurboMalloc::memory_usage(); + if usage < target { + return did_something; + } + target = min; + if span.is_none() { + span = + Some(tracing::trace_span!(parent: None, "garbage collection", usage)); + } + + let progress = gc_queue.run_gc(self, turbo_tasks); + + if progress.is_some() { + did_something = true; + } + + if let Some(g) = progress { + remaining_generations = g; + if g > 0 { + collected_generations += 1; + } + } + + counter += 1; + if counter > MAX_GC_STEPS + || collected_generations > remaining_generations + || progress.is_none() + { + let new_mem_limit = mem_limit * 4 / 3; + if self + .memory_limit + .compare_exchange( + mem_limit, + new_mem_limit, + Ordering::Relaxed, + Ordering::Relaxed, + ) + .is_ok() + { + println!( + "Ineffective GC, increasing memory limit {} MB -> {} MB", + mem_limit / 1024 / 1024, + new_mem_limit / 1024 / 1024 + ); + mem_limit = new_mem_limit; + } else { + mem_limit = self.memory_limit.load(Ordering::Relaxed); + } + continue 'outer; + } + + did_something = true; + } + } + } + false + } + + fn insert_and_connect_fresh_task( + &self, + parent_task: TaskId, + task_cache: &DashMap, + key: K, + new_id: Unused, + task: Task, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> TaskId { + let new_id = new_id.into(); + // Safety: We have a fresh task id that nobody knows about yet + unsafe { self.memory_tasks.insert(*new_id as usize, task) }; + let result_task = match task_cache.entry(key) { + Entry::Vacant(entry) => { + // This is the most likely case + entry.insert(new_id); + new_id + } + Entry::Occupied(entry) => { + // Safety: We have a fresh task id that nobody knows about yet + let task_id = *entry.get(); + drop(entry); + unsafe { + self.memory_tasks.remove(*new_id as usize); + let new_id = Unused::new_unchecked(new_id); + turbo_tasks.reuse_task_id(new_id); + } + task_id + } + }; + self.connect_task_child(parent_task, result_task, turbo_tasks); + result_task + } + + fn lookup_and_connect_task( + &self, + parent_task: TaskId, + task_cache: &DashMap, + key: &Q, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Option + where + K: Borrow + Hash + Eq, + Q: Hash + Eq + ?Sized, + { + task_cache + .get(key) + // Avoid holding the lock for too long + .map(|task_ref| *task_ref) + .map(|task_id| { + self.connect_task_child(parent_task, task_id, turbo_tasks); + + task_id + }) + } + + pub(crate) fn schedule_when_dirty_from_aggregation( + &self, + set: TaskIdSet, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + for task in set { + self.with_task(task, |task| { + task.schedule_when_dirty_from_aggregation(self, turbo_tasks) + }); + } + } + + pub fn task_statistics(&self) -> &TaskStatisticsApi { + &self.task_statistics + } +} + +impl Backend for MemoryBackend { + fn idle_start(&self, turbo_tasks: &dyn TurboTasksBackendApi) { + if self + .idle_gc_active + .compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire) + .is_ok() + { + let job = self.create_backend_job(Job::GarbageCollection); + turbo_tasks.schedule_backend_background_job(job); + } + } + + fn invalidate_task(&self, task: TaskId, turbo_tasks: &dyn TurboTasksBackendApi) { + self.with_task(task, |task| task.invalidate(self, turbo_tasks)); + } + + fn invalidate_tasks( + &self, + tasks: &[TaskId], + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + for &task in tasks { + self.with_task(task, |task| { + task.invalidate(self, turbo_tasks); + }); + } + } + + fn invalidate_tasks_set( + &self, + tasks: &TaskIdSet, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + for &task in tasks { + self.with_task(task, |task| { + task.invalidate(self, turbo_tasks); + }); + } + } + + fn get_task_description(&self, task: TaskId) -> String { + self.with_task(task, |task| task.get_description()) + } + + type ExecutionScopeFuture> + Send + 'static> = + TaskLocalFuture, T>; + fn execution_scope> + Send + 'static>( + &self, + _task: TaskId, + future: T, + ) -> Self::ExecutionScopeFuture { + DEPENDENCIES_TO_TRACK.scope(RefCell::new(TaskEdgesSet::new()), future) + } + + fn try_start_task_execution<'a>( + &'a self, + task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Option> { + let task = self.task(task); + task.execute(self, turbo_tasks) + } + + fn task_execution_result( + &self, + task_id: TaskId, + result: Result, Option>>, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.with_task(task_id, |task| { + #[cfg(debug_assertions)] + if let Ok(Ok(RawVc::TaskOutput(result))) = result.as_ref() { + if *result == task_id { + panic!("Task {} returned itself as output", task.get_description()); + } + } + task.execution_result(result, self, turbo_tasks); + }) + } + + fn task_execution_completed( + &self, + task_id: TaskId, + duration: Duration, + memory_usage: usize, + cell_counters: AutoMap, 8>, + stateful: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> bool { + let generation = if let Some(gc_queue) = &self.gc_queue { + gc_queue.generation() + } else { + // SAFETY: 1 is not zero + unsafe { NonZeroU32::new_unchecked(1) } + }; + let (reexecute, once_task) = self.with_task(task_id, |task| { + ( + task.execution_completed( + duration, + memory_usage, + generation, + cell_counters, + stateful, + self, + turbo_tasks, + ), + task.is_once(), + ) + }); + if !reexecute { + if let Some(gc_queue) = &self.gc_queue { + let _ = gc_queue.task_executed(task_id); + if once_task { + gc_queue.task_potentially_no_longer_active(task_id); + } + self.run_gc(false, turbo_tasks); + } + } + reexecute + } + + fn try_read_task_output( + &self, + task: TaskId, + reader: TaskId, + strongly_consistent: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result> { + if task == reader { + bail!("reading it's own output is not possible"); + } + self.try_get_output( + task, + strongly_consistent, + move || format!("reading task output from {reader}"), + turbo_tasks, + |output| { + Task::add_dependency_to_current(TaskEdge::Output(task)); + output.read(reader) + }, + ) + } + + fn try_read_task_output_untracked( + &self, + task: TaskId, + strongly_consistent: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result> { + self.try_get_output( + task, + strongly_consistent, + || "reading task output untracked".to_string(), + turbo_tasks, + |output| output.read_untracked(), + ) + } + + fn try_read_task_cell( + &self, + task_id: TaskId, + index: CellId, + reader: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result> { + if task_id == reader { + Ok(Ok(self + .with_task(task_id, |task| { + task.with_cell(index, |cell| cell.read_own_content_untracked()) + }) + .into_typed(index.type_id))) + } else { + Task::add_dependency_to_current(TaskEdge::Cell(task_id, index)); + self.with_task(task_id, |task| { + match task.read_cell( + index, + self.gc_queue.as_ref(), + move || format!("reading {} {} from {}", task_id, index, reader), + Some(reader), + self, + turbo_tasks, + ) { + Ok(content) => Ok(Ok(content.into_typed(index.type_id))), + Err(ReadCellError::Recomputing(listener)) => Ok(Err(listener)), + Err(ReadCellError::CellRemoved) => Err(anyhow!("Cell doesn't exist")), + } + }) + } + } + + fn try_read_own_task_cell_untracked( + &self, + current_task: TaskId, + index: CellId, + _turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result { + Ok(self.with_task(current_task, |task| { + task.with_cell(index, |cell| cell.read_own_content_untracked()) + .into_typed(index.type_id) + })) + } + + fn try_read_task_cell_untracked( + &self, + task_id: TaskId, + index: CellId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result> { + self.with_task(task_id, |task| { + match task.read_cell( + index, + self.gc_queue.as_ref(), + move || format!("reading {} {} untracked", task_id, index), + None, + self, + turbo_tasks, + ) { + Ok(content) => Ok(Ok(content.into_typed(index.type_id))), + Err(ReadCellError::Recomputing(listener)) => Ok(Err(listener)), + Err(ReadCellError::CellRemoved) => Err(anyhow!("Cell doesn't exist")), + } + }) + } + + fn read_task_collectibles( + &self, + id: TaskId, + trait_id: TraitTypeId, + reader: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> TaskCollectiblesMap { + Task::add_dependency_to_current(TaskEdge::Collectibles(id, trait_id)); + Task::read_collectibles(id, trait_id, reader, self, turbo_tasks) + } + + fn emit_collectible( + &self, + trait_type: TraitTypeId, + collectible: RawVc, + id: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.with_task(id, |task| { + task.emit_collectible(trait_type, collectible, self, turbo_tasks) + }); + } + + fn unemit_collectible( + &self, + trait_type: TraitTypeId, + collectible: RawVc, + count: u32, + id: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.with_task(id, |task| { + task.unemit_collectible(trait_type, collectible, count, self, turbo_tasks); + }); + } + + /// SAFETY: This function does not validate that the data in `content` is of + /// the same type as in `index`. It is the caller's responsibility to ensure + /// that the content is of the correct type. + fn update_task_cell( + &self, + task: TaskId, + index: CellId, + content: CellContent, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.with_task(task, |task| { + task.access_cell_for_write(index, |cell, clean| { + cell.assign(content, clean, turbo_tasks) + }) + }) + } + + /// SAFETY: Must only called once with the same id + fn run_backend_job<'a>( + &'a self, + id: BackendJobId, + turbo_tasks: &'a dyn TurboTasksBackendApi, + ) -> Pin + Send + 'a>> { + // SAFETY: id will not be reused until with job is done + if let Some(job) = unsafe { self.backend_jobs.take(*id as usize) } { + Box::pin(async move { + job.run(self, turbo_tasks).await; + // SAFETY: This id will no longer be used + unsafe { + self.backend_job_id_factory.reuse(id); + } + }) + } else { + Box::pin(async {}) + } + } + + fn get_or_create_persistent_task( + &self, + task_type: PersistentTaskType, + parent_task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> TaskId { + let task_type = prehash_task_type(task_type); + if let Some(task) = + self.lookup_and_connect_task(parent_task, &self.task_cache, &task_type, turbo_tasks) + { + // fast pass without creating a new task + self.task_statistics().map(|stats| match &*task_type { + PersistentTaskType::ResolveNative { + fn_type: function_id, + this: _, + arg: _, + } + | PersistentTaskType::Native { + fn_type: function_id, + this: _, + arg: _, + } => { + stats.increment_cache_hit(*function_id); + } + PersistentTaskType::ResolveTrait { + trait_type, + method_name: name, + this, + arg: _, + } => { + // HACK: Resolve the this argument (`self`) in order to attribute the cache hit + // to the concrete trait implementation, rather than the dynamic trait method. + // This ensures cache hits and misses are both attributed to the same thing. + // + // Because this task already resolved, in most cases `self` should either be + // resolved, or already in the process of being resolved. + // + // However, `self` could become unloaded due to cache eviction, and this might + // trigger an otherwise unnecessary re-evalutation. + // + // This is a potentially okay trade-off as long as we don't log statistics by + // default. The alternative would be to store function ids on completed + // ResolveTrait tasks. + let trait_type = *trait_type; + let name = name.clone(); + let this = *this; + let stats = Arc::clone(stats); + turbo_tasks.run_once(Box::pin(async move { + let function_id = + PersistentTaskType::resolve_trait_method(trait_type, name, this) + .await?; + stats.increment_cache_hit(function_id); + Ok(()) + })); + } + }); + task + } else { + self.task_statistics().map(|stats| match &*task_type { + PersistentTaskType::Native { + fn_type: function_id, + this: _, + arg: _, + } => { + stats.increment_cache_miss(*function_id); + } + PersistentTaskType::ResolveTrait { .. } + | PersistentTaskType::ResolveNative { .. } => { + // these types re-execute themselves as `Native` after + // resolving their arguments, skip counting their + // executions here to avoid double-counting + } + }); + // It's important to avoid overallocating memory as this will go into the task + // cache and stay there forever. We can to be as small as possible. + let (task_type_hash, task_type) = PreHashed::into_parts(task_type); + let task_type = Arc::new(PreHashed::new(task_type_hash, task_type)); + // slow pass with key lock + let id = turbo_tasks.get_fresh_task_id(); + let task = Task::new_persistent( + // Safety: That task will hold the value, but we are still in + // control of the task + *unsafe { id.get_unchecked() }, + task_type.clone(), + ); + self.insert_and_connect_fresh_task( + parent_task, + &self.task_cache, + task_type, + id, + task, + turbo_tasks, + ) + } + } + + fn connect_task( + &self, + task: TaskId, + parent_task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.connect_task_child(parent_task, task, turbo_tasks); + } + + fn mark_own_task_as_finished( + &self, + task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.with_task(task, |task| task.mark_as_finished(self, turbo_tasks)) + } + + fn create_transient_task( + &self, + task_type: TransientTaskType, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> TaskId { + let id = turbo_tasks.get_fresh_task_id(); + let id = id.into(); + match task_type { + TransientTaskType::Root(f) => { + let task = Task::new_root(id, move || f() as _); + // SAFETY: We have a fresh task id where nobody knows about yet + unsafe { self.memory_tasks.insert(*id as usize, task) }; + Task::set_root(id, self, turbo_tasks); + } + TransientTaskType::Once(f) => { + let task = Task::new_once(id, f); + // SAFETY: We have a fresh task id where nobody knows about yet + unsafe { self.memory_tasks.insert(*id as usize, task) }; + Task::set_once(id, self, turbo_tasks); + } + }; + id + } + + fn dispose_root_task(&self, task: TaskId, turbo_tasks: &dyn TurboTasksBackendApi) { + Task::unset_root(task, self, turbo_tasks); + } +} + +pub(crate) enum Job { + GarbageCollection, +} + +impl Job { + // TODO remove this method + fn before_schedule(&self, _backend: &MemoryBackend) {} + + async fn run( + self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + match self { + Job::GarbageCollection => { + let _guard = trace_span!("Job::GarbageCollection").entered(); + if backend.run_gc(true, turbo_tasks) { + let job = backend.create_backend_job(Job::GarbageCollection); + turbo_tasks.schedule_backend_background_job(job); + } else { + backend.idle_gc_active.store(false, Ordering::Release); + } + } + } + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/output.rs b/turbopack/crates/turbo-tasks-memory/src/output.rs new file mode 100644 index 0000000000000..d1c83f7ef216a --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/output.rs @@ -0,0 +1,107 @@ +use std::{ + borrow::Cow, + fmt::{Debug, Display}, + mem::take, +}; + +use anyhow::{anyhow, Error, Result}; +use turbo_tasks::{util::SharedError, RawVc, TaskId, TaskIdSet, TurboTasksBackendApi}; + +use crate::MemoryBackend; + +#[derive(Default, Debug)] +pub struct Output { + pub(crate) content: OutputContent, + pub(crate) dependent_tasks: TaskIdSet, +} + +#[derive(Clone, Debug, Default)] +pub enum OutputContent { + #[default] + Empty, + Link(RawVc), + Error(SharedError), + Panic(Option>>), +} + +impl Display for OutputContent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + OutputContent::Empty => write!(f, "empty"), + OutputContent::Link(raw_vc) => write!(f, "link {}", raw_vc), + OutputContent::Error(err) => write!(f, "error {}", err), + OutputContent::Panic(Some(message)) => write!(f, "panic {}", message), + OutputContent::Panic(None) => write!(f, "panic"), + } + } +} + +impl Output { + pub fn read(&mut self, reader: TaskId) -> Result { + self.dependent_tasks.insert(reader); + self.read_untracked() + } + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + pub fn read_untracked(&mut self) -> Result { + match &self.content { + OutputContent::Empty => Err(anyhow!("Output is empty")), + OutputContent::Error(err) => Err(anyhow::Error::new(err.clone())), + OutputContent::Link(raw_vc) => Ok(*raw_vc), + OutputContent::Panic(Some(message)) => Err(anyhow!("A task panicked: {message}")), + OutputContent::Panic(None) => Err(anyhow!("A task panicked")), + } + } + + pub fn link(&mut self, target: RawVc, turbo_tasks: &dyn TurboTasksBackendApi) { + debug_assert!(*self != target); + if let OutputContent::Link(old_target) = &self.content { + if *old_target == target { + // unchanged + return; + } + } + self.content = OutputContent::Link(target); + // notify + if !self.dependent_tasks.is_empty() { + turbo_tasks.schedule_notify_tasks_set(&take(&mut self.dependent_tasks)); + } + } + + pub fn error(&mut self, error: Error, turbo_tasks: &dyn TurboTasksBackendApi) { + self.content = OutputContent::Error(SharedError::new(error)); + // notify + if !self.dependent_tasks.is_empty() { + turbo_tasks.schedule_notify_tasks_set(&take(&mut self.dependent_tasks)); + } + } + + pub fn panic( + &mut self, + message: Option>, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.content = OutputContent::Panic(message.map(Box::new)); + // notify + if !self.dependent_tasks.is_empty() { + turbo_tasks.schedule_notify_tasks_set(&take(&mut self.dependent_tasks)); + } + } + + pub fn gc_drop(self, turbo_tasks: &dyn TurboTasksBackendApi) { + // notify + if !self.dependent_tasks.is_empty() { + turbo_tasks.schedule_notify_tasks_set(&self.dependent_tasks); + } + } +} + +impl PartialEq for Output { + fn eq(&self, rhs: &RawVc) -> bool { + match &self.content { + OutputContent::Link(old_target) => old_target == rhs, + OutputContent::Empty | OutputContent::Error(_) | OutputContent::Panic(_) => false, + } + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/task.rs b/turbopack/crates/turbo-tasks-memory/src/task.rs new file mode 100644 index 0000000000000..3e7408a2db211 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/task.rs @@ -0,0 +1,1977 @@ +use std::{ + borrow::Cow, + cell::RefCell, + fmt::{self, Debug, Display, Formatter}, + future::Future, + hash::{BuildHasherDefault, Hash}, + mem::{replace, take}, + num::NonZeroU32, + pin::Pin, + sync::{atomic::AtomicU32, Arc}, + time::Duration, +}; + +use anyhow::Result; +use auto_hash_map::AutoMap; +use either::Either; +use parking_lot::{Mutex, RwLock}; +use rustc_hash::FxHasher; +use smallvec::SmallVec; +use tokio::task_local; +use tracing::Span; +use turbo_prehash::PreHashed; +use turbo_tasks::{ + backend::{CellContent, PersistentTaskType, TaskCollectiblesMap, TaskExecutionSpec}, + event::{Event, EventListener}, + get_invalidator, registry, CellId, Invalidator, RawVc, TaskId, TaskIdSet, TraitTypeId, + TurboTasksBackendApi, ValueTypeId, +}; + +use crate::{ + aggregation::{ + aggregation_data, handle_new_edge, prepare_aggregation_data, query_root_info, + AggregationDataGuard, PreparedOperation, + }, + cell::{Cell, ReadContentError}, + edges_set::{TaskEdge, TaskEdgesList, TaskEdgesSet}, + gc::{GcQueue, GcTaskState}, + output::{Output, OutputContent}, + task::aggregation::{TaskAggregationContext, TaskChange}, + MemoryBackend, +}; + +pub type NativeTaskFuture = Pin> + Send>>; +pub type NativeTaskFn = Box NativeTaskFuture + Send + Sync>; + +mod aggregation; +mod meta_state; + +task_local! { + /// Cells/Outputs/Collectibles that are read during task execution + /// These will be stored as dependencies when the execution has finished + pub(crate) static DEPENDENCIES_TO_TRACK: RefCell; +} + +type OnceTaskFn = Mutex> + Send + 'static>>>>; + +/// Different Task types +enum TaskType { + // Note: double boxed to reduce TaskType size + /// A root task that will track dependencies and re-execute when + /// dependencies change. Task will eventually settle to the correct + /// execution. + Root(Box), + + // Note: double boxed to reduce TaskType size + /// A single root task execution. It won't track dependencies. + /// Task will definitely include all invalidations that happened before the + /// start of the task. It may or may not include invalidations that + /// happened after that. It may see these invalidations partially + /// applied. + Once(Box), + + /// A normal persistent task + Persistent { + ty: Arc>, + }, +} + +#[derive(Clone)] +enum TaskTypeForDescription { + Root, + Once, + Persistent(Arc>), +} + +impl TaskTypeForDescription { + fn from(task_type: &TaskType) -> Self { + match task_type { + TaskType::Root(..) => Self::Root, + TaskType::Once(..) => Self::Once, + TaskType::Persistent { ty, .. } => Self::Persistent(ty.clone()), + } + } +} + +impl Debug for TaskType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::Root(..) => f.debug_tuple("Root").finish(), + Self::Once(..) => f.debug_tuple("Once").finish(), + Self::Persistent { ty, .. } => Debug::fmt(ty, f), + } + } +} + +impl Display for TaskType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::Root(..) => f.debug_tuple("Root").finish(), + Self::Once(..) => f.debug_tuple("Once").finish(), + Self::Persistent { ty, .. } => Display::fmt(ty, f), + } + } +} + +/// A Task is an instantiation of an Function with some arguments. +/// The same combinations of Function and arguments usually results in the same +/// Task instance. +pub struct Task { + id: TaskId, + /// The type of the task + ty: TaskType, + /// The mutable state of the task + /// Unset state is equal to a Dirty task that has not been executed yet + state: RwLock, + /// Atomic in progress counter for graph modification + graph_modification_in_progress_counter: AtomicU32, +} + +impl Debug for Task { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut result = f.debug_struct("Task"); + result.field("id", &self.id); + result.field("ty", &self.ty); + if let Some(state) = self.try_state() { + match state { + TaskMetaStateReadGuard::Full(state) => { + result.field("state", &Task::state_string(&state)); + } + TaskMetaStateReadGuard::Partial(_) => { + result.field("state", &"partial"); + } + TaskMetaStateReadGuard::Unloaded => { + result.field("state", &"unloaded"); + } + } + } + result.finish() + } +} + +/// The full state of a [Task], it includes all information. +struct TaskState { + aggregation_node: TaskAggregationNode, + + // TODO using a Atomic might be possible here + /// More flags of task state, where not all combinations are possible. + /// dirty, scheduled, in progress + state_type: TaskStateType, + + /// Collectibles are only modified from execution + collectibles: MaybeCollectibles, + output: Output, + cells: AutoMap, BuildHasherDefault>, + + // GC state: + gc: GcTaskState, +} + +impl TaskState { + fn new() -> Self { + Self { + aggregation_node: TaskAggregationNode::new(), + state_type: Dirty { + outdated_edges: Default::default(), + }, + collectibles: Default::default(), + output: Default::default(), + cells: Default::default(), + gc: Default::default(), + #[cfg(feature = "track_wait_dependencies")] + last_waiting_task: Default::default(), + } + } + + fn new_scheduled(description: impl Fn() -> String + Send + Sync + Clone + 'static) -> Self { + let description2 = description.clone(); + Self { + aggregation_node: TaskAggregationNode::new(), + state_type: Scheduled(Box::new(ScheduledState { + start_event: Event::new(move || { + format!("TaskState({})::start_event", description()) + }), + done_event: Event::new(move || { + format!("TaskState({})::done_event", description2()) + }), + outdated_edges: Default::default(), + clean: true, + })), + collectibles: Default::default(), + output: Default::default(), + cells: Default::default(), + gc: Default::default(), + #[cfg(feature = "track_wait_dependencies")] + last_waiting_task: Default::default(), + } + } +} + +/// The partial task state. It's equal to a full TaskState with state = Dirty +/// and all other fields empty. It looks like a dirty task that has not been +/// executed yet. The task might still referenced by some parents tasks. +/// A Task can get into this state when it is unloaded by garbage collection, +/// but is still attached to parents and aggregated. +struct PartialTaskState { + aggregation_node: TaskAggregationNode, +} + +impl PartialTaskState { + fn into_full(self) -> TaskState { + TaskState { + aggregation_node: self.aggregation_node, + state_type: Dirty { + outdated_edges: Default::default(), + }, + collectibles: Default::default(), + output: Default::default(), + cells: Default::default(), + gc: Default::default(), + } + } +} + +/// A fully unloaded task state. It's equal to a partial task state without +/// being referenced by any parent. This state is stored inlined instead of in a +/// [Box] to reduce the memory consumption. Make sure to not add more fields +/// than the size of a [Box]. +struct UnloadedTaskState {} + +#[cfg(test)] +#[test] +fn test_unloaded_task_state_size() { + assert!(std::mem::size_of::() <= std::mem::size_of::>()); +} + +impl UnloadedTaskState { + fn into_full(self) -> TaskState { + TaskState { + aggregation_node: TaskAggregationNode::new(), + state_type: Dirty { + outdated_edges: Default::default(), + }, + collectibles: Default::default(), + output: Default::default(), + cells: Default::default(), + gc: Default::default(), + } + } + + fn into_partial(self) -> PartialTaskState { + PartialTaskState { + aggregation_node: TaskAggregationNode::new(), + } + } +} + +/// The collectibles of a task. +type Collectibles = AutoMap<(TraitTypeId, RawVc), i32>; + +/// Keeps track of emitted and unemitted collectibles and the +/// read_collectibles tasks. Defaults to None to avoid allocating memory when no +/// collectibles are emitted or read. +#[derive(Default)] +struct MaybeCollectibles { + inner: Option>, +} + +impl MaybeCollectibles { + /// Consumes the collectibles (if any) and return them. + fn take_collectibles(&mut self) -> Option { + self.inner.as_mut().map(|boxed| take(&mut **boxed)) + } + + /// Consumes the collectibles (if any) and return them. + fn into_inner(self) -> Option> { + self.inner + } + + /// Returns a reference to the collectibles (if any). + fn as_ref(&self) -> Option<&Collectibles> { + if let Some(inner) = &self.inner { + Some(&**inner) + } else { + None + } + } + + /// Emits a collectible. + fn emit(&mut self, trait_type: TraitTypeId, value: RawVc) { + let value = self + .inner + .get_or_insert_default() + .entry((trait_type, value)) + .or_default(); + *value += 1; + } + + /// Unemits a collectible. + fn unemit(&mut self, trait_type: TraitTypeId, value: RawVc, count: u32) { + let value = self + .inner + .get_or_insert_default() + .entry((trait_type, value)) + .or_default(); + *value -= count as i32; + } +} + +struct InProgressState { + /// Event is fired when the task is Done. + done_event: Event, + /// true, when the task was marked as finished. + count_as_finished: bool, + /// true, when the task wasn't changed since the last execution + clean: bool, + /// true, when the task was invalidated while executing. It will be + /// scheduled again. + stale: bool, + /// Dependencies and children that need to be disconnected once entering + /// Done. + outdated_edges: TaskEdgesSet, + /// Children that are connected during execution. These children are already + /// removed from `outdated_edges`. + new_children: TaskIdSet, + /// Collectibles that need to be removed once leaving this state. + outdated_collectibles: MaybeCollectibles, +} + +struct ScheduledState { + /// Event is fired when the task is IsProgress. + start_event: Event, + /// Event is fired when the task is Done. + done_event: Event, + /// Dependencies and children that need to be disconnected once entering + /// Done. + outdated_edges: Box, + /// true, when the task wasn't changed since the last execution + clean: bool, +} + +enum TaskStateType { + /// Ready + /// + /// on invalidation this will move to Dirty or Scheduled depending on active + /// flag + Done { + /// true, when the task has state and that can't be dropped + stateful: bool, + + /// Cells/Outputs/Collectibles that the task has read during execution. + /// And children that are connected to this task. + /// The Task will keep these tasks alive as invalidations that happen + /// there might affect this task. + /// + /// This back-edge is [Cell] `dependent_tasks`, which is a weak edge. + edges: TaskEdgesList, + }, + + /// Execution is invalid, but not yet scheduled + /// + /// on activation this will move to Scheduled + Dirty { outdated_edges: Box }, + + /// Execution is invalid and scheduled + /// + /// on start this will move to InProgress or Dirty depending on active flag + Scheduled(Box), + + /// Execution is happening + /// + /// on finish this will move to Done (!stale) or Scheduled (stale) + /// + /// on invalidation this will set it's stale flag + InProgress(Box), +} + +impl TaskStateType { + fn children(&self) -> impl Iterator + '_ { + match self { + TaskStateType::Done { edges, .. } => Either::Left(edges.children()), + TaskStateType::InProgress(box InProgressState { + outdated_edges, + new_children, + .. + }) => Either::Right(Either::Left( + outdated_edges + .children() + .chain(new_children.iter().copied()), + )), + TaskStateType::Dirty { outdated_edges, .. } => { + Either::Right(Either::Right(outdated_edges.children())) + } + TaskStateType::Scheduled(box ScheduledState { outdated_edges, .. }) => { + Either::Right(Either::Right(outdated_edges.children())) + } + } + } + + fn into_dependencies_and_children(self) -> (TaskEdgesSet, SmallVec<[TaskId; 6]>) { + match self { + TaskStateType::Done { edges, .. } => { + let mut edges = edges.into_set(); + let children = edges.drain_children(); + (edges, children) + } + TaskStateType::InProgress(box InProgressState { + outdated_edges, + new_children, + .. + }) => { + let mut edges = outdated_edges; + let mut children = edges.drain_children(); + children.extend(new_children.iter().copied()); + (edges, children) + } + TaskStateType::Dirty { outdated_edges, .. } + | TaskStateType::Scheduled(box ScheduledState { outdated_edges, .. }) => { + let mut edges = *outdated_edges; + let children = edges.drain_children(); + (edges, children) + } + } + } +} + +use TaskStateType::*; + +use self::{ + aggregation::{ActiveQuery, RootType, TaskAggregationNode, TaskGuard}, + meta_state::{ + FullTaskWriteGuard, TaskMetaState, TaskMetaStateReadGuard, TaskMetaStateWriteGuard, + }, +}; + +pub enum GcResult { + /// The task is not allowed to GC, e. g. due to it being non-pure or having + /// state. + NotPossible, + /// The task was rescheduled for GC and must not be GC'ed now but at a later + /// time. + Stale, + /// Dropped the content of task cells to save memory. + ContentDropped, + /// Unloaded the task completely to save memory. This disconnects the task + /// from the graph and only makes sense when the task isn't currently + /// active. + Unloaded, + AlreadyUnloaded, +} + +pub enum ReadCellError { + CellRemoved, + Recomputing(EventListener), +} + +impl Task { + pub(crate) fn new_persistent( + id: TaskId, + task_type: Arc>, + ) -> Self { + let ty = TaskType::Persistent { ty: task_type }; + Self { + id, + ty, + state: RwLock::new(TaskMetaState::Full(Box::new(TaskState::new()))), + graph_modification_in_progress_counter: AtomicU32::new(0), + } + } + + pub(crate) fn new_root( + id: TaskId, + functor: impl Fn() -> NativeTaskFuture + Sync + Send + 'static, + ) -> Self { + let ty = TaskType::Root(Box::new(Box::new(functor))); + let description = Self::get_event_description_static(id, &ty); + Self { + id, + ty, + state: RwLock::new(TaskMetaState::Full(Box::new(TaskState::new_scheduled( + description, + )))), + graph_modification_in_progress_counter: AtomicU32::new(0), + } + } + + pub(crate) fn new_once( + id: TaskId, + functor: impl Future> + Send + 'static, + ) -> Self { + let ty = TaskType::Once(Box::new(Mutex::new(Some(Box::pin(functor))))); + let description = Self::get_event_description_static(id, &ty); + Self { + id, + ty, + state: RwLock::new(TaskMetaState::Full(Box::new(TaskState::new_scheduled( + description, + )))), + graph_modification_in_progress_counter: AtomicU32::new(0), + } + } + + pub(crate) fn is_pure(&self) -> bool { + match &self.ty { + TaskType::Persistent { .. } => true, + TaskType::Root(_) => false, + TaskType::Once(_) => false, + } + } + + pub(crate) fn is_once(&self) -> bool { + match &self.ty { + TaskType::Persistent { .. } => false, + TaskType::Root(_) => false, + TaskType::Once(_) => true, + } + } + + pub(crate) fn set_root( + id: TaskId, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + { + Self::set_root_type( + &aggregation_context, + &mut aggregation_context.aggregation_data(id), + RootType::Root, + ); + } + aggregation_context.apply_queued_updates(); + } + + pub(crate) fn set_once( + id: TaskId, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + { + let mut aggregation_guard = aggregation_context.aggregation_data(id); + Self::set_root_type(&aggregation_context, &mut aggregation_guard, RootType::Once); + } + aggregation_context.apply_queued_updates(); + } + + fn set_root_type( + aggregation_context: &TaskAggregationContext, + aggregation: &mut AggregationDataGuard>, + root_type: RootType, + ) { + aggregation.root_type = Some(root_type); + let dirty_tasks = aggregation + .dirty_tasks + .iter() + .filter_map(|(&id, &count)| (count > 0).then_some(id)); + let mut tasks_to_schedule = aggregation_context.dirty_tasks_to_schedule.lock(); + tasks_to_schedule + .get_or_insert_default() + .extend(dirty_tasks); + } + + pub(crate) fn unset_root( + id: TaskId, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + { + aggregation_context.aggregation_data(id).root_type = None; + } + aggregation_context.apply_queued_updates(); + } + + pub(crate) fn get_function_name(&self) -> Option> { + if let TaskType::Persistent { ty, .. } = &self.ty { + Some(ty.get_name()) + } else { + None + } + } + + pub(crate) fn get_description(&self) -> String { + Self::format_description(&TaskTypeForDescription::from(&self.ty), self.id) + } + + fn format_description(ty: &TaskTypeForDescription, id: TaskId) -> String { + match ty { + TaskTypeForDescription::Root => format!("[{}] root", id), + TaskTypeForDescription::Once => format!("[{}] once", id), + TaskTypeForDescription::Persistent(ty) => match &***ty { + PersistentTaskType::Native { + fn_type: native_fn, + this: _, + arg: _, + } => { + format!("[{}] {}", id, registry::get_function(*native_fn).name) + } + PersistentTaskType::ResolveNative { + fn_type: native_fn, + this: _, + arg: _, + } => { + format!( + "[{}] [resolve] {}", + id, + registry::get_function(*native_fn).name + ) + } + PersistentTaskType::ResolveTrait { + trait_type, + method_name: fn_name, + this: _, + arg: _, + } => { + format!( + "[{}] [resolve trait] {} in trait {}", + id, + fn_name, + registry::get_trait(*trait_type).name + ) + } + }, + } + } + + fn get_event_description_static( + id: TaskId, + ty: &TaskType, + ) -> impl Fn() -> String + Send + Sync + Clone { + let ty = TaskTypeForDescription::from(ty); + move || Self::format_description(&ty, id) + } + + fn get_event_description(&self) -> impl Fn() -> String + Send + Sync + Clone { + Self::get_event_description_static(self.id, &self.ty) + } + + pub(crate) fn remove_dependency( + dep: TaskEdge, + reader: TaskId, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + match dep { + TaskEdge::Output(task) => { + backend.with_task(task, |task| { + task.access_output_for_removing_dependents(|output| { + output.dependent_tasks.remove(&reader); + }); + }); + } + TaskEdge::Cell(task, index) => { + backend.with_task(task, |task| { + task.access_cell_for_removing_dependents(index, |cell| { + cell.remove_dependent_task(reader); + }); + }); + } + TaskEdge::Collectibles(task, trait_type) => { + let aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let mut aggregation = aggregation_context.aggregation_data(task); + aggregation.remove_collectible_dependent_task(trait_type, reader); + } + TaskEdge::Child(_) => { + panic!("Children should not be removed via remove_dependency") + } + } + } + + fn clear_dependencies( + &self, + dependencies: TaskEdgesSet, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + for dep in dependencies.into_iter() { + Task::remove_dependency(dep, self.id, backend, turbo_tasks); + } + } + + fn state(&self) -> TaskMetaStateReadGuard<'_> { + self.state.read().into() + } + + fn try_state(&self) -> Option> { + self.state.try_read().map(|guard| guard.into()) + } + + fn state_mut(&self) -> TaskMetaStateWriteGuard<'_> { + self.state.write().into() + } + + fn full_state_mut(&self) -> FullTaskWriteGuard<'_> { + TaskMetaStateWriteGuard::full_from(self.state.write()) + } + + #[allow(dead_code, reason = "We need this in future")] + fn partial_state_mut(&self) -> TaskMetaStateWriteGuard<'_> { + TaskMetaStateWriteGuard::partial_from(self.state.write()) + } + + pub(crate) fn execute<'a>( + self: &'a Task, + backend: &'a MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Option> { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let (future, span) = { + let mut state = self.full_state_mut(); + match state.state_type { + Done { .. } | InProgress { .. } => { + // should not start in this state + return None; + } + Scheduled(box ScheduledState { + ref mut done_event, + ref mut start_event, + ref mut outdated_edges, + clean, + }) => { + start_event.notify(usize::MAX); + let done_event = done_event.take(); + let outdated_edges = *take(outdated_edges); + let outdated_collectibles = take(&mut state.collectibles); + state.state_type = InProgress(Box::new(InProgressState { + done_event, + count_as_finished: false, + clean, + stale: false, + outdated_edges, + outdated_collectibles, + new_children: Default::default(), + })); + } + Dirty { .. } => { + let state_type = Task::state_string(&state); + panic!( + "{:?} execution started in unexpected state {}", + self, state_type + ) + } + }; + self.make_execution_future(backend, turbo_tasks) + }; + aggregation_context.apply_queued_updates(); + Some(TaskExecutionSpec { future, span }) + } + + /// Prepares task execution and returns a future that will execute the task. + fn make_execution_future<'a>( + self: &'a Task, + _backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> ( + Pin> + Send + 'a>>, + Span, + ) { + match &self.ty { + TaskType::Root(bound_fn) => { + (bound_fn(), tracing::trace_span!("turbo_tasks::root_task")) + } + TaskType::Once(mutex) => ( + mutex.lock().take().expect("Task can only be executed once"), + tracing::trace_span!("turbo_tasks::once_task"), + ), + TaskType::Persistent { ty, .. } => match &***ty { + PersistentTaskType::Native { + fn_type: native_fn, + this, + arg, + } => { + let func = registry::get_function(*native_fn); + let span = func.span(); + let entered = span.enter(); + let future = func.execute(*this, &**arg); + drop(entered); + (future, span) + } + PersistentTaskType::ResolveNative { + fn_type: ref native_fn_id, + this, + arg, + } => { + let native_fn_id = *native_fn_id; + let func = registry::get_function(native_fn_id); + let span = func.resolve_span(); + let entered = span.enter(); + let turbo_tasks = turbo_tasks.pin(); + let future = Box::pin(PersistentTaskType::run_resolve_native( + native_fn_id, + *this, + &**arg, + turbo_tasks, + )); + drop(entered); + (future, span) + } + PersistentTaskType::ResolveTrait { + trait_type: trait_type_id, + method_name: name, + this, + arg, + } => { + let trait_type_id = *trait_type_id; + let trait_type = registry::get_trait(trait_type_id); + let span = trait_type.resolve_span(name); + let entered = span.enter(); + let name = name.clone(); + let turbo_tasks = turbo_tasks.pin(); + let future = Box::pin(PersistentTaskType::run_resolve_trait( + trait_type_id, + name, + *this, + &**arg, + turbo_tasks, + )); + drop(entered); + (future, span) + } + }, + } + } + + pub(crate) fn mark_as_finished( + &self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() else { + return; + }; + let TaskStateType::InProgress(box InProgressState { + ref mut count_as_finished, + ref mut stale, + ref mut outdated_collectibles, + ref mut outdated_edges, + .. + }) = state.state_type + else { + return; + }; + if *count_as_finished || *stale { + return; + } + *count_as_finished = true; + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + { + let outdated_children = outdated_edges.drain_children(); + let outdated_collectibles = outdated_collectibles.take_collectibles(); + + let mut change = TaskChange { + unfinished: -1, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update: vec![(self.id, -1)], + ..Default::default() + }; + if let Some(collectibles) = outdated_collectibles { + for ((trait_type, value), count) in collectibles.into_iter() { + change.collectibles.push((trait_type, value, -count)); + } + } + let change_job = state + .aggregation_node + .apply_change(&aggregation_context, change); + let remove_job = if outdated_children.is_empty() { + None + } else { + Some(state.aggregation_node.handle_lost_edges( + &aggregation_context, + &self.id, + outdated_children, + )) + }; + drop(state); + change_job.apply(&aggregation_context); + remove_job.apply(&aggregation_context); + } + aggregation_context.apply_queued_updates(); + } + + pub(crate) fn execution_result( + &self, + result: Result, Option>>, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let mut state = self.full_state_mut(); + match state.state_type { + InProgress(ref state) if state.stale => { + // We don't want to assign the output cell here + // as we want to avoid unnecessary updates + // TODO maybe this should be controlled by a heuristic + } + InProgress(..) => match result { + Ok(Ok(result)) => { + if state.output != result { + if cfg!(feature = "print_task_invalidation") + && !matches!(state.output.content, OutputContent::Empty) + { + println!( + "Task {{ id: {}, name: {} }} invalidates:", + *self.id, self.ty + ); + for dep in state.output.dependent_tasks.iter() { + backend.with_task(*dep, |task| { + println!("\tTask {{ id: {}, name: {} }}", *task.id, task.ty); + }); + } + } + state.output.link(result, turbo_tasks) + } + } + Ok(Err(mut err)) => { + if let Some(name) = self.get_function_name() { + err = err.context(format!("Execution of {} failed", name)); + } + state.output.error(err, turbo_tasks) + } + Err(message) => state.output.panic(message, turbo_tasks), + }, + + Dirty { .. } | Scheduled { .. } | Done { .. } => { + panic!( + "Task execution completed in unexpected state {}", + Task::state_string(&state) + ) + } + }; + } + + #[must_use] + pub(crate) fn execution_completed( + &self, + duration: Duration, + memory_usage: usize, + generation: NonZeroU32, + cell_counters: AutoMap, 8>, + stateful: bool, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> bool { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let mut schedule_task = false; + { + let mut change_job = None; + let mut remove_job = None; + let mut drained_cells = SmallVec::<[Cell; 8]>::new(); + let dependencies = DEPENDENCIES_TO_TRACK.with(|deps| deps.take()); + { + let mut state = self.full_state_mut(); + + state + .gc + .execution_completed(duration, memory_usage, generation); + + let TaskState { + ref mut cells, + ref mut state_type, + .. + } = *state; + + let InProgress(box InProgressState { + ref mut done_event, + count_as_finished, + ref mut outdated_edges, + ref mut outdated_collectibles, + ref mut new_children, + clean, + stale, + }) = *state_type + else { + panic!( + "Task execution completed in unexpected state {}", + Task::state_string(&state) + ) + }; + for (value_type, cells) in cells.iter_mut() { + let counter = + cell_counters.get(value_type).copied().unwrap_or_default() as usize; + let mut is_unused = true; + while counter < cells.len() { + let last = cells.last_mut().unwrap(); + last.empty(clean, turbo_tasks); + if is_unused { + if last.is_unused() { + drained_cells.push(cells.pop().unwrap()); + } else { + is_unused = false; + } + } + } + } + let done_event = done_event.take(); + let outdated_collectibles = outdated_collectibles.take_collectibles(); + let mut outdated_edges = take(outdated_edges); + let mut new_edges = dependencies; + let new_children = take(new_children); + if stale { + for dep in new_edges.into_iter() { + // TODO Could be more efficent + outdated_edges.insert(dep); + } + for child in new_children { + outdated_edges.insert(TaskEdge::Child(child)); + } + if let Some(collectibles) = outdated_collectibles { + let mut change = TaskChange::default(); + for ((trait_type, value), count) in collectibles.into_iter() { + change.collectibles.push((trait_type, value, -count)); + } + change_job = state + .aggregation_node + .apply_change(&aggregation_context, change); + } + let description = self.get_event_description(); + let start_event = + Event::new(move || format!("TaskState({})::start_event", description())); + state.state_type = Scheduled(Box::new(ScheduledState { + start_event, + done_event, + outdated_edges: Box::new(outdated_edges), + clean: false, + })); + drop(state); + schedule_task = true; + } else { + outdated_edges.remove_all(&new_edges); + for child in new_children { + new_edges.insert(TaskEdge::Child(child)); + outdated_edges.remove(TaskEdge::Child(child)); + } + if !backend.has_gc() { + // This will stay here for longer, so make sure to not consume too + // much memory + for cells in state.cells.values_mut() { + cells.shrink_to_fit(); + } + state.cells.shrink_to_fit(); + } + state.state_type = Done { + stateful, + edges: new_edges.into_list(), + }; + if !count_as_finished { + let mut change = TaskChange { + unfinished: -1, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update: vec![(self.id, -1)], + ..Default::default() + }; + if let Some(collectibles) = outdated_collectibles { + for ((trait_type, value), count) in collectibles.into_iter() { + change.collectibles.push((trait_type, value, -count)); + } + } + change_job = state + .aggregation_node + .apply_change(&aggregation_context, change); + } else if let Some(collectibles) = outdated_collectibles { + let mut change = TaskChange::default(); + for ((trait_type, value), count) in collectibles.into_iter() { + change.collectibles.push((trait_type, value, -count)); + } + change_job = state + .aggregation_node + .apply_change(&aggregation_context, change); + } + let outdated_children = outdated_edges.drain_children(); + if !outdated_children.is_empty() { + remove_job = state.aggregation_node.handle_lost_edges( + &aggregation_context, + &self.id, + outdated_children, + ); + } + done_event.notify(usize::MAX); + drop(state); + self.clear_dependencies(outdated_edges, backend, turbo_tasks); + } + } + for cell in drained_cells { + cell.gc_drop(turbo_tasks); + } + change_job.apply(&aggregation_context); + remove_job.apply(&aggregation_context); + } + if let TaskType::Once(_) = self.ty { + // unset the root type, so tasks below are no longer active + aggregation_context.aggregation_data(self.id).root_type = None; + } + aggregation_context.apply_queued_updates(); + + schedule_task + } + + fn make_dirty( + &self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + if let TaskType::Once(_) = self.ty { + // once task won't become dirty + return; + } + + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let should_schedule = + query_root_info(&aggregation_context, ActiveQuery::default(), self.id); + + if let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() { + match state.state_type { + Scheduled(box ScheduledState { ref mut clean, .. }) => { + *clean = false; + + // already scheduled + drop(state); + } + Dirty { .. } => { + // already dirty + drop(state); + } + Done { ref mut edges, .. } => { + let outdated_edges = take(edges).into_set(); + // add to dirty lists and potentially schedule + if should_schedule { + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + unfinished: 1, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update: vec![(self.id, 1)], + ..Default::default() + }, + ); + let description = self.get_event_description(); + let description2 = description.clone(); + state.state_type = Scheduled(Box::new(ScheduledState { + done_event: Event::new(move || { + format!("TaskState({})::done_event", description()) + }), + start_event: Event::new(move || { + format!("TaskState({})::start_event", description2()) + }), + outdated_edges: Box::new(outdated_edges), + clean: false, + })); + drop(state); + change_job.apply(&aggregation_context); + + if cfg!(feature = "print_task_invalidation") { + println!("invalidated Task {{ id: {}, name: {} }}", *self.id, self.ty); + } + turbo_tasks.schedule(self.id); + } else { + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + unfinished: 1, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update: vec![(self.id, 1)], + dirty_tasks_update: vec![(self.id, 1)], + ..Default::default() + }, + ); + state.state_type = Dirty { + outdated_edges: Box::new(outdated_edges), + }; + drop(state); + change_job.apply(&aggregation_context); + } + } + InProgress(box InProgressState { + ref mut count_as_finished, + ref mut clean, + ref mut stale, + .. + }) => { + if !*stale { + *clean = false; + *stale = true; + let change_job = if *count_as_finished { + *count_as_finished = false; + let change = TaskChange { + unfinished: 1, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update: vec![(self.id, 1)], + ..Default::default() + }; + Some( + state + .aggregation_node + .apply_change(&aggregation_context, change), + ) + } else { + None + }; + drop(state); + change_job.apply(&aggregation_context); + } + } + } + } + aggregation_context.apply_queued_updates(); + } + + /// Called when the task need to be recomputed because a gc'ed cell was + /// read. + pub(crate) fn recompute( + &self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let _span = tracing::trace_span!("turbo_tasks::recompute", id = *self.id).entered(); + + // Events that lead to recomputation of non-pure task must not happen + assert!(self.is_pure()); + + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let mut state = self.full_state_mut(); + match state.state_type { + Scheduled { .. } => { + // already scheduled + drop(state); + } + InProgress(..) => { + // already in progress + drop(state); + } + Dirty { + ref mut outdated_edges, + } => { + let description = self.get_event_description(); + let description2 = description.clone(); + state.state_type = Scheduled(Box::new(ScheduledState { + start_event: Event::new(move || { + format!("TaskState({})::start_event", description()) + }), + done_event: Event::new(move || { + format!("TaskState({})::done_event", description2()) + }), + outdated_edges: take(outdated_edges), + clean: false, + })); + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + dirty_tasks_update: vec![(self.id, -1)], + ..Default::default() + }, + ); + drop(state); + change_job.apply(&aggregation_context); + turbo_tasks.schedule(self.id); + } + Done { ref mut edges, .. } => { + let outdated_edges = take(edges).into_set(); + // add to dirty lists and potentially schedule + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + unfinished: 1, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update: vec![(self.id, 1)], + ..Default::default() + }, + ); + let description = self.get_event_description(); + let description2 = description.clone(); + state.state_type = Scheduled(Box::new(ScheduledState { + start_event: Event::new(move || { + format!("TaskState({})::start_event", description()) + }), + done_event: Event::new(move || { + format!("TaskState({})::done_event", description2()) + }), + outdated_edges: Box::new(outdated_edges), + clean: true, + })); + drop(state); + change_job.apply(&aggregation_context); + + turbo_tasks.schedule(self.id); + } + } + aggregation_context.apply_queued_updates(); + } + + pub(crate) fn schedule_when_dirty_from_aggregation( + &self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let mut state = self.full_state_mut(); + if let TaskStateType::Dirty { + ref mut outdated_edges, + } = state.state_type + { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let description = self.get_event_description(); + let description2 = description.clone(); + state.state_type = Scheduled(Box::new(ScheduledState { + start_event: Event::new(move || { + format!("TaskState({})::start_event", description()) + }), + done_event: Event::new(move || { + format!("TaskState({})::done_event", description2()) + }), + outdated_edges: take(outdated_edges), + clean: false, + })); + let job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + dirty_tasks_update: vec![(self.id, -1)], + ..Default::default() + }, + ); + drop(state); + turbo_tasks.schedule(self.id); + job.apply(&aggregation_context); + aggregation_context.apply_queued_updates(); + } + } + + pub(crate) fn add_dependency_to_current(dep: TaskEdge) { + DEPENDENCIES_TO_TRACK.with(|list| { + let mut list = list.borrow_mut(); + list.insert(dep); + }) + } + + /// Get an [Invalidator] that can be used to invalidate the current [Task] + /// based on external events. + pub fn get_invalidator() -> Invalidator { + get_invalidator() + } + + /// Called by the [Invalidator]. Invalidate the [Task]. When the task is + /// active it will be scheduled for execution. + pub(crate) fn invalidate( + &self, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + self.make_dirty(backend, turbo_tasks) + } + + /// Access to the output cell. + pub(crate) fn access_output_for_removing_dependents( + &self, + func: impl FnOnce(&mut Output) -> T, + ) -> Option { + if let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() { + Some(func(&mut state.output)) + } else { + None + } + } + + /// Read a cell. + pub(crate) fn read_cell( + &self, + index: CellId, + gc_queue: Option<&GcQueue>, + note: impl Fn() -> String + Sync + Send + 'static, + reader: Option, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result { + let task_id = self.id; + let mut state = self.full_state_mut(); + if let Some(gc_queue) = gc_queue { + let generation = gc_queue.generation(); + if state.gc.on_read(generation) { + let _ = gc_queue.task_accessed(self.id); + } + } + match state.state_type { + Done { .. } | InProgress(..) => { + let is_done = matches!(state.state_type, Done { .. }); + let list = state.cells.entry(index.type_id).or_default(); + let i = index.index as usize; + if list.len() <= i { + list.resize_with(i + 1, Default::default); + } + let cell = &mut list[i]; + let description = move || format!("{task_id} {index}"); + let read_result = if let Some(reader) = reader { + cell.read_content(reader, is_done, description, note) + } else { + cell.read_content_untracked(is_done, description, note) + }; + drop(state); + match read_result { + Ok(content) => Ok(content), + Err(ReadContentError::Computing { listener, schedule }) => { + if schedule { + self.recompute(backend, turbo_tasks); + } + Err(ReadCellError::Recomputing(listener)) + } + Err(ReadContentError::Unused) => Err(ReadCellError::CellRemoved), + } + } + Dirty { + ref mut outdated_edges, + } => { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let description = self.get_event_description(); + let description2 = description.clone(); + let start_event = + Event::new(move || format!("TaskState({})::start_event", description())); + let listener = start_event.listen_with_note(note); + state.state_type = Scheduled(Box::new(ScheduledState { + start_event, + done_event: Event::new(move || { + format!("TaskState({})::done_event", description2()) + }), + outdated_edges: take(outdated_edges), + clean: false, + })); + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + dirty_tasks_update: vec![(self.id, -1)], + ..Default::default() + }, + ); + drop(state); + turbo_tasks.schedule(self.id); + change_job.apply(&aggregation_context); + aggregation_context.apply_queued_updates(); + Err(ReadCellError::Recomputing(listener)) + } + Scheduled(box ScheduledState { + ref start_event, .. + }) => Err(ReadCellError::Recomputing( + start_event.listen_with_note(note), + )), + } + } + + /// Access to a cell. + pub(crate) fn access_cell_for_write( + &self, + index: CellId, + func: impl FnOnce(&mut Cell, bool) -> T, + ) -> T { + let mut state = self.full_state_mut(); + let clean = match state.state_type { + InProgress(box InProgressState { clean, .. }) => clean, + _ => false, + }; + let list = state.cells.entry(index.type_id).or_default(); + let i = index.index as usize; + if list.len() <= i { + list.resize_with(i + 1, Default::default); + } + func(&mut list[i], clean) + } + + /// Access to a cell. + pub(crate) fn access_cell_for_removing_dependents( + &self, + index: CellId, + func: impl FnOnce(&mut Cell) -> T, + ) -> Option { + self.state_mut() + .as_full_mut() + .and_then(|state| state.cells.get_mut(&index.type_id)) + .and_then(|list| list.get_mut(index.index as usize).map(func)) + } + + /// Access to a cell. + pub(crate) fn with_cell(&self, index: CellId, func: impl FnOnce(&Cell) -> T) -> T { + if let Some(cell) = self + .state() + .as_full() + .and_then(|state| state.cells.get(&index.type_id)) + .and_then(|list| list.get(index.index as usize)) + { + func(cell) + } else { + func(&Default::default()) + } + } + + /// Checks if the task is inactive. Returns false if it's still active. + pub(crate) fn potentially_become_inactive( + &self, + gc_queue: &GcQueue, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> bool { + let aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let active = query_root_info(&aggregation_context, ActiveQuery::default(), self.id); + if active { + return false; + } + if let TaskMetaStateWriteGuard::Full(mut state) = self.state_mut() { + if state.gc.generation.is_none() { + let generation = gc_queue.task_inactive(self.id); + state.gc.generation = Some(generation); + } + for child in state.state_type.children() { + gc_queue.task_potentially_no_longer_active(child); + } + } + true + } + + pub fn is_pending(&self) -> bool { + if let TaskMetaStateReadGuard::Full(state) = self.state() { + !matches!(state.state_type, TaskStateType::Done { .. }) + } else { + true + } + } + + pub fn is_dirty(&self) -> bool { + if let TaskMetaStateReadGuard::Full(state) = self.state() { + matches!(state.state_type, TaskStateType::Dirty { .. }) + } else { + false + } + } + + fn state_string(state: &TaskState) -> &'static str { + match state.state_type { + Scheduled { .. } => "scheduled", + InProgress(box InProgressState { stale: true, .. }) => "in progress (stale)", + InProgress(box InProgressState { clean: true, .. }) => "in progress (clean)", + InProgress(box InProgressState { + count_as_finished: true, + .. + }) => "in progress (marked as finished)", + InProgress(box InProgressState { .. }) => "in progress", + Done { .. } => "done", + Dirty { .. } => "dirty", + } + } + + pub(crate) fn connect_child( + &self, + child_id: TaskId, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + { + let mut add_job = None; + { + let mut state = self.full_state_mut(); + match &mut state.state_type { + TaskStateType::InProgress(box InProgressState { + outdated_edges, + new_children, + .. + }) => { + if new_children.insert(child_id) { + if outdated_edges.remove(TaskEdge::Child(child_id)) { + drop(state); + aggregation_context.apply_queued_updates(); + return; + } + let number_of_children = new_children.len(); + let mut guard = TaskGuard::from_full(self.id, state); + add_job = Some(handle_new_edge( + &aggregation_context, + &mut guard, + &self.id, + &child_id, + number_of_children, + )); + } + } + _ => panic!("Unexpected task state when adding a child task"), + } + } + if let Some(job) = add_job { + // To avoid bubbling up the dirty tasks into the new parent tree, we make a + // quick check for activeness of the parent when the child is dirty. This is + // purely an optimization and not required for correctness. + // So it's fine to ignore the race condition existing here. + backend.with_task(child_id, |child| { + if child.is_dirty() { + let active = + query_root_info(&aggregation_context, ActiveQuery::default(), self.id); + if active { + child.schedule_when_dirty_from_aggregation(backend, turbo_tasks); + } + } + }); + job.apply(&aggregation_context); + } + } + aggregation_context.apply_queued_updates(); + } + + pub(crate) fn get_or_wait_output Result>( + &self, + strongly_consistent: bool, + func: F, + note: impl Fn() -> String + Sync + Send + 'static, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result> { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + if strongly_consistent { + prepare_aggregation_data(&aggregation_context, &self.id); + } + let mut state = if strongly_consistent { + let mut aggregation = aggregation_data(&aggregation_context, &self.id); + if aggregation.unfinished > 0 { + if aggregation.root_type.is_none() { + Self::set_root_type( + &aggregation_context, + &mut aggregation, + RootType::ReadingStronglyConsistent, + ); + } + let listener = aggregation.unfinished_event.listen_with_note(note); + drop(aggregation); + aggregation_context.apply_queued_updates(); + + return Ok(Err(listener)); + } else if matches!( + aggregation.root_type, + Some(RootType::ReadingStronglyConsistent) + ) { + aggregation.root_type = None; + } + let state = aggregation.into_inner().into_inner().into_inner(); + TaskMetaStateWriteGuard::full_from(state) + } else { + self.full_state_mut() + }; + let result = match state.state_type { + Done { .. } => { + let result = func(&mut state.output)?; + drop(state); + + Ok(Ok(result)) + } + Dirty { + ref mut outdated_edges, + } => { + turbo_tasks.schedule(self.id); + let description = self.get_event_description(); + let description2 = description.clone(); + let done_event = + Event::new(move || format!("TaskState({})::done_event", description())); + let listener = done_event.listen_with_note(note); + state.state_type = Scheduled(Box::new(ScheduledState { + start_event: Event::new(move || { + format!("TaskState({})::start_event", description2()) + }), + done_event, + outdated_edges: take(outdated_edges), + clean: false, + })); + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + dirty_tasks_update: vec![(self.id, -1)], + ..Default::default() + }, + ); + drop(state); + change_job.apply(&aggregation_context); + Ok(Err(listener)) + } + Scheduled(box ScheduledState { ref done_event, .. }) + | InProgress(box InProgressState { ref done_event, .. }) => { + let listener = done_event.listen_with_note(note); + drop(state); + Ok(Err(listener)) + } + }; + aggregation_context.apply_queued_updates(); + result + } + + pub(crate) fn read_collectibles( + id: TaskId, + trait_type: TraitTypeId, + reader: TaskId, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> TaskCollectiblesMap { + let aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let mut aggregation_data = aggregation_context.aggregation_data(id); + aggregation_data.read_collectibles(trait_type, reader) + } + + pub(crate) fn emit_collectible( + &self, + trait_type: TraitTypeId, + collectible: RawVc, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let mut state = self.full_state_mut(); + state.collectibles.emit(trait_type, collectible); + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + collectibles: vec![(trait_type, collectible, 1)], + ..Default::default() + }, + ); + drop(state); + change_job.apply(&aggregation_context); + aggregation_context.apply_queued_updates(); + } + + pub(crate) fn unemit_collectible( + &self, + trait_type: TraitTypeId, + collectible: RawVc, + count: u32, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let mut state = self.full_state_mut(); + state.collectibles.unemit(trait_type, collectible, count); + let change_job = state.aggregation_node.apply_change( + &aggregation_context, + TaskChange { + collectibles: vec![(trait_type, collectible, -(count as i32))], + ..Default::default() + }, + ); + drop(state); + change_job.apply(&aggregation_context); + aggregation_context.apply_queued_updates(); + } + + pub(crate) fn run_gc( + &self, + generation: NonZeroU32, + gc_queue: &GcQueue, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> GcResult { + if !self.is_pure() { + return GcResult::NotPossible; + } + + let aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let active = query_root_info(&aggregation_context, ActiveQuery::default(), self.id); + + match self.state_mut() { + TaskMetaStateWriteGuard::Full(mut state) => { + if let Some(old_gen) = state.gc.generation { + if old_gen > generation { + return GcResult::Stale; + } + } else { + return GcResult::Stale; + } + state.gc.generation = None; + + match &mut state.state_type { + TaskStateType::Done { stateful, edges: _ } => { + if *stateful { + return GcResult::NotPossible; + } + } + TaskStateType::Dirty { .. } => {} + _ => { + // GC can't run in this state. We will reschedule it when the execution + // completes. + return GcResult::NotPossible; + } + } + + if active { + let mut cells_to_drop = Vec::new(); + + // shrinking memory and dropping cells + state.aggregation_node.shrink_to_fit(); + state.output.dependent_tasks.shrink_to_fit(); + state.cells.shrink_to_fit(); + for cells in state.cells.values_mut() { + cells.shrink_to_fit(); + for cell in cells.iter_mut() { + cells_to_drop.extend(cell.gc_content()); + cell.shrink_to_fit(); + } + } + + drop(state); + + gc_queue.task_gc_active(self.id); + + // Dropping cells outside of the lock + drop(cells_to_drop); + + GcResult::ContentDropped + } else { + // Task is inactive, unload task + self.unload(state, backend, turbo_tasks); + GcResult::Unloaded + } + } + TaskMetaStateWriteGuard::Partial(mut state) => { + state.aggregation_node.shrink_to_fit(); + GcResult::AlreadyUnloaded + } + TaskMetaStateWriteGuard::Unloaded(_) => GcResult::AlreadyUnloaded, + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } + + pub(crate) fn gc_state(&self) -> Option { + if let TaskMetaStateReadGuard::Full(state) = self.state() { + Some(state.gc) + } else { + None + } + } + + fn unload( + &self, + mut full_state: FullTaskWriteGuard<'_>, + backend: &MemoryBackend, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> bool { + let mut aggregation_context = TaskAggregationContext::new(turbo_tasks, backend); + let mut change_job = None; + let TaskState { + ref mut aggregation_node, + ref mut state_type, + .. + } = *full_state; + match state_type { + Done { edges: _, stateful } => { + if *stateful { + return false; + } + change_job = aggregation_node.apply_change( + &aggregation_context, + TaskChange { + unfinished: 1, + dirty_tasks_update: vec![(self.id, 1)], + ..Default::default() + }, + ); + } + Dirty { outdated_edges: _ } => {} + _ => { + // Any other state is not unloadable. + return false; + } + } + // Task is now dirty, so we can safely unload it + + let mut state = full_state.into_inner(); + let old_state = replace( + &mut *state, + // placeholder + TaskMetaState::Unloaded(UnloadedTaskState {}), + ); + let TaskState { + cells, + output, + collectibles, + mut aggregation_node, + // can be dropped as always Dirty, event has been notified above + state_type, + // can be dropped as only gc meta info + gc: _, + } = old_state.into_full().unwrap(); + + let (dependencies, children) = state_type.into_dependencies_and_children(); + + // Remove all children, as they will be added again when this task is executed + // again + let remove_job = (!children.is_empty()) + .then(|| aggregation_node.handle_lost_edges(&aggregation_context, &self.id, children)); + + // Remove all collectibles, as they will be added again when this task is + // executed again. + let collectibles_job = if let Some(collectibles) = collectibles.into_inner() { + aggregation_node.apply_change( + &aggregation_context, + TaskChange { + collectibles: collectibles + .into_iter() + .map(|((t, r), c)| (t, r, -c)) + .collect(), + ..Default::default() + }, + ) + } else { + None + }; + + aggregation_node.shrink_to_fit(); + + // TODO aggregation_node + let unset = false; + + if unset { + *state = TaskMetaState::Unloaded(UnloadedTaskState {}); + } else { + *state = TaskMetaState::Partial(Box::new(PartialTaskState { aggregation_node })); + } + drop(state); + + change_job.apply(&aggregation_context); + remove_job.apply(&aggregation_context); + collectibles_job.apply(&aggregation_context); + + // Notify everyone that is listening on our output or cells. + // This will mark everyone as dirty and will trigger a new execution when they + // become active again. + for cells in cells.into_values() { + for cell in cells { + cell.gc_drop(turbo_tasks); + } + } + output.gc_drop(turbo_tasks); + + // TODO This is a race condition, the task might be executed again while + // removing dependencies. + // We can clear the dependencies as we are already marked as dirty + self.clear_dependencies(dependencies, backend, turbo_tasks); + + aggregation_context.apply_queued_updates(); + + true + } +} + +impl Display for Task { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + if let TaskMetaStateReadGuard::Full(state) = self.state() { + write!( + f, + "Task({}, {})", + self.get_description(), + Task::state_string(&state) + ) + } else { + write!(f, "Task({}, unloaded)", self.get_description()) + } + } +} + +impl Hash for Task { + fn hash(&self, state: &mut H) { + Hash::hash(&(self as *const Task), state) + } +} + +impl PartialEq for Task { + fn eq(&self, other: &Self) -> bool { + std::ptr::eq(self, other) + } +} + +impl Eq for Task {} diff --git a/turbopack/crates/turbo-tasks-memory/src/task/aggregation.rs b/turbopack/crates/turbo-tasks-memory/src/task/aggregation.rs new file mode 100644 index 0000000000000..581768a7a753a --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/task/aggregation.rs @@ -0,0 +1,663 @@ +use std::{ + cmp::Ordering, + hash::{BuildHasher, BuildHasherDefault, Hash}, + mem::take, + ops::{ControlFlow, Deref, DerefMut}, + sync::atomic::AtomicU32, +}; + +use auto_hash_map::{map::Entry, AutoMap}; +use either::Either; +use parking_lot::Mutex; +use rustc_hash::FxHasher; +use turbo_tasks::{ + backend::TaskCollectiblesMap, event::Event, RawVc, TaskId, TaskIdSet, TraitTypeId, + TurboTasksBackendApi, +}; + +use super::{ + meta_state::{FullTaskWriteGuard, TaskMetaStateWriteGuard}, + InProgressState, TaskStateType, +}; +use crate::{ + aggregation::{ + aggregation_data, AggregationContext, AggregationDataGuard, AggregationNode, + AggregationNodeGuard, RootQuery, + }, + MemoryBackend, +}; + +pub enum RootType { + Once, + Root, + ReadingStronglyConsistent, +} + +#[derive(Debug, Default)] +pub struct CollectiblesInfo { + collectibles: TaskCollectiblesMap, + dependent_tasks: TaskIdSet, +} + +impl CollectiblesInfo { + fn is_unset(&self) -> bool { + self.collectibles.is_empty() && self.dependent_tasks.is_empty() + } +} + +pub struct Aggregated { + /// The number of unfinished items in the lower aggregation level. + /// Unfinished means not "Done". + // TODO determine if this can go negative in concurrent situations. + pub unfinished: i32, + /// Event that will be notified when all unfinished tasks are done. + pub unfinished_event: Event, + /// A list of all tasks that are unfinished. Only for debugging. + #[cfg(feature = "track_unfinished")] + pub unfinished_tasks: AutoMap>, + /// A list of all tasks that are dirty. + /// When the it becomes active, these need to be scheduled. + // TODO evaluate a more efficient data structure for this since we are copying the list on + // every level. + pub dirty_tasks: AutoMap>, + /// Emitted collectibles with count and dependent_tasks by trait type + pub collectibles: AutoMap>, + + /// Only used for the aggregation root. Which kind of root is this? + /// [RootType::Once] for OnceTasks or [RootType::Root] for Root Tasks. + /// [RootType::ReadingStronglyConsistent] while currently reading a task + /// strongly consistent. It's set to None for other tasks, when the once + /// task is done or when the root task is disposed. + pub root_type: Option, +} + +impl Default for Aggregated { + fn default() -> Self { + Self { + unfinished: 0, + unfinished_event: Event::new(|| "Aggregated::unfinished_event".to_string()), + #[cfg(feature = "track_unfinished")] + unfinished_tasks: AutoMap::with_hasher(), + dirty_tasks: AutoMap::with_hasher(), + collectibles: AutoMap::with_hasher(), + root_type: None, + } + } +} + +impl Aggregated { + pub(crate) fn remove_collectible_dependent_task( + &mut self, + trait_type: TraitTypeId, + reader: TaskId, + ) { + if let Entry::Occupied(mut entry) = self.collectibles.entry(trait_type) { + let info = entry.get_mut(); + let removed = info.dependent_tasks.remove(&reader); + if removed && info.is_unset() { + entry.remove(); + } + } + } + + pub(crate) fn read_collectibles( + &mut self, + trait_type: TraitTypeId, + reader: TaskId, + ) -> TaskCollectiblesMap { + match self.collectibles.entry(trait_type) { + Entry::Occupied(mut e) => { + let info = e.get_mut(); + info.dependent_tasks.insert(reader); + info.collectibles.clone() + } + Entry::Vacant(e) => { + e.insert(CollectiblesInfo::default()) + .dependent_tasks + .insert(reader); + AutoMap::default() + } + } + } +} + +#[derive(Default, Debug)] +pub struct TaskChange { + pub unfinished: i32, + #[cfg(feature = "track_unfinished")] + pub unfinished_tasks_update: Vec<(TaskId, i32)>, + pub dirty_tasks_update: Vec<(TaskId, i32)>, + pub collectibles: Vec<(TraitTypeId, RawVc, i32)>, +} + +impl TaskChange { + pub fn is_empty(&self) -> bool { + #[allow(unused_mut, reason = "feature flag")] + let mut empty = self.unfinished == 0 + && self.dirty_tasks_update.is_empty() + && self.collectibles.is_empty(); + #[cfg(feature = "track_unfinished")] + if !self.unfinished_tasks_update.is_empty() { + empty = false; + } + empty + } +} + +pub struct TaskAggregationContext<'a> { + pub turbo_tasks: &'a dyn TurboTasksBackendApi, + pub backend: &'a MemoryBackend, + pub dirty_tasks_to_schedule: Mutex>, + pub tasks_to_notify: Mutex>, +} + +impl<'a> TaskAggregationContext<'a> { + pub fn new( + turbo_tasks: &'a dyn TurboTasksBackendApi, + backend: &'a MemoryBackend, + ) -> Self { + Self { + turbo_tasks, + backend, + dirty_tasks_to_schedule: Mutex::new(None), + tasks_to_notify: Mutex::new(None), + } + } + + pub fn apply_queued_updates(&mut self) { + { + let mut _span = None; + let tasks = self.dirty_tasks_to_schedule.get_mut(); + if let Some(tasks) = tasks.as_mut() { + let tasks = take(tasks); + if !tasks.is_empty() { + _span.get_or_insert_with(|| { + tracing::trace_span!("task aggregation apply_queued_updates").entered() + }); + self.backend + .schedule_when_dirty_from_aggregation(tasks, self.turbo_tasks); + } + } + } + let tasks = self.tasks_to_notify.get_mut(); + if let Some(tasks) = tasks.as_mut() { + let tasks = take(tasks); + if !tasks.is_empty() { + self.turbo_tasks.schedule_notify_tasks_set(&tasks); + } + } + } + + pub fn aggregation_data(&self, id: TaskId) -> AggregationDataGuard> { + aggregation_data(self, &id) + } +} + +#[cfg(debug_assertions)] +impl<'a> Drop for TaskAggregationContext<'a> { + fn drop(&mut self) { + let tasks_to_schedule = self.dirty_tasks_to_schedule.get_mut(); + if let Some(tasks_to_schedule) = tasks_to_schedule.as_ref() { + if !tasks_to_schedule.is_empty() { + panic!("TaskAggregationContext dropped without scheduling all tasks"); + } + } + let tasks_to_notify = self.tasks_to_notify.get_mut(); + if let Some(tasks_to_notify) = tasks_to_notify.as_ref() { + if !tasks_to_notify.is_empty() { + panic!("TaskAggregationContext dropped without notifying all tasks"); + } + } + } +} + +impl<'a> AggregationContext for TaskAggregationContext<'a> { + type Guard<'l> = TaskGuard<'l> where Self: 'l; + type Data = Aggregated; + type DataChange = TaskChange; + type NodeRef = TaskId; + + fn node<'b>(&'b self, reference: &TaskId) -> Self::Guard<'b> { + let task = self.backend.task(*reference); + TaskGuard::new(*reference, task.state_mut()) + } + + fn atomic_in_progress_counter<'l>(&self, id: &'l TaskId) -> &'l AtomicU32 + where + Self: 'l, + { + &self + .backend + .task(*id) + .graph_modification_in_progress_counter + } + + fn apply_change( + &self, + info: &mut Aggregated, + change: &Self::DataChange, + ) -> Option { + let mut unfinished = 0; + if info.unfinished > 0 { + info.unfinished += change.unfinished; + if info.unfinished <= 0 { + info.unfinished_event.notify(usize::MAX); + unfinished = -1; + } + } else { + info.unfinished += change.unfinished; + if info.unfinished > 0 { + unfinished = 1; + } + } + #[cfg(feature = "track_unfinished")] + let mut unfinished_tasks_update = Vec::new(); + #[cfg(feature = "track_unfinished")] + for &(task, count) in change.unfinished_tasks_update.iter() { + match update_count_entry(info.unfinished_tasks.entry(task), count) { + (_, UpdateCountEntryChange::Removed) => unfinished_tasks_update.push((task, -1)), + (_, UpdateCountEntryChange::Inserted) => unfinished_tasks_update.push((task, 1)), + _ => {} + } + } + let mut dirty_tasks_update = Vec::new(); + let is_root = info.root_type.is_some(); + for &(task, count) in change.dirty_tasks_update.iter() { + match update_count_entry(info.dirty_tasks.entry(task), count) { + (_, UpdateCountEntryChange::Removed) => dirty_tasks_update.push((task, -1)), + (_, UpdateCountEntryChange::Inserted) => { + if is_root { + let mut tasks_to_schedule = self.dirty_tasks_to_schedule.lock(); + tasks_to_schedule.get_or_insert_default().insert(task); + } + dirty_tasks_update.push((task, 1)) + } + _ => {} + } + } + for &(trait_type_id, collectible, count) in change.collectibles.iter() { + let collectibles_info_entry = info.collectibles.entry(trait_type_id); + match collectibles_info_entry { + Entry::Occupied(mut e) => { + let collectibles_info = e.get_mut(); + let (value, _) = update_count_entry( + collectibles_info.collectibles.entry(collectible), + count, + ); + if !collectibles_info.dependent_tasks.is_empty() { + self.tasks_to_notify + .lock() + .get_or_insert_default() + .extend(take(&mut collectibles_info.dependent_tasks).into_iter()); + } + if value == 0 && collectibles_info.is_unset() { + e.remove(); + } + } + Entry::Vacant(e) => { + let mut collectibles_info = CollectiblesInfo::default(); + collectibles_info.collectibles.insert(collectible, count); + e.insert(collectibles_info); + } + } + } + #[cfg(feature = "track_unfinished")] + if info.unfinished > 0 && info.unfinished_tasks.is_empty() + || info.unfinished == 0 && !info.unfinished_tasks.is_empty() + { + panic!( + "inconsistent state: unfinished {}, unfinished_tasks {:?}, change {:?}", + info.unfinished, info.unfinished_tasks, change + ); + } + let new_change = TaskChange { + unfinished, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update: unfinished_tasks_update, + dirty_tasks_update, + collectibles: change.collectibles.clone(), + }; + if new_change.is_empty() { + None + } else { + Some(new_change) + } + } + + fn data_to_add_change(&self, data: &Aggregated) -> Option { + let mut change = TaskChange::default(); + if data.unfinished > 0 { + change.unfinished = 1; + } + #[cfg(feature = "track_unfinished")] + for (&task, &count) in data.unfinished_tasks.iter() { + if count > 0 { + change.unfinished_tasks_update.push((task, 1)); + } + } + for (&task, &count) in data.dirty_tasks.iter() { + if count > 0 { + change.dirty_tasks_update.push((task, 1)); + } + } + for (trait_type_id, collectibles_info) in data.collectibles.iter() { + for (collectible, count) in collectibles_info.collectibles.iter() { + change + .collectibles + .push((*trait_type_id, *collectible, *count)); + } + } + if change.is_empty() { + None + } else { + Some(change) + } + } + + fn data_to_remove_change(&self, data: &Aggregated) -> Option { + let mut change = TaskChange::default(); + if data.unfinished > 0 { + change.unfinished = -1; + } + #[cfg(feature = "track_unfinished")] + for (&task, &count) in data.unfinished_tasks.iter() { + change.unfinished_tasks_update.push((task, -count)); + } + for (&task, &count) in data.dirty_tasks.iter() { + if count > 0 { + change.dirty_tasks_update.push((task, -1)); + } + } + for (trait_type_id, collectibles_info) in data.collectibles.iter() { + for (collectible, count) in collectibles_info.collectibles.iter() { + change + .collectibles + .push((*trait_type_id, *collectible, -*count)); + } + } + if change.is_empty() { + None + } else { + Some(change) + } + } +} + +#[derive(Default)] +pub struct ActiveQuery { + active: bool, +} + +impl RootQuery for ActiveQuery { + type Data = Aggregated; + type Result = bool; + + fn query(&mut self, data: &Self::Data) -> ControlFlow<()> { + if data.root_type.is_some() { + self.active = true; + ControlFlow::Break(()) + } else { + ControlFlow::Continue(()) + } + } + + fn result(self) -> Self::Result { + self.active + } +} + +pub struct TaskGuard<'l> { + id: TaskId, + guard: TaskMetaStateWriteGuard<'l>, +} + +impl<'l> TaskGuard<'l> { + pub fn new(id: TaskId, mut guard: TaskMetaStateWriteGuard<'l>) -> Self { + guard.ensure_at_least_partial(); + Self { id, guard } + } + + pub fn from_full(id: TaskId, guard: FullTaskWriteGuard<'l>) -> Self { + Self { + id, + guard: TaskMetaStateWriteGuard::Full(guard), + } + } + + pub fn into_inner(self) -> TaskMetaStateWriteGuard<'l> { + self.guard + } +} + +impl<'l> Deref for TaskGuard<'l> { + type Target = AggregationNode< + ::NodeRef, + ::Data, + >; + + fn deref(&self) -> &Self::Target { + match self.guard { + TaskMetaStateWriteGuard::Full(ref guard) => &guard.aggregation_node, + TaskMetaStateWriteGuard::Partial(ref guard) => &guard.aggregation_node, + TaskMetaStateWriteGuard::Unloaded(_) => unreachable!(), + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } +} + +impl<'l> DerefMut for TaskGuard<'l> { + fn deref_mut(&mut self) -> &mut Self::Target { + match self.guard { + TaskMetaStateWriteGuard::Full(ref mut guard) => &mut guard.aggregation_node, + TaskMetaStateWriteGuard::Partial(ref mut guard) => &mut guard.aggregation_node, + TaskMetaStateWriteGuard::Unloaded(_) => unreachable!(), + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } +} + +impl<'l> AggregationNodeGuard for TaskGuard<'l> { + type Data = Aggregated; + type NodeRef = TaskId; + type DataChange = TaskChange; + type ChildrenIter<'a> = impl Iterator + 'a where Self: 'a; + + fn children(&self) -> Self::ChildrenIter<'_> { + match self.guard { + TaskMetaStateWriteGuard::Full(ref guard) => Either::Left(guard.state_type.children()), + TaskMetaStateWriteGuard::Partial(_) | TaskMetaStateWriteGuard::Unloaded(_) => { + Either::Right(std::iter::empty()) + } + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } + + fn get_add_change(&self) -> Option { + match self.guard { + TaskMetaStateWriteGuard::Full(ref guard) => { + let mut change = TaskChange::default(); + if !matches!( + guard.state_type, + TaskStateType::Done { .. } + | TaskStateType::InProgress (box InProgressState{ + count_as_finished: true, + .. + }) + ) { + change.unfinished = 1; + #[cfg(feature = "track_unfinished")] + change.unfinished_tasks_update.push((self.id, 1)); + } + if matches!(guard.state_type, TaskStateType::Dirty { .. }) { + change.dirty_tasks_update.push((self.id, 1)); + } + if let Some(collectibles) = guard.collectibles.as_ref() { + for (&(trait_type_id, collectible), count) in collectibles.iter() { + change + .collectibles + .push((trait_type_id, collectible, *count)); + } + } + if let TaskStateType::InProgress(box InProgressState { + outdated_collectibles, + .. + }) = &guard.state_type + { + if let Some(collectibles) = outdated_collectibles.as_ref() { + for (&(trait_type_id, collectible), count) in collectibles.iter() { + change + .collectibles + .push((trait_type_id, collectible, *count)); + } + } + } + if change.is_empty() { + None + } else { + Some(change) + } + } + TaskMetaStateWriteGuard::Partial(_) | TaskMetaStateWriteGuard::Unloaded(_) => { + Some(TaskChange { + unfinished: 1, + dirty_tasks_update: vec![(self.id, 1)], + collectibles: vec![], + }) + } + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } + + fn get_remove_change(&self) -> Option { + match self.guard { + TaskMetaStateWriteGuard::Full(ref guard) => { + let mut change = TaskChange::default(); + if !matches!( + guard.state_type, + TaskStateType::Done { .. } + | TaskStateType::InProgress (box InProgressState{ + count_as_finished: true, + .. + }) + ) { + change.unfinished = -1; + #[cfg(feature = "track_unfinished")] + change.unfinished_tasks_update.push((self.id, -1)); + } + if matches!(guard.state_type, TaskStateType::Dirty { .. }) { + change.dirty_tasks_update.push((self.id, -1)); + } + if let Some(collectibles) = guard.collectibles.as_ref() { + for (&(trait_type_id, collectible), count) in collectibles.iter() { + change + .collectibles + .push((trait_type_id, collectible, -count)); + } + } + if let TaskStateType::InProgress(box InProgressState { + outdated_collectibles, + .. + }) = &guard.state_type + { + if let Some(collectibles) = outdated_collectibles.as_ref() { + for (&(trait_type_id, collectible), count) in collectibles.iter() { + change + .collectibles + .push((trait_type_id, collectible, -*count)); + } + } + } + if change.is_empty() { + None + } else { + Some(change) + } + } + TaskMetaStateWriteGuard::Partial(_) | TaskMetaStateWriteGuard::Unloaded(_) => { + Some(TaskChange { + unfinished: -1, + dirty_tasks_update: vec![(self.id, -1)], + collectibles: vec![], + }) + } + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } + + fn get_initial_data(&self) -> Self::Data { + let mut data = Aggregated::default(); + if let Some(TaskChange { + unfinished, + #[cfg(feature = "track_unfinished")] + unfinished_tasks_update, + dirty_tasks_update, + collectibles, + }) = self.get_add_change() + { + data.unfinished = unfinished; + #[cfg(feature = "track_unfinished")] + { + data.unfinished_tasks = unfinished_tasks_update.into_iter().collect(); + } + for (t, n) in dirty_tasks_update.into_iter() { + data.dirty_tasks.insert(t, n); + } + for (trait_type_id, collectible, count) in collectibles.into_iter() { + let info = data.collectibles.entry(trait_type_id).or_default(); + update_count_entry(info.collectibles.entry(collectible), count); + } + } + data + } +} + +pub type TaskAggregationNode = AggregationNode; + +enum UpdateCountEntryChange { + Removed, + Inserted, + Updated, +} + +fn update_count_entry( + entry: Entry<'_, K, i32, H, I>, + update: i32, +) -> (i32, UpdateCountEntryChange) { + match entry { + Entry::Occupied(mut e) => { + let value = e.get_mut(); + if *value < 0 { + *value += update; + match (*value).cmp(&0) { + Ordering::Less => (*value, UpdateCountEntryChange::Updated), + Ordering::Equal => { + e.remove(); + (0, UpdateCountEntryChange::Updated) + } + Ordering::Greater => (*value, UpdateCountEntryChange::Inserted), + } + } else { + *value += update; + match (*value).cmp(&0) { + Ordering::Less => (*value, UpdateCountEntryChange::Removed), + Ordering::Equal => { + e.remove(); + (0, UpdateCountEntryChange::Removed) + } + Ordering::Greater => (*value, UpdateCountEntryChange::Updated), + } + } + } + Entry::Vacant(e) => match update.cmp(&0) { + Ordering::Less => { + e.insert(update); + (update, UpdateCountEntryChange::Updated) + } + Ordering::Equal => (0, UpdateCountEntryChange::Updated), + Ordering::Greater => { + e.insert(update); + (update, UpdateCountEntryChange::Inserted) + } + }, + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/task/meta_state.rs b/turbopack/crates/turbo-tasks-memory/src/task/meta_state.rs new file mode 100644 index 0000000000000..bf4843f87484b --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/task/meta_state.rs @@ -0,0 +1,266 @@ +use std::mem::replace; + +use parking_lot::{RwLockReadGuard, RwLockWriteGuard}; + +use super::{PartialTaskState, TaskState, UnloadedTaskState}; +use crate::{ + aggregation::AggregationNode, + map_guard::{ReadGuard, WriteGuard}, +}; + +pub(super) enum TaskMetaState { + Full(Box), + Partial(Box), + Unloaded(UnloadedTaskState), +} + +impl TaskMetaState { + pub(super) fn into_full(self) -> Option { + match self { + Self::Full(state) => Some(*state), + _ => None, + } + } + + pub(super) fn into_partial(self) -> Option { + match self { + Self::Partial(state) => Some(*state), + _ => None, + } + } + + pub(super) fn into_unloaded(self) -> Option { + match self { + Self::Unloaded(state) => Some(state), + _ => None, + } + } + + pub(super) fn as_full(&self) -> Option<&TaskState> { + match self { + Self::Full(state) => Some(state), + _ => None, + } + } + + pub(super) fn as_partial(&self) -> Option<&PartialTaskState> { + match self { + Self::Partial(state) => Some(state), + _ => None, + } + } + + pub(super) fn as_unloaded(&self) -> Option<&UnloadedTaskState> { + match self { + Self::Unloaded(state) => Some(state), + _ => None, + } + } + + pub(super) fn as_full_mut(&mut self) -> Option<&mut TaskState> { + match self { + Self::Full(state) => Some(state), + _ => None, + } + } + + pub(super) fn as_partial_mut(&mut self) -> Option<&mut PartialTaskState> { + match self { + Self::Partial(state) => Some(state), + _ => None, + } + } + + pub(super) fn as_unloaded_mut(&mut self) -> Option<&mut UnloadedTaskState> { + match self { + Self::Unloaded(state) => Some(state), + _ => None, + } + } +} + +pub(super) type TaskMetaStateAsFull = for<'a> fn(&'a TaskMetaState) -> Option<&'a TaskState>; +pub(super) type TaskMetaStateAsPartial = for<'a> fn(&'a TaskMetaState) -> Option<&PartialTaskState>; +pub(super) type TaskMetaStateAsUnloaded = + for<'a> fn(&'a TaskMetaState) -> Option<&'a UnloadedTaskState>; +pub(super) type TaskMetaStateAsFullMut = + for<'a> fn(&'a mut TaskMetaState) -> Option<&'a mut TaskState>; +pub(super) type TaskMetaStateAsPartialMut = + for<'a> fn(&'a mut TaskMetaState) -> Option<&'a mut PartialTaskState>; +pub(super) type TaskMetaStateAsUnloadedMut = + for<'a> fn(&'a mut TaskMetaState) -> Option<&'a mut UnloadedTaskState>; + +#[allow(dead_code, reason = "test")] +pub(super) enum TaskMetaStateReadGuard<'a> { + Full(ReadGuard<'a, TaskMetaState, TaskState, TaskMetaStateAsFull>), + Partial(ReadGuard<'a, TaskMetaState, PartialTaskState, TaskMetaStateAsPartial>), + Unloaded, +} + +pub(super) type FullTaskWriteGuard<'a> = + WriteGuard<'a, TaskMetaState, TaskState, TaskMetaStateAsFull, TaskMetaStateAsFullMut>; + +pub(super) enum TaskMetaStateWriteGuard<'a> { + Full(FullTaskWriteGuard<'a>), + Partial( + WriteGuard< + 'a, + TaskMetaState, + PartialTaskState, + TaskMetaStateAsPartial, + TaskMetaStateAsPartialMut, + >, + ), + Unloaded( + WriteGuard< + 'a, + TaskMetaState, + UnloadedTaskState, + TaskMetaStateAsUnloaded, + TaskMetaStateAsUnloadedMut, + >, + ), + TemporaryFiller, +} + +impl<'a> From> for TaskMetaStateReadGuard<'a> { + fn from(guard: RwLockReadGuard<'a, TaskMetaState>) -> Self { + match &*guard { + TaskMetaState::Full(_) => { + TaskMetaStateReadGuard::Full(ReadGuard::new(guard, TaskMetaState::as_full)) + } + TaskMetaState::Partial(_) => { + TaskMetaStateReadGuard::Partial(ReadGuard::new(guard, TaskMetaState::as_partial)) + } + TaskMetaState::Unloaded(_) => TaskMetaStateReadGuard::Unloaded, + } + } +} + +impl<'a> From> for TaskMetaStateWriteGuard<'a> { + fn from(guard: RwLockWriteGuard<'a, TaskMetaState>) -> Self { + match &*guard { + TaskMetaState::Full(_) => TaskMetaStateWriteGuard::Full(WriteGuard::new( + guard, + TaskMetaState::as_full, + TaskMetaState::as_full_mut, + )), + TaskMetaState::Partial(_) => TaskMetaStateWriteGuard::Partial(WriteGuard::new( + guard, + TaskMetaState::as_partial, + TaskMetaState::as_partial_mut, + )), + TaskMetaState::Unloaded(_) => TaskMetaStateWriteGuard::Unloaded(WriteGuard::new( + guard, + TaskMetaState::as_unloaded, + TaskMetaState::as_unloaded_mut, + )), + } + } +} + +impl<'a> TaskMetaStateReadGuard<'a> { + pub(super) fn as_full(&mut self) -> Option<&TaskState> { + match self { + TaskMetaStateReadGuard::Full(state) => Some(&**state), + _ => None, + } + } +} + +impl<'a> TaskMetaStateWriteGuard<'a> { + pub(super) fn full_from( + mut guard: RwLockWriteGuard<'a, TaskMetaState>, + ) -> FullTaskWriteGuard<'a> { + match &*guard { + TaskMetaState::Full(_) => {} + TaskMetaState::Partial(_) => { + let partial = replace( + &mut *guard, + // placeholder + TaskMetaState::Unloaded(UnloadedTaskState {}), + ) + .into_partial() + .unwrap(); + *guard = TaskMetaState::Full(Box::new(partial.into_full())); + } + TaskMetaState::Unloaded(_) => { + let unloaded = replace( + &mut *guard, + // placeholder + TaskMetaState::Unloaded(UnloadedTaskState {}), + ) + .into_unloaded() + .unwrap(); + *guard = TaskMetaState::Full(Box::new(unloaded.into_full())); + } + } + WriteGuard::new(guard, TaskMetaState::as_full, TaskMetaState::as_full_mut) + } + + #[allow(dead_code, reason = "We need this in future")] + pub(super) fn partial_from(mut guard: RwLockWriteGuard<'a, TaskMetaState>) -> Self { + match &*guard { + TaskMetaState::Full(_) => TaskMetaStateWriteGuard::Full(WriteGuard::new( + guard, + TaskMetaState::as_full, + TaskMetaState::as_full_mut, + )), + TaskMetaState::Partial(_) => TaskMetaStateWriteGuard::Partial(WriteGuard::new( + guard, + TaskMetaState::as_partial, + TaskMetaState::as_partial_mut, + )), + TaskMetaState::Unloaded(_) => { + let unloaded = replace( + &mut *guard, + // placeholder + TaskMetaState::Unloaded(UnloadedTaskState {}), + ) + .into_unloaded() + .unwrap(); + *guard = TaskMetaState::Partial(Box::new(unloaded.into_partial())); + TaskMetaStateWriteGuard::Partial(WriteGuard::new( + guard, + TaskMetaState::as_partial, + TaskMetaState::as_partial_mut, + )) + } + } + } + + pub(super) fn as_full_mut(&mut self) -> Option<&mut TaskState> { + match self { + TaskMetaStateWriteGuard::Full(state) => Some(&mut **state), + _ => None, + } + } + + pub(super) fn into_inner(self) -> RwLockWriteGuard<'a, TaskMetaState> { + match self { + TaskMetaStateWriteGuard::Full(state) => state.into_inner(), + TaskMetaStateWriteGuard::Partial(state) => state.into_inner(), + TaskMetaStateWriteGuard::Unloaded(state) => state.into_inner(), + TaskMetaStateWriteGuard::TemporaryFiller => unreachable!(), + } + } + + pub(super) fn ensure_at_least_partial(&mut self) { + if matches!(self, TaskMetaStateWriteGuard::Unloaded(..)) { + let TaskMetaStateWriteGuard::Unloaded(state) = + replace(self, TaskMetaStateWriteGuard::TemporaryFiller) + else { + unreachable!(); + }; + let mut state = state.into_inner(); + *state = TaskMetaState::Partial(Box::new(PartialTaskState { + aggregation_node: AggregationNode::new(), + })); + *self = TaskMetaStateWriteGuard::Partial(WriteGuard::new( + state, + TaskMetaState::as_partial, + TaskMetaState::as_partial_mut, + )); + } + } +} diff --git a/turbopack/crates/turbo-tasks-memory/src/task_statistics.rs b/turbopack/crates/turbo-tasks-memory/src/task_statistics.rs new file mode 100644 index 0000000000000..6df3abc0ffc3a --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/src/task_statistics.rs @@ -0,0 +1,86 @@ +use std::{ + hash::BuildHasherDefault, + sync::{Arc, OnceLock}, +}; + +use dashmap::DashMap; +use rustc_hash::FxHasher; +use serde::{ser::SerializeMap, Serialize, Serializer}; +use turbo_tasks::{registry, FunctionId}; + +/// An API for optionally enabling, updating, and reading aggregated statistics. +#[derive(Default)] +pub struct TaskStatisticsApi { + inner: OnceLock>, +} + +impl TaskStatisticsApi { + pub fn enable(&self) -> &Arc { + self.inner.get_or_init(|| { + Arc::new(TaskStatistics { + inner: DashMap::with_hasher(Default::default()), + }) + }) + } + + pub fn is_enabled(&self) -> bool { + self.inner.get().is_some() + } + + // Calls `func` if statistics have been enabled (via + // [`TaskStatisticsApi::enable`]). + pub fn map(&self, func: impl FnOnce(&Arc) -> T) -> Option { + self.get().map(func) + } + + // Calls `func` if statistics have been enabled (via + // [`TaskStatisticsApi::enable`]). + pub fn get(&self) -> Option<&Arc> { + self.inner.get() + } +} + +/// A type representing the enabled state of [`TaskStatisticsApi`]. Implements +/// [`serde::Serialize`]. +pub struct TaskStatistics { + inner: DashMap>, +} + +impl TaskStatistics { + pub(crate) fn increment_cache_hit(&self, function_id: FunctionId) { + self.with_task_type_statistics(function_id, |stats| stats.cache_hit += 1) + } + + pub(crate) fn increment_cache_miss(&self, function_id: FunctionId) { + self.with_task_type_statistics(function_id, |stats| stats.cache_miss += 1) + } + + fn with_task_type_statistics( + &self, + task_function_id: FunctionId, + func: impl Fn(&mut TaskFunctionStatistics), + ) { + func(self.inner.entry(task_function_id).or_default().value_mut()) + } +} + +/// Statistics for an individual function. +#[derive(Default, Serialize)] +struct TaskFunctionStatistics { + cache_hit: u32, + cache_miss: u32, +} + +impl Serialize for TaskStatistics { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut map = serializer.serialize_map(Some(self.inner.len()))?; + for entry in &self.inner { + let key = registry::get_function_global_name(*entry.key()); + map.serialize_entry(key, entry.value())?; + } + map.end() + } +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/all_in_one.rs b/turbopack/crates/turbo-tasks-memory/tests/all_in_one.rs new file mode 100644 index 0000000000000..b58ea58964bff --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/all_in_one.rs @@ -0,0 +1,257 @@ +#![feature(arbitrary_self_types)] + +use anyhow::{anyhow, bail, Result}; +use indexmap::{IndexMap, IndexSet}; +use turbo_tasks::{debug::ValueDebug, RcStr, Value, ValueToString, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn all_in_one() { + run(®ISTRATION, async { + let a: Vc = Vc::cell(4242); + assert_eq!(*a.await?, 4242); + + let a: Vc = Vc::cell(4242); + assert_eq!(*a.await?, 4242); + + let b = MyEnumValue::cell(MyEnumValue::More(MyEnumValue::Yeah(42).into())); + assert_eq!(*b.to_string().await?, "42"); + + let c = MyStructValue { + value: 42, + next: Some(MyStructValue::new(a)), + } + .into(); + + let result = my_function(a, b.get_last(), c, Value::new(MyEnumValue::Yeah(42))); + assert_eq!(*result.my_trait_function().await?, "42"); + assert_eq!(*result.my_trait_function2().await?, "42"); + assert_eq!(*result.my_trait_function3().await?, "4242"); + assert_eq!(*result.to_string().await?, "42"); + + // Testing Vc in traits + + let a: Vc = Vc::cell(32); + let b: Vc = Vc::cell(10); + let c: Vc = a.add(Vc::upcast(b)); + + assert_eq!(*c.await?, 42); + + let a_erased: Vc> = Vc::upcast(a); + let b_erased: Vc> = Vc::upcast(b); + let c_erased: Vc> = a_erased.add(b_erased); + + assert_eq!( + *Vc::try_resolve_downcast_type::(c_erased) + .await? + .unwrap() + .await?, + 42 + ); + + let b_erased_other: Vc> = Vc::upcast(Vc::::cell(10)); + let c_erased_invalid: Vc> = a_erased.add(b_erased_other); + assert!(c_erased_invalid.resolve().await.is_err()); + + // Testing generic types. + + let vc_42 = Vc::cell(42); + + let option: Vc>> = Vc::cell(Some(vc_42)); + assert_eq!(*option.is_some().await?, true); + assert_eq!(*option.is_none().await?, false); + assert_eq!(&*option.await?, &Some(vc_42)); + assert_eq!(option.dbg().await?.to_string(), "Some(\n 42,\n)"); + + let option: Vc>> = Default::default(); + assert_eq!(*option.is_some().await?, false); + assert_eq!(*option.is_none().await?, true); + assert_eq!(&*option.await?, &None); + assert_eq!(option.dbg().await?.to_string(), "None"); + + let vec: Vc>> = Vc::cell(vec![vc_42]); + assert_eq!(*vec.len().await?, 1); + assert_eq!(*vec.is_empty().await?, false); + assert_eq!(&*vec.await?, &[vc_42]); + assert_eq!(vec.dbg().await?.to_string(), "[\n 42,\n]"); + + let vec: Vc>> = Default::default(); + assert_eq!(*vec.len().await?, 0); + assert_eq!(*vec.is_empty().await?, true); + assert_eq!(vec.dbg().await?.to_string(), "[]"); + + let vec: Vc>>>> = Default::default(); + assert_eq!(*vec.len().await?, 0); + assert_eq!(vec.dbg().await?.to_string(), "[]"); + + let set: Vc>> = Vc::cell(IndexSet::from([vc_42])); + assert_eq!(*set.len().await?, 1); + assert_eq!(*set.is_empty().await?, false); + assert_eq!(&*set.await?, &IndexSet::from([vc_42])); + assert_eq!(set.dbg().await?.to_string(), "{\n 42,\n}"); + + let set: Vc>> = Default::default(); + assert_eq!(*set.len().await?, 0); + assert_eq!(*set.is_empty().await?, true); + assert_eq!(&*set.await?, &IndexSet::>::default()); + assert_eq!(set.dbg().await?.to_string(), "{}"); + + let map: Vc> = Vc::cell(IndexMap::from([(vc_42, vc_42)])); + assert_eq!(*map.len().await?, 1); + assert_eq!(*map.is_empty().await?, false); + assert_eq!(&*map.await?, &IndexMap::from([(vc_42, vc_42)])); + assert_eq!(map.dbg().await?.to_string(), "{\n 42: 42,\n}"); + + let map: Vc, Vc>> = Default::default(); + assert_eq!(*map.len().await?, 0); + assert_eq!(*map.is_empty().await?, true); + assert_eq!(&*map.await?, &IndexMap::, Vc>::default()); + assert_eq!(map.dbg().await?.to_string(), "{}"); + + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[turbo_tasks::value(transparent, serialization = "auto_for_input")] +#[derive(Debug, Clone, Hash)] +struct MyTransparentValue(u32); + +#[turbo_tasks::value(shared, serialization = "auto_for_input")] +#[derive(Debug, Clone, Hash)] +enum MyEnumValue { + Yeah(u32), + Nah, + More(Vc), +} + +#[turbo_tasks::value_impl] +impl MyEnumValue { + #[turbo_tasks::function] + pub async fn get_last(self: Vc) -> Result> { + let mut current = self; + while let MyEnumValue::More(more) = &*current.await? { + current = *more; + } + Ok(current) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for MyEnumValue { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + match self { + MyEnumValue::Yeah(value) => Vc::cell(value.to_string().into()), + MyEnumValue::Nah => Vc::cell("nah".into()), + MyEnumValue::More(more) => more.to_string(), + } + } +} + +#[turbo_tasks::value(shared)] +struct MyStructValue { + value: u32, + next: Option>, +} + +#[turbo_tasks::value_impl] +impl MyStructValue { + #[turbo_tasks::function] + pub async fn new(value: Vc) -> Result> { + Ok(Self::cell(MyStructValue { + value: *value.await?, + next: None, + })) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for MyStructValue { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(self.value.to_string().into()) + } +} + +#[turbo_tasks::value_impl] +impl MyTrait for MyStructValue { + #[turbo_tasks::function] + fn my_trait_function2(self: Vc) -> Vc { + self.to_string() + } + #[turbo_tasks::function] + async fn my_trait_function3(&self) -> Result> { + if let Some(next) = self.next { + return Ok(next.my_trait_function3()); + } + Ok(Vc::cell(self.value.to_string().into())) + } +} + +#[turbo_tasks::value_trait] +trait MyTrait: ValueToString { + // TODO #[turbo_tasks::function] + async fn my_trait_function(self: Vc) -> Result> { + if *self.to_string().await? != "42" { + return Err(anyhow!( + "my_trait_function must only be called with 42 as value" + )); + } + // Calling a function twice + Ok(self.to_string()) + } + + fn my_trait_function2(self: Vc) -> Vc; + fn my_trait_function3(self: Vc) -> Vc; +} + +#[turbo_tasks::function] +async fn my_function( + a: Vc, + b: Vc, + c: Vc, + d: Value, +) -> Result> { + assert_eq!(*a.await?, 4242); + assert_eq!(*b.await?, MyEnumValue::Yeah(42)); + assert_eq!(c.await?.value, 42); + assert_eq!(d.into_value(), MyEnumValue::Yeah(42)); + Ok(c) +} + +#[turbo_tasks::value_trait] +trait Add { + fn add(self: Vc, other: Vc>) -> Vc; +} + +#[turbo_tasks::value(transparent)] +struct Number(u32); + +#[turbo_tasks::value_impl] +impl Add for Number { + #[turbo_tasks::function] + async fn add(self: Vc, other: Vc>) -> Result> { + let Some(other) = Vc::try_resolve_downcast_type::(other).await? else { + bail!("Expected Number"); + }; + Ok(Vc::cell(*self.await? + *other.await?)) + } +} + +#[turbo_tasks::value(transparent)] +struct NumberB(u32); + +#[turbo_tasks::value_impl] +impl Add for NumberB { + #[turbo_tasks::function] + async fn add(self: Vc, other: Vc>) -> Result> { + let Some(other) = Vc::try_resolve_downcast_type::(other).await? else { + bail!("Expected NumberB"); + }; + Ok(Vc::cell(*self.await? + *other.await?)) + } +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/call_types.rs b/turbopack/crates/turbo-tasks-memory/tests/call_types.rs new file mode 100644 index 0000000000000..6870d396e64f1 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/call_types.rs @@ -0,0 +1,193 @@ +#![feature(arbitrary_self_types)] + +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn functions() { + run(®ISTRATION, async { + assert_eq!(*fn_plain().await?, 42); + assert_eq!(*fn_arg(43).await?, 43); + assert_eq!(*fn_vc_arg(Vc::cell(44)).await?, 44); + assert_eq!(*async_fn_plain().await?, 42); + assert_eq!(*async_fn_arg(43).await?, 43); + assert_eq!(*async_fn_vc_arg(Vc::cell(44)).await?, 44); + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[turbo_tasks::function] +fn fn_plain() -> Vc { + Vc::cell(42) +} + +#[turbo_tasks::function] +fn fn_arg(n: u32) -> Vc { + Vc::cell(n) +} + +#[turbo_tasks::function] +fn fn_vc_arg(n: Vc) -> Vc { + n +} + +#[turbo_tasks::function] +async fn async_fn_plain() -> Result> { + Ok(Vc::cell(42)) +} + +#[turbo_tasks::function] +async fn async_fn_arg(n: u32) -> Result> { + Ok(Vc::cell(n)) +} + +#[turbo_tasks::function] +async fn async_fn_vc_arg(n: Vc) -> Result> { + Ok(Vc::cell(*n.await?)) +} + +#[tokio::test] +async fn methods() { + run(®ISTRATION, async { + assert_eq!(*Value::static_method().await?, 42); + assert_eq!(*Value::async_static_method().await?, 42); + + let value = Value(43).cell(); + assert_eq!(*value.method().await?, 43); + assert_eq!(*value.async_method().await?, 43); + assert_eq!(*value.vc_method().await?, 42); + assert_eq!(*value.async_vc_method().await?, 43); + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[turbo_tasks::value] +struct Value(u32); + +#[turbo_tasks::value_impl] +impl Value { + #[turbo_tasks::function] + fn static_method() -> Vc { + Vc::cell(42) + } + + #[turbo_tasks::function] + async fn async_static_method() -> Result> { + Ok(Vc::cell(42)) + } + + #[turbo_tasks::function] + fn method(&self) -> Vc { + Vc::cell(self.0) + } + + #[turbo_tasks::function] + async fn async_method(&self) -> Result> { + Ok(Vc::cell(self.0)) + } + + #[turbo_tasks::function] + fn vc_method(self: Vc) -> Vc { + Vc::cell(42) + } + + #[turbo_tasks::function] + async fn async_vc_method(self: Vc) -> Result> { + Ok(Vc::cell(self.await?.0)) + } +} + +#[tokio::test] +async fn trait_methods() { + run(®ISTRATION, async { + assert_eq!(*Value::static_trait_method().await?, 42); + assert_eq!(*Value::async_static_trait_method().await?, 42); + + let value = Value(43).cell(); + assert_eq!(*value.trait_method().await?, 43); + assert_eq!(*value.async_trait_method().await?, 43); + assert_eq!(*value.default_trait_method().await?, 42); + assert_eq!(*value.default_async_trait_method().await?, 42); + + let trait_value: Vc> = Vc::upcast(value); + assert_eq!(*trait_value.trait_method().await?, 43); + assert_eq!(*trait_value.async_trait_method().await?, 43); + assert_eq!(*trait_value.default_trait_method().await?, 42); + assert_eq!(*trait_value.default_async_trait_method().await?, 42); + + let value = wrap_value(value); + assert_eq!(*value.trait_method().await?, 43); + assert_eq!(*value.async_trait_method().await?, 43); + assert_eq!(*value.default_trait_method().await?, 42); + assert_eq!(*value.default_async_trait_method().await?, 42); + + let trait_value = wrap_trait_value(trait_value); + assert_eq!(*trait_value.trait_method().await?, 43); + assert_eq!(*trait_value.async_trait_method().await?, 43); + assert_eq!(*trait_value.default_trait_method().await?, 42); + assert_eq!(*trait_value.default_async_trait_method().await?, 42); + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[turbo_tasks::function] +fn wrap_value(v: Vc) -> Vc { + v +} + +#[turbo_tasks::function] +fn wrap_trait_value(v: Vc>) -> Vc> { + v +} + +#[turbo_tasks::value_trait] +trait ValueTrait { + fn static_trait_method() -> Vc; + async fn async_static_trait_method() -> Result>; + fn default_static_trait_method() -> Vc { + Vc::cell(42) + } + async fn default_async_static_trait_method() -> Result> { + Ok(Vc::cell(42)) + } + fn trait_method(&self) -> Vc; + fn async_trait_method(&self) -> Result>; + fn default_trait_method(self: Vc) -> Vc { + Vc::cell(42) + } + async fn default_async_trait_method(self: Vc) -> Result> { + Ok(Vc::cell(42)) + } +} + +#[turbo_tasks::value_impl] +impl ValueTrait for Value { + #[turbo_tasks::function] + fn static_trait_method() -> Vc { + Vc::cell(42) + } + + #[turbo_tasks::function] + async fn async_static_trait_method() -> Result> { + Ok(Vc::cell(42)) + } + + #[turbo_tasks::function] + fn trait_method(&self) -> Vc { + Vc::cell(self.0) + } + + #[turbo_tasks::function] + async fn async_trait_method(&self) -> Result> { + Ok(Vc::cell(self.0)) + } +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/collectibles.rs b/turbopack/crates/turbo-tasks-memory/tests/collectibles.rs new file mode 100644 index 0000000000000..2bf0b392117ab --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/collectibles.rs @@ -0,0 +1,217 @@ +#![feature(arbitrary_self_types)] + +use std::{collections::HashSet, time::Duration}; + +use anyhow::Result; +use auto_hash_map::AutoSet; +use tokio::time::sleep; +use turbo_tasks::{emit, CollectiblesSource, RcStr, ValueToString, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn transitive_emitting() { + run(®ISTRATION, async { + let result = my_transitive_emitting_function("".into(), "".into()); + result.strongly_consistent().await?; + let list = result.peek_collectibles::>(); + assert_eq!(list.len(), 2); + let mut expected = ["123", "42"].into_iter().collect::>(); + for collectible in list { + assert!(expected.remove(collectible.to_string().await?.as_str())) + } + assert_eq!(result.await?.0, 0); + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[tokio::test] +async fn transitive_emitting_indirect() { + run(®ISTRATION, async { + let result = my_transitive_emitting_function("".into(), "".into()); + let collectibles = my_transitive_emitting_function_collectibles("".into(), "".into()); + let list = collectibles.strongly_consistent().await?; + assert_eq!(list.len(), 2); + let mut expected = ["123", "42"].into_iter().collect::>(); + for collectible in list.iter() { + assert!(expected.remove(collectible.to_string().await?.as_str())) + } + assert_eq!(result.await?.0, 0); + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[tokio::test] +async fn multi_emitting() { + run(®ISTRATION, async { + let result = my_multi_emitting_function(); + result.strongly_consistent().await?; + let list = result.peek_collectibles::>(); + assert_eq!(list.len(), 2); + let mut expected = ["123", "42"].into_iter().collect::>(); + for collectible in list { + assert!(expected.remove(collectible.to_string().await?.as_str())) + } + assert_eq!(result.await?.0, 0); + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[tokio::test] +async fn taking_collectibles() { + run(®ISTRATION, async { + let result = my_collecting_function(); + let list = result.take_collectibles::>(); + // my_collecting_function already processed the collectibles so the list should + // be empty + assert!(list.is_empty()); + assert_eq!(result.await?.0, 0); + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[tokio::test] +async fn taking_collectibles_extra_layer() { + run(®ISTRATION, async { + let result = my_collecting_function_indirect(); + result.strongly_consistent().await?; + let list = result.take_collectibles::>(); + // my_collecting_function already processed the collectibles so the list should + // be empty + assert!(list.is_empty()); + assert_eq!(result.await?.0, 0); + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[tokio::test] +async fn taking_collectibles_parallel() { + run(®ISTRATION, async { + let result = my_transitive_emitting_function("".into(), "a".into()); + result.strongly_consistent().await?; + let list = result.take_collectibles::>(); + assert_eq!(list.len(), 2); + assert_eq!(result.await?.0, 0); + + let result = my_transitive_emitting_function("".into(), "b".into()); + result.strongly_consistent().await?; + let list = result.take_collectibles::>(); + assert_eq!(list.len(), 2); + assert_eq!(result.await?.0, 0); + + let result = + my_transitive_emitting_function_with_child_scope("".into(), "b".into(), "1".into()); + result.strongly_consistent().await?; + let list = result.take_collectibles::>(); + assert_eq!(list.len(), 2); + assert_eq!(result.await?.0, 0); + + let result = + my_transitive_emitting_function_with_child_scope("".into(), "b".into(), "2".into()); + result.strongly_consistent().await?; + let list = result.take_collectibles::>(); + assert_eq!(list.len(), 2); + assert_eq!(result.await?.0, 0); + + let result = + my_transitive_emitting_function_with_child_scope("".into(), "c".into(), "3".into()); + result.strongly_consistent().await?; + let list = result.take_collectibles::>(); + assert_eq!(list.len(), 2); + assert_eq!(result.await?.0, 0); + + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[turbo_tasks::value(transparent)] +struct Collectibles(AutoSet>>); + +#[turbo_tasks::function] +async fn my_collecting_function() -> Result> { + let result = my_transitive_emitting_function("".into(), "".into()); + result.take_collectibles::>(); + Ok(result) +} + +#[turbo_tasks::function] +async fn my_collecting_function_indirect() -> Result> { + let result = my_collecting_function(); + result.strongly_consistent().await?; + let list = result.peek_collectibles::>(); + // my_collecting_function already processed the collectibles so the list should + // be empty + assert!(list.is_empty()); + Ok(result) +} + +#[turbo_tasks::function] +async fn my_multi_emitting_function() -> Result> { + my_transitive_emitting_function("".into(), "a".into()).await?; + my_transitive_emitting_function("".into(), "b".into()).await?; + my_emitting_function("".into()).await?; + Ok(Thing::cell(Thing(0))) +} + +#[turbo_tasks::function] +async fn my_transitive_emitting_function(key: RcStr, _key2: RcStr) -> Result> { + my_emitting_function(key).await?; + Ok(Thing::cell(Thing(0))) +} + +#[turbo_tasks::function] +async fn my_transitive_emitting_function_collectibles(key: RcStr, key2: RcStr) -> Vc { + let result = my_transitive_emitting_function(key, key2); + Vc::cell(result.peek_collectibles::>()) +} + +#[turbo_tasks::function] +async fn my_transitive_emitting_function_with_child_scope( + key: RcStr, + key2: RcStr, + _key3: RcStr, +) -> Result> { + let thing = my_transitive_emitting_function(key, key2); + thing.strongly_consistent().await?; + let list = thing.peek_collectibles::>(); + assert_eq!(list.len(), 2); + Ok(thing) +} + +#[turbo_tasks::function] +async fn my_emitting_function(_key: RcStr) -> Result<()> { + sleep(Duration::from_millis(100)).await; + emit(Vc::upcast::>(Thing::new(123))); + emit(Vc::upcast::>(Thing::new(42))); + Ok(()) +} + +#[turbo_tasks::value(shared)] +struct Thing(u32); + +impl Thing { + fn new(v: u32) -> Vc { + Self::cell(Thing(v)) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for Thing { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(self.0.to_string().into()) + } +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/debug.rs b/turbopack/crates/turbo-tasks-memory/tests/debug.rs new file mode 100644 index 0000000000000..579b84025d1a8 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/debug.rs @@ -0,0 +1,180 @@ +#![feature(arbitrary_self_types)] + +use std::sync::Mutex; + +use turbo_tasks::{debug::ValueDebug, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn primitive_debug() { + run(®ISTRATION, async { + let a: Vc = Vc::cell(42); + assert_eq!(format!("{:?}", a.dbg().await.unwrap()), "42"); + }) + .await +} + +#[tokio::test] +async fn transparent_debug() { + run(®ISTRATION, async { + let a: Vc = Transparent(42).cell(); + assert_eq!(format!("{:?}", a.dbg().await.unwrap()), "42"); + }) + .await +} + +#[tokio::test] +async fn enum_none_debug() { + run(®ISTRATION, async { + let a: Vc = Enum::None.cell(); + assert_eq!(format!("{:?}", a.dbg().await.unwrap()), "Enum::None"); + }) + .await +} + +#[tokio::test] +async fn enum_transparent_debug() { + run(®ISTRATION, async { + let a: Vc = Enum::Transparent(Transparent(42).cell()).cell(); + assert_eq!( + format!("{:?}", a.dbg().await.unwrap()), + r#"Enum::Transparent( + 42, +)"# + ); + }) + .await +} + +#[tokio::test] +async fn enum_inner_vc_debug() { + run(®ISTRATION, async { + let a: Vc = Enum::Enum(Enum::None.cell()).cell(); + assert_eq!( + format!("{:?}", a.dbg().await.unwrap()), + r#"Enum::Enum( + Enum::None, +)"# + ); + }) + .await +} + +#[tokio::test] +async fn struct_unit_debug() { + run(®ISTRATION, async { + let a: Vc = StructUnit.cell(); + assert_eq!(format!("{:?}", a.dbg().await.unwrap()), "StructUnit"); + }) + .await +} + +#[tokio::test] +async fn struct_transparent_debug() { + run(®ISTRATION, async { + let a: Vc = StructWithTransparent { + transparent: Transparent(42).cell(), + } + .cell(); + assert_eq!( + format!("{:?}", a.dbg().await.unwrap()), + r#"StructWithTransparent { + transparent: 42, +}"# + ); + }) + .await +} + +#[tokio::test] +async fn struct_vec_debug() { + run(®ISTRATION, async { + let a: Vc = StructWithVec { vec: vec![] }.cell(); + assert_eq!( + format!("{:?}", a.dbg().await.unwrap()), + r#"StructWithVec { + vec: [], +}"# + ); + + let b: Vc = StructWithVec { + vec: vec![Transparent(42).cell()], + } + .cell(); + assert_eq!( + format!("{:?}", b.dbg().await.unwrap()), + r#"StructWithVec { + vec: [ + 42, + ], +}"# + ); + }) + .await +} + +#[tokio::test] +async fn struct_ignore_debug() { + run(®ISTRATION, async { + let a: Vc = StructWithIgnore { + dont_ignore: 42, + ignore: Mutex::new(()), + } + .cell(); + assert_eq!( + format!("{:?}", a.dbg().await.unwrap()), + r#"StructWithIgnore { + dont_ignore: 42, +}"# + ); + }) + .await +} + +#[turbo_tasks::value(transparent, shared)] +struct Transparent(u32); + +// Allow Enum::Enum +#[allow(clippy::enum_variant_names)] +#[turbo_tasks::value(shared)] +enum Enum { + None, + Transparent(Vc), + Enum(Vc), +} + +#[turbo_tasks::value(shared)] +struct StructUnit; + +#[turbo_tasks::value(shared)] +struct StructWithTransparent { + transparent: Vc, +} + +#[turbo_tasks::value(shared)] +struct StructWithOption { + option: Option>, +} + +#[turbo_tasks::value(shared)] +struct StructWithVec { + vec: Vec>, +} + +#[turbo_tasks::value(shared, eq = "manual")] +struct StructWithIgnore { + dont_ignore: u32, + // We're using a `Mutex` instead of a `T: Debug` type to ensure we support `T: !Debug`. + #[turbo_tasks(debug_ignore, trace_ignore)] + ignore: Mutex<()>, +} + +impl PartialEq for StructWithIgnore { + fn eq(&self, other: &Self) -> bool { + self.dont_ignore == other.dont_ignore + } +} + +impl Eq for StructWithIgnore {} diff --git a/turbopack/crates/turbo-tasks-memory/tests/dirty_in_progress.rs b/turbopack/crates/turbo-tasks-memory/tests/dirty_in_progress.rs new file mode 100644 index 0000000000000..6f67cdc0b45b5 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/dirty_in_progress.rs @@ -0,0 +1,102 @@ +#![feature(arbitrary_self_types)] + +use std::time::Duration; + +use anyhow::{bail, Result}; +use turbo_tasks::{emit, CollectiblesSource, RcStr, State, ValueToString, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn dirty_in_progress() { + run(®ISTRATION, async { + let cases = [ + (1, 3, 2, 2, ""), + (11, 13, 12, 42, "12"), + (1, 13, 11, 42, "11"), + (1, 3, 11, 42, "11"), + (11, 3, 2, 2, ""), + (11, 13, 2, 2, ""), + ]; + for (a, b, c, value, collectible) in cases { + println!("{} -> {} -> {} = {} {}", a, b, c, value, collectible); + let input = ChangingInput { + state: State::new(a), + } + .cell(); + let input_val = input.await.unwrap(); + let output = compute(input); + output.await.unwrap(); + println!("update to {}", b); + input_val.state.set(b); + tokio::time::sleep(Duration::from_millis(100)).await; + println!("update to {}", c); + input_val.state.set(c); + let read = output.strongly_consistent().await.unwrap(); + assert_eq!(read.value, value); + assert_eq!(read.collectible, collectible); + } + }) + .await +} + +#[turbo_tasks::value] +struct ChangingInput { + state: State, +} + +#[turbo_tasks::value] +struct Output { + value: u32, + collectible: String, +} + +#[turbo_tasks::value] +struct Collectible { + value: u32, +} + +#[turbo_tasks::value_impl] +impl ValueToString for Collectible { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(self.value.to_string().into()) + } +} + +#[turbo_tasks::function] +async fn inner_compute(input: Vc) -> Result> { + println!("start inner_compute"); + let value = *input.await?.state.get(); + tokio::time::sleep(Duration::from_millis(200)).await; + if value > 10 { + let collectible: Vc> = Vc::upcast(Collectible { value }.cell()); + emit(collectible); + + println!("end inner_compute with collectible"); + Ok(Vc::cell(42)) + } else { + println!("end inner_compute without collectible"); + Ok(Vc::cell(value)) + } +} + +#[turbo_tasks::function] +async fn compute(input: Vc) -> Result> { + println!("start compute"); + let operation = inner_compute(input); + let value = *operation.await?; + let collectibles = operation.peek_collectibles::>(); + if collectibles.len() > 1 { + bail!("expected 0..1 collectible, found {}", collectibles.len()); + } + let first = collectibles.iter().next(); + let collectible = if let Some(first) = first { + first.to_string().await?.to_string() + } else { + "".to_string() + }; + println!("end compute"); + Ok(Output { value, collectible }.cell()) +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/emptied_cells.rs b/turbopack/crates/turbo-tasks-memory/tests/emptied_cells.rs new file mode 100644 index 0000000000000..326636c709b54 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/emptied_cells.rs @@ -0,0 +1,67 @@ +#![feature(arbitrary_self_types)] + +use anyhow::Result; +use turbo_tasks::{State, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn recompute() { + run(®ISTRATION, async { + let input = ChangingInput { + state: State::new(1), + } + .cell(); + let output = compute(input); + assert_eq!(*output.await.unwrap(), 1); + + println!("changing input"); + input.await.unwrap().state.set(10); + assert_eq!(*output.strongly_consistent().await.unwrap(), 10); + + println!("changing input"); + input.await.unwrap().state.set(5); + assert_eq!(*output.strongly_consistent().await.unwrap(), 5); + + println!("changing input"); + input.await.unwrap().state.set(20); + assert_eq!(*output.strongly_consistent().await.unwrap(), 20); + + println!("changing input"); + input.await.unwrap().state.set(15); + assert_eq!(*output.strongly_consistent().await.unwrap(), 15); + + println!("changing input"); + input.await.unwrap().state.set(1); + assert_eq!(*output.strongly_consistent().await.unwrap(), 1); + }) + .await +} + +#[turbo_tasks::value] +struct ChangingInput { + state: State, +} + +#[turbo_tasks::function] +async fn compute(input: Vc) -> Result> { + let value = *inner_compute(input).await?; + Ok(Vc::cell(value)) +} + +#[turbo_tasks::function] +async fn inner_compute(input: Vc) -> Result> { + let state_value = *input.await?.state.get(); + let mut last = None; + for i in 0..=state_value { + last = Some(compute2(Vc::cell(i))); + } + Ok(last.unwrap()) +} + +#[turbo_tasks::function] +async fn compute2(input: Vc) -> Result> { + let value = *input.await?; + Ok(Vc::cell(value)) +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/read_ref_cell.rs b/turbopack/crates/turbo-tasks-memory/tests/read_ref_cell.rs new file mode 100644 index 0000000000000..6266d3c56fe5d --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/read_ref_cell.rs @@ -0,0 +1,85 @@ +#![feature(arbitrary_self_types)] + +use std::sync::Mutex; + +use anyhow::Result; +use turbo_tasks::{get_invalidator, Invalidator, ReadRef, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn read_ref() { + run(®ISTRATION, async { + let counter = Counter::cell(Counter { + value: Mutex::new((0, None)), + }); + + let counter_value = counter.get_value(); + + assert_eq!(*counter.get_value().strongly_consistent().await?, 0); + assert_eq!(*counter_value.strongly_consistent().await?, 0); + + counter.await?.incr(); + + assert_eq!(*counter.get_value().strongly_consistent().await?, 1); + assert_eq!(*counter_value.strongly_consistent().await?, 1); + + // `ref_counter` will still point to the same `counter` instance as `counter`. + let ref_counter = ReadRef::cell(counter.await?); + let ref_counter_value = ref_counter.get_value(); + + // However, `local_counter_value` will point to the value of `counter_value` + // at the time it was turned into a trait reference (just like a `ReadRef` + // would). + let local_counter_value = ReadRef::cell(counter_value.await?).get_value(); + + counter.await?.incr(); + + assert_eq!(*counter.get_value().strongly_consistent().await?, 2); + assert_eq!(*counter_value.strongly_consistent().await?, 2); + assert_eq!(*ref_counter_value.strongly_consistent().await?, 2); + assert_eq!(*local_counter_value.strongly_consistent().await?, 1); + + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[turbo_tasks::value(transparent)] +struct CounterValue(usize); + +#[turbo_tasks::value(serialization = "none", cell = "new", eq = "manual")] +struct Counter { + #[turbo_tasks(debug_ignore, trace_ignore)] + value: Mutex<(usize, Option)>, +} + +impl Counter { + fn incr(&self) { + let mut lock = self.value.lock().unwrap(); + lock.0 += 1; + if let Some(i) = lock.1.take() { + i.invalidate(); + } + } +} + +#[turbo_tasks::value_impl] +impl Counter { + #[turbo_tasks::function] + async fn get_value(&self) -> Result> { + let mut lock = self.value.lock().unwrap(); + lock.1 = Some(get_invalidator()); + Ok(Vc::cell(lock.0)) + } +} + +#[turbo_tasks::value_impl] +impl CounterValue { + #[turbo_tasks::function] + fn get_value(self: Vc) -> Vc { + self + } +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/recompute.rs b/turbopack/crates/turbo-tasks-memory/tests/recompute.rs new file mode 100644 index 0000000000000..976efd03e66b7 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/recompute.rs @@ -0,0 +1,93 @@ +#![feature(arbitrary_self_types)] + +use anyhow::Result; +use turbo_tasks::{State, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn recompute() { + run(®ISTRATION, async { + let input = ChangingInput { + state: State::new(1), + } + .cell(); + let input2 = ChangingInput { + state: State::new(10), + } + .cell(); + let output = compute(input, input2); + let read = output.await?; + assert_eq!(read.state_value, 1); + assert_eq!(read.state_value2, 10); + let random_value = read.random_value; + + println!("changing input"); + input.await?.state.set(2); + let read = output.strongly_consistent().await?; + assert_eq!(read.state_value, 2); + assert_ne!(read.random_value, random_value); + let random_value = read.random_value; + + println!("changing input2"); + input2.await?.state.set(20); + let read = output.strongly_consistent().await?; + assert_eq!(read.state_value2, 20); + assert_ne!(read.random_value, random_value); + let random_value = read.random_value; + + println!("changing input"); + input.await?.state.set(5); + let read = output.strongly_consistent().await?; + assert_eq!(read.state_value, 5); + assert_eq!(read.state_value2, 42); + assert_ne!(read.random_value, random_value); + let random_value = read.random_value; + + println!("changing input2"); + input2.await?.state.set(30); + let read = output.strongly_consistent().await?; + assert_eq!(read.random_value, random_value); + + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[turbo_tasks::value] +struct ChangingInput { + state: State, +} + +#[turbo_tasks::value] +struct Output { + state_value: u32, + state_value2: u32, + random_value: u32, +} + +#[turbo_tasks::function] +async fn compute(input: Vc, input2: Vc) -> Result> { + let state_value = *input.await?.state.get(); + let state_value2 = if state_value < 5 { + *compute2(input2).await? + } else { + 42 + }; + let random_value = rand::random(); + + Ok(Output { + state_value, + state_value2, + random_value, + } + .cell()) +} + +#[turbo_tasks::function] +async fn compute2(input: Vc) -> Result> { + let state_value = *input.await?.state.get(); + Ok(Vc::cell(state_value)) +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/recompute_collectibles.rs b/turbopack/crates/turbo-tasks-memory/tests/recompute_collectibles.rs new file mode 100644 index 0000000000000..07391c207a703 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/recompute_collectibles.rs @@ -0,0 +1,94 @@ +#![feature(arbitrary_self_types)] + +use anyhow::{bail, Result}; +use turbo_tasks::{emit, CollectiblesSource, RcStr, State, ValueToString, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn recompute() { + run(®ISTRATION, async { + let input = ChangingInput { + state: State::new(1), + } + .cell(); + let output = compute(input, 100); + let read = output.await.unwrap(); + assert_eq!(read.value, 42); + assert_eq!(read.collectible, "1"); + + for i in 2..100 { + input.await.unwrap().state.set(i); + let read = output.strongly_consistent().await.unwrap(); + assert_eq!(read.value, 42); + assert_eq!(read.collectible, i.to_string()); + } + }) + .await +} + +#[turbo_tasks::value] +struct ChangingInput { + state: State, +} + +#[turbo_tasks::value] +struct Output { + value: u32, + collectible: String, +} + +#[turbo_tasks::value] +struct Collectible { + value: u32, +} + +#[turbo_tasks::value_impl] +impl ValueToString for Collectible { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(self.value.to_string().into()) + } +} + +#[turbo_tasks::function] +fn inner_compute(input: Vc) -> Vc { + inner_compute2(input, 1000) +} + +#[turbo_tasks::function] +async fn inner_compute2(input: Vc, innerness: u32) -> Result> { + if innerness > 0 { + return Ok(inner_compute2(input, innerness - 1)); + } + let collectible: Vc> = Vc::upcast( + Collectible { + value: *input.await?.state.get(), + } + .cell(), + ); + emit(collectible); + + Ok(Vc::cell(42)) +} + +#[turbo_tasks::function] +async fn compute(input: Vc, innerness: u32) -> Result> { + if innerness > 0 { + return Ok(compute(input, innerness - 1)); + } + let operation = inner_compute(input); + let value = *operation.await?; + let collectibles = operation.peek_collectibles::>(); + if collectibles.len() != 1 { + bail!("expected 1 collectible, found {}", collectibles.len()); + } + let first = *collectibles.iter().next().unwrap(); + let collectible = first.to_string().await?; + Ok(Output { + value, + collectible: collectible.to_string(), + } + .cell()) +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/scope_stress.rs b/turbopack/crates/turbo-tasks-memory/tests/scope_stress.rs new file mode 100644 index 0000000000000..fa5e827269815 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/scope_stress.rs @@ -0,0 +1,52 @@ +#![feature(arbitrary_self_types)] + +use anyhow::Result; +use turbo_tasks::{Completion, TryJoinIterExt, TurboTasks, Vc}; +use turbo_tasks_memory::MemoryBackend; +use turbo_tasks_testing::{register, Registration}; + +static REGISTRATION: Registration = register!(); + +#[test] +fn rectangle_stress() { + REGISTRATION.ensure_registered(); + let rt = tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap(); + rt.block_on(async { + let tt = TurboTasks::new(MemoryBackend::default()); + let size = std::env::var("TURBOPACK_TEST_RECTANGLE_STRESS_SIZE") + .map(|size| size.parse().unwrap()) + .unwrap_or(50); + (0..size) + .map(|a| (a, size - 1)) + .chain((0..size - 1).map(|b| (size - 1, b))) + .map(|(a, b)| { + let tt = &tt; + async move { + let task = tt.spawn_once_task(async move { + rectangle(a, b).strongly_consistent().await?; + Ok(Vc::<()>::default()) + }); + tt.wait_task_completion(task, false).await + } + }) + .try_join() + .await + .unwrap(); + }) +} + +/// This fills a rectagle from (0, 0) to (a, b) by +/// first filling (0, 0) to (a - 1, b) and then (0, 0) to (a, b - 1) recursively +#[turbo_tasks::function] +async fn rectangle(a: u32, b: u32) -> Result> { + if a > 0 { + rectangle(a - 1, b).await?; + } + if b > 0 { + rectangle(a, b - 1).await?; + } + Ok(Completion::new()) +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/task_statistics.rs b/turbopack/crates/turbo-tasks-memory/tests/task_statistics.rs new file mode 100644 index 0000000000000..e6775812a1983 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/task_statistics.rs @@ -0,0 +1,272 @@ +#![feature(arbitrary_self_types)] + +use std::{ + future::{Future, IntoFuture}, + sync::Arc, +}; + +use anyhow::Result; +use once_cell::sync::Lazy; +use regex::Regex; +use serde_json::json; +use turbo_tasks::{TurboTasks, Vc}; +use turbo_tasks_memory::MemoryBackend; +use turbo_tasks_testing::{register, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn test_simple_task() { + run_with_tt(|tt| async move { + for i in 0..10 { + double(i).await.unwrap(); + // use cached results + double(i).await.unwrap(); + } + for i in 0..5 { + double(i).await.unwrap(); + } + assert_eq!( + stats_json(&tt), + json!({ + "turbo-tasks-memory::::double": { + "cache_miss": 10, + "cache_hit": 15, + }, + }) + ); + }) + .await; +} + +#[tokio::test] +async fn test_await_same_vc_multiple_times() { + run_with_tt(|tt| async move { + let dvc = double(0); + // this is awaited multiple times, but only resolved once + tokio::try_join!(dvc.into_future(), dvc.into_future()).unwrap(); + dvc.await.unwrap(); + assert_eq!( + stats_json(&tt), + json!({ + "turbo-tasks-memory::::double": { + "cache_miss": 1, + "cache_hit": 0, + }, + }) + ); + }) + .await; +} + +#[tokio::test] +async fn test_vc_receiving_task() { + run_with_tt(|tt| async move { + for i in 0..10 { + let dvc = double(i); + double_vc(dvc).await.unwrap(); + // use cached results + double_vc(dvc).await.unwrap(); + } + for i in 0..5 { + let dvc = double(i); + double_vc(dvc).await.unwrap(); + } + assert_eq!( + stats_json(&tt), + json!({ + "turbo-tasks-memory::::double": { + "cache_miss": 10, + "cache_hit": 5, + }, + "turbo-tasks-memory::::double_vc": { + "cache_miss": 10, + "cache_hit": 15, + }, + }) + ); + }) + .await; +} + +#[tokio::test] +async fn test_trait_methods() { + run_with_tt(|tt| async move { + for i in 0..10 { + let wvc = wrap(i); + tokio::try_join!(wvc.double().into_future(), wvc.double().into_future()).unwrap(); + tokio::try_join!(wvc.double_vc().into_future(), wvc.double_vc().into_future()).unwrap(); + } + // use cached results + for i in 0..5 { + let wvc = wrap(i); + wvc.double().await.unwrap(); + wvc.double_vc().await.unwrap(); + } + assert_eq!( + stats_json(&tt), + json!({ + "turbo-tasks-memory::::wrap": { + "cache_miss": 10, + "cache_hit": 5, + }, + "turbo-tasks-memory::::WrappedU64::Doublable::double": { + "cache_miss": 10, + "cache_hit": 15, + }, + "turbo-tasks-memory::::WrappedU64::Doublable::double_vc": { + "cache_miss": 10, + "cache_hit": 15, + }, + }) + ); + }) + .await; +} + +#[tokio::test] +async fn test_dyn_trait_methods() { + run_with_tt(|tt| async move { + for i in 0..10 { + let wvc: Vc> = Vc::upcast(wrap(i)); + let _ = tokio::try_join!(wvc.double().resolve(), wvc.double().resolve()).unwrap(); + let _ = tokio::try_join!(wvc.double_vc().resolve(), wvc.double_vc().resolve()).unwrap(); + } + // use cached results + for i in 0..5 { + let wvc: Vc> = Vc::upcast(wrap(i)); + let _ = wvc.double().resolve().await.unwrap(); + let _ = wvc.double_vc().resolve().await.unwrap(); + } + // use cached results without dynamic dispatch + for i in 0..2 { + let wvc = wrap(i); + let _ = wvc.double().await.unwrap(); + let _ = wvc.double_vc().await.unwrap(); + } + assert_eq!( + stats_json(&tt), + json!({ + "turbo-tasks-memory::::wrap": { + "cache_miss": 10, + "cache_hit": 7, + }, + "turbo-tasks-memory::::WrappedU64::Doublable::double": { + "cache_miss": 10, + "cache_hit": 17, + }, + "turbo-tasks-memory::::WrappedU64::Doublable::double_vc": { + "cache_miss": 10, + "cache_hit": 17, + }, + }) + ); + }) + .await; +} + +// creates Vcs, but doesn't ever execute them +#[tokio::test] +async fn test_no_execution() { + run_with_tt(|tt| async move { + // don't await this! + let _ = wrap_vc(double_vc(double(123))).double().double_vc(); + assert_eq!( + stats_json(&tt), + json!({ + "turbo-tasks-memory::::double": { + "cache_miss": 1, + "cache_hit": 0, + }, + }) + ); + }) + .await; +} + +// Internally, this function uses `PersistentTaskType::Native`. +#[turbo_tasks::function] +fn double(val: u64) -> Vc { + Vc::cell(val * 2) +} + +// Internally, this function uses `PersistentTaskType::ResolveNative`. +#[turbo_tasks::function] +async fn double_vc(val: Vc) -> Result> { + let val = *val.await?; + Ok(Vc::cell(val * 2)) +} + +#[turbo_tasks::value] +struct WrappedU64(u64); + +#[turbo_tasks::function] +fn wrap(val: u64) -> Vc { + WrappedU64(val).cell() +} + +#[turbo_tasks::function] +async fn wrap_vc(val: Vc) -> Result> { + Ok(WrappedU64(*val.await?).cell()) +} + +#[turbo_tasks::value_trait] +pub trait Doublable { + fn double(&self) -> Vc; + fn double_vc(self: Vc) -> Vc; +} + +#[turbo_tasks::value_impl] +impl Doublable for WrappedU64 { + #[turbo_tasks::function] + fn double(&self) -> Vc { + WrappedU64(self.0 * 2).cell() + } + + #[turbo_tasks::function] + async fn double_vc(self: Vc) -> Result> { + let val = self.await?.0; + Ok(WrappedU64(val * 2).cell()) + } +} + +#[turbo_tasks::function] +async fn fail(val: u64) -> Result> { + anyhow::bail!("failed using {val}"); +} + +async fn run_with_tt(func: impl FnOnce(Arc>) -> Fut) +where + Fut: Future + Send + 'static, +{ + REGISTRATION.ensure_registered(); + let tt = TurboTasks::new(MemoryBackend::default()); + tt.backend().task_statistics().enable(); + let fut = func(Arc::clone(&tt)); + tt.run_once(async move { + fut.await; + Ok(()) + }) + .await + .unwrap(); +} + +fn stats_json(tt: &TurboTasks) -> serde_json::Value { + remove_hashes(serde_json::to_value(tt.backend().task_statistics().get()).unwrap()) +} + +// Global task identifiers can contain a hash of the crate and dependencies. +// Remove that so that we can compare against a stable value in tests. +fn remove_hashes(mut json: serde_json::Value) -> serde_json::Value { + static HASH_RE: Lazy = Lazy::new(|| Regex::new("@[^:]+").unwrap()); + match &mut json { + serde_json::Value::Object(map) => { + let old_map = std::mem::take(map); + for (k, v) in old_map { + map.insert(HASH_RE.replace(&k, "").into_owned(), v); + } + } + _ => unreachable!("expected object"), + }; + json +} diff --git a/turbopack/crates/turbo-tasks-memory/tests/trait_ref_cell.rs b/turbopack/crates/turbo-tasks-memory/tests/trait_ref_cell.rs new file mode 100644 index 0000000000000..cfde0d3f4d828 --- /dev/null +++ b/turbopack/crates/turbo-tasks-memory/tests/trait_ref_cell.rs @@ -0,0 +1,104 @@ +#![feature(arbitrary_self_types)] + +use std::sync::Mutex; + +use anyhow::Result; +use turbo_tasks::{get_invalidator, IntoTraitRef, Invalidator, TraitRef, Vc}; +use turbo_tasks_testing::{register, run, Registration}; + +static REGISTRATION: Registration = register!(); + +#[tokio::test] +async fn trait_ref() { + run(®ISTRATION, async { + let counter = Counter::cell(Counter { + value: Mutex::new((0, None)), + }); + + let counter_value = counter.get_value(); + + assert_eq!(*counter.get_value().strongly_consistent().await?, 0); + assert_eq!(*counter_value.strongly_consistent().await?, 0); + + counter.await?.incr(); + + assert_eq!(*counter.get_value().strongly_consistent().await?, 1); + assert_eq!(*counter_value.strongly_consistent().await?, 1); + + // `ref_counter` will still point to the same `counter` instance as `counter`. + let ref_counter = TraitRef::cell( + Vc::upcast::>(counter) + .into_trait_ref() + .await?, + ); + let ref_counter_value = ref_counter.get_value(); + + // However, `local_counter_value` will point to the value of `counter_value` + // at the time it was turned into a trait reference (just like a `ReadRef` + // would). + let local_counter_value = TraitRef::cell( + Vc::upcast::>(counter_value) + .into_trait_ref() + .await?, + ) + .get_value(); + + counter.await?.incr(); + + assert_eq!(*counter.get_value().strongly_consistent().await?, 2); + assert_eq!(*counter_value.strongly_consistent().await?, 2); + assert_eq!(*ref_counter_value.strongly_consistent().await?, 2); + assert_eq!(*local_counter_value.strongly_consistent().await?, 1); + + anyhow::Ok(()) + }) + .await + .unwrap() +} + +#[turbo_tasks::value(transparent)] +struct CounterValue(usize); + +#[turbo_tasks::value(serialization = "none", cell = "new", eq = "manual")] +struct Counter { + #[turbo_tasks(debug_ignore, trace_ignore)] + value: Mutex<(usize, Option)>, +} + +impl Counter { + fn incr(&self) { + let mut lock = self.value.lock().unwrap(); + lock.0 += 1; + if let Some(i) = lock.1.take() { + i.invalidate(); + } + } +} + +#[turbo_tasks::value_trait] +trait CounterTrait { + fn get_value(&self) -> Vc; +} + +#[turbo_tasks::value_impl] +impl CounterTrait for Counter { + #[turbo_tasks::function] + async fn get_value(&self) -> Result> { + let mut lock = self.value.lock().unwrap(); + lock.1 = Some(get_invalidator()); + Ok(Vc::cell(lock.0)) + } +} + +#[turbo_tasks::value_trait] +trait CounterValueTrait { + fn get_value(&self) -> Vc; +} + +#[turbo_tasks::value_impl] +impl CounterValueTrait for CounterValue { + #[turbo_tasks::function] + fn get_value(self: Vc) -> Vc { + self + } +} diff --git a/turbopack/crates/turbo-tasks-signposter-sys/Cargo.toml b/turbopack/crates/turbo-tasks-signposter-sys/Cargo.toml new file mode 100644 index 0000000000000..49db299004b03 --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter-sys/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "signposter-sys" +version = "0.1.0" +description = "Automatically generated bindings for the macOS Signpost API" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[build-dependencies] +bindgen = "0.65.1" diff --git a/turbopack/crates/turbo-tasks-signposter-sys/build.rs b/turbopack/crates/turbo-tasks-signposter-sys/build.rs new file mode 100644 index 0000000000000..bfcc551d761b2 --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter-sys/build.rs @@ -0,0 +1,31 @@ +use std::{env, path::PathBuf}; + +fn main() { + if env::var("CARGO_CFG_TARGET_OS").unwrap() != "macos" { + return; + } + + let sdk_path = std::process::Command::new("xcrun") + .arg("--show-sdk-path") + .output() + .expect("Failed to execute xcrun") + .stdout; + let sdk_path = std::str::from_utf8(&sdk_path).expect("Failed to parse xcrun output"); + let sdk_path = sdk_path.trim(); + println!("cargo:rustc-link-search={}/usr/lib/log", sdk_path); + + println!("cargo:rustc-link-lib=log_signpost"); + + println!("cargo:rerun-if-changed=src/wrapper.h"); + + let bindings = bindgen::Builder::default() + .header("src/wrapper.h") + .parse_callbacks(Box::new(bindgen::CargoCallbacks)) + .generate() + .expect("Unable to generate bindings"); + + let out_path = PathBuf::from(env::var("OUT_DIR").unwrap()); + bindings + .write_to_file(out_path.join("bindings.rs")) + .expect("Couldn't write bindings!"); +} diff --git a/turbopack/crates/turbo-tasks-signposter-sys/src/lib.rs b/turbopack/crates/turbo-tasks-signposter-sys/src/lib.rs new file mode 100644 index 0000000000000..385eefb391259 --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter-sys/src/lib.rs @@ -0,0 +1,9 @@ +#![allow(non_upper_case_globals)] +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(clippy::unnecessary_cast)] +#![allow(clippy::useless_transmute)] +#![allow(clippy::missing_safety_doc)] + +#[cfg(target_os = "macos")] +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); diff --git a/turbopack/crates/turbo-tasks-signposter-sys/src/wrapper.h b/turbopack/crates/turbo-tasks-signposter-sys/src/wrapper.h new file mode 100644 index 0000000000000..4e0b46fe48627 --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter-sys/src/wrapper.h @@ -0,0 +1 @@ +#include diff --git a/turbopack/crates/turbo-tasks-signposter/Cargo.toml b/turbopack/crates/turbo-tasks-signposter/Cargo.toml new file mode 100644 index 0000000000000..d0f376bdf604a --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "signposter" +version = "0.1.0" +description = "Bindings for the macOS Signpost API" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[features] +default = ["global"] +global = ["dep:once_cell"] + +[lints] +workspace = true + +[dependencies] +once_cell = { workspace = true, optional = true } +signposter-sys = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-signposter/examples/simple_signposter.rs b/turbopack/crates/turbo-tasks-signposter/examples/simple_signposter.rs new file mode 100644 index 0000000000000..e88be84782f38 --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter/examples/simple_signposter.rs @@ -0,0 +1,16 @@ +#[cfg(target_os = "macos")] +fn main() { + signposter::event!("Event"); + signposter::event!("Event with message", "Event message"); + + let _interval = signposter::interval!("Interval"); + let _interval_with_message = signposter::interval!("Interval with message", "Interval message"); + let interval_with_end_message = + signposter::interval!("Interval with end message", "Interval start message"); + interval_with_end_message.end_with_message("Interval end message"); +} + +#[cfg(not(target_os = "macos"))] +fn main() { + println!("This example only works on macOS."); +} diff --git a/turbopack/crates/turbo-tasks-signposter/src/global.rs b/turbopack/crates/turbo-tasks-signposter/src/global.rs new file mode 100644 index 0000000000000..276769ad0cae8 --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter/src/global.rs @@ -0,0 +1,46 @@ +use once_cell::sync::OnceCell; + +use crate::{Log, LogCategory}; + +static LOG_INSTANCE: OnceCell = OnceCell::new(); + +#[doc(hidden)] +pub fn global_log() -> &'static Log { + LOG_INSTANCE.get_or_init(|| { + Log::new_with_subsystem_and_category("com.global.Global", LogCategory::PointsOfInterest) + }) +} + +#[macro_export] +macro_rules! event { + ($name:expr) => { + $crate::global_log().signpost().event($name) + }; + ($name:expr, $message:expr) => { + $crate::global_log() + .signpost() + .event_with_message($name, $message) + }; + ($name:expr, $message:expr, $($arg:tt)+) => { + $crate::global_log() + .signpost() + .event_with_message($name, &format!($message, $($arg)+)) + }; +} + +#[macro_export] +macro_rules! interval { + ($name:expr) => { + $crate::global_log().signpost().interval($name) + }; + ($name:expr, $message:expr) => { + $crate::global_log() + .signpost() + .interval_with_message($name, $message) + }; + ($name:expr, $message:expr, $($arg:tt)+) => { + $crate::global_log() + .signpost() + .interval_with_message($name, &format!($message, $($arg)+)) + }; +} diff --git a/turbopack/crates/turbo-tasks-signposter/src/lib.rs b/turbopack/crates/turbo-tasks-signposter/src/lib.rs new file mode 100644 index 0000000000000..5f7db7460965f --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter/src/lib.rs @@ -0,0 +1,9 @@ +#[cfg(all(target_os = "macos", feature = "global"))] +mod global; +#[cfg(target_os = "macos")] +mod log; + +#[cfg(all(target_os = "macos", feature = "global"))] +pub use global::*; +#[cfg(target_os = "macos")] +pub use log::*; diff --git a/turbopack/crates/turbo-tasks-signposter/src/log.rs b/turbopack/crates/turbo-tasks-signposter/src/log.rs new file mode 100644 index 0000000000000..b9138b3ad3327 --- /dev/null +++ b/turbopack/crates/turbo-tasks-signposter/src/log.rs @@ -0,0 +1,201 @@ +use std::{ + ffi::{CStr, CString}, + ptr::{addr_of, null}, +}; + +use signposter_sys::*; + +pub enum LogCategory { + /// Signposts provide high-level events that can be used to orient a + /// developer looking at performance data. These will be displayed by + /// default by performance tools like Instruments.app. + PointsOfInterest, + /// Signposts should be disabled by default, reducing the runtime overhead. + /// [`Log::signpost_enabled`] calls will only return 'true' when a + /// performance tool like Instruments.app is recording. + DynamicTracing, + /// Signposts should capture user backtraces. This behavior is more + /// expensive, so [`Log::signpost_enabled`] will only return 'true' when + /// a performance tool like Instruments.app is recording. + DynamicStackTracing, +} + +impl LogCategory { + fn as_c_str(&self) -> &CStr { + match self { + LogCategory::PointsOfInterest => { + CStr::from_bytes_with_nul(b"PointsOfInterest\0").unwrap() + } + LogCategory::DynamicTracing => CStr::from_bytes_with_nul(b"DynamicTracing\0").unwrap(), + LogCategory::DynamicStackTracing => { + CStr::from_bytes_with_nul(b"DynamicStackTracing\0").unwrap() + } + } + } +} + +/// A log is a collection of signposts. +#[derive(Debug, Clone, Copy)] +pub struct Log { + os_log: *mut os_log_s, +} + +// Safety: unclear +unsafe impl Sync for Log {} + +// Safety: unclear +unsafe impl Send for Log {} + +impl Default for Log { + fn default() -> Self { + Log { + os_log: unsafe { addr_of!(_os_log_default) as *const _ as *mut _ }, + } + } +} + +impl Log { + /// Create a new log with the given subsystem and category. + pub fn new_with_subsystem_and_category(subsystem: &str, category: LogCategory) -> Self { + let subsystem = CString::new(subsystem).unwrap(); + let category = category.as_c_str(); + let os_log = unsafe { os_log_create(subsystem.as_ptr(), category.as_ptr()) }; + Log { os_log } + } + + /// Create a new [`Signpost`] for this log. + pub fn signpost(&self) -> Signpost { + let id = unsafe { os_signpost_id_generate(self.os_log) }; + Signpost { + id, + log: self.os_log, + } + } +} + +/// A signpost is a marker that can be used to annotate a log with +/// information about the execution of a program. +#[derive(Debug, Clone, Copy)] +pub struct Signpost { + id: os_signpost_id_t, + log: *mut os_log_s, +} + +// Safety: unclear +unsafe impl Sync for Signpost {} + +// Safety: unclear +unsafe impl Send for Signpost {} + +// NOTE(alexkirsz) Not sure that's correct, but it's what the Dart SDK does and +// it seems to work. +// See https://github.com/dart-lang/sdk/blob/3e2d3bc77fa8bb5139b869e9b3a5357b5487df18/runtime/vm/timeline_macos.cc#L34-L35 +const FORMAT_BUFFER_LEN: usize = 64; +static FORMAT_BUFFER: [u8; 64] = [0; FORMAT_BUFFER_LEN]; + +#[repr(u8)] +enum SignpostType { + Event = os_signpost_type_t_OS_SIGNPOST_EVENT, + IntervalBegin = os_signpost_type_t_OS_SIGNPOST_INTERVAL_BEGIN, + IntervalEnd = os_signpost_type_t_OS_SIGNPOST_INTERVAL_END, +} + +impl Signpost { + /// Emits a signpost event with the given name. + pub fn event(&self, name: &str) { + let name = CString::new(name).unwrap(); + self.emit(name.as_c_str(), None, SignpostType::Event) + } + + /// Emits a signpost event with the given name and message. + pub fn event_with_message(&self, name: &str, message: &str) { + let name = CString::new(name).unwrap(); + let message = CString::new(escape_message(message)).unwrap(); + self.emit( + name.as_c_str(), + Some(message.as_c_str()), + SignpostType::Event, + ) + } + + /// Starts a new interval signpost with the given name. + pub fn interval(&self, name: &str) -> SignpostInterval { + let name = CString::new(name).unwrap(); + + self.emit(name.as_c_str(), None, SignpostType::IntervalBegin); + + SignpostInterval { + signpost: *self, + name, + } + } + + /// Starts a new interval signpost with the given name and message. + pub fn interval_with_message(&self, name: &str, message: &str) -> SignpostInterval { + let name = CString::new(name).unwrap(); + let message = CString::new(escape_message(message)).unwrap(); + + self.emit( + name.as_c_str(), + Some(message.as_c_str()), + SignpostType::IntervalBegin, + ); + + SignpostInterval { + signpost: *self, + name, + } + } + + fn emit(&self, name: &CStr, message: Option<&CStr>, signpost_type: SignpostType) { + unsafe { + _os_signpost_emit_with_name_impl( + addr_of!(__dso_handle) as *const _ as *mut _, + self.log, + signpost_type as _, + self.id, + name.as_ptr(), + message.map(|message| message.as_ptr()).unwrap_or(null()), + &FORMAT_BUFFER as *const _ as *mut _, + FORMAT_BUFFER_LEN as _, + ) + } + } +} + +/// A signpost interval. +pub struct SignpostInterval { + signpost: Signpost, + name: CString, +} + +impl SignpostInterval { + /// Ends the interval signpost. Calling this is equivalent to dropping the + /// interval. + pub fn end(self) {} + + /// Ends the interval signpost with the given message. + pub fn end_with_message(self, message: &str) { + let message = CString::new(escape_message(message)).unwrap(); + + self.signpost.emit( + self.name.as_c_str(), + Some(message.as_c_str()), + SignpostType::IntervalEnd, + ) + } +} + +impl Drop for SignpostInterval { + fn drop(&mut self) { + self.signpost + .emit(self.name.as_c_str(), None, SignpostType::IntervalEnd); + } +} + +// TODO(alexkirsz) This should likely return a Cow instead. +/// Escapes a message for use with signposts, which will try to parse it as a +/// format string. +fn escape_message(message: &str) -> String { + message.replace('%', "%%") +} diff --git a/turbopack/crates/turbo-tasks-testing/Cargo.toml b/turbopack/crates/turbo-tasks-testing/Cargo.toml new file mode 100644 index 0000000000000..30de612015616 --- /dev/null +++ b/turbopack/crates/turbo-tasks-testing/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "turbo-tasks-testing" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +auto-hash-map = { workspace = true } +futures = { workspace = true } +rustc-hash = { workspace = true } +tokio = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-memory = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-testing/src/lib.rs b/turbopack/crates/turbo-tasks-testing/src/lib.rs new file mode 100644 index 0000000000000..a3845d24b1e85 --- /dev/null +++ b/turbopack/crates/turbo-tasks-testing/src/lib.rs @@ -0,0 +1,294 @@ +//! Testing utilities and macros for turbo-tasks and applications based on it. + +pub mod retry; +mod run; + +use std::{ + borrow::Cow, + collections::HashMap, + future::Future, + mem::replace, + panic::AssertUnwindSafe, + sync::{Arc, Mutex, Weak}, +}; + +use anyhow::{anyhow, Result}; +use futures::FutureExt; +use turbo_tasks::{ + backend::{CellContent, TaskCollectiblesMap, TypedCellContent}, + event::{Event, EventListener}, + registry, + test_helpers::with_turbo_tasks_for_testing, + util::{SharedError, StaticOrArc}, + CellId, InvalidationReason, MagicAny, RawVc, TaskId, TraitTypeId, TurboTasksApi, + TurboTasksCallApi, +}; + +pub use crate::run::{run, Registration}; + +enum Task { + Spawned(Event), + Finished(Result), +} + +#[derive(Default)] +pub struct VcStorage { + this: Weak, + cells: Mutex>, + tasks: Mutex>, +} + +impl VcStorage { + fn dynamic_call( + &self, + func: turbo_tasks::FunctionId, + this_arg: Option, + arg: Box, + ) -> RawVc { + let this = self.this.upgrade().unwrap(); + let handle = tokio::runtime::Handle::current(); + let future = registry::get_function(func).execute(this_arg, &*arg); + let i = { + let mut tasks = self.tasks.lock().unwrap(); + let i = tasks.len(); + tasks.push(Task::Spawned(Event::new(move || { + format!("Task({i})::event") + }))); + i + }; + let id = TaskId::from(i as u32 + 1); + handle.spawn(with_turbo_tasks_for_testing(this.clone(), id, async move { + let result = AssertUnwindSafe(future).catch_unwind().await; + + // Convert the unwind panic to an anyhow error that can be cloned. + let result = result + .map_err(|any| match any.downcast::() { + Ok(owned) => anyhow!(owned), + Err(any) => match any.downcast::<&'static str>() { + Ok(str) => anyhow!(str), + Err(_) => anyhow!("unknown panic"), + }, + }) + .and_then(|r| r) + .map_err(SharedError::new); + + let mut tasks = this.tasks.lock().unwrap(); + if let Task::Spawned(event) = replace(&mut tasks[i], Task::Finished(result)) { + event.notify(usize::MAX); + } + })); + RawVc::TaskOutput(id) + } +} + +impl TurboTasksCallApi for VcStorage { + fn dynamic_call(&self, func: turbo_tasks::FunctionId, arg: Box) -> RawVc { + self.dynamic_call(func, None, arg) + } + + fn dynamic_this_call( + &self, + func: turbo_tasks::FunctionId, + this_arg: RawVc, + arg: Box, + ) -> RawVc { + self.dynamic_call(func, Some(this_arg), arg) + } + + fn native_call(&self, _func: turbo_tasks::FunctionId, _arg: Box) -> RawVc { + unreachable!() + } + + fn this_call( + &self, + _func: turbo_tasks::FunctionId, + _this: RawVc, + _arg: Box, + ) -> RawVc { + unreachable!() + } + + fn trait_call( + &self, + _trait_type: turbo_tasks::TraitTypeId, + _trait_fn_name: Cow<'static, str>, + _this: RawVc, + _arg: Box, + ) -> RawVc { + unreachable!() + } + + fn run_once( + &self, + _future: std::pin::Pin> + Send + 'static>>, + ) -> TaskId { + unreachable!() + } + + fn run_once_with_reason( + &self, + _reason: StaticOrArc, + _future: std::pin::Pin> + Send + 'static>>, + ) -> TaskId { + unreachable!() + } + + fn run_once_process( + &self, + _future: std::pin::Pin> + Send + 'static>>, + ) -> TaskId { + unreachable!() + } +} + +impl TurboTasksApi for VcStorage { + fn pin(&self) -> Arc { + self.this.upgrade().unwrap() + } + + fn invalidate(&self, _task: TaskId) { + unreachable!() + } + + fn invalidate_with_reason( + &self, + _task: TaskId, + _reason: turbo_tasks::util::StaticOrArc, + ) { + unreachable!() + } + + fn notify_scheduled_tasks(&self) { + // ignore + } + + fn try_read_task_output( + &self, + id: TaskId, + _strongly_consistent: bool, + ) -> Result> { + let tasks = self.tasks.lock().unwrap(); + let i = *id - 1; + let task = tasks.get(i as usize).unwrap(); + match task { + Task::Spawned(event) => Ok(Err(event.listen())), + Task::Finished(result) => match result { + Ok(vc) => Ok(Ok(*vc)), + Err(err) => Err(anyhow!(err.clone())), + }, + } + } + + fn try_read_task_output_untracked( + &self, + task: TaskId, + strongly_consistent: bool, + ) -> Result> { + self.try_read_task_output(task, strongly_consistent) + } + + fn try_read_task_cell( + &self, + task: TaskId, + index: CellId, + ) -> Result> { + let map = self.cells.lock().unwrap(); + Ok(Ok(if let Some(cell) = map.get(&(task, index)) { + cell.clone() + } else { + Default::default() + } + .into_typed(index.type_id))) + } + + fn try_read_task_cell_untracked( + &self, + task: TaskId, + index: CellId, + ) -> Result> { + let map = self.cells.lock().unwrap(); + Ok(Ok(if let Some(cell) = map.get(&(task, index)) { + cell.to_owned() + } else { + Default::default() + } + .into_typed(index.type_id))) + } + + fn try_read_own_task_cell_untracked( + &self, + current_task: TaskId, + index: CellId, + ) -> Result { + self.read_own_task_cell(current_task, index) + } + + fn emit_collectible(&self, _trait_type: turbo_tasks::TraitTypeId, _collectible: RawVc) { + unimplemented!() + } + + fn unemit_collectible( + &self, + _trait_type: turbo_tasks::TraitTypeId, + _collectible: RawVc, + _count: u32, + ) { + unimplemented!() + } + + fn unemit_collectibles( + &self, + _trait_type: turbo_tasks::TraitTypeId, + _collectibles: &TaskCollectiblesMap, + ) { + unimplemented!() + } + + fn read_task_collectibles(&self, _task: TaskId, _trait_id: TraitTypeId) -> TaskCollectiblesMap { + unimplemented!() + } + + fn read_own_task_cell(&self, task: TaskId, index: CellId) -> Result { + let map = self.cells.lock().unwrap(); + Ok(if let Some(cell) = map.get(&(task, index)) { + cell.to_owned() + } else { + Default::default() + } + .into_typed(index.type_id)) + } + + fn update_own_task_cell(&self, task: TaskId, index: CellId, content: CellContent) { + let mut map = self.cells.lock().unwrap(); + let cell = map.entry((task, index)).or_default(); + *cell = content; + } + + fn connect_task(&self, _task: TaskId) { + // no-op + } + + fn mark_own_task_as_finished(&self, _task: TaskId) { + // no-op + } + + fn detached( + &self, + _f: std::pin::Pin> + Send + 'static>>, + ) -> std::pin::Pin> + Send + 'static>> { + unimplemented!() + } +} + +impl VcStorage { + pub fn with(f: impl Future) -> impl Future { + with_turbo_tasks_for_testing( + Arc::new_cyclic(|weak| VcStorage { + this: weak.clone(), + ..Default::default() + }), + TaskId::from(u32::MAX), + f, + ) + } +} diff --git a/turbopack/crates/turbo-tasks-testing/src/retry.rs b/turbopack/crates/turbo-tasks-testing/src/retry.rs new file mode 100644 index 0000000000000..d8d02ab3a2061 --- /dev/null +++ b/turbopack/crates/turbo-tasks-testing/src/retry.rs @@ -0,0 +1,52 @@ +use std::{future::Future, time::Duration}; + +pub fn retry( + mut args: A, + f: F, + max_retries: usize, + mut timeout: Duration, +) -> Result +where + F: Fn(&mut A) -> Result, +{ + let mut retries = 0usize; + loop { + match f(&mut args) { + Ok(value) => return Ok(value), + Err(e) => { + if retries >= max_retries { + return Err(e); + } + retries += 1; + std::thread::sleep(timeout); + timeout += timeout; + } + } + } +} + +pub async fn retry_async( + mut args: A, + f: F, + max_retries: usize, + mut timeout: Duration, +) -> Result +where + F: Fn(&mut A) -> Fut, + Fut: Future>, +{ + let mut retries = 0usize; + loop { + match f(&mut args).await { + Ok(value) => return Ok(value), + Err(e) => { + if retries >= max_retries { + return Err(e); + } + retries += 1; + tokio::time::sleep(timeout).await; + timeout += timeout; + } + } + } +} diff --git a/turbopack/crates/turbo-tasks-testing/src/run.rs b/turbopack/crates/turbo-tasks-testing/src/run.rs new file mode 100644 index 0000000000000..7b101049af59b --- /dev/null +++ b/turbopack/crates/turbo-tasks-testing/src/run.rs @@ -0,0 +1,52 @@ +use std::{future::Future, sync::OnceLock}; + +use turbo_tasks::{trace::TraceRawVcs, TurboTasks}; +use turbo_tasks_memory::MemoryBackend; + +pub struct Registration { + execution_lock: OnceLock<()>, + func: fn(), +} + +impl Registration { + #[doc(hidden)] + pub const fn new(func: fn()) -> Self { + Registration { + execution_lock: OnceLock::new(), + func, + } + } + + /// Called by [`run`]. You can call this manually if you're not using + /// [`run`] (e.g. because you're using a customized `turbo_tasks` + /// implementation or tokio runtime). + pub fn ensure_registered(&self) { + self.execution_lock.get_or_init(self.func); + } +} + +#[macro_export] +macro_rules! register { + ($($other_register_fns:expr),* $(,)?) => {{ + fn register_impl() { + $($other_register_fns();)* + turbo_tasks::register(); + include!(concat!( + env!("OUT_DIR"), + "/register_test_", + module_path!(), + ".rs", + )); + } + turbo_tasks_testing::Registration::new(register_impl) + }}; +} + +pub async fn run(registration: &Registration, fut: impl Future + Send + 'static) -> T +where + T: TraceRawVcs + Send + 'static, +{ + registration.ensure_registered(); + let tt = TurboTasks::new(MemoryBackend::default()); + tt.run_once(async move { Ok(fut.await) }).await.unwrap() +} diff --git a/turbopack/crates/turbo-tasks-tracing-signpost/Cargo.toml b/turbopack/crates/turbo-tasks-tracing-signpost/Cargo.toml new file mode 100644 index 0000000000000..f1789eff7505b --- /dev/null +++ b/turbopack/crates/turbo-tasks-tracing-signpost/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "tracing-signpost" +version = "0.1.0" +description = "A tracing layer for the macOS Signpost API" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +dashmap = { workspace = true } +signposter = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } diff --git a/turbopack/crates/turbo-tasks-tracing-signpost/src/layer.rs b/turbopack/crates/turbo-tasks-tracing-signpost/src/layer.rs new file mode 100644 index 0000000000000..c3b30e2cd79eb --- /dev/null +++ b/turbopack/crates/turbo-tasks-tracing-signpost/src/layer.rs @@ -0,0 +1,130 @@ +use dashmap::DashMap; +use signposter::{Log, LogCategory, Signpost, SignpostInterval}; +use tracing::{span, subscriber::Subscriber, Event, Id}; +use tracing_subscriber::{layer::Context, Layer}; + +/// A [`tracing::Layer`] implementation that emits signposts for each span and +/// event. +pub struct SignpostLayer { + signposts: DashMap, + current_intervals: DashMap, + log: Log, +} + +impl Default for SignpostLayer { + /// Create a new `SignpostLayer`. + fn default() -> SignpostLayer { + SignpostLayer { + signposts: Default::default(), + current_intervals: Default::default(), + log: Log::new_with_subsystem_and_category( + "com.global.Global", + LogCategory::PointsOfInterest, + ), + } + } +} + +impl Layer for SignpostLayer +where + S: Subscriber, +{ + fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) { + let mut visitor: KeyValueVisitor = KeyValueVisitor::new(); + + event.record(&mut visitor); + + self.log + .signpost() + .event_with_message(event.metadata().name(), &visitor.output); + } + + fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, _ctx: Context<'_, S>) { + let mut visitor: KeyValueVisitor = KeyValueVisitor::new(); + + attrs.record(&mut visitor); + + self.signposts.insert( + id.clone(), + SignpostDescriptor { + name: attrs.metadata().name().to_string(), + description: visitor.output, + signpost: self.log.signpost(), + }, + ); + } + + fn on_enter(&self, id: &span::Id, _ctx: Context<'_, S>) { + let signpost = self.signposts.get(id).unwrap(); + self.current_intervals.insert( + id.clone(), + signpost + .signpost + .interval_with_message(&signpost.name, &signpost.description), + ); + } + + fn on_exit(&self, id: &span::Id, _ctx: Context<'_, S>) { + let (_, interval) = self.current_intervals.remove(id).unwrap(); + interval.end(); + } +} + +struct SignpostDescriptor { + name: String, + description: String, + signpost: Signpost, +} + +use std::fmt; + +use tracing::field::{Field, Visit}; + +struct KeyValueVisitor { + output: String, + first: bool, +} + +impl KeyValueVisitor { + fn new() -> Self { + KeyValueVisitor { + output: String::new(), + first: true, + } + } +} + +impl Visit for KeyValueVisitor { + fn record_debug(&mut self, field: &Field, value: &dyn fmt::Debug) { + self.record_any(field, format!("{:?}", value)); + } + + fn record_i64(&mut self, field: &Field, value: i64) { + self.record_any(field, value.to_string()); + } + + fn record_u64(&mut self, field: &Field, value: u64) { + self.record_any(field, value.to_string()); + } + + fn record_bool(&mut self, field: &Field, value: bool) { + self.record_any(field, value.to_string()); + } + + fn record_str(&mut self, field: &Field, value: &str) { + self.record_any(field, value.to_string()); + } +} + +impl KeyValueVisitor { + fn record_any(&mut self, field: &Field, value: T) { + if !self.first { + self.output.push_str(", "); + } else { + self.first = false; + } + + self.output + .push_str(&format!("{}: {}", field.name(), value)); + } +} diff --git a/turbopack/crates/turbo-tasks-tracing-signpost/src/lib.rs b/turbopack/crates/turbo-tasks-tracing-signpost/src/lib.rs new file mode 100644 index 0000000000000..3d96f58f259df --- /dev/null +++ b/turbopack/crates/turbo-tasks-tracing-signpost/src/lib.rs @@ -0,0 +1,5 @@ +#[cfg(target_os = "macos")] +mod layer; + +#[cfg(target_os = "macos")] +pub use layer::SignpostLayer; diff --git a/turbopack/crates/turbo-tasks/Cargo.toml b/turbopack/crates/turbo-tasks/Cargo.toml new file mode 100644 index 0000000000000..8e21f292ac503 --- /dev/null +++ b/turbopack/crates/turbo-tasks/Cargo.toml @@ -0,0 +1,53 @@ +[package] +name = "turbo-tasks" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +[lib] +bench = false + +[features] +default = [] +assert_task_state = [] +tokio_tracing = ["tokio/tracing"] +log_function_stats = [] +hanging_detection = [] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +async-trait = { workspace = true } +auto-hash-map = { workspace = true } +concurrent-queue = { workspace = true } +dashmap = { workspace = true } +erased-serde = "0.3.20" +event-listener = "2.5.3" +futures = { workspace = true } +indexmap = { workspace = true, features = ["serde"] } +mopa = "0.2.0" +once_cell = { workspace = true } +parking_lot = { workspace = true } +pin-project-lite = { workspace = true } +regex = { workspace = true } +rustc-hash = { workspace = true } +serde = { workspace = true, features = ["rc", "derive"] } +serde_json = { workspace = true } +serde_regex = "1.1.0" +thiserror = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tracing = { workspace = true } +triomphe = { workspace = true, features = ["unsize"] } +turbo-tasks-hash = { workspace = true } +turbo-tasks-macros = { workspace = true } +turbo-tasks-malloc = { workspace = true } +unsize = { workspace = true } + +[dev-dependencies] +serde_test = "1.0.157" + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbo-tasks/build.rs b/turbopack/crates/turbo-tasks/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbo-tasks/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbo-tasks/src/backend.rs b/turbopack/crates/turbo-tasks/src/backend.rs new file mode 100644 index 0000000000000..bb1572bc3a1de --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/backend.rs @@ -0,0 +1,682 @@ +use std::{ + any::Any, + borrow::Cow, + fmt::{self, Debug, Display, Write}, + future::Future, + hash::BuildHasherDefault, + pin::Pin, + sync::Arc, + time::Duration, +}; + +use anyhow::{anyhow, Result}; +use auto_hash_map::AutoMap; +use rustc_hash::FxHasher; +use tracing::Span; + +pub use crate::id::{BackendJobId, ExecutionId}; +use crate::{ + event::EventListener, + magic_any::MagicAny, + manager::TurboTasksBackendApi, + raw_vc::CellId, + registry, + trait_helpers::{get_trait_method, has_trait, traits}, + FunctionId, RawVc, ReadRef, SharedReference, TaskId, TaskIdProvider, TaskIdSet, TraitRef, + TraitTypeId, ValueTypeId, VcValueTrait, VcValueType, +}; + +pub enum TaskType { + /// Tasks that only exist for a certain operation and + /// won't persist between sessions + Transient(TransientTaskType), + + /// Tasks that can persist between sessions and potentially + /// shared globally + Persistent(PersistentTaskType), +} + +type TransientTaskRoot = + Box Pin> + Send>> + Send + Sync>; + +pub enum TransientTaskType { + /// A root task that will track dependencies and re-execute when + /// dependencies change. Task will eventually settle to the correct + /// execution. + /// Always active. Automatically scheduled. + Root(TransientTaskRoot), + + // TODO implement these strongly consistency + /// A single root task execution. It won't track dependencies. + /// Task will definitely include all invalidations that happened before the + /// start of the task. It may or may not include invalidations that + /// happened after that. It may see these invalidations partially + /// applied. + /// Active until done. Automatically scheduled. + Once(Pin> + Send + 'static>>), +} + +impl Debug for TransientTaskType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::Root(_) => f.debug_tuple("Root").finish(), + Self::Once(_) => f.debug_tuple("Once").finish(), + } + } +} + +#[derive(Debug, PartialEq, Eq, Hash)] +pub enum PersistentTaskType { + /// A normal task execution a native (rust) function + Native { + fn_type: FunctionId, + this: Option, + arg: Box, + }, + + /// A resolve task, which resolves arguments and calls the function with + /// resolve arguments. The inner function call will do a cache lookup. + ResolveNative { + fn_type: FunctionId, + this: Option, + arg: Box, + }, + + /// A trait method resolve task. It resolves the first (`self`) argument and + /// looks up the trait method on that value. Then it calls that method. + /// The method call will do a cache lookup and might resolve arguments + /// before. + ResolveTrait { + trait_type: TraitTypeId, + method_name: Cow<'static, str>, + this: RawVc, + arg: Box, + }, +} + +impl Display for PersistentTaskType { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(&self.get_name()) + } +} + +mod ser { + use serde::{ + ser::{SerializeSeq, SerializeTuple}, + Deserialize, Deserializer, Serialize, Serializer, + }; + + use super::*; + + enum FunctionAndArg<'a> { + Owned { + fn_type: FunctionId, + arg: Box, + }, + Borrowed { + fn_type: FunctionId, + arg: &'a dyn MagicAny, + }, + } + + impl<'a> Serialize for FunctionAndArg<'a> { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: Serializer, + { + let FunctionAndArg::Borrowed { fn_type, arg } = self else { + unreachable!(); + }; + let mut state = serializer.serialize_seq(Some(2))?; + state.serialize_element(&fn_type)?; + let arg = *arg; + let arg = registry::get_function(*fn_type).arg_meta.as_serialize(arg); + state.serialize_element(arg)?; + state.end() + } + } + + impl<'de> Deserialize<'de> for FunctionAndArg<'de> { + fn deserialize>(deserializer: D) -> Result { + struct Visitor; + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = FunctionAndArg<'de>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a valid PersistentTaskType") + } + + fn visit_seq(self, mut seq: A) -> std::result::Result + where + A: serde::de::SeqAccess<'de>, + { + let fn_type = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; + let seed = registry::get_function(fn_type) + .arg_meta + .deserialization_seed(); + let arg = seq + .next_element_seed(seed)? + .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?; + Ok(FunctionAndArg::Owned { fn_type, arg }) + } + } + deserializer.deserialize_seq(Visitor) + } + } + + impl Serialize for PersistentTaskType { + fn serialize(&self, serializer: S) -> std::result::Result + where + S: ser::Serializer, + { + match self { + PersistentTaskType::Native { fn_type, this, arg } => { + let mut s = serializer.serialize_seq(Some(3))?; + s.serialize_element::(&0)?; + s.serialize_element(&FunctionAndArg::Borrowed { + fn_type: *fn_type, + arg, + })?; + s.serialize_element(this)?; + s.end() + } + PersistentTaskType::ResolveNative { fn_type, this, arg } => { + let mut s = serializer.serialize_seq(Some(3))?; + s.serialize_element::(&1)?; + s.serialize_element(&FunctionAndArg::Borrowed { + fn_type: *fn_type, + arg, + })?; + s.serialize_element(this)?; + s.end() + } + PersistentTaskType::ResolveTrait { + trait_type, + method_name, + this, + arg, + } => { + let mut s = serializer.serialize_tuple(5)?; + s.serialize_element::(&2)?; + s.serialize_element(trait_type)?; + s.serialize_element(method_name)?; + s.serialize_element(this)?; + let arg = if let Some(method) = + registry::get_trait(*trait_type).methods.get(method_name) + { + method.arg_serializer.as_serialize(arg) + } else { + return Err(serde::ser::Error::custom("Method not found")); + }; + s.serialize_element(arg)?; + s.end() + } + } + } + } + + impl<'de> Deserialize<'de> for PersistentTaskType { + fn deserialize>(deserializer: D) -> Result { + #[derive(Deserialize)] + enum VariantKind { + Native, + ResolveNative, + ResolveTrait, + } + struct Visitor; + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = PersistentTaskType; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a valid PersistentTaskType") + } + + fn visit_seq(self, mut seq: A) -> std::result::Result + where + A: serde::de::SeqAccess<'de>, + { + let kind = seq + .next_element::()? + .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; + match kind { + 0 => { + let FunctionAndArg::Owned { fn_type, arg } = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(1, &self))? + else { + unreachable!(); + }; + let this = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(2, &self))?; + Ok(PersistentTaskType::Native { fn_type, this, arg }) + } + 1 => { + let FunctionAndArg::Owned { fn_type, arg } = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(1, &self))? + else { + unreachable!(); + }; + let this = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(2, &self))?; + Ok(PersistentTaskType::ResolveNative { fn_type, this, arg }) + } + 2 => { + let trait_type = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(0, &self))?; + let method_name = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(1, &self))?; + let this = seq + .next_element()? + .ok_or_else(|| serde::de::Error::invalid_length(2, &self))?; + let Some(method) = + registry::get_trait(trait_type).methods.get(&method_name) + else { + return Err(serde::de::Error::custom("Method not found")); + }; + let arg = seq + .next_element_seed(method.arg_deserializer)? + .ok_or_else(|| serde::de::Error::invalid_length(3, &self))?; + Ok(PersistentTaskType::ResolveTrait { + trait_type, + method_name, + this, + arg, + }) + } + _ => Err(serde::de::Error::custom("Invalid variant")), + } + } + } + deserializer.deserialize_seq(Visitor) + } + } +} + +impl PersistentTaskType { + /// Returns the name of the function in the code. Trait methods are + /// formatted as `TraitName::method_name`. + /// + /// Equivalent to [`ToString::to_string`], but potentially more efficient as + /// it can return a `&'static str` in many cases. + pub fn get_name(&self) -> Cow<'static, str> { + match self { + PersistentTaskType::Native { + fn_type: native_fn, + this: _, + arg: _, + } + | PersistentTaskType::ResolveNative { + fn_type: native_fn, + this: _, + arg: _, + } => Cow::Borrowed(®istry::get_function(*native_fn).name), + PersistentTaskType::ResolveTrait { + trait_type: trait_id, + method_name: fn_name, + this: _, + arg: _, + } => format!("{}::{}", registry::get_trait(*trait_id).name, fn_name).into(), + } + } +} + +pub struct TaskExecutionSpec<'a> { + pub future: Pin> + Send + 'a>>, + pub span: Span, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)] +pub struct CellContent(pub Option); +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct TypedCellContent(pub ValueTypeId, pub CellContent); + +impl Display for CellContent { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &self.0 { + None => write!(f, "empty"), + Some(content) => Display::fmt(content, f), + } + } +} + +impl TypedCellContent { + pub fn cast(self) -> Result> { + let data = self.1 .0.ok_or_else(|| anyhow!("Cell is empty"))?; + let data = data + .downcast() + .map_err(|_err| anyhow!("Unexpected type in cell"))?; + Ok(ReadRef::new_arc(data)) + } + + /// # Safety + /// + /// The caller must ensure that the TypedCellContent contains a vc + /// that implements T. + pub fn cast_trait(self) -> Result> + where + T: VcValueTrait + ?Sized, + { + let shared_reference = self + .1 + .0 + .ok_or_else(|| anyhow!("Cell is empty"))? + .typed(self.0); + Ok( + // Safety: It is a TypedSharedReference + TraitRef::new(shared_reference), + ) + } + + pub fn try_cast(self) -> Option> { + Some(ReadRef::new_arc(self.1 .0?.downcast().ok()?)) + } + + pub fn into_untyped(self) -> CellContent { + self.1 + } +} + +impl CellContent { + pub fn into_typed(self, type_id: ValueTypeId) -> TypedCellContent { + TypedCellContent(type_id, self) + } +} + +pub type TaskCollectiblesMap = AutoMap, 1>; + +pub trait Backend: Sync + Send { + #[allow(unused_variables)] + fn initialize(&mut self, task_id_provider: &dyn TaskIdProvider) {} + + #[allow(unused_variables)] + fn startup(&self, turbo_tasks: &dyn TurboTasksBackendApi) {} + + #[allow(unused_variables)] + fn stop(&self, turbo_tasks: &dyn TurboTasksBackendApi) {} + + #[allow(unused_variables)] + fn idle_start(&self, turbo_tasks: &dyn TurboTasksBackendApi) {} + + fn invalidate_task(&self, task: TaskId, turbo_tasks: &dyn TurboTasksBackendApi); + + fn invalidate_tasks(&self, tasks: &[TaskId], turbo_tasks: &dyn TurboTasksBackendApi); + fn invalidate_tasks_set(&self, tasks: &TaskIdSet, turbo_tasks: &dyn TurboTasksBackendApi); + + fn get_task_description(&self, task: TaskId) -> String; + + type ExecutionScopeFuture> + Send + 'static>: Future> + + Send + + 'static; + + fn execution_scope> + Send + 'static>( + &self, + task: TaskId, + future: T, + ) -> Self::ExecutionScopeFuture; + + fn try_start_task_execution<'a>( + &'a self, + task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Option>; + + fn task_execution_result( + &self, + task: TaskId, + result: Result, Option>>, + turbo_tasks: &dyn TurboTasksBackendApi, + ); + + fn task_execution_completed( + &self, + task: TaskId, + duration: Duration, + memory_usage: usize, + cell_counters: AutoMap, 8>, + stateful: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> bool; + + fn run_backend_job<'a>( + &'a self, + id: BackendJobId, + turbo_tasks: &'a dyn TurboTasksBackendApi, + ) -> Pin + Send + 'a>>; + + fn try_read_task_output( + &self, + task: TaskId, + reader: TaskId, + strongly_consistent: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result>; + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + fn try_read_task_output_untracked( + &self, + task: TaskId, + strongly_consistent: bool, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result>; + + fn try_read_task_cell( + &self, + task: TaskId, + index: CellId, + reader: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result>; + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + fn try_read_task_cell_untracked( + &self, + task: TaskId, + index: CellId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result>; + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + fn try_read_own_task_cell_untracked( + &self, + current_task: TaskId, + index: CellId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> Result { + match self.try_read_task_cell_untracked(current_task, index, turbo_tasks)? { + Ok(content) => Ok(content), + Err(_) => Ok(TypedCellContent(index.type_id, CellContent(None))), + } + } + + fn read_task_collectibles( + &self, + task: TaskId, + trait_id: TraitTypeId, + reader: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> TaskCollectiblesMap; + + fn emit_collectible( + &self, + trait_type: TraitTypeId, + collectible: RawVc, + task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ); + + fn unemit_collectible( + &self, + trait_type: TraitTypeId, + collectible: RawVc, + count: u32, + task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ); + + fn update_task_cell( + &self, + task: TaskId, + index: CellId, + content: CellContent, + turbo_tasks: &dyn TurboTasksBackendApi, + ); + + fn get_or_create_persistent_task( + &self, + task_type: PersistentTaskType, + parent_task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> TaskId; + + fn connect_task( + &self, + task: TaskId, + parent_task: TaskId, + turbo_tasks: &dyn TurboTasksBackendApi, + ); + + fn mark_own_task_as_finished( + &self, + _task: TaskId, + _turbo_tasks: &dyn TurboTasksBackendApi, + ) { + // Do nothing by default + } + + fn create_transient_task( + &self, + task_type: TransientTaskType, + turbo_tasks: &dyn TurboTasksBackendApi, + ) -> TaskId; + + fn dispose_root_task(&self, task: TaskId, turbo_tasks: &dyn TurboTasksBackendApi); +} + +impl PersistentTaskType { + pub async fn run_resolve_native( + fn_id: FunctionId, + mut this: Option, + arg: &dyn MagicAny, + turbo_tasks: Arc>, + ) -> Result { + if let Some(this) = this.as_mut() { + *this = this.resolve().await?; + } + let arg = registry::get_function(fn_id).arg_meta.resolve(arg).await?; + Ok(if let Some(this) = this { + turbo_tasks.this_call(fn_id, this, arg) + } else { + turbo_tasks.native_call(fn_id, arg) + }) + } + + pub async fn resolve_trait_method( + trait_type: TraitTypeId, + name: Cow<'static, str>, + this: RawVc, + ) -> Result { + let TypedCellContent(value_type, _) = this.into_read().await?; + Self::resolve_trait_method_from_value(trait_type, value_type, name) + } + + pub async fn run_resolve_trait( + trait_type: TraitTypeId, + name: Cow<'static, str>, + this: RawVc, + arg: &dyn MagicAny, + turbo_tasks: Arc>, + ) -> Result { + let this = this.resolve().await?; + let TypedCellContent(this_ty, _) = this.into_read().await?; + + let native_fn = Self::resolve_trait_method_from_value(trait_type, this_ty, name)?; + let arg = registry::get_function(native_fn) + .arg_meta + .resolve(arg) + .await?; + Ok(turbo_tasks.dynamic_this_call(native_fn, this, arg)) + } + + /// Shared helper used by [`Self::resolve_trait_method`] and + /// [`Self::run_resolve_trait`]. + fn resolve_trait_method_from_value( + trait_type: TraitTypeId, + value_type: ValueTypeId, + name: Cow<'static, str>, + ) -> Result { + match get_trait_method(trait_type, value_type, name) { + Ok(native_fn) => Ok(native_fn), + Err(name) => { + if !has_trait(value_type, trait_type) { + let traits = traits(value_type).iter().fold(String::new(), |mut out, t| { + let _ = write!(out, " {}", t); + out + }); + Err(anyhow!( + "{} doesn't implement {} (only{})", + registry::get_value_type(value_type), + registry::get_trait(trait_type), + traits, + )) + } else { + Err(anyhow!( + "{} implements trait {}, but method {} is missing", + registry::get_value_type(value_type), + registry::get_trait(trait_type), + name + )) + } + } + } + } +} + +#[cfg(test)] +pub(crate) mod tests { + use super::*; + use crate::{self as turbo_tasks, Vc}; + + #[turbo_tasks::function] + fn mock_func_task() -> Vc<()> { + Vc::cell(()) + } + + #[turbo_tasks::value_trait] + trait MockTrait { + fn mock_method_task() -> Vc<()>; + } + + #[test] + fn test_get_name() { + crate::register(); + assert_eq!( + PersistentTaskType::Native { + fn_type: *MOCK_FUNC_TASK_FUNCTION_ID, + this: None, + arg: Box::new(()), + } + .get_name(), + "mock_func_task", + ); + assert_eq!( + PersistentTaskType::ResolveTrait { + trait_type: *MOCKTRAIT_TRAIT_TYPE_ID, + method_name: "mock_method_task".into(), + this: RawVc::TaskOutput(unsafe { TaskId::new_unchecked(1) }), + arg: Box::new(()), + } + .get_name(), + "MockTrait::mock_method_task", + ); + } +} diff --git a/turbopack/crates/turbo-tasks/src/capture_future.rs b/turbopack/crates/turbo-tasks/src/capture_future.rs new file mode 100644 index 0000000000000..8a7b5d621b2e4 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/capture_future.rs @@ -0,0 +1,76 @@ +use std::{ + future::Future, + pin::Pin, + sync::{Arc, Mutex}, + task::{Context, Poll}, + time::{Duration, Instant}, +}; + +use pin_project_lite::pin_project; +use tokio::{task::futures::TaskLocalFuture, task_local}; +use turbo_tasks_malloc::{AllocationInfo, TurboMalloc}; + +task_local! { + static EXTRA: Arc>; +} + +pin_project! { + pub struct CaptureFuture> { + cell: Arc>, + #[pin] + future: TaskLocalFuture>, F>, + duration: Duration, + allocations: usize, + deallocations: usize, + } +} + +impl> CaptureFuture { + pub fn new(future: F) -> Self { + let cell = Arc::new(Mutex::new((Duration::ZERO, 0, 0))); + Self { + future: EXTRA.scope(cell.clone(), future), + cell, + duration: Duration::ZERO, + allocations: 0, + deallocations: 0, + } + } +} + +pub fn add_duration(duration: Duration) { + EXTRA.with(|cell| cell.lock().unwrap().0 += duration); +} + +pub fn add_allocation_info(alloc_info: AllocationInfo) { + EXTRA.with(|cell| { + let mut guard = cell.lock().unwrap(); + guard.1 += alloc_info.allocations; + guard.2 += alloc_info.deallocations; + }); +} + +impl> Future for CaptureFuture { + type Output = (T, Duration, usize); + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.project(); + let start = Instant::now(); + let start_allocations = TurboMalloc::allocation_counters(); + let result = this.future.poll(cx); + let elapsed = start.elapsed(); + let allocations = start_allocations.until_now(); + *this.duration += elapsed; + *this.allocations += allocations.allocations; + *this.deallocations += allocations.deallocations; + match result { + Poll::Ready(r) => { + let (duration, allocations, deallocations) = *this.cell.lock().unwrap(); + let memory_usage = (*this.allocations + allocations) + .saturating_sub(*this.deallocations + deallocations); + Poll::Ready((r, *this.duration + duration, memory_usage)) + } + Poll::Pending => Poll::Pending, + } + } +} diff --git a/turbopack/crates/turbo-tasks/src/collectibles.rs b/turbopack/crates/turbo-tasks/src/collectibles.rs new file mode 100644 index 0000000000000..e4f9aed0de1ae --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/collectibles.rs @@ -0,0 +1,8 @@ +use auto_hash_map::AutoSet; + +use crate::{Vc, VcValueTrait}; + +pub trait CollectiblesSource { + fn take_collectibles(self) -> AutoSet>; + fn peek_collectibles(self) -> AutoSet>; +} diff --git a/turbopack/crates/turbo-tasks/src/completion.rs b/turbopack/crates/turbo-tasks/src/completion.rs new file mode 100644 index 0000000000000..cbd7501a7fab0 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/completion.rs @@ -0,0 +1,73 @@ +use crate::{self as turbo_tasks, RawVc, TryJoinIterExt, Vc}; +/// Just an empty type, but it's never equal to itself. +/// [`Vc`] can be used as return value instead of `()` +/// to have a concrete reference that can be awaited. +/// It will invalidate the awaiting task everytime the referenced +/// task has been executed. +/// +/// Note: [`PartialEq`] is not implemented since it doesn't make sense to +/// compare `Completion` this way. You probably want to use [`ReadRef::ptr_eq`] +/// instead. +#[turbo_tasks::value(cell = "new", eq = "manual")] +#[derive(Debug)] +pub struct Completion; + +#[turbo_tasks::value_impl] +impl Completion { + /// This will always be the same and never invalidates the reading task. + #[turbo_tasks::function] + pub fn immutable() -> Vc { + Completion::cell(Completion) + } +} + +// no #[turbo_tasks::value_impl] to inline new into the caller task +// this ensures it's re-created on each execution +impl Completion { + /// This will always be a new completion and invalidates the reading task. + pub fn new() -> Vc { + Completion::cell(Completion) + } + + /// Uses the previous completion. Can be used to cancel without triggering a + /// new invalidation. + pub fn unchanged() -> Vc { + // This is the same code that Completion::cell uses except that it + // only updates the cell when it is empty (Completion::cell opted-out of + // that via `#[turbo_tasks::value(cell = "new")]`) + let cell = turbo_tasks::macro_helpers::find_cell_by_type(*COMPLETION_VALUE_TYPE_ID); + cell.conditional_update_shared(|old| old.is_none().then_some(Completion)); + let raw: RawVc = cell.into(); + raw.into() + } +} + +#[turbo_tasks::value(transparent)] +pub struct Completions(Vec>); + +#[turbo_tasks::value_impl] +impl Completions { + /// Merges multiple completions into one. The passed list will be part of + /// the cache key, so this function should not be used with varying lists. + /// + /// Varying lists should use `Vc::cell(list).completed()` + /// instead. + #[turbo_tasks::function] + pub fn all(completions: Vec>) -> Vc { + Vc::::cell(completions).completed() + } + + /// Merges the list of completions into one. + #[turbo_tasks::function] + pub async fn completed(self: Vc) -> anyhow::Result> { + self.await? + .iter() + .map(|&c| async move { + c.await?; + Ok(()) + }) + .try_join() + .await?; + Ok(Completion::new()) + } +} diff --git a/turbopack/crates/turbo-tasks/src/debug/internal.rs b/turbopack/crates/turbo-tasks/src/debug/internal.rs new file mode 100644 index 0000000000000..6299dd36828c9 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/debug/internal.rs @@ -0,0 +1,129 @@ +use std::{borrow::Cow, future::Future}; + +use futures::future::join_all; +pub use turbo_tasks_macros::ValueDebug; + +/// Representation of a named field of a structure for formatting purposes of +/// `ValueDebug` implementations. +#[derive(Debug)] +pub struct FormattingField<'a> { + name: &'a str, + contents: String, +} + +impl<'a> FormattingField<'a> { + pub fn new(name: &'a str, contents: String) -> Self { + Self { name, contents } + } +} + +/// Representation of a named field of a structure for formatting purposes of +/// `ValueDebug` implementations. +#[derive(Debug)] +pub struct AsyncFormattingField<'a, Fut> +where + Fut: Future, +{ + name: &'a str, + contents: Fut, +} + +impl<'a, Fut: Future> AsyncFormattingField<'a, Fut> +where + Fut: Future, +{ + pub fn new(name: &'a str, contents: Fut) -> Self { + Self { name, contents } + } + + pub async fn resolve(self) -> FormattingField<'a> { + let Self { name, contents } = self; + FormattingField { + name, + contents: contents.await, + } + } +} + +/// Representation of a structure for formatting purposes of `ValueDebug` +/// implementations. +pub enum FormattingStruct<'a> { + /// Structure with named fields (e.g. `struct Foo { bar: u32 }`). + Named { + name: &'a str, + fields: Vec>, + }, + /// Structure with unnamed fields (e.g. `struct Foo(u32)`, `Foo::Bar(u32)`). + Unnamed { name: &'a str, fields: Vec }, +} + +impl<'a> FormattingStruct<'a> { + pub fn new_named(name: &'a str, fields: Vec>) -> Self { + Self::Named { name, fields } + } + + pub fn new_unnamed(name: &'a str, fields: Vec) -> Self { + Self::Unnamed { name, fields } + } + + pub async fn new_named_async( + name: &'a str, + fields: Vec>>, + ) -> Self { + Self::Named { + name, + fields: join_all(fields.into_iter().map(AsyncFormattingField::resolve)).await, + } + } + + pub async fn new_unnamed_async( + name: &'a str, + fields: Vec>, + ) -> Self { + Self::Unnamed { + name, + fields: join_all(fields).await, + } + } +} + +impl<'a> std::fmt::Debug for FormattingStruct<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FormattingStruct::Named { name, fields } => { + let mut debug_struct = f.debug_struct(name); + for field in fields { + debug_struct.field(field.name, &PassthroughDebug::new_str(&field.contents)); + } + debug_struct.finish() + } + FormattingStruct::Unnamed { name, fields } => { + let mut debug_tuple = f.debug_tuple(name); + for field in fields { + debug_tuple.field(&PassthroughDebug::new_str(field)); + } + debug_tuple.finish() + } + } + } +} + +/// Debug implementation that prints an unquoted, unescaped string. +#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PassthroughDebug<'a>(Cow<'a, str>); + +impl<'a> PassthroughDebug<'a> { + pub fn new_str(s: &'a str) -> Self { + Self(Cow::Borrowed(s)) + } + + pub fn new_string(s: String) -> Self { + Self(Cow::Owned(s)) + } +} + +impl<'a> std::fmt::Debug for PassthroughDebug<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(self.0.as_ref()) + } +} diff --git a/turbopack/crates/turbo-tasks/src/debug/mod.rs b/turbopack/crates/turbo-tasks/src/debug/mod.rs new file mode 100644 index 0000000000000..eb9790ab42d85 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/debug/mod.rs @@ -0,0 +1,393 @@ +use std::fmt::{Debug, Display}; + +use auto_hash_map::{AutoMap, AutoSet}; +use indexmap::{IndexMap, IndexSet}; +use turbo_tasks::Vc; +pub use turbo_tasks_macros::ValueDebugFormat; + +use crate::{self as turbo_tasks}; + +#[doc(hidden)] +pub mod internal; +mod vdbg; + +use internal::PassthroughDebug; + +/// The return type of [`ValueDebug::dbg`]. +/// +/// We don't use [`Vc`][crate::RcStr] or [`String`] directly because we +/// don't want the [`Debug`]/[`Display`] representations to be escaped. +#[turbo_tasks::value] +pub struct ValueDebugString(String); + +impl Debug for ValueDebugString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.0) + } +} + +impl Display for ValueDebugString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&self.0) + } +} + +impl ValueDebugString { + /// Returns the underlying string. + pub fn as_str(&self) -> &str { + &self.0 + } +} + +impl ValueDebugString { + /// Create a new `ValueDebugString` from a string. + pub fn new(s: String) -> Vc { + ValueDebugString::cell(ValueDebugString(s)) + } +} + +/// [`Debug`]-like trait for [`Vc`] types, automatically derived when using +/// [`macro@turbo_tasks::value`] and [`turbo_tasks::value_trait`]. +/// +/// # Usage +/// +/// ```ignore +/// dbg!(any_vc.dbg().await?); +/// ``` +#[turbo_tasks::value_trait(no_debug)] +pub trait ValueDebug { + fn dbg(self: Vc) -> Vc; + + /// Like `dbg`, but with a depth limit. + fn dbg_depth(self: Vc, depth: usize) -> Vc; +} + +/// Use [autoref specialization] to implement [`ValueDebug`] for `T: Debug`. +/// +/// [autoref specialization]: https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md +pub trait ValueDebugFormat { + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString; +} + +impl ValueDebugFormat for String { + fn value_debug_format(&self, _depth: usize) -> ValueDebugFormatString { + ValueDebugFormatString::Sync(format!("{:#?}", self)) + } +} + +// Use autoref specialization [1] to implement `ValueDebugFormat` for `T: +// Debug` as a fallback if `T` does not implement it directly, hence the `for +// &T` clause. +// +// [1] https://github.com/dtolnay/case-studies/blob/master/autoref-specialization/README.md +impl ValueDebugFormat for &T +where + T: Debug, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + ValueDebugFormatString::Sync(format!("{:#?}", self)) + } +} + +impl ValueDebugFormat for Option +where + T: ValueDebugFormat, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + match self { + None => ValueDebugFormatString::Sync(format!("{:#?}", Option::<()>::None)), + Some(value) => match value.value_debug_format(depth.saturating_sub(1)) { + ValueDebugFormatString::Sync(string) => ValueDebugFormatString::Sync(format!( + "{:#?}", + Some(PassthroughDebug::new_string(string)) + )), + ValueDebugFormatString::Async(future) => { + ValueDebugFormatString::Async(Box::pin(async move { + let string = future.await?; + Ok(format!("{:#?}", Some(PassthroughDebug::new_string(string)))) + })) + } + }, + } + } +} + +impl ValueDebugFormat for Vec +where + T: ValueDebugFormat, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + let values = self + .iter() + .map(|value| value.value_debug_format(depth.saturating_sub(1))) + .collect::>(); + + ValueDebugFormatString::Async(Box::pin(async move { + let mut values_string = vec![]; + for value in values { + match value { + ValueDebugFormatString::Sync(string) => { + values_string.push(PassthroughDebug::new_string(string)); + } + ValueDebugFormatString::Async(future) => { + values_string.push(PassthroughDebug::new_string(future.await?)); + } + } + } + Ok(format!("{:#?}", values_string)) + })) + } +} + +impl ValueDebugFormat for AutoSet +where + K: ValueDebugFormat, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + let values = self + .iter() + .map(|item| item.value_debug_format(depth.saturating_sub(1))) + .collect::>(); + + ValueDebugFormatString::Async(Box::pin(async move { + let mut values_string = Vec::with_capacity(values.len()); + for item in values { + match item { + ValueDebugFormatString::Sync(string) => { + values_string.push(PassthroughDebug::new_string(string)); + } + ValueDebugFormatString::Async(future) => { + values_string.push(PassthroughDebug::new_string(future.await?)); + } + } + } + Ok(format!("{:#?}", values_string)) + })) + } +} + +impl ValueDebugFormat for std::collections::HashMap +where + K: Debug, + V: ValueDebugFormat, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + let values = self + .iter() + .map(|(key, value)| { + ( + format!("{:#?}", key), + value.value_debug_format(depth.saturating_sub(1)), + ) + }) + .collect::>(); + + ValueDebugFormatString::Async(Box::pin(async move { + let mut values_string = std::collections::HashMap::new(); + for (key, value) in values { + match value { + ValueDebugFormatString::Sync(string) => { + values_string.insert(key, PassthroughDebug::new_string(string)); + } + ValueDebugFormatString::Async(future) => { + values_string.insert(key, PassthroughDebug::new_string(future.await?)); + } + } + } + Ok(format!("{:#?}", values_string)) + })) + } +} + +impl ValueDebugFormat for AutoMap +where + K: Debug, + V: ValueDebugFormat, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + let values = self + .iter() + .map(|(key, value)| { + ( + format!("{:#?}", key), + value.value_debug_format(depth.saturating_sub(1)), + ) + }) + .collect::>(); + + ValueDebugFormatString::Async(Box::pin(async move { + let mut values_string = AutoMap::new(); + for (key, value) in values { + match value { + ValueDebugFormatString::Sync(string) => { + values_string.insert(key, PassthroughDebug::new_string(string)); + } + ValueDebugFormatString::Async(future) => { + values_string.insert(key, PassthroughDebug::new_string(future.await?)); + } + } + } + Ok(format!("{:#?}", values_string)) + })) + } +} + +impl ValueDebugFormat for IndexSet +where + T: ValueDebugFormat, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + let values = self + .iter() + .map(|value| value.value_debug_format(depth.saturating_sub(1))) + .collect::>(); + + ValueDebugFormatString::Async(Box::pin(async move { + let mut values_string = IndexSet::new(); + for value in values { + let value = match value { + ValueDebugFormatString::Sync(string) => string, + ValueDebugFormatString::Async(future) => future.await?, + }; + values_string.insert(PassthroughDebug::new_string(value)); + } + Ok(format!("{:#?}", values_string)) + })) + } +} + +impl ValueDebugFormat for IndexMap +where + K: ValueDebugFormat, + V: ValueDebugFormat, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + let values = self + .iter() + .map(|(key, value)| { + ( + key.value_debug_format(depth.saturating_sub(1)), + value.value_debug_format(depth.saturating_sub(1)), + ) + }) + .collect::>(); + + ValueDebugFormatString::Async(Box::pin(async move { + let mut values_string = IndexMap::new(); + for (key, value) in values { + let key = match key { + ValueDebugFormatString::Sync(string) => string, + ValueDebugFormatString::Async(future) => future.await?, + }; + let value = match value { + ValueDebugFormatString::Sync(string) => string, + ValueDebugFormatString::Async(future) => future.await?, + }; + values_string.insert( + PassthroughDebug::new_string(key), + PassthroughDebug::new_string(value), + ); + } + Ok(format!("{:#?}", values_string)) + })) + } +} + +macro_rules! tuple_impls { + ( $( $name:ident )+ ) => { + impl<$($name: ValueDebugFormat),+> ValueDebugFormat for ($($name,)+) + { + #[allow(non_snake_case)] + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + if depth == 0 { + return ValueDebugFormatString::Sync(std::any::type_name::().to_string()); + } + + let ($($name,)+) = self; + let ($($name,)+) = ($($name.value_debug_format(depth.saturating_sub(1)),)+); + + ValueDebugFormatString::Async(Box::pin(async move { + let values = ($(PassthroughDebug::new_string($name.try_to_string().await?),)+); + Ok(format!("{:#?}", values)) + })) + } + } + }; +} + +tuple_impls! { A } +tuple_impls! { A B } +tuple_impls! { A B C } +tuple_impls! { A B C D } +tuple_impls! { A B C D E } +tuple_impls! { A B C D E F } +tuple_impls! { A B C D E F G } +tuple_impls! { A B C D E F G H } +tuple_impls! { A B C D E F G H I } +tuple_impls! { A B C D E F G H I J } +tuple_impls! { A B C D E F G H I J K } +tuple_impls! { A B C D E F G H I J K L } + +/// Output of `ValueDebugFormat::value_debug_format`. +pub enum ValueDebugFormatString<'a> { + /// For the `T: Debug` fallback implementation, we can output a string + /// directly as the result of `format!("{:?}", t)`. + Sync(String), + /// For the `Vc` types and `Vc`-containing types implementations, we need to + /// resolve types asynchronously before we can format them, hence the need + /// for a future. + Async( + core::pin::Pin> + Send + 'a>>, + ), +} + +impl<'a> ValueDebugFormatString<'a> { + /// Convert the `ValueDebugFormatString` into a `String`. + /// + /// This can fail when resolving `Vc` types. + pub async fn try_to_string(self) -> anyhow::Result { + Ok(match self { + ValueDebugFormatString::Sync(value) => value, + ValueDebugFormatString::Async(future) => future.await?, + }) + } + + /// Convert the `ValueDebugFormatString` into a `Vc`. + /// + /// This can fail when resolving `Vc` types. + pub async fn try_to_value_debug_string(self) -> anyhow::Result> { + Ok(ValueDebugString::new(self.try_to_string().await?)) + } +} diff --git a/turbopack/crates/turbo-tasks/src/debug/vdbg.rs b/turbopack/crates/turbo-tasks/src/debug/vdbg.rs new file mode 100644 index 0000000000000..8b7407c54910e --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/debug/vdbg.rs @@ -0,0 +1,74 @@ +// NOTE(alexkirsz) Implementation and comments are based on the `dbg!` macro +// from the Rust standard library. +/// This macro supports the same syntax as `dbg!`, but also supports +/// pretty-printing `Vc` types. +/// +/// Beware: this macro should only be used for debugging purposes. Its behavior +/// around dependency tracking is not well-defined and could lead to unexpected +/// results. +#[macro_export] +macro_rules! vdbg { + // NOTE: We cannot use `concat!` to make a static string as a format argument + // of `eprintln!` because `file!` could contain a `{` or + // `$val` expression could be a block (`{ .. }`), in which case the `eprintln!` + // will be malformed. + () => { + eprintln!("[{}:{}]", file!(), line!()) + }; + + (__init $depth:expr ; [ $val:expr $(, $rest:expr)* ] [ $($tt:tt)* ] ) => { + { + let valstr = stringify!($val); + // We move the value into a new binding so we may refer to it multiple + // times without re-evaluating the expression. + let valmove = $val; + // We convert the value to an owned value which will be moved into the + // spawned thread. This is necessary in order to ensure a 'static lifetime + // for the value, but it may require a clone. + let valowned = valmove.to_owned(); + $crate::vdbg!(__init $depth ; [ $($rest),* ] [ $($tt)* valstr valmove valowned ]) + } + }; + (__init $depth:expr ; [ ] [ $($valstr:ident $valmove:ident $valowned:ident)* ] ) => { + { + use $crate::debug::ValueDebugFormat; + let depth = $depth; + $crate::macro_helpers::spawn_detached(async move { + $crate::vdbg!(__expand depth ; [ $($valstr $valowned)* ] []); + Ok(()) + }); + ($($valmove),*) + } + }; + + (__expand $depth:ident ; [ $valstr:ident $val:ident $($rest:tt)* ] [ $($tt:tt)* ]) => { + let valdbg = (&$val).value_debug_format($depth).try_to_string().await?; + $crate::vdbg!(__expand $depth ; [ $($rest)* ] [ $($tt)* $valstr valdbg ]); + }; + (__expand $depth:ident ; [] [ $( $valstr:ident $valdbg:ident )* ]) => { + // By pre-awaiting, then printing everything at once, we ensure that the + // output won't be interleaved with output from other threads, and that + // it will always appear in the order that the macro was invoked. + eprint!( + $crate::vdbg!(__repeat "[{file}:{line}] {} = {}\n" $($valstr)*), + $( + $valstr, + $valdbg, + )* + file = file!(), + line = line!(), + ); + }; + + // Sub-macro for repeating a string N times, where N is controlled by the number of identifiers + // passed to the macro. + (__repeat $str:literal $x:ident $($rest:ident)*) => { concat!($str, $crate::vdbg!(__repeat $str $($rest)*)) }; + (__repeat $str:literal) => { "" }; + + ($($val:expr),* ; depth = $depth:expr) => { + $crate::vdbg!(__init $depth ; [ $($val),* ] []) + }; + ($($val:expr),+ $(,)?) => { + $crate::vdbg!(__init usize::MAX ; [ $($val),* ] []) + }; +} diff --git a/turbopack/crates/turbo-tasks/src/display.rs b/turbopack/crates/turbo-tasks/src/display.rs new file mode 100644 index 0000000000000..78a8e05cb965f --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/display.rs @@ -0,0 +1,8 @@ +use turbo_tasks::Vc; + +use crate::{self as turbo_tasks, RcStr}; + +#[turbo_tasks::value_trait] +pub trait ValueToString { + fn to_string(self: Vc) -> Vc; +} diff --git a/turbopack/crates/turbo-tasks/src/duration_span.rs b/turbopack/crates/turbo-tasks/src/duration_span.rs new file mode 100644 index 0000000000000..3e181ebbdb74f --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/duration_span.rs @@ -0,0 +1,44 @@ +use std::time::Instant; + +/// Guard that emits a tracing event when dropped with the duration of the +/// lifetime of the guard. +pub struct DurationSpanGuard { + start: Instant, + f: Option, +} + +impl DurationSpanGuard { + pub fn new(f: F) -> Self { + Self { + start: Instant::now(), + f: Some(f), + } + } +} + +impl Drop for DurationSpanGuard { + fn drop(&mut self) { + if let Some(f) = self.f.take() { + f(self.start.elapsed().as_micros() as u64); + } + } +} + +/// Creates a event-based span that traces a certain duration (lifetime of the +/// guard). It's not a real span, which means it can be used across threads. It +/// will trace a duration and not the time the cpu is doing actual work. This +/// way it can be used to trace non-cpu-time or time that is spend in other +/// processes. +#[macro_export] +macro_rules! duration_span { + ($name:literal) => { + turbo_tasks::duration_span::DurationSpanGuard::new(|duration| { + turbo_tasks::macro_helpers::tracing::info!(name = $name, duration = duration); + }) + }; + ($name:literal, $($arg:tt)+) => { + turbo_tasks::duration_span::DurationSpanGuard::new(|duration| { + turbo_tasks::macro_helpers::tracing::info!(name = $name, $($arg)+, duration = duration); + }) + }; +} diff --git a/turbopack/crates/turbo-tasks/src/event.rs b/turbopack/crates/turbo-tasks/src/event.rs new file mode 100644 index 0000000000000..b786da1a1fb12 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/event.rs @@ -0,0 +1,211 @@ +#[cfg(feature = "hanging_detection")] +use std::sync::Arc; +#[cfg(feature = "hanging_detection")] +use std::task::ready; +#[cfg(feature = "hanging_detection")] +use std::task::Poll; +#[cfg(feature = "hanging_detection")] +use std::time::Duration; +use std::{ + fmt::{Debug, Formatter}, + future::Future, + mem::replace, + pin::Pin, +}; + +#[cfg(feature = "hanging_detection")] +use tokio::time::timeout; +#[cfg(feature = "hanging_detection")] +use tokio::time::Timeout; + +pub struct Event { + #[cfg(feature = "hanging_detection")] + description: Arc String + Sync + Send>, + event: event_listener::Event, +} + +#[cfg(not(feature = "hanging_detection"))] +impl Event { + /// see [event_listener::Event]::new + #[inline(always)] + pub fn new(_description: impl Fn() -> String + Sync + Send + 'static) -> Self { + Self { + event: event_listener::Event::new(), + } + } + + /// see [event_listener::Event]::listen + pub fn listen(&self) -> EventListener { + EventListener { + listener: self.event.listen(), + } + } + + /// see [event_listener::Event]::listen + pub fn listen_with_note( + &self, + _note: impl Fn() -> String + Sync + Send + 'static, + ) -> EventListener { + EventListener { + listener: self.event.listen(), + } + } + + /// pulls out the event listener, leaving a new, empty event in its place. + pub fn take(&mut self) -> Self { + Self { + event: replace(&mut self.event, event_listener::Event::new()), + } + } +} + +#[cfg(feature = "hanging_detection")] +impl Event { + /// see [event_listener::Event]::new + #[inline(always)] + pub fn new(description: impl Fn() -> String + Sync + Send + 'static) -> Self { + Self { + description: Arc::new(description), + event: event_listener::Event::new(), + } + } + + /// see [event_listener::Event]::listen + pub fn listen(&self) -> EventListener { + EventListener { + description: self.description.clone(), + note: Arc::new(|| String::new()), + future: Some(Box::pin(timeout( + Duration::from_secs(10), + self.event.listen(), + ))), + duration: Duration::from_secs(10), + } + } + + /// see [event_listener::Event]::listen + pub fn listen_with_note( + &self, + note: impl Fn() -> String + Sync + Send + 'static, + ) -> EventListener { + EventListener { + description: self.description.clone(), + note: Arc::new(note), + future: Some(Box::pin(timeout( + Duration::from_secs(10), + self.event.listen(), + ))), + duration: Duration::from_secs(10), + } + } + + /// pulls out the event listener, leaving a new, empty event in its place. + pub fn take(&mut self) -> Event { + Self { + description: self.description.clone(), + event: replace(&mut self.event, event_listener::Event::new()), + } + } +} + +impl Event { + /// see [event_listener::Event]::notify + pub fn notify(&self, n: usize) { + self.event.notify(n); + } +} + +impl Debug for Event { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut t = f.debug_tuple("Event"); + #[cfg(feature = "hanging_detection")] + t.field(&(self.description)()); + t.finish() + } +} + +#[cfg(not(feature = "hanging_detection"))] +pub struct EventListener { + listener: event_listener::EventListener, +} + +#[cfg(not(feature = "hanging_detection"))] +impl Debug for EventListener { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("EventListener").finish() + } +} + +#[cfg(not(feature = "hanging_detection"))] +impl Future for EventListener { + type Output = (); + + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + unsafe { Pin::new_unchecked(&mut self.get_unchecked_mut().listener) }.poll(cx) + } +} + +#[cfg(feature = "hanging_detection")] +pub struct EventListener { + description: Arc String + Sync + Send>, + note: Arc String + Sync + Send>, + // Timeout need to stay pinned while polling and also while it's dropped. + // So it's important to put it into a pinned Box to be able to take it out of the Option. + future: Option>>>, + duration: Duration, +} + +#[cfg(feature = "hanging_detection")] +impl Debug for EventListener { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let mut t = f.debug_tuple("EventListener"); + t.field(&(self.description)()); + let note = (self.note)(); + if !note.is_empty() { + t.field(¬e); + } + t.finish() + } +} + +#[cfg(feature = "hanging_detection")] +impl Future for EventListener { + type Output = (); + + fn poll( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + while let Some(future) = self.future.as_mut() { + match ready!(future.as_mut().poll(cx)) { + Ok(_) => { + self.future = None; + return Poll::Ready(()); + } + Err(_) => { + use crate::util::FormatDuration; + eprintln!( + "{:?} is potentially hanging (waiting for {})", + self, + FormatDuration(self.duration) + ); + self.duration *= 2; + // SAFETY: Taking from Option is safe because the value is inside of a pinned + // Box. Pinning must continue until dropped. + let future = self.future.take().unwrap(); + self.future = Some(Box::pin(timeout( + self.duration, + // SAFETY: We can move the inner future since it's an EventListener and + // that is Unpin. + unsafe { Pin::into_inner_unchecked(future) }.into_inner(), + ))); + } + } + } + // EventListener was awaited again after completion + Poll::Ready(()) + } +} diff --git a/turbopack/crates/turbo-tasks/src/generics/index_map.rs b/turbopack/crates/turbo-tasks/src/generics/index_map.rs new file mode 100644 index 0000000000000..47713c95555dd --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/generics/index_map.rs @@ -0,0 +1,83 @@ +use anyhow::Result; +use indexmap::IndexMap; +// This specific macro identifier is detected by turbo-tasks-build. +use turbo_tasks_macros::generic_type as __turbo_tasks_internal_generic_type; + +use crate::{ + self as turbo_tasks, + debug::{ValueDebug, ValueDebugFormat, ValueDebugString}, + ValueDefault, Vc, +}; + +__turbo_tasks_internal_generic_type!(, IndexMap, Vc>); + +#[turbo_tasks::function] +async fn index_map_len(index_map: Vc, Vc<()>>>) -> Result> { + let index_map = index_map.await?; + Ok(Vc::cell(index_map.len())) +} + +#[turbo_tasks::function] +async fn index_map_is_empty(index_map: Vc, Vc<()>>>) -> Result> { + let index_map = index_map.await?; + Ok(Vc::cell(index_map.is_empty())) +} + +impl Vc, Vc>> +where + K: Send, + V: Send, +{ + /// See [`IndexMap::len`]. + pub fn len(self) -> Vc { + index_map_len(Self::to_repr(self)) + } + + /// See [`IndexMap::is_empty`]. + pub fn is_empty(self) -> Vc { + index_map_is_empty(Self::to_repr(self)) + } +} + +#[turbo_tasks::function] +fn index_map_default() -> Vc, Vc<()>>> { + Vc::cell(Default::default()) +} + +impl ValueDefault for IndexMap, Vc> +where + K: Send, + V: Send, +{ + fn value_default() -> Vc { + // Safety: `index_map_default` creates an empty map, which is a valid + // representation of any index set of `Vc`. + unsafe { Vc::::from_repr(index_map_default()) } + } +} + +#[turbo_tasks::function] +async fn index_map_dbg_depth( + index_map: Vc, Vc<()>>>, + depth: usize, +) -> Result> { + index_map + .await? + .value_debug_format(depth) + .try_to_value_debug_string() + .await +} + +impl ValueDebug for IndexMap, Vc> +where + K: Send, + V: Send, +{ + fn dbg(self: Vc) -> Vc { + index_map_dbg_depth(Vc::::to_repr(self), usize::MAX) + } + + fn dbg_depth(self: Vc, depth: usize) -> Vc { + index_map_dbg_depth(Vc::::to_repr(self), depth) + } +} diff --git a/turbopack/crates/turbo-tasks/src/generics/index_set.rs b/turbopack/crates/turbo-tasks/src/generics/index_set.rs new file mode 100644 index 0000000000000..49e6bce7d4108 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/generics/index_set.rs @@ -0,0 +1,80 @@ +use anyhow::Result; +use indexmap::IndexSet; +// This specific macro identifier is detected by turbo-tasks-build. +use turbo_tasks_macros::generic_type as __turbo_tasks_internal_generic_type; + +use crate::{ + self as turbo_tasks, + debug::{ValueDebug, ValueDebugFormat, ValueDebugString}, + ValueDefault, Vc, +}; + +__turbo_tasks_internal_generic_type!(, IndexSet>); + +#[turbo_tasks::function] +async fn index_set_len(index_set: Vc>>) -> Result> { + let index_set = index_set.await?; + Ok(Vc::cell(index_set.len())) +} + +#[turbo_tasks::function] +async fn index_set_is_empty(index_set: Vc>>) -> Result> { + let index_set = index_set.await?; + Ok(Vc::cell(index_set.is_empty())) +} + +impl Vc>> +where + T: Send, +{ + /// See [`IndexSet::len`]. + pub fn len(self) -> Vc { + index_set_len(Self::to_repr(self)) + } + + /// See [`IndexSet::is_empty`]. + pub fn is_empty(self) -> Vc { + index_set_is_empty(Self::to_repr(self)) + } +} + +#[turbo_tasks::function] +fn index_set_default() -> Vc>> { + Vc::cell(Default::default()) +} + +impl ValueDefault for IndexSet> +where + T: Send, +{ + fn value_default() -> Vc { + // Safety: `index_set_default` creates an empty set, which is a valid + // representation of any index set of `Vc`. + unsafe { Vc::::from_repr(index_set_default()) } + } +} + +#[turbo_tasks::function] +async fn index_set_dbg_depth( + index_set: Vc>>, + depth: usize, +) -> Result> { + index_set + .await? + .value_debug_format(depth) + .try_to_value_debug_string() + .await +} + +impl ValueDebug for IndexSet> +where + T: Send, +{ + fn dbg(self: Vc) -> Vc { + index_set_dbg_depth(Vc::::to_repr(self), usize::MAX) + } + + fn dbg_depth(self: Vc, depth: usize) -> Vc { + index_set_dbg_depth(Vc::::to_repr(self), depth) + } +} diff --git a/turbopack/crates/turbo-tasks/src/generics/mod.rs b/turbopack/crates/turbo-tasks/src/generics/mod.rs new file mode 100644 index 0000000000000..9bbc961eb1b69 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/generics/mod.rs @@ -0,0 +1,4 @@ +pub(crate) mod index_map; +pub(crate) mod index_set; +pub(crate) mod option; +pub(crate) mod vec; diff --git a/turbopack/crates/turbo-tasks/src/generics/option.rs b/turbopack/crates/turbo-tasks/src/generics/option.rs new file mode 100644 index 0000000000000..2b4710ffd3e82 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/generics/option.rs @@ -0,0 +1,79 @@ +use anyhow::Result; +// This specific macro identifier is detected by turbo-tasks-build. +use turbo_tasks_macros::generic_type as __turbo_tasks_internal_generic_type; + +use crate::{ + self as turbo_tasks, + debug::{ValueDebug, ValueDebugFormat, ValueDebugString}, + ValueDefault, Vc, +}; + +__turbo_tasks_internal_generic_type!(, Option>); + +#[turbo_tasks::function] +async fn option_is_none(option: Vc>>) -> Result> { + let option = option.await?; + Ok(Vc::cell(option.is_none())) +} + +#[turbo_tasks::function] +async fn option_is_some(option: Vc>>) -> Result> { + let option = option.await?; + Ok(Vc::cell(option.is_some())) +} + +impl Vc>> +where + T: Send, +{ + /// See [`Option::is_none`]. + pub fn is_none(self) -> Vc { + option_is_none(Self::to_repr(self)) + } + + /// See [`Option::is_some`]. + pub fn is_some(self) -> Vc { + option_is_some(Self::to_repr(self)) + } +} + +#[turbo_tasks::function] +fn option_default() -> Vc>> { + Vc::cell(Default::default()) +} + +impl ValueDefault for Option> +where + T: Send, +{ + fn value_default() -> Vc { + // Safety: `option_default` creates a None variant, which is a valid + // representation of any option of `Vc`. + unsafe { Vc::::from_repr(option_default()) } + } +} + +#[turbo_tasks::function] +async fn option_dbg_depth( + option: Vc>>, + depth: usize, +) -> Result> { + option + .await? + .value_debug_format(depth) + .try_to_value_debug_string() + .await +} + +impl ValueDebug for Option> +where + T: Send, +{ + fn dbg(self: Vc) -> Vc { + option_dbg_depth(Vc::::to_repr(self), usize::MAX) + } + + fn dbg_depth(self: Vc, depth: usize) -> Vc { + option_dbg_depth(Vc::::to_repr(self), depth) + } +} diff --git a/turbopack/crates/turbo-tasks/src/generics/vec.rs b/turbopack/crates/turbo-tasks/src/generics/vec.rs new file mode 100644 index 0000000000000..4472e6b86c9de --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/generics/vec.rs @@ -0,0 +1,75 @@ +use anyhow::Result; +// This specific macro identifier is detected by turbo-tasks-build. +use turbo_tasks_macros::generic_type as __turbo_tasks_internal_generic_type; + +use crate::{ + self as turbo_tasks, + debug::{ValueDebug, ValueDebugFormat, ValueDebugString}, + ValueDefault, Vc, +}; + +__turbo_tasks_internal_generic_type!(, Vec>); + +#[turbo_tasks::function] +async fn vec_len(vec: Vc>>) -> Result> { + let vec = vec.await?; + Ok(Vc::cell(vec.len())) +} + +#[turbo_tasks::function] +async fn vec_is_empty(vec: Vc>>) -> Result> { + let vec = vec.await?; + Ok(Vc::cell(vec.is_empty())) +} + +impl Vc>> +where + T: Send, +{ + /// See [`Vec::len`]. + pub fn len(self) -> Vc { + vec_len(Self::to_repr(self)) + } + + /// See [`Vec::is_empty`]. + pub fn is_empty(self) -> Vc { + vec_is_empty(Self::to_repr(self)) + } +} + +#[turbo_tasks::function] +fn vec_default() -> Vc>> { + Vc::cell(Default::default()) +} + +impl ValueDefault for Vec> +where + T: Send, +{ + fn value_default() -> Vc { + // Safety: `vec_default` creates an empty vector, which is a valid + // representation of any vector of `Vc`s. + unsafe { Vc::::from_repr(vec_default()) } + } +} + +#[turbo_tasks::function] +async fn vec_dbg_depth(vec: Vc>>, depth: usize) -> Result> { + vec.await? + .value_debug_format(depth) + .try_to_value_debug_string() + .await +} + +impl ValueDebug for Vec> +where + T: Send, +{ + fn dbg(self: Vc) -> Vc { + vec_dbg_depth(Vc::::to_repr(self), usize::MAX) + } + + fn dbg_depth(self: Vc, depth: usize) -> Vc { + vec_dbg_depth(Vc::::to_repr(self), depth) + } +} diff --git a/turbopack/crates/turbo-tasks/src/graph/adjacency_map.rs b/turbopack/crates/turbo-tasks/src/graph/adjacency_map.rs new file mode 100644 index 0000000000000..63dbcf4ca0470 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/graph/adjacency_map.rs @@ -0,0 +1,226 @@ +use std::collections::{HashMap, HashSet}; + +use serde::{Deserialize, Serialize}; +use turbo_tasks_macros::{TraceRawVcs, ValueDebugFormat}; + +use super::graph_store::{GraphNode, GraphStore}; +use crate as turbo_tasks; + +/// A graph traversal that builds an adjacency map +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, ValueDebugFormat)] +pub struct AdjacencyMap +where + T: Eq + std::hash::Hash + Clone, +{ + adjacency_map: HashMap>, + roots: Vec, +} + +impl Default for AdjacencyMap +where + T: Eq + std::hash::Hash + Clone, +{ + fn default() -> Self { + Self::new() + } +} + +impl AdjacencyMap +where + T: Eq + std::hash::Hash + Clone, +{ + /// Creates a new adjacency map + pub fn new() -> Self { + Self { + adjacency_map: HashMap::new(), + roots: Vec::new(), + } + } + + /// Returns an iterator over the root nodes of the graph + pub fn roots(&self) -> impl Iterator { + self.roots.iter() + } + + /// Returns an iterator over the children of the given node + pub fn get(&self, node: &T) -> Option> { + self.adjacency_map.get(node).map(|vec| vec.iter()) + } +} + +impl GraphStore for AdjacencyMap +where + T: Eq + std::hash::Hash + Clone, +{ + type Node = T; + type Handle = T; + + fn insert(&mut self, from_handle: Option, node: GraphNode) -> Option<(Self::Handle, &T)> { + let vec = if let Some(from_handle) = from_handle { + self.adjacency_map + .entry(from_handle) + .or_insert_with(|| Vec::with_capacity(1)) + } else { + &mut self.roots + }; + + vec.push(node.node().clone()); + Some((node.into_node(), vec.last().unwrap())) + } +} + +impl AdjacencyMap +where + T: Eq + std::hash::Hash + Clone, +{ + /// Returns an owned iterator over the nodes in reverse topological order, + /// starting from the roots. + pub fn into_reverse_topological(self) -> IntoReverseTopologicalIter { + IntoReverseTopologicalIter { + adjacency_map: self.adjacency_map, + stack: self + .roots + .into_iter() + .rev() + .map(|root| (ReverseTopologicalPass::Pre, root)) + .collect(), + visited: HashSet::new(), + } + } + + /// Returns an iterator over the nodes in reverse topological order, + /// starting from the roots. + pub fn reverse_topological(&self) -> ReverseTopologicalIter { + ReverseTopologicalIter { + adjacency_map: &self.adjacency_map, + stack: self + .roots + .iter() + .rev() + .map(|root| (ReverseTopologicalPass::Pre, root)) + .collect(), + visited: HashSet::new(), + } + } + + /// Returns an iterator over the nodes in reverse topological order, + /// starting from the given node. + pub fn reverse_topological_from_node<'graph>( + &'graph self, + node: &'graph T, + ) -> ReverseTopologicalIter<'graph, T> { + ReverseTopologicalIter { + adjacency_map: &self.adjacency_map, + stack: vec![(ReverseTopologicalPass::Pre, node)], + visited: HashSet::new(), + } + } +} + +#[derive(Debug)] +enum ReverseTopologicalPass { + Pre, + Post, +} + +/// An iterator over the nodes of a graph in reverse topological order, starting +/// from the roots. +pub struct IntoReverseTopologicalIter +where + T: Eq + std::hash::Hash + Clone, +{ + adjacency_map: HashMap>, + stack: Vec<(ReverseTopologicalPass, T)>, + visited: HashSet, +} + +impl Iterator for IntoReverseTopologicalIter +where + T: Eq + std::hash::Hash + Clone, +{ + type Item = T; + + fn next(&mut self) -> Option { + let current = loop { + let (pass, current) = self.stack.pop()?; + + match pass { + ReverseTopologicalPass::Post => { + break current; + } + ReverseTopologicalPass::Pre => { + if self.visited.contains(¤t) { + continue; + } + + self.visited.insert(current.clone()); + + let Some(neighbors) = self.adjacency_map.get(¤t) else { + break current; + }; + + self.stack.push((ReverseTopologicalPass::Post, current)); + self.stack.extend( + neighbors + .iter() + .rev() + .map(|neighbor| (ReverseTopologicalPass::Pre, neighbor.clone())), + ); + } + } + }; + + Some(current) + } +} + +/// An iterator over the nodes of a graph in reverse topological order, starting +/// from the roots. +pub struct ReverseTopologicalIter<'graph, T> +where + T: Eq + std::hash::Hash + Clone, +{ + adjacency_map: &'graph HashMap>, + stack: Vec<(ReverseTopologicalPass, &'graph T)>, + visited: HashSet<&'graph T>, +} + +impl<'graph, T> Iterator for ReverseTopologicalIter<'graph, T> +where + T: Eq + std::hash::Hash + Clone, +{ + type Item = &'graph T; + + fn next(&mut self) -> Option { + let current = loop { + let (pass, current) = self.stack.pop()?; + + match pass { + ReverseTopologicalPass::Post => { + break current; + } + ReverseTopologicalPass::Pre => { + if self.visited.contains(current) { + continue; + } + + self.visited.insert(current); + + let Some(neighbors) = self.adjacency_map.get(current) else { + break current; + }; + + self.stack.push((ReverseTopologicalPass::Post, current)); + self.stack.extend( + neighbors + .iter() + .rev() + .map(|neighbor| (ReverseTopologicalPass::Pre, neighbor)), + ); + } + } + }; + + Some(current) + } +} diff --git a/turbopack/crates/turbo-tasks/src/graph/control_flow.rs b/turbopack/crates/turbo-tasks/src/graph/control_flow.rs new file mode 100644 index 0000000000000..7402d204000bd --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/graph/control_flow.rs @@ -0,0 +1,35 @@ +/// The control flow of visiting an edge during a graph traversal. +pub enum VisitControlFlow { + /// The traversal should continue on the outgoing edges of the given node. + Continue(Node), + /// The traversal should skip visiting the edges the given node. + Skip(Node), + /// The traversal should abort and return immediately. + Abort(Abort), +} + +impl VisitControlFlow { + /// Map the continue and skip values of this control flow. + pub fn map_node(self, mut map: Map) -> VisitControlFlow + where + Map: FnMut(Node) -> Mapped, + { + match self { + VisitControlFlow::Continue(node) => VisitControlFlow::Continue(map(node)), + VisitControlFlow::Skip(node) => VisitControlFlow::Skip(map(node)), + VisitControlFlow::Abort(abort) => VisitControlFlow::Abort(abort), + } + } + + /// Map the abort value of this control flow. + pub fn map_abort(self, mut map: Map) -> VisitControlFlow + where + Map: FnMut(Abort) -> Mapped, + { + match self { + VisitControlFlow::Continue(node) => VisitControlFlow::Continue(node), + VisitControlFlow::Skip(node) => VisitControlFlow::Skip(node), + VisitControlFlow::Abort(abort) => VisitControlFlow::Abort(map(abort)), + } + } +} diff --git a/turbopack/crates/turbo-tasks/src/graph/graph_store.rs b/turbopack/crates/turbo-tasks/src/graph/graph_store.rs new file mode 100644 index 0000000000000..30c43b85faeee --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/graph/graph_store.rs @@ -0,0 +1,101 @@ +use std::collections::HashSet; + +/// A graph store is a data structure that will be built up during a graph +/// traversal. It is used to store the results of the traversal. +pub trait GraphStore { + type Node; + type Handle: Clone; + + // TODO(alexkirsz) An `entry(from_handle) -> Entry` API would be more + // efficient, as right now we're getting the same key multiple times. + /// Inserts a node into the graph store, and returns a handle to it. + /// + /// If this method returns `None`, the node edges will not be visited. + fn insert( + &mut self, + from_handle: Option, + node: GraphNode, + ) -> Option<(Self::Handle, &Self::Node)>; +} + +/// Utility type to ensure that GraphStore::insert can only ever be called from +/// within this module, as a GraphNode can't be constructed outside of it. +#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash, Ord, PartialOrd)] +pub struct GraphNode(pub(super) Node); + +impl GraphNode { + /// Consumes this `GraphNode` and returns the underlying node. + pub fn into_node(self) -> Node { + self.0 + } + + /// Returns a reference the underlying node. + pub fn node(&self) -> &Node { + &self.0 + } + + /// Returns a mutable reference the underlying node. + pub fn node_mut(&mut self) -> &mut Node { + &mut self.0 + } +} + +/// A [`GraphStore`] wrapper that skips nodes that have already been +/// visited. This is necessary to avoid repeated work when traversing non-tree +/// graphs (i.e. where a node can have more than one incoming edge). +#[derive(Debug)] +pub struct SkipDuplicates +where + StoreImpl: GraphStore, +{ + store: StoreImpl, + visited: HashSet, +} + +impl SkipDuplicates +where + StoreImpl: GraphStore, +{ + pub fn new(store: StoreImpl) -> Self { + Self { + store, + visited: Default::default(), + } + } +} + +impl GraphStore for SkipDuplicates +where + StoreImpl: GraphStore, + StoreImpl::Node: Eq + std::hash::Hash + Clone, +{ + type Node = StoreImpl::Node; + type Handle = StoreImpl::Handle; + + fn insert( + &mut self, + from_handle: Option, + node: GraphNode, + ) -> Option<(Self::Handle, &StoreImpl::Node)> { + if !self.visited.contains(node.node()) { + self.visited.insert(node.node().clone()); + self.store.insert(from_handle, node) + } else { + // Always insert the node into the store, even if we've already + // visited it. This is necessary to ensure that the store sees all + // edges. + self.store.insert(from_handle, node); + None + } + } +} + +impl SkipDuplicates +where + StoreImpl: GraphStore, +{ + /// Consumes the wrapper and returns the underlying store. + pub fn into_inner(self) -> StoreImpl { + self.store + } +} diff --git a/turbopack/crates/turbo-tasks/src/graph/graph_traversal.rs b/turbopack/crates/turbo-tasks/src/graph/graph_traversal.rs new file mode 100644 index 0000000000000..d5c1832211aef --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/graph/graph_traversal.rs @@ -0,0 +1,221 @@ +use std::{future::Future, pin::Pin}; + +use anyhow::Result; +use futures::{stream::FuturesUnordered, Stream}; + +use super::{ + graph_store::{GraphNode, GraphStore}, + with_future::With, + SkipDuplicates, Visit, VisitControlFlow, +}; + +/// [`GraphTraversal`] is a utility type that can be used to traverse a graph of +/// nodes, where each node can have a variable number of outgoing edges. The +/// traversal is done in parallel, and the order of the nodes in the traversal +/// result is determined by the [`GraphStore`] parameter. +pub trait GraphTraversal: GraphStore + Sized { + fn visit( + self, + root_edges: RootEdgesIt, + visit: VisitImpl, + ) -> GraphTraversalFuture + where + VisitImpl: Visit, + RootEdgesIt: IntoIterator; + + fn skip_duplicates(self) -> SkipDuplicates; +} + +impl GraphTraversal for Store +where + Store: GraphStore, +{ + /// Visits the graph starting from the given `roots`, and returns a future + /// that will resolve to the traversal result. + fn visit( + mut self, + root_edges: RootEdgesIt, + mut visit: VisitImpl, + ) -> GraphTraversalFuture + where + VisitImpl: Visit, + RootEdgesIt: IntoIterator, + { + let futures = FuturesUnordered::new(); + for edge in root_edges { + match visit.visit(edge) { + VisitControlFlow::Continue(node) => { + if let Some((parent_handle, node_ref)) = self.insert(None, GraphNode(node)) { + let span = visit.span(node_ref); + futures.push(With::new(visit.edges(node_ref), span, parent_handle)); + } + } + VisitControlFlow::Skip(node) => { + self.insert(None, GraphNode(node)); + } + VisitControlFlow::Abort(abort) => { + return GraphTraversalFuture { + state: GraphTraversalState::Aborted { abort }, + }; + } + } + } + GraphTraversalFuture { + state: GraphTraversalState::Running(GraphTraversalRunningState { + store: self, + futures, + visit, + _phantom: std::marker::PhantomData, + }), + } + } + + fn skip_duplicates(self) -> SkipDuplicates { + SkipDuplicates::new(self) + } +} + +/// A future that resolves to a [`GraphStore`] containing the result of a graph +/// traversal. +pub struct GraphTraversalFuture +where + Store: GraphStore, + VisitImpl: Visit, + EdgesFuture: Future, +{ + state: GraphTraversalState, +} + +#[derive(Default)] +enum GraphTraversalState +where + Store: GraphStore, + VisitImpl: Visit, + EdgesFuture: Future, +{ + #[default] + Completed, + Aborted { + abort: Abort, + }, + Running(GraphTraversalRunningState), +} + +struct GraphTraversalRunningState +where + Store: GraphStore, + VisitImpl: Visit, + EdgesFuture: Future, +{ + store: Store, + // This should be VisitImpl::EdgesFuture, but this causes a bug in the Rust + // compiler (see https://github.com/rust-lang/rust/issues/102211). + // Instead, we pass the associated type as an additional generic parameter. + futures: FuturesUnordered>, + visit: VisitImpl, + _phantom: std::marker::PhantomData<(Abort, Impl)>, +} + +pub enum GraphTraversalResult { + Completed(Completed), + Aborted(Aborted), +} + +impl GraphTraversalResult { + pub fn completed(self) -> Completed { + match self { + GraphTraversalResult::Completed(completed) => completed, + GraphTraversalResult::Aborted(_) => unreachable!("the type parameter `Aborted` is `!`"), + } + } +} + +impl Future + for GraphTraversalFuture +where + Store: GraphStore, + // The EdgesFuture bound is necessary to avoid the compiler bug mentioned + // above. + VisitImpl: Visit, + EdgesFuture: Future>, +{ + type Output = GraphTraversalResult, Abort>; + + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + let this = unsafe { self.get_unchecked_mut() }; + + let result; + (this.state, result) = match std::mem::take(&mut this.state) { + GraphTraversalState::Completed => { + panic!("polled after completion") + } + GraphTraversalState::Aborted { abort } => ( + GraphTraversalState::Completed, + std::task::Poll::Ready(GraphTraversalResult::Aborted(abort)), + ), + GraphTraversalState::Running(mut running) => 'outer: loop { + let futures_pin = unsafe { Pin::new_unchecked(&mut running.futures) }; + match futures_pin.poll_next(cx) { + std::task::Poll::Ready(Some((parent_handle, span, Ok(edges)))) => { + let _guard = span.enter(); + for edge in edges { + match running.visit.visit(edge) { + VisitControlFlow::Continue(node) => { + if let Some((node_handle, node_ref)) = running + .store + .insert(Some(parent_handle.clone()), GraphNode(node)) + { + let span = running.visit.span(node_ref); + running.futures.push(With::new( + running.visit.edges(node_ref), + span, + node_handle, + )); + } + } + VisitControlFlow::Skip(node) => { + running + .store + .insert(Some(parent_handle.clone()), GraphNode(node)); + } + VisitControlFlow::Abort(abort) => { + break 'outer ( + GraphTraversalState::Completed, + std::task::Poll::Ready(GraphTraversalResult::Aborted( + abort, + )), + ); + } + } + } + } + std::task::Poll::Ready(Some((_, _, Err(err)))) => { + break ( + GraphTraversalState::Completed, + std::task::Poll::Ready(GraphTraversalResult::Completed(Err(err))), + ); + } + std::task::Poll::Ready(None) => { + break ( + GraphTraversalState::Completed, + std::task::Poll::Ready(GraphTraversalResult::Completed(Ok( + running.store + ))), + ); + } + std::task::Poll::Pending => { + break ( + GraphTraversalState::Running(running), + std::task::Poll::Pending, + ); + } + } + }, + }; + + result + } +} diff --git a/turbopack/crates/turbo-tasks/src/graph/mod.rs b/turbopack/crates/turbo-tasks/src/graph/mod.rs new file mode 100644 index 0000000000000..e2c0754485387 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/graph/mod.rs @@ -0,0 +1,14 @@ +mod adjacency_map; +mod control_flow; +mod graph_store; +mod graph_traversal; +mod non_deterministic; +mod visit; +mod with_future; + +pub use adjacency_map::AdjacencyMap; +pub use control_flow::VisitControlFlow; +pub use graph_store::{GraphStore, SkipDuplicates}; +pub use graph_traversal::{GraphTraversal, GraphTraversalResult}; +pub use non_deterministic::NonDeterministic; +pub use visit::Visit; diff --git a/turbopack/crates/turbo-tasks/src/graph/non_deterministic.rs b/turbopack/crates/turbo-tasks/src/graph/non_deterministic.rs new file mode 100644 index 0000000000000..ef64f514176f4 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/graph/non_deterministic.rs @@ -0,0 +1,42 @@ +use super::graph_store::{GraphNode, GraphStore}; + +/// A graph traversal that does not guarantee any particular order, and may not +/// return the same order every time it is run. +pub struct NonDeterministic { + output: Vec, +} + +impl Default for NonDeterministic { + fn default() -> Self { + Self::new() + } +} + +impl NonDeterministic { + pub fn new() -> Self { + Self { output: Vec::new() } + } +} + +impl GraphStore for NonDeterministic { + type Node = T; + type Handle = (); + + fn insert( + &mut self, + _from_handle: Option, + node: GraphNode, + ) -> Option<(Self::Handle, &T)> { + self.output.push(node.into_node()); + Some(((), self.output.last().unwrap())) + } +} + +impl IntoIterator for NonDeterministic { + type Item = T; + type IntoIter = as IntoIterator>::IntoIter; + + fn into_iter(self) -> Self::IntoIter { + self.output.into_iter() + } +} diff --git a/turbopack/crates/turbo-tasks/src/graph/visit.rs b/turbopack/crates/turbo-tasks/src/graph/visit.rs new file mode 100644 index 0000000000000..d0d0003a709be --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/graph/visit.rs @@ -0,0 +1,80 @@ +use std::future::Future; + +use anyhow::Result; +use tracing::Span; + +use super::VisitControlFlow; + +/// A trait that allows a graph traversal to visit the edges of a node +/// transitively. +pub trait Visit { + type Edge; + type EdgesIntoIter: IntoIterator; + type EdgesFuture: Future>; + + /// Visits an edge to get to the neighbor node. Should return a + /// [`VisitControlFlow`] that indicates whether to: + /// * continue visiting the neighbor node edges; + /// * skip visiting the neighbor node's edges; + /// * abort the traversal entirely. + fn visit(&mut self, edge: Self::Edge) -> VisitControlFlow; + + /// Returns a future that resolves to the outgoing edges of the given + /// `node`. + fn edges(&mut self, node: &Node) -> Self::EdgesFuture; + + /// Returns a [Span] for the given `node`, under which all edges are + /// processed. + fn span(&mut self, node: &Node) -> Span { + let _ = node; + Span::current() + } +} + +// The different `Impl*` here are necessary in order to avoid the `Conflicting +// implementations of trait` error when implementing `Visit` on different +// kinds of `FnMut`. +// See https://users.rust-lang.org/t/conflicting-implementation-when-implementing-traits-for-fn/53359/3 + +pub struct ImplRef; + +impl Visit for VisitFn +where + VisitFn: FnMut(&Node) -> NeighFut, + NeighFut: Future>, + NeighIt: IntoIterator, +{ + type Edge = Node; + type EdgesIntoIter = NeighIt; + type EdgesFuture = NeighFut; + + fn visit(&mut self, edge: Self::Edge) -> VisitControlFlow { + VisitControlFlow::Continue(edge) + } + + fn edges(&mut self, node: &Node) -> Self::EdgesFuture { + (self)(node) + } +} + +pub struct ImplValue; + +impl Visit for VisitFn +where + Node: Clone, + VisitFn: FnMut(Node) -> NeighFut, + NeighFut: Future>, + NeighIt: IntoIterator, +{ + type Edge = Node; + type EdgesIntoIter = NeighIt; + type EdgesFuture = NeighFut; + + fn visit(&mut self, edge: Self::Edge) -> VisitControlFlow { + VisitControlFlow::Continue(edge) + } + + fn edges(&mut self, node: &Node) -> Self::EdgesFuture { + (self)(node.clone()) + } +} diff --git a/turbopack/crates/turbo-tasks/src/graph/with_future.rs b/turbopack/crates/turbo-tasks/src/graph/with_future.rs new file mode 100644 index 0000000000000..76e5a9f69a6f4 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/graph/with_future.rs @@ -0,0 +1,55 @@ +use std::{future::Future, mem::replace}; + +use pin_project_lite::pin_project; +use tracing::Span; + +pin_project! { + pub struct With + where + T: Future, + { + #[pin] + future: T, + span: Span, + handle: Option, + } +} + +impl With +where + T: Future, +{ + pub fn new(future: T, span: Span, handle: H) -> Self { + Self { + future, + span, + handle: Some(handle), + } + } +} + +impl Future for With +where + T: Future, +{ + type Output = (H, Span, T::Output); + + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + let this = self.project(); + let guard = this.span.enter(); + match this.future.poll(cx) { + std::task::Poll::Ready(result) => { + drop(guard); + std::task::Poll::Ready(( + this.handle.take().expect("polled after completion"), + replace(this.span, Span::none()), + result, + )) + } + std::task::Poll::Pending => std::task::Poll::Pending, + } + } +} diff --git a/turbopack/crates/turbo-tasks/src/id.rs b/turbopack/crates/turbo-tasks/src/id.rs new file mode 100644 index 0000000000000..06fff1068d958 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/id.rs @@ -0,0 +1,180 @@ +use std::{ + fmt::{Debug, Display}, + mem::transmute_copy, + num::{NonZero, NonZeroU64, TryFromIntError}, + ops::Deref, +}; + +use serde::{de::Visitor, Deserialize, Serialize}; + +use crate::registry; + +macro_rules! define_id { + ($name:ident : $primitive:ty $(,derive($($derive:ty),*))?) => { + #[derive(Hash, Clone, Copy, PartialEq, Eq, PartialOrd, Ord $($(,$derive)*)? )] + pub struct $name { + id: NonZero<$primitive>, + } + + impl $name { + /// Constructs a wrapper type from the numeric identifier. + /// + /// # Safety + /// + /// The passed `id` must not be zero. + pub unsafe fn new_unchecked(id: $primitive) -> Self { + Self { id: unsafe { NonZero::<$primitive>::new_unchecked(id) } } + } + } + + impl Display for $name { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, concat!(stringify!($name), " {}"), self.id) + } + } + + impl Deref for $name { + type Target = $primitive; + + fn deref(&self) -> &Self::Target { + unsafe { transmute_copy(&&self.id) } + } + } + + /// Converts a numeric identifier to the wrapper type. + /// + /// Panics if the given id value is zero. + impl From<$primitive> for $name { + fn from(id: $primitive) -> Self { + Self { + id: NonZero::<$primitive>::new(id) + .expect("Ids can only be created from non zero values") + } + } + } + + /// Converts a numeric identifier to the wrapper type. + impl TryFrom for $name { + type Error = TryFromIntError; + + fn try_from(id: NonZeroU64) -> Result { + Ok(Self { id: NonZero::try_from(id)? }) + } + } + }; +} + +define_id!(TaskId: u32); +define_id!(FunctionId: u32); +define_id!(ValueTypeId: u32); +define_id!(TraitTypeId: u32); +define_id!(BackendJobId: u32); +define_id!(ExecutionId: u64, derive(Debug)); + +impl Debug for TaskId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TaskId").field("id", &self.id).finish() + } +} + +macro_rules! make_serializable { + ($ty:ty, $get_global_name:path, $get_id:path, $visitor_name:ident) => { + impl Serialize for $ty { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_str($get_global_name(*self)) + } + } + + impl<'de> Deserialize<'de> for $ty { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + deserializer.deserialize_str($visitor_name) + } + } + + struct $visitor_name; + + impl<'de> Visitor<'de> for $visitor_name { + type Value = $ty; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str(concat!("a name of a registered ", stringify!($ty))) + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + $get_id(v).ok_or_else(|| E::unknown_variant(v, &[])) + } + } + + impl Debug for $ty { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct(stringify!($ty)) + .field("id", &self.id) + .field("name", &$get_global_name(*self)) + .finish() + } + } + }; +} + +make_serializable!( + FunctionId, + registry::get_function_global_name, + registry::get_function_id_by_global_name, + FunctionIdVisitor +); +make_serializable!( + ValueTypeId, + registry::get_value_type_global_name, + registry::get_value_type_id_by_global_name, + ValueTypeVisitor +); +make_serializable!( + TraitTypeId, + registry::get_trait_type_global_name, + registry::get_trait_type_id_by_global_name, + TraitTypeVisitor +); + +impl Serialize for TaskId { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_u32(**self) + } +} + +impl<'de> Deserialize<'de> for TaskId { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct V; + + impl Visitor<'_> for V { + type Value = TaskId; + + fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "task id") + } + + fn visit_u32(self, v: u32) -> Result + where + E: serde::de::Error, + { + Ok(TaskId::from(v)) + } + } + + deserializer.deserialize_u64(V) + } +} diff --git a/turbopack/crates/turbo-tasks/src/id_factory.rs b/turbopack/crates/turbo-tasks/src/id_factory.rs new file mode 100644 index 0000000000000..1abce319654b2 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/id_factory.rs @@ -0,0 +1,118 @@ +use std::{ + any::type_name, + marker::PhantomData, + num::NonZeroU64, + sync::atomic::{AtomicU64, Ordering}, +}; + +use concurrent_queue::ConcurrentQueue; + +/// A helper for constructing id types like [`FunctionId`][crate::FunctionId]. +/// +/// For ids that may be re-used, see [`IdFactoryWithReuse`]. +pub struct IdFactory { + next_id: AtomicU64, + _phantom_data: PhantomData, +} + +impl IdFactory { + pub const fn new() -> Self { + Self { + next_id: AtomicU64::new(1), + _phantom_data: PhantomData, + } + } +} + +impl Default for IdFactory { + fn default() -> Self { + Self::new() + } +} + +impl IdFactory +where + T: TryFrom, +{ + /// Return a unique new id. + /// + /// Panics (best-effort) if the id type overflows. + pub fn get(&self) -> T { + // Safety: u64 will not overflow. This is *very* unlikely to happen (would take + // decades). + let new_id = + unsafe { NonZeroU64::new_unchecked(self.next_id.fetch_add(1, Ordering::Relaxed)) }; + + // Use the extra bits of the AtomicU64 as cheap overflow detection when the + // value is less than 64 bits. + match new_id.try_into() { + Ok(id) => id, + Err(_) => panic!( + "Overflow detected while attempting to generate a unique {}", + type_name::(), + ), + } + } +} + +/// An [`IdFactory`], but extended with a free list to allow for id reuse for +/// ids such as [`BackendJobId`][crate::backend::BackendJobId]. +pub struct IdFactoryWithReuse { + factory: IdFactory, + free_ids: ConcurrentQueue, +} + +impl IdFactoryWithReuse { + pub const fn new() -> Self { + Self { + factory: IdFactory::new(), + free_ids: ConcurrentQueue::unbounded(), + } + } +} + +impl Default for IdFactoryWithReuse { + fn default() -> Self { + Self::new() + } +} + +impl IdFactoryWithReuse +where + T: TryFrom, +{ + /// Return a new or potentially reused id. + /// + /// Panics (best-effort) if the id type overflows. + pub fn get(&self) -> T { + self.free_ids.pop().unwrap_or_else(|_| self.factory.get()) + } + + /// Add an id to the free list, allowing it to be re-used on a subsequent + /// call to [`IdFactoryWithReuse::get`]. + /// + /// # Safety + /// + /// It must be ensured that the id is no longer used + pub unsafe fn reuse(&self, id: T) { + let _ = self.free_ids.push(id); + } +} + +#[cfg(test)] +mod tests { + use std::num::NonZeroU8; + + use super::*; + + #[test] + #[should_panic(expected = "Overflow detected")] + fn test_overflow() { + let factory = IdFactory::::new(); + assert_eq!(factory.get(), NonZeroU8::new(1).unwrap()); + assert_eq!(factory.get(), NonZeroU8::new(2).unwrap()); + for _i in 2..256 { + factory.get(); + } + } +} diff --git a/turbopack/crates/turbo-tasks/src/invalidation.rs b/turbopack/crates/turbo-tasks/src/invalidation.rs new file mode 100644 index 0000000000000..9d62cd50cd386 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/invalidation.rs @@ -0,0 +1,190 @@ +use std::{ + any::{Any, TypeId}, + fmt::Display, + hash::{Hash, Hasher}, + mem::replace, +}; + +use indexmap::{map::Entry, IndexMap, IndexSet}; + +use crate::{magic_any::HasherMut, util::StaticOrArc}; + +pub trait DynamicEqHash { + fn as_any(&self) -> &dyn Any; + fn dyn_eq(&self, other: &dyn Any) -> bool; + fn dyn_hash(&self, state: &mut dyn Hasher); +} + +impl DynamicEqHash for T { + fn as_any(&self) -> &dyn Any { + self + } + + fn dyn_eq(&self, other: &dyn Any) -> bool { + other + .downcast_ref::() + .map(|other| self.eq(other)) + .unwrap_or(false) + } + + fn dyn_hash(&self, state: &mut dyn Hasher) { + Hash::hash(&(TypeId::of::(), self), &mut HasherMut(state)); + } +} + +/// A user-facing reason why a task was invalidated. This should only be used +/// for invalidation that were triggered by the user. +/// +/// Reasons are deduplicated, so this need to implement [Eq] and [Hash] +pub trait InvalidationReason: DynamicEqHash + Display + Send + Sync + 'static { + fn kind(&self) -> Option> { + None + } +} + +/// Invalidation reason kind. This is used to merge multiple reasons of the same +/// kind into a combined description. +/// +/// Reason kinds are used a hash map key, so this need to implement [Eq] and +/// [Hash] +pub trait InvalidationReasonKind: DynamicEqHash + Send + Sync + 'static { + /// Displays a description of multiple invalidation reasons of the same + /// kind. It is only called with two or more reasons. + fn fmt( + &self, + data: &IndexSet>, + f: &mut std::fmt::Formatter<'_>, + ) -> std::fmt::Result; +} + +macro_rules! impl_eq_hash { + ($ty:ty) => { + impl PartialEq for $ty { + fn eq(&self, other: &Self) -> bool { + DynamicEqHash::dyn_eq(self, other.as_any()) + } + } + + impl Eq for $ty {} + + impl Hash for $ty { + fn hash(&self, state: &mut H) { + self.as_any().type_id().hash(state); + DynamicEqHash::dyn_hash(self, state as &mut dyn Hasher) + } + } + }; +} + +impl_eq_hash!(dyn InvalidationReason); +impl_eq_hash!(dyn InvalidationReasonKind); + +#[derive(PartialEq, Eq, Hash)] +enum MapKey { + Untyped { + unique_tag: usize, + }, + Typed { + kind: StaticOrArc, + }, +} + +enum MapEntry { + Single { + reason: StaticOrArc, + }, + Multiple { + reasons: IndexSet>, + }, +} + +/// A set of [InvalidationReason]s. They are automatically deduplicated and +/// merged by kind during insertion. It implements [Display] to get a readable +/// representation. +#[derive(Default)] +pub struct InvalidationReasonSet { + next_unique_tag: usize, + // We track typed and untyped entries in the same map to keep the occurence order of entries. + map: IndexMap, +} + +impl InvalidationReasonSet { + pub(crate) fn insert(&mut self, reason: StaticOrArc) { + if let Some(kind) = reason.kind() { + let key = MapKey::Typed { kind }; + match self.map.entry(key) { + Entry::Occupied(mut entry) => { + let entry = &mut *entry.get_mut(); + match replace( + entry, + MapEntry::Multiple { + reasons: IndexSet::new(), + }, + ) { + MapEntry::Single { + reason: existing_reason, + } => { + if reason == existing_reason { + *entry = MapEntry::Single { + reason: existing_reason, + }; + return; + } + let mut reasons = IndexSet::new(); + reasons.insert(existing_reason); + reasons.insert(reason); + *entry = MapEntry::Multiple { reasons }; + } + MapEntry::Multiple { mut reasons } => { + reasons.insert(reason); + *entry = MapEntry::Multiple { reasons }; + } + } + } + Entry::Vacant(entry) => { + entry.insert(MapEntry::Single { reason }); + } + } + } else { + let key = MapKey::Untyped { + unique_tag: self.next_unique_tag, + }; + self.next_unique_tag += 1; + self.map.insert(key, MapEntry::Single { reason }); + } + } + + pub fn is_empty(&self) -> bool { + self.map.is_empty() + } + + pub fn len(&self) -> usize { + self.map.len() + } +} + +impl Display for InvalidationReasonSet { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let count = self.map.len(); + for (i, (key, entry)) in self.map.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + if i == count - 1 { + write!(f, "and ")?; + } + } + match entry { + MapEntry::Single { reason } => { + write!(f, "{}", reason)?; + } + MapEntry::Multiple { reasons } => { + let MapKey::Typed { kind } = key else { + unreachable!("An untyped reason can't collect more than one reason"); + }; + kind.fmt(reasons, f)? + } + } + } + Ok(()) + } +} diff --git a/turbopack/crates/turbo-tasks/src/join_iter_ext.rs b/turbopack/crates/turbo-tasks/src/join_iter_ext.rs new file mode 100644 index 0000000000000..b5b933f028f1c --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/join_iter_ext.rs @@ -0,0 +1,180 @@ +use std::{ + future::{Future, IntoFuture}, + pin::Pin, + task::Poll, +}; + +use anyhow::Result; +use futures::{ + future::{join_all, JoinAll}, + FutureExt, +}; +use pin_project_lite::pin_project; + +pin_project! { + /// Future for the [JoinIterExt::join] method. + pub struct Join + where + F: Future, + { + #[pin] + inner: JoinAll, + } +} + +impl Future for Join +where + F: Future, +{ + type Output = Vec; + + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + self.project().inner.poll(cx) + } +} + +pub trait JoinIterExt: Iterator +where + F: Future, +{ + /// Returns a future that resolves to a vector of the outputs of the futures + /// in the iterator. + fn join(self) -> Join; +} + +pin_project! { + /// Future for the [TryJoinIterExt::try_join] method. + #[must_use] + pub struct TryJoin + where + F: Future, + { + #[pin] + inner: JoinAll, + } +} + +impl Future for TryJoin +where + F: Future>, +{ + type Output = Result>; + + fn poll( + self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll { + match self.project().inner.poll_unpin(cx) { + std::task::Poll::Ready(res) => { + std::task::Poll::Ready(res.into_iter().collect::>>()) + } + std::task::Poll::Pending => std::task::Poll::Pending, + } + } +} + +pub trait TryJoinIterExt: Iterator +where + F: Future>, +{ + /// Returns a future that resolves to a vector of the outputs of the futures + /// in the iterator, or to an error if one of the futures fail. + /// + /// Unlike `Futures::future::try_join_all`, this returns the Error that + /// occurs first in the list of futures, not the first to fail in time. + fn try_join(self) -> TryJoin; +} + +impl JoinIterExt for It +where + F: Future, + IF: IntoFuture, + It: Iterator, +{ + fn join(self) -> Join { + Join { + inner: join_all(self.map(|f| f.into_future())), + } + } +} + +impl TryJoinIterExt for It +where + F: Future>, + IF: IntoFuture, IntoFuture = F>, + It: Iterator, +{ + fn try_join(self) -> TryJoin { + TryJoin { + inner: join_all(self.map(|f| f.into_future())), + } + } +} + +pin_project! { + /// Future for the [TryFlatJoinIterExt::try_flat_join] method. + pub struct TryFlatJoin + where + F: Future, + { + #[pin] + inner: JoinAll, + } +} + +impl Future for TryFlatJoin +where + F: Future>, + I: IntoIterator, + U: Iterator, +{ + type Output = Result>; + + fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { + match self.project().inner.poll_unpin(cx) { + Poll::Ready(res) => { + let mut v = Vec::new(); + for r in res { + v.extend(r?); + } + + Poll::Ready(Ok(v)) + } + Poll::Pending => Poll::Pending, + } + } +} + +pub trait TryFlatJoinIterExt: Iterator +where + F: Future>, + I: IntoIterator, + U: Iterator, +{ + /// Returns a future that resolves to a vector of the outputs of the futures + /// in the iterator, or to an error if one of the futures fail. + /// + /// It also flattens the result. + /// + /// Unlike `Futures::future::try_join_all`, this returns the Error that + /// occurs first in the list of futures, not the first to fail in time. + fn try_flat_join(self) -> TryFlatJoin; +} + +impl TryFlatJoinIterExt for It +where + F: Future>, + IF: IntoFuture, IntoFuture = F>, + It: Iterator, + I: IntoIterator, + U: Iterator, +{ + fn try_flat_join(self) -> TryFlatJoin { + TryFlatJoin { + inner: join_all(self.map(|f| f.into_future())), + } + } +} diff --git a/turbopack/crates/turbo-tasks/src/lib.rs b/turbopack/crates/turbo-tasks/src/lib.rs new file mode 100644 index 0000000000000..198bd4d870045 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/lib.rs @@ -0,0 +1,122 @@ +//! A task scheduling and caching system that is focused on incremental +//! execution. +//! +//! It defines 4 primitives: +//! - functions: Unit of execution, invalidation and reexecution. +//! - values: Data created, stored and returned by functions. +//! - traits: Traits that define a set of functions on values. +//! - collectibles: Values emitted in functions that bubble up the call graph +//! and can be collected in parent functions. +//! +//! It also defines some derived elements from that: +//! - cells: The locations in functions where values are stored. The content of +//! a cell can change after the reexecution of a function. +//! - Vcs: A reference to a cell in a function or a return value of a function. +//! - task: An instance of a function together with its arguments. +//! +//! A Vc can be read to get a read-only reference to the stored data. +//! +//! On execution of functions, turbo-tasks will track which Vcs are read. Once +//! any of these change, turbo-tasks will invalidate the task created from the +//! function's execution and it will eventually be scheduled and reexecuted. +//! +//! Collectibles go through a similar process. + +#![feature(trivial_bounds)] +#![feature(min_specialization)] +#![feature(try_trait_v2)] +#![feature(hash_extract_if)] +#![deny(unsafe_op_in_unsafe_fn)] +#![feature(result_flattening)] +#![feature(error_generic_member_access)] +#![feature(new_uninit)] +#![feature(arbitrary_self_types)] +#![feature(type_alias_impl_trait)] +#![feature(never_type)] +#![feature(impl_trait_in_assoc_type)] + +pub mod backend; +mod capture_future; +mod collectibles; +mod completion; +pub mod debug; +mod display; +pub mod duration_span; +pub mod event; +mod generics; +pub mod graph; +mod id; +mod id_factory; +mod invalidation; +mod join_iter_ext; +#[doc(hidden)] +pub mod macro_helpers; +mod magic_any; +mod manager; +mod native_function; +mod no_move_vec; +mod once_map; +pub mod persisted_graph; +pub mod primitives; +mod raw_vc; +mod rcstr; +mod read_ref; +pub mod registry; +pub mod small_duration; +mod state; +pub mod task; +pub mod trace; +mod trait_helpers; +mod trait_ref; +mod triomphe_utils; +pub mod util; +mod value; +mod value_type; +mod vc; + +use std::hash::BuildHasherDefault; + +pub use anyhow::{Error, Result}; +use auto_hash_map::AutoSet; +pub use collectibles::CollectiblesSource; +pub use completion::{Completion, Completions}; +pub use display::ValueToString; +pub use id::{FunctionId, TaskId, TraitTypeId, ValueTypeId}; +pub use invalidation::{ + DynamicEqHash, InvalidationReason, InvalidationReasonKind, InvalidationReasonSet, +}; +pub use join_iter_ext::{JoinIterExt, TryFlatJoinIterExt, TryJoinIterExt}; +pub use magic_any::MagicAny; +pub use manager::{ + dynamic_call, dynamic_this_call, emit, get_invalidator, mark_finished, mark_stateful, + prevent_gc, run_once, run_once_with_reason, spawn_blocking, spawn_thread, trait_call, + turbo_tasks, CurrentCellRef, Invalidator, TaskIdProvider, TurboTasks, TurboTasksApi, + TurboTasksBackendApi, TurboTasksCallApi, Unused, UpdateInfo, +}; +pub use native_function::NativeFunction; +pub use raw_vc::{CellId, RawVc, ReadRawVcFuture, ResolveTypeError}; +pub use read_ref::ReadRef; +use rustc_hash::FxHasher; +pub use state::State; +pub use task::{task_input::TaskInput, SharedReference}; +pub use trait_ref::{IntoTraitRef, TraitRef}; +pub use turbo_tasks_macros::{function, value, value_impl, value_trait, TaskInput}; +pub use value::{TransientInstance, TransientValue, Value}; +pub use value_type::{TraitMethod, TraitType, ValueType}; +pub use vc::{ + Dynamic, ResolvedValue, ResolvedVc, TypedForInput, Upcast, ValueDefault, Vc, VcCast, + VcCellNewMode, VcCellSharedMode, VcDefaultRead, VcRead, VcTransparentRead, VcValueTrait, + VcValueTraitCast, VcValueType, VcValueTypeCast, +}; + +pub use crate::rcstr::RcStr; + +pub type TaskIdSet = AutoSet, 2>; + +pub mod test_helpers { + pub use super::manager::{current_task_for_testing, with_turbo_tasks_for_testing}; +} + +pub fn register() { + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbo-tasks/src/macro_helpers.rs b/turbopack/crates/turbo-tasks/src/macro_helpers.rs new file mode 100644 index 0000000000000..00b58c2cfbf42 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/macro_helpers.rs @@ -0,0 +1,29 @@ +//! Runtime helpers for [turbo-tasks-macro]. +pub use async_trait::async_trait; +pub use once_cell::sync::{Lazy, OnceCell}; +pub use serde; +pub use tracing; + +pub use super::{ + magic_any::MagicAny, + manager::{find_cell_by_type, notify_scheduled_tasks, spawn_detached}, +}; +use crate::debug::ValueDebugFormatString; + +#[inline(never)] +pub async fn value_debug_format_field(value: ValueDebugFormatString<'_>) -> String { + match value.try_to_value_debug_string().await { + Ok(result) => match result.await { + Ok(result) => result.to_string(), + Err(err) => format!("{0:?}", err), + }, + Err(err) => format!("{0:?}", err), + } +} + +#[macro_export] +macro_rules! stringify_path { + ($path:path) => { + stringify!($path) + }; +} diff --git a/turbopack/crates/turbo-tasks/src/magic_any.rs b/turbopack/crates/turbo-tasks/src/magic_any.rs new file mode 100644 index 0000000000000..7c2af51ef9253 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/magic_any.rs @@ -0,0 +1,218 @@ +use core::fmt; +use std::{ + any::{Any, TypeId}, + fmt::Debug, + hash::{Hash, Hasher}, + ops::DerefMut, + sync::Arc, +}; + +use serde::{de::DeserializeSeed, Deserialize, Serialize}; + +pub trait MagicAny: mopa::Any + Send + Sync { + fn magic_any_arc(self: Arc) -> Arc; + + fn magic_debug(&self, f: &mut fmt::Formatter) -> fmt::Result; + + fn magic_eq(&self, other: &dyn MagicAny) -> bool; + + fn magic_hash(&self, hasher: &mut dyn Hasher); + + #[cfg(debug_assertions)] + fn magic_type_name(&self) -> &'static str; +} + +#[allow(clippy::transmute_ptr_to_ref)] // can't fix as it's in the macro +mod clippy { + use mopa::mopafy; + + use super::MagicAny; + + mopafy!(MagicAny); +} + +impl MagicAny for T { + fn magic_any_arc(self: Arc) -> Arc { + self + } + + fn magic_debug(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut d = f.debug_tuple("MagicAny"); + d.field(&TypeId::of::()); + + #[cfg(debug_assertions)] + d.field(&std::any::type_name::()); + + d.field(&(self as &Self)); + d.finish() + } + + fn magic_eq(&self, other: &dyn MagicAny) -> bool { + match other.downcast_ref::() { + None => false, + Some(other) => self == other, + } + } + + fn magic_hash(&self, hasher: &mut dyn Hasher) { + Hash::hash(&(TypeId::of::(), self), &mut HasherMut(hasher)) + } + + #[cfg(debug_assertions)] + fn magic_type_name(&self) -> &'static str { + std::any::type_name::() + } +} + +impl fmt::Debug for dyn MagicAny { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.magic_debug(f) + } +} + +impl PartialEq for dyn MagicAny { + fn eq(&self, other: &Self) -> bool { + self.magic_eq(other) + } +} + +impl Eq for dyn MagicAny {} + +impl Hash for dyn MagicAny { + fn hash(&self, hasher: &mut H) { + self.magic_hash(hasher) + } +} + +pub struct HasherMut(pub H); + +impl Hasher for HasherMut +where + H::Target: Hasher, +{ + fn finish(&self) -> u64 { + self.0.finish() + } + + fn write(&mut self, bytes: &[u8]) { + self.0.write(bytes) + } +} + +impl dyn MagicAny { + pub fn as_serialize( + &self, + ) -> &dyn erased_serde::Serialize { + if let Some(r) = self.downcast_ref::() { + r + } else { + #[cfg(debug_assertions)] + panic!( + "MagicAny::as_serializable broken: got {} but expected {}", + self.magic_type_name(), + std::any::type_name::() + ); + #[cfg(not(debug_assertions))] + panic!("MagicAny::as_serializable bug"); + } + } +} + +type MagicAnySerializeFunctor = fn(&dyn MagicAny) -> &dyn erased_serde::Serialize; + +#[derive(Clone, Copy)] +pub struct MagicAnySerializeSeed { + functor: MagicAnySerializeFunctor, +} + +impl MagicAnySerializeSeed { + pub fn new() -> Self { + fn serialize( + value: &dyn MagicAny, + ) -> &dyn erased_serde::Serialize { + value.as_serialize::() + } + Self { + functor: serialize::, + } + } + + pub fn as_serialize<'a>(&self, value: &'a dyn MagicAny) -> &'a dyn erased_serde::Serialize { + (self.functor)(value) + } +} + +type MagicAnyDeserializeSeedFunctor = + fn(&mut dyn erased_serde::Deserializer<'_>) -> Result, erased_serde::Error>; + +#[derive(Clone, Copy)] +pub struct MagicAnyDeserializeSeed { + functor: MagicAnyDeserializeSeedFunctor, +} + +impl MagicAnyDeserializeSeed { + pub fn new() -> Self + where + T: for<'de> Deserialize<'de> + Debug + Eq + Hash + Send + Sync + 'static, + { + fn deserialize Deserialize<'de> + Send + Sync + 'static>( + deserializer: &mut dyn erased_serde::Deserializer<'_>, + ) -> Result, erased_serde::Error> { + let value: T = erased_serde::deserialize(deserializer)?; + Ok(Box::new(value)) + } + Self { + functor: deserialize::, + } + } +} + +impl<'de> DeserializeSeed<'de> for MagicAnyDeserializeSeed { + type Value = Box; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let mut deserializer = ::erase(deserializer); + (self.functor)(&mut deserializer).map_err(serde::de::Error::custom) + } +} + +type AnyDeserializeSeedFunctor = fn( + &mut dyn erased_serde::Deserializer<'_>, +) -> Result, erased_serde::Error>; + +#[derive(Clone, Copy)] +pub struct AnyDeserializeSeed { + functor: AnyDeserializeSeedFunctor, +} + +impl AnyDeserializeSeed { + pub fn new() -> Self + where + T: for<'de> Deserialize<'de> + Any + Send + Sync + 'static, + { + fn deserialize Deserialize<'de> + Send + Sync + 'static>( + deserializer: &mut dyn erased_serde::Deserializer<'_>, + ) -> Result, erased_serde::Error> { + let value: T = erased_serde::deserialize(deserializer)?; + Ok(Box::new(value)) + } + Self { + functor: deserialize::, + } + } +} + +impl<'de> DeserializeSeed<'de> for AnyDeserializeSeed { + type Value = Box; + + fn deserialize(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let mut deserializer = ::erase(deserializer); + (self.functor)(&mut deserializer).map_err(serde::de::Error::custom) + } +} diff --git a/turbopack/crates/turbo-tasks/src/manager.rs b/turbopack/crates/turbo-tasks/src/manager.rs new file mode 100644 index 0000000000000..5c0c2f3a5c35c --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/manager.rs @@ -0,0 +1,1603 @@ +use std::{ + borrow::Cow, + cell::RefCell, + future::Future, + hash::{BuildHasherDefault, Hash}, + mem::take, + panic::AssertUnwindSafe, + pin::Pin, + sync::{ + atomic::{AtomicBool, AtomicUsize, Ordering}, + Arc, Mutex, Weak, + }, + thread, + time::{Duration, Instant}, +}; + +use anyhow::{anyhow, Result}; +use auto_hash_map::AutoMap; +use futures::FutureExt; +use rustc_hash::FxHasher; +use serde::{de::Visitor, Deserialize, Serialize}; +use tokio::{runtime::Handle, select, task_local}; +use tracing::{info_span, instrument, trace_span, Instrument, Level}; +use turbo_tasks_malloc::TurboMalloc; + +use crate::{ + backend::{ + Backend, CellContent, PersistentTaskType, TaskCollectiblesMap, TaskExecutionSpec, + TransientTaskType, TypedCellContent, + }, + capture_future::{self, CaptureFuture}, + event::{Event, EventListener}, + id::{BackendJobId, FunctionId, TraitTypeId}, + id_factory::IdFactoryWithReuse, + magic_any::MagicAny, + raw_vc::{CellId, RawVc}, + registry, + trace::TraceRawVcs, + trait_helpers::get_trait_method, + util::StaticOrArc, + vc::ReadVcFuture, + Completion, InvalidationReason, InvalidationReasonSet, SharedReference, TaskId, TaskIdSet, + ValueTypeId, Vc, VcRead, VcValueTrait, VcValueType, +}; + +pub trait TurboTasksCallApi: Sync + Send { + fn dynamic_call(&self, func: FunctionId, arg: Box) -> RawVc; + fn dynamic_this_call(&self, func: FunctionId, this: RawVc, arg: Box) -> RawVc; + fn native_call(&self, func: FunctionId, arg: Box) -> RawVc; + fn this_call(&self, func: FunctionId, this: RawVc, arg: Box) -> RawVc; + fn trait_call( + &self, + trait_type: TraitTypeId, + trait_fn_name: Cow<'static, str>, + this: RawVc, + arg: Box, + ) -> RawVc; + + fn run_once( + &self, + future: Pin> + Send + 'static>>, + ) -> TaskId; + fn run_once_with_reason( + &self, + reason: StaticOrArc, + future: Pin> + Send + 'static>>, + ) -> TaskId; + fn run_once_process( + &self, + future: Pin> + Send + 'static>>, + ) -> TaskId; +} + +pub trait TurboTasksApi: TurboTasksCallApi + Sync + Send { + fn pin(&self) -> Arc; + + fn invalidate(&self, task: TaskId); + fn invalidate_with_reason(&self, task: TaskId, reason: StaticOrArc); + + /// Eagerly notifies all tasks that were scheduled for notifications via + /// `schedule_notify_tasks_set()` + fn notify_scheduled_tasks(&self); + + fn try_read_task_output( + &self, + task: TaskId, + strongly_consistent: bool, + ) -> Result>; + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + fn try_read_task_output_untracked( + &self, + task: TaskId, + strongly_consistent: bool, + ) -> Result>; + + fn try_read_task_cell( + &self, + task: TaskId, + index: CellId, + ) -> Result>; + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + fn try_read_task_cell_untracked( + &self, + task: TaskId, + index: CellId, + ) -> Result>; + + fn read_task_collectibles(&self, task: TaskId, trait_id: TraitTypeId) -> TaskCollectiblesMap; + + fn emit_collectible(&self, trait_type: TraitTypeId, collectible: RawVc); + fn unemit_collectible(&self, trait_type: TraitTypeId, collectible: RawVc, count: u32); + fn unemit_collectibles(&self, trait_type: TraitTypeId, collectibles: &TaskCollectiblesMap); + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + fn try_read_own_task_cell_untracked( + &self, + current_task: TaskId, + index: CellId, + ) -> Result; + + fn read_own_task_cell(&self, task: TaskId, index: CellId) -> Result; + fn update_own_task_cell(&self, task: TaskId, index: CellId, content: CellContent); + fn mark_own_task_as_finished(&self, task: TaskId); + + fn connect_task(&self, task: TaskId); + + /// Wraps the given future in the current task. + fn detached( + &self, + f: Pin> + Send + 'static>>, + ) -> Pin> + Send + 'static>>; +} + +pub trait TaskIdProvider { + fn get_fresh_task_id(&self) -> Unused; + fn reuse_task_id(&self, id: Unused); +} + +impl TaskIdProvider for IdFactoryWithReuse { + fn get_fresh_task_id(&self) -> Unused { + // Safety: This is a fresh id from the factory + unsafe { Unused::new_unchecked(self.get()) } + } + + fn reuse_task_id(&self, id: Unused) { + unsafe { self.reuse(id.into()) } + } +} + +/// A wrapper around a value that is unused. +pub struct Unused { + inner: T, +} + +impl Unused { + /// Creates a new unused value. + /// + /// # Safety + /// + /// The wrapped value must not be used. + pub unsafe fn new_unchecked(inner: T) -> Self { + Self { inner } + } + + /// Get the inner value, without consuming the `Unused` wrapper. + /// + /// # Safety + /// + /// The user need to make sure that the value stays unused. + pub unsafe fn get_unchecked(&self) -> &T { + &self.inner + } + + /// Unwraps the value, consuming the `Unused` wrapper. + pub fn into(self) -> T { + self.inner + } +} + +pub trait TurboTasksBackendApi: + TaskIdProvider + TurboTasksCallApi + Sync + Send +{ + fn pin(&self) -> Arc>; + + fn schedule(&self, task: TaskId); + fn schedule_backend_background_job(&self, id: BackendJobId); + fn schedule_backend_foreground_job(&self, id: BackendJobId); + + fn try_foreground_done(&self) -> Result<(), EventListener>; + fn wait_foreground_done_excluding_own<'a>( + &'a self, + ) -> Option + Send + 'a>>>; + + /// Enqueues tasks for notification of changed dependencies. This will + /// eventually call `invalidate_tasks()` on all tasks. + fn schedule_notify_tasks(&self, tasks: &[TaskId]); + + /// Enqueues tasks for notification of changed dependencies. This will + /// eventually call `invalidate_tasks()` on all tasks. + fn schedule_notify_tasks_set(&self, tasks: &TaskIdSet); + + /// Returns the duration from the start of the program to the given instant. + fn program_duration_until(&self, instant: Instant) -> Duration; + /// Returns a reference to the backend. + fn backend(&self) -> &B; +} + +impl TaskIdProvider for &dyn TurboTasksBackendApi { + fn get_fresh_task_id(&self) -> Unused { + (*self).get_fresh_task_id() + } + + fn reuse_task_id(&self, id: Unused) { + (*self).reuse_task_id(id) + } +} + +impl TaskIdProvider for &dyn TaskIdProvider { + fn get_fresh_task_id(&self) -> Unused { + (*self).get_fresh_task_id() + } + + fn reuse_task_id(&self, id: Unused) { + (*self).reuse_task_id(id) + } +} + +#[allow(clippy::manual_non_exhaustive)] +pub struct UpdateInfo { + pub duration: Duration, + pub tasks: usize, + pub reasons: InvalidationReasonSet, + #[allow(dead_code)] + placeholder_for_future_fields: (), +} + +pub struct TurboTasks { + this: Weak, + backend: B, + task_id_factory: IdFactoryWithReuse, + stopped: AtomicBool, + currently_scheduled_tasks: AtomicUsize, + currently_scheduled_foreground_jobs: AtomicUsize, + currently_scheduled_background_jobs: AtomicUsize, + scheduled_tasks: AtomicUsize, + start: Mutex>, + aggregated_update: Mutex<(Option<(Duration, usize)>, InvalidationReasonSet)>, + event: Event, + event_start: Event, + event_foreground: Event, + event_background: Event, + program_start: Instant, +} + +#[derive(Default)] +struct CurrentTaskState { + /// Affected tasks, that are tracked during task execution. These tasks will + /// be invalidated when the execution finishes or before reading a cell + /// value. + tasks_to_notify: Vec, + + /// True if the current task has state in cells + stateful: bool, +} + +// TODO implement our own thread pool and make these thread locals instead +task_local! { + /// The current TurboTasks instance + static TURBO_TASKS: Arc; + + static CELL_COUNTERS: RefCell, 8>>; + + static CURRENT_TASK_ID: TaskId; + + static CURRENT_TASK_STATE: RefCell; +} + +impl TurboTasks { + // TODO better lifetime management for turbo tasks + // consider using unsafe for the task_local turbo tasks + // that should be safe as long tasks can't outlife turbo task + // so we probably want to make sure that all tasks are joined + // when trying to drop turbo tasks + pub fn new(mut backend: B) -> Arc { + let task_id_factory = IdFactoryWithReuse::new(); + backend.initialize(&task_id_factory); + let this = Arc::new_cyclic(|this| Self { + this: this.clone(), + backend, + task_id_factory, + stopped: AtomicBool::new(false), + currently_scheduled_tasks: AtomicUsize::new(0), + currently_scheduled_background_jobs: AtomicUsize::new(0), + currently_scheduled_foreground_jobs: AtomicUsize::new(0), + scheduled_tasks: AtomicUsize::new(0), + start: Default::default(), + aggregated_update: Default::default(), + event: Event::new(|| "TurboTasks::event".to_string()), + event_start: Event::new(|| "TurboTasks::event_start".to_string()), + event_foreground: Event::new(|| "TurboTasks::event_foreground".to_string()), + event_background: Event::new(|| "TurboTasks::event_background".to_string()), + program_start: Instant::now(), + }); + this.backend.startup(&*this); + this + } + + pub fn pin(&self) -> Arc { + self.this.upgrade().unwrap() + } + + /// Creates a new root task + pub fn spawn_root_task(&self, functor: F) -> TaskId + where + T: Send, + F: Fn() -> Fut + Send + Sync + Clone + 'static, + Fut: Future>> + Send, + { + let id = self.backend.create_transient_task( + TransientTaskType::Root(Box::new(move || { + let functor = functor.clone(); + Box::pin(async move { Ok(functor().await?.node) }) + })), + self, + ); + self.schedule(id); + id + } + + pub fn dispose_root_task(&self, task_id: TaskId) { + self.backend.dispose_root_task(task_id, self); + } + + // TODO make sure that all dependencies settle before reading them + /// Creates a new root task, that is only executed once. + /// Dependencies will not invalidate the task. + #[track_caller] + pub fn spawn_once_task(&self, future: Fut) -> TaskId + where + T: Send, + Fut: Future>> + Send + 'static, + { + let id = self.backend.create_transient_task( + TransientTaskType::Once(Box::pin(async move { Ok(future.await?.node) })), + self, + ); + self.schedule(id); + id + } + + pub async fn run_once( + &self, + future: impl Future> + Send + 'static, + ) -> Result { + let (tx, rx) = tokio::sync::oneshot::channel(); + let task_id = self.spawn_once_task(async move { + let result = future.await?; + tx.send(result) + .map_err(|_| anyhow!("unable to send result"))?; + Ok(Completion::new()) + }); + // INVALIDATION: A Once task will never invalidate, therefore we don't need to + // track a dependency + let raw_result = read_task_output_untracked(self, task_id, false).await?; + ReadVcFuture::::from(raw_result.into_read_untracked_with_turbo_tasks(self)) + .await?; + + Ok(rx.await?) + } + + /// Call a native function with arguments. + /// All inputs must be resolved. + pub(crate) fn native_call(&self, func: FunctionId, arg: Box) -> RawVc { + RawVc::TaskOutput(self.backend.get_or_create_persistent_task( + PersistentTaskType::Native { + fn_type: func, + this: None, + arg, + }, + current_task("turbo_function calls"), + self, + )) + } + + /// Call a native function with arguments. + /// All inputs must be resolved. + pub(crate) fn this_call(&self, func: FunctionId, this: RawVc, arg: Box) -> RawVc { + RawVc::TaskOutput(self.backend.get_or_create_persistent_task( + PersistentTaskType::Native { + fn_type: func, + this: Some(this), + arg, + }, + current_task("turbo_function calls"), + self, + )) + } + + /// Calls a native function with arguments. Resolves arguments when needed + /// with a wrapper task. + pub fn dynamic_call(&self, func: FunctionId, arg: Box) -> RawVc { + if registry::get_function(func).arg_meta.is_resolved(&*arg) { + self.native_call(func, arg) + } else { + RawVc::TaskOutput(self.backend.get_or_create_persistent_task( + PersistentTaskType::ResolveNative { + fn_type: func, + this: None, + arg, + }, + current_task("turbo_function calls"), + self, + )) + } + } + + /// Calls a native function with arguments. Resolves arguments when needed + /// with a wrapper task. + pub fn dynamic_this_call( + &self, + func: FunctionId, + this: RawVc, + arg: Box, + ) -> RawVc { + if this.is_resolved() && registry::get_function(func).arg_meta.is_resolved(&*arg) { + self.this_call(func, this, arg) + } else { + RawVc::TaskOutput(self.backend.get_or_create_persistent_task( + PersistentTaskType::ResolveNative { + fn_type: func, + this: Some(this), + arg, + }, + current_task("turbo_function calls"), + self, + )) + } + } + + /// Calls a trait method with arguments. First input is the `self` object. + /// Uses a wrapper task to resolve + pub fn trait_call( + &self, + trait_type: TraitTypeId, + mut trait_fn_name: Cow<'static, str>, + this: RawVc, + arg: Box, + ) -> RawVc { + // avoid creating a wrapper task if self is already resolved + // for resolved cells we already know the value type so we can lookup the + // function + if let RawVc::TaskCell(_, CellId { type_id, .. }) = this { + match get_trait_method(trait_type, type_id, trait_fn_name) { + Ok(native_fn) => { + return self.dynamic_this_call(native_fn, this, arg); + } + Err(name) => { + trait_fn_name = name; + } + } + } + + // create a wrapper task to resolve all inputs + RawVc::TaskOutput(self.backend.get_or_create_persistent_task( + PersistentTaskType::ResolveTrait { + trait_type, + method_name: trait_fn_name, + this, + arg, + }, + current_task("turbo_function calls"), + self, + )) + } + + #[track_caller] + pub(crate) fn schedule(&self, task_id: TaskId) { + self.begin_primary_job(); + self.scheduled_tasks.fetch_add(1, Ordering::AcqRel); + + #[cfg(feature = "tokio_tracing")] + let description = self.backend.get_task_description(task_id); + + let this = self.pin(); + let future = async move { + #[allow(clippy::blocks_in_conditions)] + while CURRENT_TASK_STATE + .scope(Default::default(), async { + if this.stopped.load(Ordering::Acquire) { + return false; + } + + // Setup thread locals + CELL_COUNTERS + .scope(Default::default(), async { + let Some(TaskExecutionSpec { future, span }) = + this.backend.try_start_task_execution(task_id, &*this) + else { + return false; + }; + + async { + let (result, duration, memory_usage) = + CaptureFuture::new(AssertUnwindSafe(future).catch_unwind()) + .await; + + let result = result.map_err(|any| match any.downcast::() { + Ok(owned) => Some(Cow::Owned(*owned)), + Err(any) => match any.downcast::<&'static str>() { + Ok(str) => Some(Cow::Borrowed(*str)), + Err(_) => None, + }, + }); + this.backend.task_execution_result(task_id, result, &*this); + let stateful = this.finish_current_task_state(); + let cell_counters = + CELL_COUNTERS.with(|cc| take(&mut *cc.borrow_mut())); + let schedule_again = this.backend.task_execution_completed( + task_id, + duration, + memory_usage, + cell_counters, + stateful, + &*this, + ); + // task_execution_completed might need to notify tasks + this.notify_scheduled_tasks(); + schedule_again + } + .instrument(span) + .await + }) + .await + }) + .await + {} + this.finish_primary_job(); + anyhow::Ok(()) + }; + + let future = TURBO_TASKS + .scope( + self.pin(), + CURRENT_TASK_ID.scope(task_id, self.backend.execution_scope(task_id, future)), + ) + .in_current_span(); + + #[cfg(feature = "tokio_tracing")] + tokio::task::Builder::new() + .name(&description) + .spawn(future) + .unwrap(); + #[cfg(not(feature = "tokio_tracing"))] + tokio::task::spawn(future); + } + + fn begin_primary_job(&self) { + if self + .currently_scheduled_tasks + .fetch_add(1, Ordering::AcqRel) + == 0 + { + *self.start.lock().unwrap() = Some(Instant::now()); + self.event_start.notify(usize::MAX); + } + } + + fn begin_foreground_job(&self) { + self.begin_primary_job(); + self.currently_scheduled_foreground_jobs + .fetch_add(1, Ordering::AcqRel); + } + + fn finish_primary_job(&self) { + if self + .currently_scheduled_tasks + .fetch_sub(1, Ordering::AcqRel) + == 1 + { + self.backend.idle_start(self); + // That's not super race-condition-safe, but it's only for + // statistical reasons + let total = self.scheduled_tasks.load(Ordering::Acquire); + self.scheduled_tasks.store(0, Ordering::Release); + if let Some(start) = *self.start.lock().unwrap() { + let (update, _) = &mut *self.aggregated_update.lock().unwrap(); + if let Some(update) = update.as_mut() { + update.0 += start.elapsed(); + update.1 += total; + } else { + *update = Some((start.elapsed(), total)); + } + } + self.event.notify(usize::MAX); + } + } + + fn finish_foreground_job(&self) { + if self + .currently_scheduled_foreground_jobs + .fetch_sub(1, Ordering::AcqRel) + == 1 + { + self.event_foreground.notify(usize::MAX); + } + self.finish_primary_job(); + } + + pub async fn wait_foreground_done(&self) { + if self + .currently_scheduled_foreground_jobs + .load(Ordering::Acquire) + == 0 + { + return; + } + let listener = self.event_foreground.listen(); + if self + .currently_scheduled_foreground_jobs + .load(Ordering::Acquire) + == 0 + { + return; + } + listener + .instrument(trace_span!("wait_foreground_done")) + .await; + } + + pub fn get_in_progress_count(&self) -> usize { + self.currently_scheduled_tasks.load(Ordering::Acquire) + } + + pub async fn wait_task_completion(&self, id: TaskId, fully_settled: bool) -> Result<()> { + // INVALIDATION: This doesn't return a value, only waits for it to be ready. + let result = read_task_output_untracked(self, id, fully_settled).await; + result.map(|_| ()) + } + + #[deprecated(note = "Use get_or_wait_aggregated_update_info instead")] + pub async fn get_or_wait_update_info(&self, aggregation: Duration) -> (Duration, usize) { + let UpdateInfo { + duration, tasks, .. + } = self.get_or_wait_aggregated_update_info(aggregation).await; + (duration, tasks) + } + + #[deprecated(note = "Use aggregated_update_info instead")] + pub async fn update_info( + &self, + aggregation: Duration, + timeout: Duration, + ) -> Option<(Duration, usize)> { + self.aggregated_update_info(aggregation, timeout).await.map( + |UpdateInfo { + duration, tasks, .. + }| (duration, tasks), + ) + } + + /// Returns [UpdateInfo] with all updates aggregated over a given duration + /// (`aggregation`). Will wait until an update happens. + pub async fn get_or_wait_aggregated_update_info(&self, aggregation: Duration) -> UpdateInfo { + self.aggregated_update_info(aggregation, Duration::MAX) + .await + .unwrap() + } + + /// Returns [UpdateInfo] with all updates aggregated over a given duration + /// (`aggregation`). Will only return None when the timeout is reached while + /// waiting for the first update. + pub async fn aggregated_update_info( + &self, + aggregation: Duration, + timeout: Duration, + ) -> Option { + let listener = self + .event + .listen_with_note(|| "wait for update info".to_string()); + let wait_for_finish = { + let (update, reason_set) = &mut *self.aggregated_update.lock().unwrap(); + if aggregation.is_zero() { + if let Some((duration, tasks)) = update.take() { + return Some(UpdateInfo { + duration, + tasks, + reasons: take(reason_set), + placeholder_for_future_fields: (), + }); + } else { + true + } + } else { + update.is_none() + } + }; + if wait_for_finish { + if timeout == Duration::MAX { + // wait for finish + listener.await; + } else { + // wait for start, then wait for finish or timeout + let start_listener = self + .event_start + .listen_with_note(|| "wait for update info".to_string()); + if self.currently_scheduled_tasks.load(Ordering::Acquire) == 0 { + start_listener.await; + } else { + drop(start_listener); + } + if timeout.is_zero() || tokio::time::timeout(timeout, listener).await.is_err() { + // Timeout + return None; + } + } + } + if !aggregation.is_zero() { + loop { + select! { + () = tokio::time::sleep(aggregation) => { + break; + } + () = self.event.listen_with_note(|| "wait for update info".to_string()) => { + // Resets the sleep + } + } + } + } + let (update, reason_set) = &mut *self.aggregated_update.lock().unwrap(); + if let Some((duration, tasks)) = update.take() { + Some(UpdateInfo { + duration, + tasks, + reasons: take(reason_set), + placeholder_for_future_fields: (), + }) + } else { + panic!("aggregated_update_info must not called concurrently") + } + } + + pub async fn wait_background_done(&self) { + let listener = self.event_background.listen(); + if self + .currently_scheduled_background_jobs + .load(Ordering::Acquire) + != 0 + { + listener.await; + } + } + + pub async fn stop_and_wait(&self) { + self.stopped.store(true, Ordering::Release); + { + let listener = self.event.listen_with_note(|| "wait for stop".to_string()); + if self.currently_scheduled_tasks.load(Ordering::Acquire) != 0 { + listener.await; + } + } + { + let listener = self.event_background.listen(); + if self + .currently_scheduled_background_jobs + .load(Ordering::Acquire) + != 0 + { + listener.await; + } + } + self.backend.stop(self); + } + + #[track_caller] + pub(crate) fn schedule_background_job< + T: FnOnce(Arc>) -> F + Send + 'static, + F: Future + Send + 'static, + >( + &self, + func: T, + ) { + let this = self.pin(); + self.currently_scheduled_background_jobs + .fetch_add(1, Ordering::AcqRel); + tokio::spawn( + TURBO_TASKS + .scope(this.clone(), async move { + while this.currently_scheduled_tasks.load(Ordering::Acquire) != 0 { + let listener = this.event.listen_with_note(|| { + "background job waiting for execution".to_string() + }); + if this.currently_scheduled_tasks.load(Ordering::Acquire) != 0 { + listener.await; + } + } + let this2 = this.clone(); + if !this.stopped.load(Ordering::Acquire) { + func(this).await; + } + if this2 + .currently_scheduled_background_jobs + .fetch_sub(1, Ordering::AcqRel) + == 1 + { + this2.event_background.notify(usize::MAX); + } + }) + .in_current_span(), + ); + } + + #[track_caller] + pub(crate) fn schedule_foreground_job< + T: FnOnce(Arc>) -> F + Send + 'static, + F: Future + Send + 'static, + >( + &self, + func: T, + ) { + let this = self.pin(); + this.begin_foreground_job(); + tokio::spawn( + TURBO_TASKS + .scope(this.clone(), async move { + if !this.stopped.load(Ordering::Acquire) { + func(this.clone()).await; + } + this.finish_foreground_job(); + }) + .in_current_span(), + ); + } + + fn finish_current_task_state(&self) -> bool { + let (stateful, tasks) = CURRENT_TASK_STATE.with(|cell| { + let CurrentTaskState { + tasks_to_notify, + stateful, + } = &mut *cell.borrow_mut(); + (*stateful, take(tasks_to_notify)) + }); + + if !tasks.is_empty() { + self.backend.invalidate_tasks(&tasks, self); + } + stateful + } + + pub fn backend(&self) -> &B { + &self.backend + } +} + +impl TurboTasksCallApi for TurboTasks { + fn dynamic_call(&self, func: FunctionId, arg: Box) -> RawVc { + self.dynamic_call(func, arg) + } + fn dynamic_this_call(&self, func: FunctionId, this: RawVc, arg: Box) -> RawVc { + self.dynamic_this_call(func, this, arg) + } + fn native_call(&self, func: FunctionId, arg: Box) -> RawVc { + self.native_call(func, arg) + } + fn this_call(&self, func: FunctionId, this: RawVc, arg: Box) -> RawVc { + self.this_call(func, this, arg) + } + fn trait_call( + &self, + trait_type: TraitTypeId, + trait_fn_name: Cow<'static, str>, + this: RawVc, + arg: Box, + ) -> RawVc { + self.trait_call(trait_type, trait_fn_name, this, arg) + } + + #[track_caller] + fn run_once( + &self, + future: Pin> + Send + 'static>>, + ) -> TaskId { + self.spawn_once_task(async move { + future.await?; + Ok(Completion::new()) + }) + } + + #[track_caller] + fn run_once_with_reason( + &self, + reason: StaticOrArc, + future: Pin> + Send + 'static>>, + ) -> TaskId { + { + let (_, reason_set) = &mut *self.aggregated_update.lock().unwrap(); + reason_set.insert(reason); + } + self.spawn_once_task(async move { + future.await?; + Ok(Completion::new()) + }) + } + + #[track_caller] + fn run_once_process( + &self, + future: Pin> + Send + 'static>>, + ) -> TaskId { + let this = self.pin(); + self.spawn_once_task(async move { + this.finish_primary_job(); + future.await?; + this.begin_primary_job(); + Ok(Completion::new()) + }) + } +} + +impl TurboTasksApi for TurboTasks { + fn pin(&self) -> Arc { + self.pin() + } + + #[instrument(level = Level::INFO, skip_all, name = "invalidate")] + fn invalidate(&self, task: TaskId) { + self.backend.invalidate_task(task, self); + } + + #[instrument(level = Level::INFO, skip_all, name = "invalidate", fields(name = display(&reason)))] + fn invalidate_with_reason(&self, task: TaskId, reason: StaticOrArc) { + { + let (_, reason_set) = &mut *self.aggregated_update.lock().unwrap(); + reason_set.insert(reason); + } + self.backend.invalidate_task(task, self); + } + + fn notify_scheduled_tasks(&self) { + let _ = CURRENT_TASK_STATE.try_with(|cell| { + let tasks = { + let CurrentTaskState { + tasks_to_notify, .. + } = &mut *cell.borrow_mut(); + take(tasks_to_notify) + }; + if tasks.is_empty() { + return; + } + self.backend.invalidate_tasks(&tasks, self); + }); + } + + fn try_read_task_output( + &self, + task: TaskId, + strongly_consistent: bool, + ) -> Result> { + self.backend.try_read_task_output( + task, + current_task("reading Vcs"), + strongly_consistent, + self, + ) + } + + fn try_read_task_output_untracked( + &self, + task: TaskId, + strongly_consistent: bool, + ) -> Result> { + self.backend + .try_read_task_output_untracked(task, strongly_consistent, self) + } + + fn try_read_task_cell( + &self, + task: TaskId, + index: CellId, + ) -> Result> { + self.backend + .try_read_task_cell(task, index, current_task("reading Vcs"), self) + } + + fn try_read_task_cell_untracked( + &self, + task: TaskId, + index: CellId, + ) -> Result> { + self.backend.try_read_task_cell_untracked(task, index, self) + } + + fn try_read_own_task_cell_untracked( + &self, + current_task: TaskId, + index: CellId, + ) -> Result { + self.backend + .try_read_own_task_cell_untracked(current_task, index, self) + } + + fn read_task_collectibles(&self, task: TaskId, trait_id: TraitTypeId) -> TaskCollectiblesMap { + self.backend.read_task_collectibles( + task, + trait_id, + current_task("reading collectibles"), + self, + ) + } + + fn emit_collectible(&self, trait_type: TraitTypeId, collectible: RawVc) { + self.backend.emit_collectible( + trait_type, + collectible, + current_task("emitting collectible"), + self, + ); + } + + fn unemit_collectible(&self, trait_type: TraitTypeId, collectible: RawVc, count: u32) { + self.backend.unemit_collectible( + trait_type, + collectible, + count, + current_task("emitting collectible"), + self, + ); + } + + fn unemit_collectibles(&self, trait_type: TraitTypeId, collectibles: &TaskCollectiblesMap) { + for (&collectible, &count) in collectibles { + if count > 0 { + self.backend.unemit_collectible( + trait_type, + collectible, + count as u32, + current_task("emitting collectible"), + self, + ); + } + } + } + + fn read_own_task_cell(&self, task: TaskId, index: CellId) -> Result { + // INVALIDATION: don't need to track a dependency to itself + self.try_read_own_task_cell_untracked(task, index) + } + + fn update_own_task_cell(&self, task: TaskId, index: CellId, content: CellContent) { + self.backend.update_task_cell(task, index, content, self); + } + + fn connect_task(&self, task: TaskId) { + self.backend + .connect_task(task, current_task("connecting task"), self); + } + + fn mark_own_task_as_finished(&self, task: TaskId) { + self.backend.mark_own_task_as_finished(task, self); + } + + fn detached( + &self, + f: Pin> + Send + 'static>>, + ) -> Pin> + Send + 'static>> { + let current_task_id = CURRENT_TASK_ID.get(); + Box::pin(TURBO_TASKS.scope( + turbo_tasks(), + CURRENT_TASK_ID.scope( + current_task_id, + CELL_COUNTERS.scope( + Default::default(), + self.backend.execution_scope(current_task_id, f), + ), + ), + )) + } +} + +impl TurboTasksBackendApi for TurboTasks { + fn pin(&self) -> Arc> { + self.pin() + } + fn backend(&self) -> &B { + &self.backend + } + #[track_caller] + fn schedule_backend_background_job(&self, id: BackendJobId) { + self.schedule_background_job(move |this| async move { + this.backend.run_backend_job(id, &*this).await; + }) + } + #[track_caller] + fn schedule_backend_foreground_job(&self, id: BackendJobId) { + self.schedule_foreground_job(move |this| async move { + this.backend.run_backend_job(id, &*this).await; + }) + } + + fn try_foreground_done(&self) -> Result<(), EventListener> { + if self + .currently_scheduled_foreground_jobs + .load(Ordering::Acquire) + == 0 + { + return Ok(()); + } + let listener = self.event_foreground.listen(); + if self + .currently_scheduled_foreground_jobs + .load(Ordering::Acquire) + == 0 + { + return Ok(()); + } + Err(listener) + } + + fn wait_foreground_done_excluding_own<'a>( + &'a self, + ) -> Option + Send + 'a>>> { + if self + .currently_scheduled_foreground_jobs + .load(Ordering::Acquire) + == 0 + { + return None; + } + Some(Box::pin(async { + self.finish_foreground_job(); + self.wait_foreground_done().await; + self.begin_foreground_job(); + })) + } + + /// Enqueues tasks for notification of changed dependencies. This will + /// eventually call `dependent_cell_updated()` on all tasks. + fn schedule_notify_tasks(&self, tasks: &[TaskId]) { + let result = CURRENT_TASK_STATE.try_with(|cell| { + let CurrentTaskState { + tasks_to_notify, .. + } = &mut *cell.borrow_mut(); + tasks_to_notify.extend(tasks.iter()); + }); + if result.is_err() { + let _guard = trace_span!("schedule_notify_tasks", count = tasks.len()).entered(); + self.backend.invalidate_tasks(tasks, self); + } + } + + /// Enqueues tasks for notification of changed dependencies. This will + /// eventually call `dependent_cell_updated()` on all tasks. + fn schedule_notify_tasks_set(&self, tasks: &TaskIdSet) { + let result = CURRENT_TASK_STATE.try_with(|cell| { + let CurrentTaskState { + tasks_to_notify, .. + } = &mut *cell.borrow_mut(); + tasks_to_notify.extend(tasks.iter()); + }); + if result.is_err() { + let _guard = trace_span!("schedule_notify_tasks_set", count = tasks.len()).entered(); + self.backend.invalidate_tasks_set(tasks, self); + }; + } + + #[track_caller] + fn schedule(&self, task: TaskId) { + self.schedule(task) + } + + fn program_duration_until(&self, instant: Instant) -> Duration { + instant - self.program_start + } +} + +impl TaskIdProvider for TurboTasks { + fn get_fresh_task_id(&self) -> Unused { + // Safety: This is a fresh id from the factory + unsafe { Unused::new_unchecked(self.task_id_factory.get()) } + } + + fn reuse_task_id(&self, id: Unused) { + unsafe { self.task_id_factory.reuse(id.into()) } + } +} + +pub(crate) fn current_task(from: &str) -> TaskId { + match CURRENT_TASK_ID.try_with(|id| *id) { + Ok(id) => id, + Err(_) => panic!( + "{} can only be used in the context of turbo_tasks task execution", + from + ), + } +} + +pub struct Invalidator { + task: TaskId, + turbo_tasks: Weak, + handle: Handle, +} + +impl Hash for Invalidator { + fn hash(&self, state: &mut H) { + self.task.hash(state); + } +} + +impl PartialEq for Invalidator { + fn eq(&self, other: &Self) -> bool { + self.task == other.task + } +} + +impl Eq for Invalidator {} + +impl Invalidator { + pub fn invalidate(self) { + let Invalidator { + task, + turbo_tasks, + handle, + } = self; + let _ = handle.enter(); + if let Some(turbo_tasks) = turbo_tasks.upgrade() { + turbo_tasks.invalidate(task); + } + } + + pub fn invalidate_with_reason(self, reason: T) { + let Invalidator { + task, + turbo_tasks, + handle, + } = self; + let _ = handle.enter(); + if let Some(turbo_tasks) = turbo_tasks.upgrade() { + turbo_tasks.invalidate_with_reason( + task, + (Arc::new(reason) as Arc).into(), + ); + } + } + + pub fn invalidate_with_static_reason(self, reason: &'static T) { + let Invalidator { + task, + turbo_tasks, + handle, + } = self; + let _ = handle.enter(); + if let Some(turbo_tasks) = turbo_tasks.upgrade() { + turbo_tasks + .invalidate_with_reason(task, (reason as &'static dyn InvalidationReason).into()); + } + } +} + +impl TraceRawVcs for Invalidator { + fn trace_raw_vcs(&self, _context: &mut crate::trace::TraceRawVcsContext) { + // nothing here + } +} + +impl Serialize for Invalidator { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.serialize_newtype_struct("Invalidator", &self.task) + } +} + +impl<'de> Deserialize<'de> for Invalidator { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct V; + + impl<'de> Visitor<'de> for V { + type Value = Invalidator; + + fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "an Invalidator") + } + + fn visit_newtype_struct(self, deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Ok(Invalidator { + task: TaskId::deserialize(deserializer)?, + turbo_tasks: weak_turbo_tasks(), + handle: tokio::runtime::Handle::current(), + }) + } + } + deserializer.deserialize_newtype_struct("Invalidator", V) + } +} + +pub async fn run_once( + tt: Arc, + future: impl Future> + Send + 'static, +) -> Result { + let (tx, rx) = tokio::sync::oneshot::channel(); + + let task_id = tt.run_once(Box::pin(async move { + let result = future.await?; + tx.send(result) + .map_err(|_| anyhow!("unable to send result"))?; + Ok(()) + })); + + // INVALIDATION: A Once task will never invalidate, therefore we don't need to + // track a dependency + let raw_result = read_task_output_untracked(&*tt, task_id, false).await?; + ReadVcFuture::::from(raw_result.into_read_untracked_with_turbo_tasks(&*tt)).await?; + + Ok(rx.await?) +} + +pub async fn run_once_with_reason( + tt: Arc, + reason: impl InvalidationReason, + future: impl Future> + Send + 'static, +) -> Result { + let (tx, rx) = tokio::sync::oneshot::channel(); + + let task_id = tt.run_once_with_reason( + (Arc::new(reason) as Arc).into(), + Box::pin(async move { + let result = future.await?; + tx.send(result) + .map_err(|_| anyhow!("unable to send result"))?; + Ok(()) + }), + ); + + // INVALIDATION: A Once task will never invalidate, therefore we don't need to + // track a dependency + let raw_result = read_task_output_untracked(&*tt, task_id, false).await?; + ReadVcFuture::::from(raw_result.into_read_untracked_with_turbo_tasks(&*tt)).await?; + + Ok(rx.await?) +} + +/// Calls [`TurboTasks::dynamic_call`] for the current turbo tasks instance. +pub fn dynamic_call(func: FunctionId, arg: Box) -> RawVc { + with_turbo_tasks(|tt| tt.dynamic_call(func, arg)) +} + +/// Calls [`TurboTasks::dynamic_this_call`] for the current turbo tasks +/// instance. +pub fn dynamic_this_call(func: FunctionId, this: RawVc, arg: Box) -> RawVc { + with_turbo_tasks(|tt| tt.dynamic_this_call(func, this, arg)) +} + +/// Calls [`TurboTasks::trait_call`] for the current turbo tasks instance. +pub fn trait_call( + trait_type: TraitTypeId, + trait_fn_name: Cow<'static, str>, + this: RawVc, + arg: Box, +) -> RawVc { + with_turbo_tasks(|tt| tt.trait_call(trait_type, trait_fn_name, this, arg)) +} + +pub fn turbo_tasks() -> Arc { + TURBO_TASKS.with(|arc| arc.clone()) +} + +pub fn with_turbo_tasks(func: impl FnOnce(&Arc) -> T) -> T { + TURBO_TASKS.with(|arc| func(arc)) +} + +pub fn weak_turbo_tasks() -> Weak { + TURBO_TASKS.with(Arc::downgrade) +} + +pub fn with_turbo_tasks_for_testing( + tt: Arc, + current_task: TaskId, + f: impl Future, +) -> impl Future { + TURBO_TASKS.scope( + tt, + CURRENT_TASK_ID.scope(current_task, CELL_COUNTERS.scope(Default::default(), f)), + ) +} + +/// Spawns the given future within the context of the current task. +/// +/// Beware: this method is not safe to use in production code. It is only +/// intended for use in tests and for debugging purposes. +pub fn spawn_detached(f: impl Future> + Send + 'static) { + tokio::spawn(turbo_tasks().detached(Box::pin(f.in_current_span()))); +} + +pub fn current_task_for_testing() -> TaskId { + CURRENT_TASK_ID.with(|id| *id) +} + +/// Get an [`Invalidator`] that can be used to invalidate the current task +/// based on external events. +pub fn get_invalidator() -> Invalidator { + let handle = Handle::current(); + Invalidator { + task: current_task("turbo_tasks::get_invalidator()"), + turbo_tasks: weak_turbo_tasks(), + handle, + } +} + +/// Marks the current task as finished. This excludes it from waiting for +/// strongly consistency. +pub fn mark_finished() { + with_turbo_tasks(|tt| { + tt.mark_own_task_as_finished(current_task("turbo_tasks::mark_finished()")) + }); +} + +/// Marks the current task as stateful. This prevents the tasks from being +/// dropped without persisting the state. +pub fn mark_stateful() { + CURRENT_TASK_STATE.with(|cell| { + let CurrentTaskState { stateful, .. } = &mut *cell.borrow_mut(); + *stateful = true; + }) +} + +pub fn prevent_gc() { + mark_stateful(); +} + +/// Notifies scheduled tasks for execution. +pub fn notify_scheduled_tasks() { + with_turbo_tasks(|tt| tt.notify_scheduled_tasks()) +} + +pub fn emit(collectible: Vc) { + with_turbo_tasks(|tt| tt.emit_collectible(T::get_trait_type_id(), collectible.node)) +} + +pub async fn spawn_blocking(func: impl FnOnce() -> T + Send + 'static) -> T { + let span = trace_span!("blocking operation").or_current(); + let (result, duration, alloc_info) = tokio::task::spawn_blocking(|| { + let _guard = span.entered(); + let start = Instant::now(); + let start_allocations = TurboMalloc::allocation_counters(); + let r = func(); + (r, start.elapsed(), start_allocations.until_now()) + }) + .await + .unwrap(); + capture_future::add_duration(duration); + capture_future::add_allocation_info(alloc_info); + result +} + +pub fn spawn_thread(func: impl FnOnce() + Send + 'static) { + let handle = Handle::current(); + let span = info_span!("thread").or_current(); + thread::spawn(move || { + let span = span.entered(); + let guard = handle.enter(); + func(); + drop(guard); + drop(span); + }); +} + +pub(crate) async fn read_task_output( + this: &dyn TurboTasksApi, + id: TaskId, + strongly_consistent: bool, +) -> Result { + loop { + match this.try_read_task_output(id, strongly_consistent)? { + Ok(result) => return Ok(result), + Err(listener) => listener.await, + } + } +} + +/// INVALIDATION: Be careful with this, it will not track dependencies, so +/// using it could break cache invalidation. +pub(crate) async fn read_task_output_untracked( + this: &dyn TurboTasksApi, + id: TaskId, + strongly_consistent: bool, +) -> Result { + loop { + match this.try_read_task_output_untracked(id, strongly_consistent)? { + Ok(result) => return Ok(result), + Err(listener) => listener.await, + } + } +} + +pub(crate) async fn read_task_cell( + this: &dyn TurboTasksApi, + id: TaskId, + index: CellId, +) -> Result { + loop { + match this.try_read_task_cell(id, index)? { + Ok(result) => return Ok(result), + Err(listener) => listener.await, + } + } +} + +#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub struct CurrentCellRef { + current_task: TaskId, + index: CellId, +} + +impl CurrentCellRef { + pub fn conditional_update_shared< + T: VcValueType + 'static, + F: FnOnce(Option<&T>) -> Option, + >( + &self, + functor: F, + ) { + let tt = turbo_tasks(); + let content = tt + .read_own_task_cell(self.current_task, self.index) + .ok() + .and_then(|v| v.try_cast::()); + let update = + functor(content.as_deref().map(|content| { + <::Read as VcRead>::target_to_value_ref(content) + })); + if let Some(update) = update { + tt.update_own_task_cell( + self.current_task, + self.index, + CellContent(Some(SharedReference::new(triomphe::Arc::new(update)))), + ) + } + } + + pub fn compare_and_update_shared(&self, new_content: T) { + self.conditional_update_shared(|old_content| { + if let Some(old_content) = old_content { + if PartialEq::eq(&new_content, old_content) { + return None; + } + } + Some(new_content) + }); + } + + pub fn update_shared(&self, new_content: T) { + let tt = turbo_tasks(); + tt.update_own_task_cell( + self.current_task, + self.index, + CellContent(Some(SharedReference::new(triomphe::Arc::new(new_content)))), + ) + } + + pub fn update_shared_reference(&self, shared_ref: SharedReference) { + let tt = turbo_tasks(); + let content = tt.read_own_task_cell(self.current_task, self.index).ok(); + let update = if let Some(TypedCellContent(_, CellContent(shared_ref_exp))) = content { + shared_ref_exp.as_ref().ne(&Some(&shared_ref)) + } else { + true + }; + if update { + tt.update_own_task_cell(self.current_task, self.index, CellContent(Some(shared_ref))) + } + } +} + +impl From for RawVc { + fn from(cell: CurrentCellRef) -> Self { + RawVc::TaskCell(cell.current_task, cell.index) + } +} + +pub fn find_cell_by_type(ty: ValueTypeId) -> CurrentCellRef { + CELL_COUNTERS.with(|cell| { + let current_task = current_task("celling turbo_tasks values"); + let mut map = cell.borrow_mut(); + let current_index = map.entry(ty).or_default(); + let index = *current_index; + *current_index += 1; + CurrentCellRef { + current_task, + index: CellId { type_id: ty, index }, + } + }) +} diff --git a/turbopack/crates/turbo-tasks/src/native_function.rs b/turbopack/crates/turbo-tasks/src/native_function.rs new file mode 100644 index 0000000000000..6a774fc6272e6 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/native_function.rs @@ -0,0 +1,184 @@ +use std::{fmt::Debug, hash::Hash, pin::Pin}; + +use anyhow::{Context, Result}; +use futures::Future; +use serde::{Deserialize, Serialize}; +use tracing::Span; + +use crate::{ + self as turbo_tasks, + magic_any::{MagicAny, MagicAnyDeserializeSeed, MagicAnySerializeSeed}, + registry::register_function, + task::{ + function::{IntoTaskFnWithThis, NativeTaskFuture}, + IntoTaskFn, TaskFn, + }, + RawVc, TaskInput, +}; + +type ResolveFunctor = + for<'a> fn( + &'a dyn MagicAny, + ) -> Pin>> + Send + 'a>>; + +type IsResolvedFunctor = fn(&dyn MagicAny) -> bool; + +pub struct ArgMeta { + serializer: MagicAnySerializeSeed, + deserializer: MagicAnyDeserializeSeed, + is_resolved: IsResolvedFunctor, + resolve: ResolveFunctor, +} + +impl ArgMeta { + pub fn new() -> Self + where + T: TaskInput + Serialize + for<'de> Deserialize<'de> + 'static, + { + fn downcast(value: &dyn MagicAny) -> &T + where + T: MagicAny, + { + value + .downcast_ref::() + .with_context(|| { + #[cfg(debug_assertions)] + return format!( + "Invalid argument type, expected {} got {}", + std::any::type_name::(), + value.magic_type_name() + ); + #[cfg(not(debug_assertions))] + return "Invalid argument type"; + }) + .unwrap() + } + Self { + serializer: MagicAnySerializeSeed::new::(), + deserializer: MagicAnyDeserializeSeed::new::(), + is_resolved: |value| downcast::(value).is_resolved(), + resolve: |value| { + Box::pin(async { + let value = downcast::(value); + let resolved = value.resolve().await?; + Ok(Box::new(resolved) as Box) + }) + }, + } + } + + pub fn deserialization_seed(&self) -> MagicAnyDeserializeSeed { + self.deserializer + } + + pub fn as_serialize<'a>(&self, value: &'a dyn MagicAny) -> &'a dyn erased_serde::Serialize { + self.serializer.as_serialize(value) + } + + pub fn is_resolved(&self, value: &dyn MagicAny) -> bool { + (self.is_resolved)(value) + } + + pub async fn resolve(&self, value: &dyn MagicAny) -> Result> { + (self.resolve)(value).await + } +} + +/// A native (rust) turbo-tasks function. It's used internally by +/// `#[turbo_tasks::function]`. +#[turbo_tasks::value(cell = "new", serialization = "none", eq = "manual")] +pub struct NativeFunction { + /// A readable name of the function that is used to reporting purposes. + pub name: String, + /// The functor that creates a functor from inputs. The inner functor + /// handles the task execution. + #[turbo_tasks(debug_ignore, trace_ignore)] + pub implementation: Box, + + #[turbo_tasks(debug_ignore, trace_ignore)] + pub arg_meta: ArgMeta, +} + +impl Debug for NativeFunction { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("NativeFunction") + .field("name", &self.name) + .finish_non_exhaustive() + } +} + +impl NativeFunction { + pub fn new_function(name: String, implementation: I) -> Self + where + Inputs: TaskInput + Serialize + for<'de> Deserialize<'de> + 'static, + I: IntoTaskFn, + { + Self { + name, + implementation: Box::new(implementation.into_task_fn()), + arg_meta: ArgMeta::new::(), + } + } + + pub fn new_method(name: String, implementation: I) -> Self + where + This: Sync + Send + 'static, + Inputs: TaskInput + Serialize + for<'de> Deserialize<'de> + 'static, + I: IntoTaskFnWithThis, + { + Self { + name, + implementation: Box::new(implementation.into_task_fn_with_this()), + arg_meta: ArgMeta::new::(), + } + } + + /// Executed the function + pub fn execute(&'static self, this: Option, arg: &dyn MagicAny) -> NativeTaskFuture { + match (self.implementation).functor(this, arg) { + Ok(functor) => functor, + Err(err) => Box::pin(async { Err(err) }), + } + } + + pub fn span(&'static self) -> Span { + tracing::trace_span!("turbo_tasks::function", name = self.name.as_str()) + } + + pub fn resolve_span(&'static self) -> Span { + tracing::trace_span!("turbo_tasks::resolve_call", name = self.name.as_str()) + } + + pub fn register(&'static self, global_name: &'static str) { + register_function(global_name, self); + } +} + +impl PartialEq for &'static NativeFunction { + fn eq(&self, other: &Self) -> bool { + std::ptr::eq(*self, *other) + } +} + +impl Eq for &'static NativeFunction {} + +impl Hash for &'static NativeFunction { + fn hash(&self, state: &mut H) { + Hash::hash(&(*self as *const NativeFunction), state); + } +} + +impl PartialOrd for &'static NativeFunction { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for &'static NativeFunction { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + Ord::cmp( + &(*self as *const NativeFunction), + &(*other as *const NativeFunction), + ) + } +} diff --git a/turbopack/crates/turbo-tasks/src/no_move_vec.rs b/turbopack/crates/turbo-tasks/src/no_move_vec.rs new file mode 100644 index 0000000000000..830b809dbe520 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/no_move_vec.rs @@ -0,0 +1,305 @@ +use std::{ + ptr::null_mut, + slice::from_raw_parts_mut, + sync::{ + atomic::{AtomicPtr, Ordering}, + Mutex, + }, +}; + +const BUCKETS: usize = (usize::BITS + 1) as usize; + +/// An `Option`-like type that guarantees that a fully zeroed value is a valid +/// `None` variant. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +#[repr(u8)] +enum COption { + // TODO(alexkirsz) We need a way to guarantee that a fully zeroed value is a + // valid `None` variant. This is theoretically possible when the wrapped + // type has no valid value that can be represented by all zeros, but there + // is no way to enforce this at the type level. For now, we just use a custom + // option type with explicit discriminant for the `None` variant. + // The issue with this implementation is that it disables niche optimization. + None = 0, + Some(T), +} + +impl Default for COption { + fn default() -> Self { + Self::None + } +} + +impl COption { + /// Returns a slice of the given size filled with the `None` variant. + fn new_none_slice(size: usize) -> Box<[Self]> { + let slice = Box::<[COption]>::new_zeroed_slice(size); + // Safety: + // We know that a zeroed COption is a valid COption::None value. + unsafe { slice.assume_init() } + } + + /// Returns a reference to the contained value, or `None` if it is `None`. + fn as_option_ref(&self) -> Option<&T> { + match self { + COption::None => None, + COption::Some(t) => Some(t), + } + } + + /// Takes the value out of the option, leaving a `None` in its place. + fn take(&mut self) -> Option { + match std::mem::take(self) { + COption::None => None, + COption::Some(t) => Some(t), + } + } +} + +impl COption { + /// Returns a slice of the given size filled with the `Some` variant and + /// filled with default values. + fn new_default_slice(size: usize) -> Box<[Self]> { + (0..size) + .map(|_| COption::Some(Default::default())) + .collect::>() + .into_boxed_slice() + } +} + +pub struct NoMoveVec { + buckets: [(AtomicPtr>, Mutex<()>); BUCKETS], +} + +fn get_bucket_index(idx: usize) -> u32 { + (usize::BITS - idx.leading_zeros()).saturating_sub(INITIAL_CAPACITY_BITS) +} + +fn get_bucket_size(bucket_index: u32) -> usize { + if bucket_index != 0 { + 1 << (bucket_index + INITIAL_CAPACITY_BITS - 1) + } else { + 1 << INITIAL_CAPACITY_BITS + } +} + +fn get_index_in_bucket(idx: usize, bucket_index: u32) -> usize { + if bucket_index != 0 { + idx ^ (1 << (bucket_index + INITIAL_CAPACITY_BITS - 1)) + } else { + idx + } +} + +/// Allocates a new bucket of `COption`s, all initialized to `None`. +fn allocate_bucket(bucket_index: u32) -> *mut COption { + let size = get_bucket_size::(bucket_index); + let slice = COption::::new_none_slice(size); + Box::into_raw(slice) as *mut COption +} + +/// Allocates a new bucket of `COption`s, all initialized to `None`. +fn allocate_default_bucket( + bucket_index: u32, +) -> *mut COption { + let size = get_bucket_size::(bucket_index); + let slice = COption::::new_default_slice(size); + Box::into_raw(slice) as *mut COption +} + +impl Default for NoMoveVec { + fn default() -> Self { + Self::new() + } +} + +impl NoMoveVec { + pub fn new() -> Self { + let mut buckets = [null_mut(); BUCKETS]; + buckets[0] = allocate_bucket::(0); + let buckets = buckets.map(|p| (AtomicPtr::new(p), Mutex::new(()))); + NoMoveVec { buckets } + } + + pub fn get(&self, idx: usize) -> Option<&T> { + let bucket_idx = get_bucket_index::(idx); + let bucket_ptr = unsafe { self.buckets.get_unchecked(bucket_idx as usize) } + .0 + .load(Ordering::Acquire); + if bucket_ptr.is_null() { + return None; + } + let index = get_index_in_bucket::(idx, bucket_idx); + unsafe { &*bucket_ptr.add(index) }.as_option_ref() + } + + /// # Safety + /// There must not be a concurrent operation to this idx + pub unsafe fn take(&self, idx: usize) -> Option { + let bucket_idx = get_bucket_index::(idx); + let bucket = unsafe { self.buckets.get_unchecked(bucket_idx as usize) }; + let bucket_ptr = bucket.0.load(Ordering::Acquire); + if bucket_ptr.is_null() { + return None; + } + let index = get_index_in_bucket::(idx, bucket_idx); + let item = unsafe { &mut *bucket_ptr.add(index) }; + let item = item.take(); + // To sync with any acquire load of the bucket ptr + bucket.0.store(bucket_ptr, Ordering::Release); + item + } + + /// # Safety + /// There must not be a concurrent operation to this idx + pub unsafe fn insert(&self, idx: usize, value: T) -> &T { + let bucket_idx = get_bucket_index::(idx); + let bucket = unsafe { self.buckets.get_unchecked(bucket_idx as usize) }; + // SAFETY: This is safe to be relaxed as the bucket will never become null + // again. We perform a acquire load when it's null. + let mut bucket_ptr = bucket.0.load(Ordering::Relaxed); + if bucket_ptr.is_null() { + bucket_ptr = bucket.0.load(Ordering::Acquire); + if bucket_ptr.is_null() { + let lock = bucket.1.lock(); + let guarded_bucket_ptr = bucket.0.load(Ordering::Acquire); + if guarded_bucket_ptr.is_null() { + let new_bucket = allocate_bucket::(bucket_idx); + bucket_ptr = match bucket.0.compare_exchange( + null_mut(), + new_bucket, + Ordering::AcqRel, + Ordering::Relaxed, + ) { + Ok(_) => new_bucket, + Err(current_bucket) => { + drop(unsafe { Box::from_raw(new_bucket) }); + current_bucket + } + }; + drop(lock); + } else { + bucket_ptr = guarded_bucket_ptr; + } + } + } + let index = get_index_in_bucket::(idx, bucket_idx); + let item = unsafe { &mut *bucket_ptr.add(index) }; + *item = COption::Some(value); + // To sync with any acquire load of the bucket ptr + bucket.0.store(bucket_ptr, Ordering::Release); + item.as_option_ref().unwrap() + } + + /// # Safety + /// There must not be a concurrent operation to this idx + pub unsafe fn remove(&self, idx: usize) { + let bucket_idx = get_bucket_index::(idx); + let bucket = unsafe { self.buckets.get_unchecked(bucket_idx as usize) }; + let bucket_ptr = bucket.0.load(Ordering::Acquire); + if bucket_ptr.is_null() { + return; + } + let index = get_index_in_bucket::(idx, bucket_idx); + let item = unsafe { &mut *bucket_ptr.add(index) }; + *item = COption::None; + // To sync with any acquire load of the bucket ptr + bucket.0.store(bucket_ptr, Ordering::Release); + } +} + +impl NoMoveVec { + pub fn new_init_default() -> Self { + let mut buckets = [null_mut(); BUCKETS]; + buckets[0] = allocate_default_bucket::(0); + let buckets = buckets.map(|p| (AtomicPtr::new(p), Mutex::new(()))); + NoMoveVec { buckets } + } + + pub fn get_init_default(&self, idx: usize) -> &T { + let bucket_idx = get_bucket_index::(idx); + let bucket = unsafe { self.buckets.get_unchecked(bucket_idx as usize) }; + // SAFETY: This is safe to be relaxed as the bucket will never become null + // again. We perform a acquire load when it's null. + let mut bucket_ptr = bucket.0.load(Ordering::Relaxed); + if bucket_ptr.is_null() { + bucket_ptr = bucket.0.load(Ordering::Acquire); + if bucket_ptr.is_null() { + let lock = bucket.1.lock(); + let guarded_bucket_ptr = bucket.0.load(Ordering::Acquire); + if guarded_bucket_ptr.is_null() { + let new_bucket = + allocate_default_bucket::(bucket_idx); + bucket_ptr = match bucket.0.compare_exchange( + null_mut(), + new_bucket, + Ordering::AcqRel, + Ordering::Relaxed, + ) { + Ok(_) => new_bucket, + Err(current_bucket) => { + drop(unsafe { Box::from_raw(new_bucket) }); + current_bucket + } + }; + drop(lock); + } else { + bucket_ptr = guarded_bucket_ptr; + } + } + } + let index = get_index_in_bucket::(idx, bucket_idx); + let value = unsafe { &*bucket_ptr.add(index) }.as_option_ref(); + value.expect("get_init_default must not be combined with normal insert") + } +} + +impl Drop for NoMoveVec { + fn drop(&mut self) { + for (bucket_index, (bucket, _)) in self.buckets.iter_mut().enumerate() { + if bucket_index < (usize::BITS + 1 - INITIAL_CAPACITY_BITS) as usize { + let bucket_size = get_bucket_size::(bucket_index as u32); + let bucket_ptr = *bucket.get_mut(); + + if !bucket_ptr.is_null() { + drop(unsafe { Box::from_raw(from_raw_parts_mut(bucket_ptr, bucket_size)) }); + } + } + } + } +} + +#[cfg(test)] +mod tests { + use super::NoMoveVec; + + #[test] + fn basic_operations() { + let v = NoMoveVec::<(usize, usize)>::new(); + assert_eq!(v.get(0), None); + assert_eq!(v.get(1), None); + assert_eq!(v.get(8), None); + assert_eq!(v.get(9), None); + assert_eq!(v.get(15), None); + assert_eq!(v.get(16), None); + assert_eq!(v.get(100), None); + assert_eq!(v.get(1000), None); + + for i in 0..1000 { + unsafe { + v.insert(i, (i, i)); + } + assert_eq!(v.get(i), Some(&(i, i))); + } + for i in 0..1000 { + assert_eq!(v.get(i), Some(&(i, i))); + } + assert_eq!(v.get(1001), None); + + unsafe { + v.insert(1000000, (0, 0)); + } + assert_eq!(v.get(1000000), Some(&(0, 0))); + assert_eq!(v.get(10000), None); + } +} diff --git a/turbopack/crates/turbo-tasks/src/once_map.rs b/turbopack/crates/turbo-tasks/src/once_map.rs new file mode 100644 index 0000000000000..22508785bb043 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/once_map.rs @@ -0,0 +1,141 @@ +use std::{ + hash::Hash, + sync::{Arc, Mutex}, +}; + +use dashmap::{mapref::entry::Entry, DashMap}; + +pub struct OnceConcurrentlyMap { + inner: DashMap<&'static K, Arc>>>, +} + +impl Default + for OnceConcurrentlyMap +{ + fn default() -> Self { + Self::new() + } +} + +impl OnceConcurrentlyMap { + pub fn new() -> Self { + Self { + inner: DashMap::new(), + } + } + + pub fn action(&self, key: &K, func: impl FnOnce() -> V) -> V { + let temp = TemporarilyInserted { + inner: &self.inner, + key, + }; + let mutex = match temp.entry() { + Entry::Occupied(e) => e.get().clone(), + Entry::Vacant(e) => e.insert(Arc::new(Mutex::new(None))).clone(), + }; + let mut guard = mutex.lock().unwrap(); + if let Some(value) = &*guard { + // Yeah, somebody else already did it for us + return value.clone(); + } + // We are the one responsible for computing + let value = func(); + *guard = Some(value.clone()); + drop(guard); + drop(temp); + value + } +} + +struct TemporarilyInserted<'a, K: 'static + Hash + Eq + Ord + Send + Sync, V: Send + Sync> { + inner: &'a DashMap<&'static K, V>, + key: &'a K, +} + +impl<'a, K: Hash + Eq + Ord + Send + Sync, V: Send + Sync> TemporarilyInserted<'a, K, V> { + fn entry(&self) -> Entry<'a, &'static K, V> { + // SAFETY: We remove the value again after this function is done + let static_key: &'static K = unsafe { std::mem::transmute(self.key) }; + self.inner.entry(static_key) + } +} + +impl<'a, K: Hash + Eq + Ord + Send + Sync, V: Send + Sync> Drop for TemporarilyInserted<'a, K, V> { + fn drop(&mut self) { + let static_key: &'static K = unsafe { std::mem::transmute(self.key) }; + self.inner.remove(&static_key); + } +} + +pub struct SafeOnceConcurrentlyMap< + K: Clone + Hash + Eq + Ord + Send + Sync + 'static, + V: Clone + Send + Sync, +> { + inner: DashMap>>>, +} + +impl Default + for SafeOnceConcurrentlyMap +{ + fn default() -> Self { + Self::new() + } +} + +impl + SafeOnceConcurrentlyMap +{ + pub fn new() -> Self { + Self { + inner: DashMap::new(), + } + } + + pub fn action(&self, key: &K, func: impl FnOnce() -> V) -> V { + let temp = SafeTemporarilyInserted { + inner: &self.inner, + key, + }; + let mutex = match temp.entry() { + Entry::Occupied(e) => e.get().clone(), + Entry::Vacant(e) => e.insert(Arc::new(Mutex::new(None))).clone(), + }; + let mut guard = mutex.lock().unwrap(); + if let Some(value) = &*guard { + // Yeah, somebody else already did it for us + return value.clone(); + } + // We are the one responsible for computing + let value = func(); + *guard = Some(value.clone()); + drop(guard); + drop(temp); + value + } +} + +struct SafeTemporarilyInserted< + 'a, + K: 'static + Clone + Hash + Eq + Ord + Send + Sync, + V: Send + Sync, +> { + inner: &'a DashMap, + key: &'a K, +} + +impl<'a, K: Clone + Hash + Eq + Ord + Send + Sync, V: Send + Sync> + SafeTemporarilyInserted<'a, K, V> +{ + fn entry(&self) -> Entry<'_, K, V> { + // SAFETY: We remove the value again after this function is done + self.inner.entry(self.key.clone()) + } +} + +impl<'a, K: Clone + Hash + Eq + Ord + Send + Sync, V: Send + Sync> Drop + for SafeTemporarilyInserted<'a, K, V> +{ + fn drop(&mut self) { + self.inner.remove(self.key); + } +} diff --git a/turbopack/crates/turbo-tasks/src/persisted_graph.rs b/turbopack/crates/turbo-tasks/src/persisted_graph.rs new file mode 100644 index 0000000000000..e317dc903714b --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/persisted_graph.rs @@ -0,0 +1,385 @@ +use anyhow::Result; +use serde::{ser::SerializeSeq, Deserialize, Serialize}; + +use crate::{ + backend::{CellContent, PersistentTaskType}, + task::shared_reference::TypedSharedReference, + CellId, RawVc, TaskId, +}; + +#[derive(Clone, Debug)] +pub enum TaskCell { + Content(CellContent), + NeedComputation, +} + +impl Default for TaskCell { + fn default() -> Self { + TaskCell::Content(CellContent(None)) + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct TaskData { + pub children: Vec, + pub dependencies: Vec, + pub cells: TaskCells, + pub output: RawVc, +} + +/// A newtype struct that intercepts serde. This is required +/// because for safety reasons, TaskCell<()> is not allowed to +/// be deserialized. We augment it with type data then write +/// it. This is inefficient on disk but could be alleviated later. +#[derive(Debug)] +pub struct TaskCells(pub Vec<(CellId, TaskCell)>); + +// the on-disk representation of a task cell. it is local to this impl +// to prevent users accidentally ser/de the untyped data +#[derive(Serialize, Deserialize)] +struct SerializableTaskCell(Option>); +impl From for TaskCell { + fn from(val: SerializableTaskCell) -> Self { + match val.0 { + Some(d) => TaskCell::Content(CellContent(d.map(|d| d.untyped().1))), + None => TaskCell::NeedComputation, + } + } +} + +impl Serialize for TaskCells { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut seq = serializer.serialize_seq(Some(self.0.len()))?; + for (cell_id, cell) in &self.0 { + let task_cell = SerializableTaskCell(match cell { + TaskCell::Content(CellContent(opt)) => { + Some(opt.as_ref().map(|d| d.typed(cell_id.type_id))) + } + TaskCell::NeedComputation => None, + }); + seq.serialize_element(&(cell_id, task_cell))?; + } + seq.end() + } +} + +impl<'de> Deserialize<'de> for TaskCells { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let data: Vec<(CellId, SerializableTaskCell)> = Vec::deserialize(deserializer)?; + Ok(TaskCells( + data.into_iter() + .map(|(id, cell)| (id, cell.into())) + .collect(), + )) + } +} + +pub struct ReadTaskState { + pub clean: bool, + pub keeps_external_active: bool, +} + +pub struct PersistTaskState { + pub externally_active: bool, +} + +/* + +There are 4 kinds of task: + +(A) A task that exists only in memory. +(B) A task that exists in persistent graph and in memory (either "store" or "read" has been called) +(C) A task that exists only in persistent graph. + +Parent-child relationships: + +(A) as child: active_parents is tracked only in memory. +(B) as child: active_parents is tracked in memory and either as internal_active_parents or external_active_parents in the persisted graph. +(C) as child: either as internal_active_parents or external_active_parents in the persisted graph. + +(A) as parent: It will use external_active_parents for (B) or (C) as child. + update_active_parents() is used to modify the external_active_parents count. +(B) as parent: It will use internal_active_parents for (B) or (C) as child. + compute_active() returns the changes needed for (A) or (C) as child +(C) as parent: It will use internal_active_parents for (B) or (C) as child. + compute_active() returns the changes needed for (A) or (C) as child + +(A) as child of (B) or (C): active count tracked as external_active_children, have task ids assigned in persistent graph + +*/ + +#[derive(Debug)] +pub struct ActivateResult { + /// Keeps the external version of the task active + pub keeps_external_active: bool, + + /// Task doesn't live in the persisted graph but + /// should be track externally + pub external: bool, + + /// Task is dirty and need to be scheduled for execution + pub dirty: bool, + + /// Further tasks that need to be activated that + /// didn't fit into that batch + pub more_tasks_to_activate: Vec, +} + +#[derive(Debug)] +pub struct PersistResult { + /// Tasks that need to be activated + pub tasks_to_activate: Vec, + + /// Tasks that need to be deactivated + pub tasks_to_deactivate: Vec, +} + +#[derive(Debug)] +pub struct DeactivateResult { + /// Further tasks that need to be deactivated that + /// didn't fit into that batch + pub more_tasks_to_deactivate: Vec, +} + +pub trait PersistedGraph: Sync + Send { + /// read task data and state for a specific task. + fn read( + &self, + task: TaskId, + api: &dyn PersistedGraphApi, + ) -> Result>; + + /// lookup all cache entries for a partial task type + /// returns true if all cache entries has been initialized + /// returns false if that were too many + fn lookup( + &self, + partial_task_type: &PersistentTaskType, + api: &dyn PersistedGraphApi, + ) -> Result; + + /// lookup one cache entry + fn lookup_one( + &self, + task_type: &PersistentTaskType, + api: &dyn PersistedGraphApi, + ) -> Result>; + + /// checks if a task is persisted + fn is_persisted(&self, task: TaskId, api: &dyn PersistedGraphApi) -> Result; + + /// store a completed task into the persisted graph + /// together with dependencies, children and cells. + /// Returns false, if the task failed to persist. + fn persist( + &self, + task: TaskId, + data: TaskData, + state: PersistTaskState, + api: &dyn PersistedGraphApi, + ) -> Result>; + + /// Activate a task in the persisted graph when active_parents > 0 or it's + /// externally kept alive. + fn activate_when_needed( + &self, + task: TaskId, + api: &dyn PersistedGraphApi, + ) -> Result>; + + /// Deactivate a task in the persisted graph when active_parents == 0 and + /// it's not externally kept alive. + fn deactivate_when_needed( + &self, + task: TaskId, + api: &dyn PersistedGraphApi, + ) -> Result>; + + /// Marks a task as kept alive by the consumer graph + /// (usually from memory to persisted graph) + /// Returns true when activate_when_needed should be called soonish + fn set_externally_active(&self, task: TaskId, api: &dyn PersistedGraphApi) -> Result; + + /// No longer marks a task as kept alive by the consumer graph + /// (usually from memory to persisted graph) + /// Returns true when deactivate_when_needed should be called soonish + fn unset_externally_active(&self, task: TaskId, api: &dyn PersistedGraphApi) -> Result; + + /// Removes all external keep alives that were not renewed this round. + /// This is usually called after the initial build has finished and all + /// external keep alives has been renewed. + fn remove_outdated_externally_active(&self, api: &dyn PersistedGraphApi) + -> Result>; + + /// update the dirty flag for a stored task + /// Returns true, when the task is active and should be scheduled + fn make_dirty(&self, task: TaskId, api: &dyn PersistedGraphApi) -> Result; + + /// update the dirty flag for a stored task + fn make_clean(&self, task: TaskId, api: &dyn PersistedGraphApi) -> Result<()>; + + /// make all tasks that depend on that vc dirty and + /// return a list of active tasks that should be scheduled + fn make_dependent_dirty(&self, vc: RawVc, api: &dyn PersistedGraphApi) -> Result>; + + /// Get all tasks that are active, but not persisted. + /// This is usually called at beginning to create and schedule + /// tasks that are missing in the persisted graph + fn get_active_external_tasks(&self, api: &dyn PersistedGraphApi) -> Result>; + + /// Get all tasks that are dirty and active. + /// This is usually called at the beginning to schedule these tasks. + fn get_dirty_active_tasks(&self, api: &dyn PersistedGraphApi) -> Result>; + + /// Get tasks that have active update pending that need to be continued + /// returns (tasks_to_activate, tasks_to_deactivate) + fn get_pending_active_update( + &self, + api: &dyn PersistedGraphApi, + ) -> Result<(Vec, Vec)>; + + /// Stop operations + #[allow(unused_variables)] + fn stop(&self, api: &dyn PersistedGraphApi) -> Result<()> { + Ok(()) + } +} + +pub trait PersistedGraphApi { + fn get_or_create_task_type(&self, ty: PersistentTaskType) -> TaskId; + + fn lookup_task_type(&self, id: TaskId) -> &PersistentTaskType; +} + +/* + +read: + + data: (TaskId) => (TaskData) + cache: (PersistentTaskType) => (TaskId) + type: (TaskId) => (PersistentTaskType) + +read_dependents: + + dependents: (RawVc) => [TaskId] + +store: + + external_active_parents: (TaskId) -> (usize) + internal_active_parents: (TaskId) -> (usize) + inactive_tasks: [TaskId] + +B+C? + + + + +*/ + +impl PersistedGraph for () { + fn read( + &self, + _task: TaskId, + _api: &dyn PersistedGraphApi, + ) -> Result> { + Ok(None) + } + + fn lookup( + &self, + _partial_task_type: &PersistentTaskType, + _api: &dyn PersistedGraphApi, + ) -> Result { + Ok(false) + } + + fn lookup_one( + &self, + _task_type: &PersistentTaskType, + _api: &dyn PersistedGraphApi, + ) -> Result> { + Ok(None) + } + + fn is_persisted(&self, _task: TaskId, _api: &dyn PersistedGraphApi) -> Result { + Ok(false) + } + + fn persist( + &self, + _task: TaskId, + _data: TaskData, + _state: PersistTaskState, + _api: &dyn PersistedGraphApi, + ) -> Result> { + Ok(None) + } + + fn activate_when_needed( + &self, + _task: TaskId, + _api: &dyn PersistedGraphApi, + ) -> Result> { + Ok(None) + } + + fn deactivate_when_needed( + &self, + _task: TaskId, + _api: &dyn PersistedGraphApi, + ) -> Result> { + Ok(None) + } + + fn set_externally_active(&self, _task: TaskId, _api: &dyn PersistedGraphApi) -> Result { + Ok(false) + } + + fn unset_externally_active(&self, _task: TaskId, _api: &dyn PersistedGraphApi) -> Result { + Ok(false) + } + + fn remove_outdated_externally_active( + &self, + _api: &dyn PersistedGraphApi, + ) -> Result> { + Ok(Vec::new()) + } + + fn make_dirty(&self, _task: TaskId, _api: &dyn PersistedGraphApi) -> Result { + Ok(false) + } + + fn make_clean(&self, _task: TaskId, _api: &dyn PersistedGraphApi) -> Result<()> { + Ok(()) + } + + fn make_dependent_dirty( + &self, + _vc: RawVc, + _api: &dyn PersistedGraphApi, + ) -> Result> { + Ok(Vec::new()) + } + + fn get_active_external_tasks(&self, _api: &dyn PersistedGraphApi) -> Result> { + Ok(Vec::new()) + } + + fn get_dirty_active_tasks(&self, _api: &dyn PersistedGraphApi) -> Result> { + Ok(Vec::new()) + } + + fn get_pending_active_update( + &self, + _api: &dyn PersistedGraphApi, + ) -> Result<(Vec, Vec)> { + Ok((Vec::new(), Vec::new())) + } +} diff --git a/turbopack/crates/turbo-tasks/src/primitives.rs b/turbopack/crates/turbo-tasks/src/primitives.rs new file mode 100644 index 0000000000000..0d433ed7e376d --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/primitives.rs @@ -0,0 +1,138 @@ +use std::{future::IntoFuture, ops::Deref}; + +use anyhow::Result; +use futures::TryFutureExt; +// This specific macro identifier is detected by turbo-tasks-build. +use turbo_tasks_macros::primitive as __turbo_tasks_internal_primitive; + +use crate::{ + RcStr, TryJoinIterExt, Vc, {self as turbo_tasks}, +}; + +__turbo_tasks_internal_primitive!(()); +__turbo_tasks_internal_primitive!(String); +__turbo_tasks_internal_primitive!(RcStr); + +#[turbo_tasks::function] +fn empty_string() -> Vc { + Vc::cell(RcStr::default()) +} + +impl Vc { + #[deprecated(note = "use Default::default() instead")] + #[inline(always)] + pub fn empty() -> Vc { + empty_string() + } +} + +__turbo_tasks_internal_primitive!(Option); +__turbo_tasks_internal_primitive!(Option); +__turbo_tasks_internal_primitive!(Vec); + +#[turbo_tasks::function] +fn empty_string_vec() -> Vc> { + Vc::cell(Vec::new()) +} + +impl Vc> { + #[deprecated(note = "use Default::default() instead")] + #[inline(always)] + pub fn empty() -> Vc> { + empty_string_vec() + } +} + +__turbo_tasks_internal_primitive!(Option); + +#[turbo_tasks::function] +fn option_string_none() -> Vc> { + Vc::cell(None) +} + +impl Vc> { + #[deprecated(note = "use Default::default() instead")] + pub fn none() -> Self { + option_string_none() + } +} + +__turbo_tasks_internal_primitive!(bool); +__turbo_tasks_internal_primitive!(u8); +__turbo_tasks_internal_primitive!(u16); +__turbo_tasks_internal_primitive!(u32); +__turbo_tasks_internal_primitive!(u64); +__turbo_tasks_internal_primitive!(u128); +__turbo_tasks_internal_primitive!(i8); +__turbo_tasks_internal_primitive!(i16); +__turbo_tasks_internal_primitive!(i32); +__turbo_tasks_internal_primitive!(i64); +__turbo_tasks_internal_primitive!(i128); +__turbo_tasks_internal_primitive!(usize); +__turbo_tasks_internal_primitive!(isize); +__turbo_tasks_internal_primitive!(serde_json::Value); +__turbo_tasks_internal_primitive!(Vec); + +__turbo_tasks_internal_primitive!(Vec); + +#[turbo_tasks::value(transparent)] +pub struct Bools(Vec>); + +#[turbo_tasks::value_impl] +impl Bools { + #[turbo_tasks::function] + pub fn empty() -> Vc { + Vc::cell(Vec::new()) + } + + #[turbo_tasks::function] + async fn into_bools(self: Vc) -> Result>> { + let this = self.await?; + + let bools = this + .iter() + .map(|b| b.into_future().map_ok(|b| *b)) + .try_join() + .await?; + + Ok(Vc::cell(bools)) + } + + #[turbo_tasks::function] + pub async fn all(self: Vc) -> Result> { + let bools = self.into_bools().await?; + + Ok(Vc::cell(bools.iter().all(|b| *b))) + } + + #[turbo_tasks::function] + pub async fn any(self: Vc) -> Result> { + let bools = self.into_bools().await?; + + Ok(Vc::cell(bools.iter().any(|b| *b))) + } +} + +#[turbo_tasks::value(transparent, eq = "manual")] +#[derive(Debug, Clone)] +pub struct Regex( + #[turbo_tasks(trace_ignore)] + #[serde(with = "serde_regex")] + pub regex::Regex, +); + +impl Deref for Regex { + type Target = regex::Regex; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl PartialEq for Regex { + fn eq(&self, other: &Regex) -> bool { + // Context: https://github.com/rust-lang/regex/issues/313#issuecomment-269898900 + self.0.as_str() == other.0.as_str() + } +} +impl Eq for Regex {} diff --git a/turbopack/crates/turbo-tasks/src/raw_vc.rs b/turbopack/crates/turbo-tasks/src/raw_vc.rs new file mode 100644 index 0000000000000..ec6fa115fc1ad --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/raw_vc.rs @@ -0,0 +1,377 @@ +use std::{ + fmt::{Debug, Display}, + future::Future, + hash::Hash, + pin::Pin, + sync::Arc, + task::Poll, +}; + +use anyhow::Result; +use auto_hash_map::AutoSet; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +use crate::{ + backend::{CellContent, TypedCellContent}, + event::EventListener, + manager::{read_task_cell, read_task_output, TurboTasksApi}, + registry::{self, get_value_type}, + turbo_tasks, CollectiblesSource, TaskId, TraitTypeId, ValueTypeId, Vc, VcValueTrait, +}; + +#[derive(Error, Debug)] +pub enum ResolveTypeError { + #[error("no content in the cell")] + NoContent, + #[error("the content in the cell has no type")] + UntypedContent, + #[error("content is not available as task execution failed")] + TaskError { source: anyhow::Error }, + #[error("reading the cell content failed")] + ReadError { source: anyhow::Error }, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct CellId { + pub type_id: ValueTypeId, + pub index: u32, +} + +impl Display for CellId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{}#{}", + registry::get_value_type(self.type_id).name, + self.index + ) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub enum RawVc { + TaskOutput(TaskId), + TaskCell(TaskId, CellId), +} + +impl RawVc { + pub(crate) fn is_resolved(&self) -> bool { + match self { + RawVc::TaskOutput(_) => false, + RawVc::TaskCell(_, _) => true, + } + } + + pub(crate) fn into_read(self) -> ReadRawVcFuture { + // returns a custom future to have something concrete and sized + // this avoids boxing in IntoFuture + ReadRawVcFuture::new(self) + } + + pub(crate) fn into_strongly_consistent_read(self) -> ReadRawVcFuture { + ReadRawVcFuture::new_strongly_consistent(self) + } + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + pub(crate) fn into_read_untracked(self) -> ReadRawVcFuture { + ReadRawVcFuture::new_untracked(self) + } + + /// INVALIDATION: Be careful with this, it will not track dependencies, so + /// using it could break cache invalidation. + pub(crate) fn into_read_untracked_with_turbo_tasks( + self, + turbo_tasks: &dyn TurboTasksApi, + ) -> ReadRawVcFuture { + ReadRawVcFuture::new_untracked_with_turbo_tasks(self, turbo_tasks) + } + + pub(crate) fn into_strongly_consistent_read_untracked(self) -> ReadRawVcFuture { + ReadRawVcFuture::new_strongly_consistent_untracked(self) + } + + pub(crate) async fn resolve_trait( + self, + trait_type: TraitTypeId, + ) -> Result, ResolveTypeError> { + let tt = turbo_tasks(); + tt.notify_scheduled_tasks(); + let mut current = self; + loop { + match current { + RawVc::TaskOutput(task) => { + current = read_task_output(&*tt, task, false) + .await + .map_err(|source| ResolveTypeError::TaskError { source })?; + } + RawVc::TaskCell(task, index) => { + let content = read_task_cell(&*tt, task, index) + .await + .map_err(|source| ResolveTypeError::ReadError { source })?; + if let TypedCellContent(value_type, CellContent(Some(_))) = content { + if get_value_type(value_type).has_trait(&trait_type) { + return Ok(Some(RawVc::TaskCell(task, index))); + } else { + return Ok(None); + } + } else { + return Err(ResolveTypeError::NoContent); + } + } + } + } + } + + pub(crate) async fn resolve_value( + self, + value_type: ValueTypeId, + ) -> Result, ResolveTypeError> { + let tt = turbo_tasks(); + tt.notify_scheduled_tasks(); + let mut current = self; + loop { + match current { + RawVc::TaskOutput(task) => { + current = read_task_output(&*tt, task, false) + .await + .map_err(|source| ResolveTypeError::TaskError { source })?; + } + RawVc::TaskCell(task, index) => { + let content = read_task_cell(&*tt, task, index) + .await + .map_err(|source| ResolveTypeError::ReadError { source })?; + if let TypedCellContent(cell_value_type, CellContent(Some(_))) = content { + if cell_value_type == value_type { + return Ok(Some(RawVc::TaskCell(task, index))); + } else { + return Ok(None); + } + } else { + return Err(ResolveTypeError::NoContent); + } + } + } + } + } + + /// See [`crate::Vc::resolve`]. + pub(crate) async fn resolve(self) -> Result { + let tt = turbo_tasks(); + let mut current = self; + let mut notified = false; + loop { + match current { + RawVc::TaskOutput(task) => { + if !notified { + tt.notify_scheduled_tasks(); + notified = true; + } + current = read_task_output(&*tt, task, false).await?; + } + RawVc::TaskCell(_, _) => return Ok(current), + } + } + } + + /// See [`crate::Vc::resolve_strongly_consistent`]. + pub(crate) async fn resolve_strongly_consistent(self) -> Result { + let tt = turbo_tasks(); + let mut current = self; + let mut notified = false; + loop { + match current { + RawVc::TaskOutput(task) => { + if !notified { + tt.notify_scheduled_tasks(); + notified = true; + } + current = read_task_output(&*tt, task, true).await?; + } + RawVc::TaskCell(_, _) => return Ok(current), + } + } + } + + pub(crate) fn connect(&self) { + let tt = turbo_tasks(); + tt.connect_task(self.get_task_id()); + } + + pub fn get_task_id(&self) -> TaskId { + match self { + RawVc::TaskOutput(t) | RawVc::TaskCell(t, _) => *t, + } + } +} + +impl CollectiblesSource for RawVc { + fn peek_collectibles(self) -> AutoSet> { + let tt = turbo_tasks(); + tt.notify_scheduled_tasks(); + let map = tt.read_task_collectibles(self.get_task_id(), T::get_trait_type_id()); + map.into_iter() + .filter_map(|(raw, count)| (count > 0).then_some(raw.into())) + .collect() + } + + fn take_collectibles(self) -> AutoSet> { + let tt = turbo_tasks(); + tt.notify_scheduled_tasks(); + let map = tt.read_task_collectibles(self.get_task_id(), T::get_trait_type_id()); + tt.unemit_collectibles(T::get_trait_type_id(), &map); + map.into_iter() + .filter_map(|(raw, count)| (count > 0).then_some(raw.into())) + .collect() + } +} + +impl Display for RawVc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + RawVc::TaskOutput(task) => { + write!(f, "output of {}", task) + } + RawVc::TaskCell(task, index) => { + write!(f, "value {} of {}", index, task) + } + } + } +} + +pub struct ReadRawVcFuture { + turbo_tasks: Arc, + strongly_consistent: bool, + current: RawVc, + untracked: bool, + listener: Option, +} + +impl ReadRawVcFuture { + pub(crate) fn new(vc: RawVc) -> Self { + let tt = turbo_tasks(); + ReadRawVcFuture { + turbo_tasks: tt, + strongly_consistent: false, + current: vc, + untracked: false, + listener: None, + } + } + + fn new_untracked_with_turbo_tasks(vc: RawVc, turbo_tasks: &dyn TurboTasksApi) -> Self { + let tt = turbo_tasks.pin(); + ReadRawVcFuture { + turbo_tasks: tt, + strongly_consistent: false, + current: vc, + untracked: true, + listener: None, + } + } + + fn new_untracked(vc: RawVc) -> Self { + let tt = turbo_tasks(); + ReadRawVcFuture { + turbo_tasks: tt, + strongly_consistent: false, + current: vc, + untracked: true, + listener: None, + } + } + + fn new_strongly_consistent(vc: RawVc) -> Self { + let tt = turbo_tasks(); + ReadRawVcFuture { + turbo_tasks: tt, + strongly_consistent: true, + current: vc, + untracked: false, + listener: None, + } + } + + fn new_strongly_consistent_untracked(vc: RawVc) -> Self { + let tt = turbo_tasks(); + ReadRawVcFuture { + turbo_tasks: tt, + strongly_consistent: true, + current: vc, + untracked: true, + listener: None, + } + } +} + +impl Future for ReadRawVcFuture { + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { + self.turbo_tasks.notify_scheduled_tasks(); + // SAFETY: we are not moving this + let this = unsafe { self.get_unchecked_mut() }; + 'outer: loop { + if let Some(listener) = &mut this.listener { + // SAFETY: listener is from previous pinned this + let listener = unsafe { Pin::new_unchecked(listener) }; + if listener.poll(cx).is_pending() { + return Poll::Pending; + } + this.listener = None; + } + let mut listener = match this.current { + RawVc::TaskOutput(task) => { + let read_result = if this.untracked { + this.turbo_tasks + .try_read_task_output_untracked(task, this.strongly_consistent) + } else { + this.turbo_tasks + .try_read_task_output(task, this.strongly_consistent) + }; + match read_result { + Ok(Ok(vc)) => { + // We no longer need to read strongly consistent, as any Vc returned + // from the first task will be inside of the scope of the first task. So + // it's already strongly consistent. + this.strongly_consistent = false; + this.current = vc; + continue 'outer; + } + Ok(Err(listener)) => listener, + Err(err) => return Poll::Ready(Err(err)), + } + } + RawVc::TaskCell(task, index) => { + let read_result = if this.untracked { + this.turbo_tasks.try_read_task_cell_untracked(task, index) + } else { + this.turbo_tasks.try_read_task_cell(task, index) + }; + match read_result { + Ok(Ok(content)) => { + // SAFETY: Constructor ensures that T and U are binary identical + return Poll::Ready(Ok(content)); + } + Ok(Err(listener)) => listener, + Err(err) => return Poll::Ready(Err(err)), + } + } + }; + // SAFETY: listener is from previous pinned this + match unsafe { Pin::new_unchecked(&mut listener) }.poll(cx) { + Poll::Ready(_) => continue, + Poll::Pending => { + this.listener = Some(listener); + return Poll::Pending; + } + }; + } + } +} + +unsafe impl Send for ReadRawVcFuture {} +unsafe impl Sync for ReadRawVcFuture {} + +impl Unpin for ReadRawVcFuture {} diff --git a/turbopack/crates/turbo-tasks/src/rcstr.rs b/turbopack/crates/turbo-tasks/src/rcstr.rs new file mode 100644 index 0000000000000..65c946ffd7b3b --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/rcstr.rs @@ -0,0 +1,158 @@ +use std::{ + borrow::{Borrow, Cow}, + ffi::OsStr, + fmt::{Debug, Display}, + ops::Deref, + path::{Path, PathBuf}, +}; + +use serde::{Deserialize, Serialize}; +use triomphe::Arc; +use turbo_tasks_hash::{DeterministicHash, DeterministicHasher}; + +use crate::debug::{ValueDebugFormat, ValueDebugFormatString}; + +/// A reference counted [`String`], similar to [`Arc`][std::sync::Arc]. +/// +/// This type is intentionally opaque to allow for optimizations to the +/// underlying representation. Future implementations may use inline +/// representations or interning. +// +// If you want to change the underlying string type to `Arc`, please ensure that you profile +// performance. The current implementation offers very cheap `String -> RcStr -> String`, meaning we +// only pay for the allocation for `Arc` when we pass `format!("").into()` to a function. +#[derive(Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)] +#[serde(transparent)] +pub struct RcStr(Arc); + +impl RcStr { + pub fn as_str(&self) -> &str { + self.0.as_str() + } + + /// This implementation is more efficient than `.to_string()` + pub fn into_owned(self) -> String { + match Arc::try_unwrap(self.0) { + Ok(v) => v, + Err(arc) => arc.to_string(), + } + } + + pub fn map(self, f: impl FnOnce(String) -> String) -> Self { + RcStr(Arc::new(f(self.into_owned()))) + } +} + +impl DeterministicHash for RcStr { + fn deterministic_hash(&self, state: &mut H) { + state.write_usize(self.len()); + state.write_bytes(self.as_bytes()); + } +} + +impl Deref for RcStr { + type Target = str; + + fn deref(&self) -> &Self::Target { + self.0.as_str() + } +} + +impl Borrow for RcStr { + fn borrow(&self) -> &str { + self.0.as_str() + } +} + +impl From> for RcStr { + fn from(s: Arc) -> Self { + RcStr(s) + } +} + +impl From for RcStr { + fn from(s: String) -> Self { + RcStr(Arc::new(s)) + } +} + +impl From<&'_ str> for RcStr { + fn from(s: &str) -> Self { + RcStr(Arc::new(s.to_string())) + } +} + +impl From> for RcStr { + fn from(s: Cow) -> Self { + RcStr(Arc::new(s.into_owned())) + } +} + +/// Mimic `&str` +impl AsRef for RcStr { + fn as_ref(&self) -> &Path { + (*self.0).as_ref() + } +} + +/// Mimic `&str` +impl AsRef for RcStr { + fn as_ref(&self) -> &OsStr { + (*self.0).as_ref() + } +} + +/// Mimic `&str` +impl AsRef<[u8]> for RcStr { + fn as_ref(&self) -> &[u8] { + (*self.0).as_ref() + } +} + +impl PartialEq for RcStr { + fn eq(&self, other: &str) -> bool { + self.0.as_str() == other + } +} + +impl PartialEq<&'_ str> for RcStr { + fn eq(&self, other: &&str) -> bool { + self.0.as_str() == *other + } +} + +impl PartialEq for RcStr { + fn eq(&self, other: &String) -> bool { + self.as_str() == other.as_str() + } +} + +impl Debug for RcStr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt(&self.0, f) + } +} + +impl Display for RcStr { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Display::fmt(&self.0, f) + } +} + +impl From for String { + fn from(s: RcStr) -> Self { + s.into_owned() + } +} + +impl From for PathBuf { + fn from(s: RcStr) -> Self { + String::from(s).into() + } +} + +impl ValueDebugFormat for RcStr { + fn value_debug_format(&self, _: usize) -> ValueDebugFormatString { + ValueDebugFormatString::Sync(self.to_string()) + } +} diff --git a/turbopack/crates/turbo-tasks/src/read_ref.rs b/turbopack/crates/turbo-tasks/src/read_ref.rs new file mode 100644 index 0000000000000..df4b6e4f3df2c --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/read_ref.rs @@ -0,0 +1,264 @@ +use std::{ + fmt::{Debug, Display}, + hash::Hash, + marker::PhantomData, + mem::transmute_copy, +}; + +use serde::{Deserialize, Serialize}; +use turbo_tasks_hash::DeterministicHash; + +use crate::{ + debug::{ValueDebugFormat, ValueDebugFormatString}, + macro_helpers::find_cell_by_type, + trace::{TraceRawVcs, TraceRawVcsContext}, + SharedReference, Vc, VcRead, VcValueType, +}; + +type VcReadTarget = <::Read as VcRead>::Target; + +/// The read value of a value cell. The read value is immutable, while the cell +/// itself might change over time. It's basically a snapshot of a value at a +/// certain point in time. +/// +/// Internally it stores a reference counted reference to a value on the heap. +pub struct ReadRef(triomphe::Arc); + +impl Clone for ReadRef { + fn clone(&self) -> Self { + Self(self.0.clone()) + } +} + +impl std::ops::Deref for ReadRef +where + T: VcValueType, +{ + type Target = VcReadTarget; + + fn deref(&self) -> &Self::Target { + T::Read::value_to_target_ref(&self.0) + } +} + +impl Display for ReadRef +where + T: VcValueType, + VcReadTarget: Display, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Display::fmt(&**self, f) + } +} + +impl Debug for ReadRef +where + T: VcValueType, + VcReadTarget: Debug, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Debug::fmt(&**self, f) + } +} + +impl TraceRawVcs for ReadRef +where + T: VcValueType, + VcReadTarget: TraceRawVcs, +{ + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + (**self).trace_raw_vcs(trace_context); + } +} + +impl ValueDebugFormat for ReadRef +where + T: VcValueType, + VcReadTarget: ValueDebugFormat + 'static, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + let value = &**self; + value.value_debug_format(depth) + } +} + +impl PartialEq for ReadRef +where + T: VcValueType, + VcReadTarget: PartialEq, +{ + fn eq(&self, other: &Self) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +impl Eq for ReadRef +where + T: VcValueType, + VcReadTarget: Eq, +{ +} + +impl PartialOrd for ReadRef +where + T: VcValueType, + VcReadTarget: PartialOrd, +{ + fn partial_cmp(&self, other: &Self) -> Option { + PartialOrd::partial_cmp(&**self, &**other) + } +} + +impl Ord for ReadRef +where + T: VcValueType, + VcReadTarget: Ord, +{ + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + Ord::cmp(&**self, &**other) + } +} + +impl Hash for ReadRef +where + T: VcValueType, + VcReadTarget: Hash, +{ + fn hash(&self, state: &mut H) { + Hash::hash(&**self, state) + } +} + +impl DeterministicHash for ReadRef +where + T: VcValueType, + VcReadTarget: DeterministicHash, +{ + fn deterministic_hash(&self, state: &mut H) { + let p = &**self; + p.deterministic_hash(state); + } +} + +impl<'a, T, I, J: Iterator> IntoIterator for &'a ReadRef +where + T: VcValueType, + &'a VcReadTarget: IntoIterator, +{ + type Item = I; + + type IntoIter = J; + + fn into_iter(self) -> Self::IntoIter { + (&**self).into_iter() + } +} + +impl> IntoIterator for ReadRef +where + T: VcValueType, + &'static VcReadTarget: IntoIterator, +{ + type Item = I; + + type IntoIter = ReadRefIter; + + fn into_iter(self) -> Self::IntoIter { + let r = &*self; + // # Safety + // The reference will we valid as long as the ReadRef is valid. + let r = unsafe { transmute_copy::<&'_ VcReadTarget, &'static VcReadTarget>(&r) }; + ReadRefIter { + read_ref: self, + iter: r.into_iter(), + } + } +} + +pub struct ReadRefIter> +where + T: VcValueType, +{ + iter: J, + #[allow(dead_code)] + read_ref: ReadRef, +} + +impl> Iterator for ReadRefIter +where + T: VcValueType, +{ + type Item = I; + + fn next(&mut self) -> Option { + self.iter.next() + } +} + +impl Serialize for ReadRef +where + T: VcValueType, + VcReadTarget: Serialize, +{ + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + (**self).serialize(serializer) + } +} + +impl<'de, T> Deserialize<'de> for ReadRef +where + T: Deserialize<'de>, +{ + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let value = T::deserialize(deserializer)?; + Ok(Self(triomphe::Arc::new(value))) + } +} + +impl ReadRef { + pub fn new_owned(value: T) -> Self { + Self(triomphe::Arc::new(value)) + } + + pub fn new_arc(arc: triomphe::Arc) -> Self { + Self(arc) + } + + pub fn ptr_eq(&self, other: &ReadRef) -> bool { + triomphe::Arc::ptr_eq(&self.0, &other.0) + } +} + +impl ReadRef +where + T: VcValueType, +{ + /// Returns a new cell that points to the same value as the given + /// reference. + pub fn cell(read_ref: ReadRef) -> Vc { + let local_cell = find_cell_by_type(T::get_value_type_id()); + local_cell.update_shared_reference(SharedReference::new(read_ref.0)); + Vc { + node: local_cell.into(), + _t: PhantomData, + } + } +} + +impl ReadRef +where + T: VcValueType, + VcReadTarget: Clone, +{ + /// This will clone the contained value instead of cloning the ReadRef. + /// This clone is more expensive, but allows to get an mutable owned value. + pub fn clone_value(&self) -> VcReadTarget { + (**self).clone() + } +} diff --git a/turbopack/crates/turbo-tasks/src/registry.rs b/turbopack/crates/turbo-tasks/src/registry.rs new file mode 100644 index 0000000000000..e4e0581fe6e80 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/registry.rs @@ -0,0 +1,148 @@ +use std::{fmt::Debug, hash::Hash, num::NonZeroU64, ops::Deref}; + +use dashmap::{mapref::entry::Entry, DashMap}; +use once_cell::sync::Lazy; + +use crate::{ + id::{FunctionId, TraitTypeId, ValueTypeId}, + id_factory::IdFactory, + no_move_vec::NoMoveVec, + NativeFunction, TraitType, ValueType, +}; + +static FUNCTION_ID_FACTORY: IdFactory = IdFactory::new(); +static FUNCTIONS_BY_NAME: Lazy> = Lazy::new(DashMap::new); +static FUNCTIONS_BY_VALUE: Lazy> = + Lazy::new(DashMap::new); +static FUNCTIONS: Lazy> = + Lazy::new(NoMoveVec::new); + +static VALUE_TYPE_ID_FACTORY: IdFactory = IdFactory::new(); +static VALUE_TYPES_BY_NAME: Lazy> = Lazy::new(DashMap::new); +static VALUE_TYPES_BY_VALUE: Lazy> = + Lazy::new(DashMap::new); +static VALUE_TYPES: Lazy> = Lazy::new(NoMoveVec::new); + +static TRAIT_TYPE_ID_FACTORY: IdFactory = IdFactory::new(); +static TRAIT_TYPES_BY_NAME: Lazy> = Lazy::new(DashMap::new); +static TRAIT_TYPES_BY_VALUE: Lazy> = + Lazy::new(DashMap::new); +static TRAIT_TYPES: Lazy> = Lazy::new(NoMoveVec::new); + +fn register_thing< + K: TryFrom + Deref + Sync + Send + Copy, + V: Clone + Hash + Eq + Sync + Send + Copy, + const INITIAL_CAPACITY_BITS: u32, +>( + global_name: &'static str, + value: V, + id_factory: &IdFactory, + store: &NoMoveVec<(V, &'static str), INITIAL_CAPACITY_BITS>, + map_by_name: &DashMap<&'static str, K>, + map_by_value: &DashMap, +) { + if let Entry::Vacant(e) = map_by_value.entry(value) { + let new_id = id_factory.get(); + // SAFETY: this is a fresh id + unsafe { + store.insert(*new_id as usize, (value, global_name)); + } + map_by_name.insert(global_name, new_id); + e.insert(new_id); + } +} + +fn get_thing_id< + K: From + Deref + Sync + Send + Copy + Debug, + V: Clone + Hash + Eq + Debug + Sync + Send + Debug, +>( + value: V, + map_by_value: &DashMap, +) -> K { + if let Some(id) = map_by_value.get(&value) { + *id + } else { + panic!("Use of unregistered {:?}", value); + } +} + +pub fn register_function(global_name: &'static str, func: &'static NativeFunction) { + register_thing( + global_name, + func, + &FUNCTION_ID_FACTORY, + &FUNCTIONS, + &FUNCTIONS_BY_NAME, + &FUNCTIONS_BY_VALUE, + ) +} + +pub fn get_function_id(func: &'static NativeFunction) -> FunctionId { + get_thing_id(func, &FUNCTIONS_BY_VALUE) +} + +pub fn get_function_id_by_global_name(global_name: &str) -> Option { + FUNCTIONS_BY_NAME.get(global_name).map(|x| *x) +} + +pub fn get_function(id: FunctionId) -> &'static NativeFunction { + FUNCTIONS.get(*id as usize).unwrap().0 +} + +pub fn get_function_global_name(id: FunctionId) -> &'static str { + FUNCTIONS.get(*id as usize).unwrap().1 +} + +pub fn register_value_type(global_name: &'static str, ty: &'static ValueType) { + register_thing( + global_name, + ty, + &VALUE_TYPE_ID_FACTORY, + &VALUE_TYPES, + &VALUE_TYPES_BY_NAME, + &VALUE_TYPES_BY_VALUE, + ) +} + +pub fn get_value_type_id(func: &'static ValueType) -> ValueTypeId { + get_thing_id(func, &VALUE_TYPES_BY_VALUE) +} + +pub fn get_value_type_id_by_global_name(global_name: &str) -> Option { + VALUE_TYPES_BY_NAME.get(global_name).map(|x| *x) +} + +pub fn get_value_type(id: ValueTypeId) -> &'static ValueType { + VALUE_TYPES.get(*id as usize).unwrap().0 +} + +pub fn get_value_type_global_name(id: ValueTypeId) -> &'static str { + VALUE_TYPES.get(*id as usize).unwrap().1 +} + +pub fn register_trait_type(global_name: &'static str, ty: &'static TraitType) { + register_thing( + global_name, + ty, + &TRAIT_TYPE_ID_FACTORY, + &TRAIT_TYPES, + &TRAIT_TYPES_BY_NAME, + &TRAIT_TYPES_BY_VALUE, + ) +} + +pub fn get_trait_type_id(func: &'static TraitType) -> TraitTypeId { + get_thing_id(func, &TRAIT_TYPES_BY_VALUE) +} + +pub fn get_trait_type_id_by_global_name(global_name: &str) -> Option { + TRAIT_TYPES_BY_NAME.get(global_name).map(|x| *x) +} + +pub fn get_trait(id: TraitTypeId) -> &'static TraitType { + TRAIT_TYPES.get(*id as usize).unwrap().0 +} + +pub fn get_trait_type_global_name(id: TraitTypeId) -> &'static str { + TRAIT_TYPES.get(*id as usize).unwrap().1 +} diff --git a/turbopack/crates/turbo-tasks/src/small_duration.rs b/turbopack/crates/turbo-tasks/src/small_duration.rs new file mode 100644 index 0000000000000..dac0969d67e52 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/small_duration.rs @@ -0,0 +1,216 @@ +use std::{ + fmt::{Debug, Display}, + time::Duration, +}; + +/// Stores a [`Duration`] in a given precision (in nanoseconds) in 4 bytes. +/// +/// For instance, for `P = 10_000` (10 microseconds), this allows a for a total +/// duration of 11.9 hours. Values smaller than 10 microseconds are stored as 10 +/// microseconds. +#[derive(Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)] +pub struct SmallDuration(u32); + +impl SmallDuration

{ + pub const ZERO: SmallDuration

= SmallDuration(0); + // TODO(alexkirsz) Figure out if MIN should be 0 or 1. + pub const MIN: SmallDuration

= SmallDuration(1); + pub const MAX: SmallDuration

= SmallDuration(u32::MAX); + + pub const fn from_nanos(nanos: u64) -> Self { + if nanos == 0 { + return SmallDuration::ZERO; + } + if nanos <= P { + return SmallDuration::MIN; + } + let value = nanos / P; + if value > u32::MAX as u64 { + return SmallDuration::MAX; + } + SmallDuration(value as u32) + } + + pub const fn from_micros(micros: u64) -> Self { + if micros == 0 { + return SmallDuration::ZERO; + } + let micros_precision = P / 1_000; + if micros <= micros_precision { + return SmallDuration::MIN; + } + let value = micros * 1_000 / P; + if value > u32::MAX as u64 { + return SmallDuration::MAX; + } + SmallDuration(value as u32) + } + + pub const fn from_millis(millis: u64) -> Self { + if millis == 0 { + return SmallDuration::ZERO; + } + let millis_precision = P / 1_000_000; + if millis <= millis_precision { + return SmallDuration::MIN; + } + let value = millis * 1_000_000 / P; + if value > u32::MAX as u64 { + return SmallDuration::MAX; + } + SmallDuration(value as u32) + } + + pub const fn from_secs(secs: u64) -> Self { + if secs == 0 { + return SmallDuration::ZERO; + } + let secs_precision = P / 1_000_000_000; + if secs <= secs_precision { + return SmallDuration::MIN; + } + let value = secs * 1_000_000_000 / P; + if value > u32::MAX as u64 { + return SmallDuration::MAX; + } + SmallDuration(value as u32) + } + + pub(self) fn to_duration(self) -> Duration { + Duration::from_nanos(self.0 as u64 * P) + } +} + +impl From for SmallDuration

{ + fn from(duration: Duration) -> Self { + if duration.is_zero() { + return SmallDuration::ZERO; + } + let nanos = duration.as_nanos(); + if nanos <= P as u128 { + return SmallDuration::MIN; + } + (nanos / P as u128) + .try_into() + .map_or(SmallDuration::MAX, SmallDuration) + } +} + +impl From> for Duration { + fn from(duration: SmallDuration

) -> Self { + duration.to_duration() + } +} + +impl Display for SmallDuration

{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let duration = Duration::from(*self); + duration.fmt(f) + } +} + +impl Debug for SmallDuration

{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let duration = Duration::from(*self); + duration.fmt(f) + } +} + +impl PartialEq for SmallDuration

  • {name} [{ty}] {title}
  • ", + name = HtmlEscaped(name), + title = HtmlEscaped(title), + path = HtmlStringEscaped(urlencoding::encode(&path)), + ty = HtmlEscaped(ty), + )) + }) + .try_join() + .await?; + let details = if details.is_empty() { + String::new() + } else if has_children { + format!( + "

    Details

    {details}
    ", + details = HtmlEscaped(details) + ) + } else { + format!( + "

    Details

    {details}
    ", + details = HtmlEscaped(details) + ) + }; + let html: RcStr = format!( + " + {title} + +

    {internal_ty}

    +

    {ty}

    +

    {title}

    + {details} +
      {children}
    + + ", + title = HtmlEscaped(title), + ty = HtmlEscaped(ty), + children = FormatIter(|| children.iter()) + ) + .into(); + Ok(ContentSourceContent::static_content( + AssetContent::file( + File::from(html) + .with_content_type(mime::TEXT_HTML_UTF_8) + .into(), + ) + .versioned(), + )) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/invalidation.rs b/turbopack/crates/turbopack-dev-server/src/invalidation.rs new file mode 100644 index 0000000000000..7f846358eafe0 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/invalidation.rs @@ -0,0 +1,103 @@ +use std::fmt::{Display, Formatter}; + +use hyper::{Method, Uri}; +use indexmap::IndexSet; +use turbo_tasks::{util::StaticOrArc, InvalidationReason, InvalidationReasonKind}; + +/// Computation was caused by a request to the server. +#[derive(PartialEq, Eq, Hash)] +pub struct ServerRequest { + pub method: Method, + pub uri: Uri, +} + +impl InvalidationReason for ServerRequest { + fn kind(&self) -> Option> { + Some(StaticOrArc::Static(&SERVER_REQUEST_KIND)) + } +} + +impl Display for ServerRequest { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{} {}", self.method, self.uri.path()) + } +} + +/// Invalidation kind for [ServerRequest] +#[derive(PartialEq, Eq, Hash)] +struct ServerRequestKind; + +static SERVER_REQUEST_KIND: ServerRequestKind = ServerRequestKind; + +impl InvalidationReasonKind for ServerRequestKind { + fn fmt( + &self, + reasons: &IndexSet>, + f: &mut Formatter<'_>, + ) -> std::fmt::Result { + let example = reasons + .into_iter() + .map(|reason| reason.as_any().downcast_ref::().unwrap()) + .min_by_key(|reason| reason.uri.path().len()) + .unwrap(); + write!( + f, + "{} requests ({} {}, ...)", + reasons.len(), + example.method, + example.uri.path() + ) + } +} + +/// Side effect that was caused by a request to the server. +#[derive(PartialEq, Eq, Hash)] +pub struct ServerRequestSideEffects { + pub method: Method, + pub uri: Uri, +} + +impl InvalidationReason for ServerRequestSideEffects { + fn kind(&self) -> Option> { + Some(StaticOrArc::Static(&SERVER_REQUEST_SIDE_EFFECTS_KIND)) + } +} + +impl Display for ServerRequestSideEffects { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "side effects of {} {}", self.method, self.uri.path()) + } +} + +/// Invalidation kind for [ServerRequestSideEffects] +#[derive(PartialEq, Eq, Hash)] +struct ServerRequestSideEffectsKind; + +static SERVER_REQUEST_SIDE_EFFECTS_KIND: ServerRequestSideEffectsKind = + ServerRequestSideEffectsKind; + +impl InvalidationReasonKind for ServerRequestSideEffectsKind { + fn fmt( + &self, + reasons: &IndexSet>, + f: &mut Formatter<'_>, + ) -> std::fmt::Result { + let example = reasons + .into_iter() + .map(|reason| { + reason + .as_any() + .downcast_ref::() + .unwrap() + }) + .min_by_key(|reason| reason.uri.path().len()) + .unwrap(); + write!( + f, + "side effects of {} requests ({} {}, ...)", + reasons.len(), + example.method, + example.uri.path() + ) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/lib.rs b/turbopack/crates/turbopack-dev-server/src/lib.rs new file mode 100644 index 0000000000000..41ccae1a02fb9 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/lib.rs @@ -0,0 +1,300 @@ +#![feature(min_specialization)] +#![feature(trait_alias)] +#![feature(array_chunks)] +#![feature(iter_intersperse)] +#![feature(str_split_remainder)] +#![feature(arbitrary_self_types)] + +pub mod html; +mod http; +pub mod introspect; +mod invalidation; +pub mod source; +pub mod update; + +use std::{ + collections::VecDeque, + future::Future, + net::{SocketAddr, TcpListener}, + pin::Pin, + sync::Arc, + time::{Duration, Instant}, +}; + +use anyhow::{Context, Result}; +use hyper::{ + server::{conn::AddrIncoming, Builder}, + service::{make_service_fn, service_fn}, + Request, Response, Server, +}; +use parking_lot::Mutex; +use socket2::{Domain, Protocol, Socket, Type}; +use tokio::task::JoinHandle; +use tracing::{event, info_span, Instrument, Level, Span}; +use turbo_tasks::{ + run_once_with_reason, trace::TraceRawVcs, util::FormatDuration, TurboTasksApi, Vc, +}; +use turbopack_core::{ + error::PrettyPrintError, + issue::{handle_issues, IssueReporter, IssueSeverity}, +}; + +use self::{source::ContentSource, update::UpdateServer}; +use crate::{ + invalidation::{ServerRequest, ServerRequestSideEffects}, + source::ContentSourceSideEffect, +}; + +pub trait SourceProvider: Send + Clone + 'static { + /// must call a turbo-tasks function internally + fn get_source(&self) -> Vc>; +} + +impl SourceProvider for T +where + T: Fn() -> Vc> + Send + Clone + 'static, +{ + fn get_source(&self) -> Vc> { + self() + } +} + +#[derive(TraceRawVcs, Debug)] +pub struct DevServerBuilder { + #[turbo_tasks(trace_ignore)] + pub addr: SocketAddr, + #[turbo_tasks(trace_ignore)] + server: Builder, +} + +#[derive(TraceRawVcs)] +pub struct DevServer { + #[turbo_tasks(trace_ignore)] + pub addr: SocketAddr, + #[turbo_tasks(trace_ignore)] + pub future: Pin> + Send + 'static>>, +} + +impl DevServer { + pub fn listen(addr: SocketAddr) -> Result { + // This is annoying. The hyper::Server doesn't allow us to know which port was + // bound (until we build it with a request handler) when using the standard + // `server::try_bind` approach. This is important when binding the `0` port, + // because the OS will remap that to an actual free port, and we need to know + // that port before we build the request handler. So we need to construct a + // real TCP listener, see if it bound, and get its bound address. + let socket = Socket::new(Domain::for_address(addr), Type::STREAM, Some(Protocol::TCP)) + .context("unable to create socket")?; + // Allow the socket to be reused immediately after closing. This ensures that + // the dev server can be restarted on the same address without a buffer time for + // the OS to release the socket. + // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse + #[cfg(not(windows))] + let _ = socket.set_reuse_address(true); + if matches!(addr, SocketAddr::V6(_)) { + // When possible bind to v4 and v6, otherwise ignore the error + let _ = socket.set_only_v6(false); + } + let sock_addr = addr.into(); + socket + .bind(&sock_addr) + .context("not able to bind address")?; + socket.listen(128).context("not able to listen on socket")?; + + let listener: TcpListener = socket.into(); + let addr = listener + .local_addr() + .context("not able to get bound address")?; + let server = Server::from_tcp(listener).context("Not able to start server")?; + Ok(DevServerBuilder { addr, server }) + } +} + +impl DevServerBuilder { + pub fn serve( + self, + turbo_tasks: Arc, + source_provider: impl SourceProvider + Sync, + get_issue_reporter: Arc Vc> + Send + Sync>, + ) -> DevServer { + let ongoing_side_effects = Arc::new(Mutex::new(VecDeque::< + Arc>>>>, + >::with_capacity(16))); + let make_svc = make_service_fn(move |_| { + let tt = turbo_tasks.clone(); + let source_provider = source_provider.clone(); + let get_issue_reporter = get_issue_reporter.clone(); + let ongoing_side_effects = ongoing_side_effects.clone(); + async move { + let handler = move |request: Request| { + let request_span = info_span!(parent: None, "request", name = ?request.uri()); + let start = Instant::now(); + let tt = tt.clone(); + let get_issue_reporter = get_issue_reporter.clone(); + let ongoing_side_effects = ongoing_side_effects.clone(); + let source_provider = source_provider.clone(); + let future = async move { + event!(parent: Span::current(), Level::DEBUG, "request start"); + // Wait until all ongoing side effects are completed + // We only need to wait for the ongoing side effects that were started + // before this request. Later added side effects are not relevant for this. + let current_ongoing_side_effects = { + // Cleanup the ongoing_side_effects list + let mut guard = ongoing_side_effects.lock(); + while let Some(front) = guard.front() { + let Ok(front_guard) = front.try_lock() else { + break; + }; + if front_guard.is_some() { + break; + } + drop(front_guard); + guard.pop_front(); + } + // Get a clone of the remaining list + (*guard).clone() + }; + // Wait for the side effects to complete + for side_effect_mutex in current_ongoing_side_effects { + let mut guard = side_effect_mutex.lock().await; + if let Some(join_handle) = guard.take() { + join_handle.await??; + } + drop(guard); + } + let reason = ServerRequest { + method: request.method().clone(), + uri: request.uri().clone(), + }; + let side_effects_reason = ServerRequestSideEffects { + method: request.method().clone(), + uri: request.uri().clone(), + }; + run_once_with_reason(tt.clone(), reason, async move { + let issue_reporter = get_issue_reporter(); + + if hyper_tungstenite::is_upgrade_request(&request) { + let uri = request.uri(); + let path = uri.path(); + + if path == "/turbopack-hmr" { + let (response, websocket) = + hyper_tungstenite::upgrade(request, None)?; + let update_server = + UpdateServer::new(source_provider, issue_reporter); + update_server.run(&*tt, websocket); + return Ok(response); + } + + println!("[404] {} (WebSocket)", path); + if path == "/_next/webpack-hmr" { + // Special-case requests to webpack-hmr as these are made by + // Next.js clients built + // without turbopack, which may be making requests in + // development. + println!( + "A non-turbopack next.js client is trying to connect." + ); + println!( + "Make sure to reload/close any browser window which has \ + been opened without --turbo." + ); + } + + return Ok(Response::builder() + .status(404) + .body(hyper::Body::empty())?); + } + + let uri = request.uri(); + let path = uri.path().to_string(); + let source = source_provider.get_source(); + let resolved_source = source.resolve_strongly_consistent().await?; + handle_issues( + source, + issue_reporter, + IssueSeverity::Fatal.cell(), + Some(&path), + Some("get source"), + ) + .await?; + let (response, side_effects) = + http::process_request_with_content_source( + resolved_source, + request, + issue_reporter, + ) + .await?; + let status = response.status().as_u16(); + let is_error = response.status().is_client_error() + || response.status().is_server_error(); + let elapsed = start.elapsed(); + if is_error + || (cfg!(feature = "log_request_stats") + && elapsed > Duration::from_secs(1)) + { + println!( + "[{status}] {path} ({duration})", + duration = FormatDuration(elapsed) + ); + } + if !side_effects.is_empty() { + let join_handle = tokio::spawn(run_once_with_reason( + tt.clone(), + side_effects_reason, + async move { + for side_effect in side_effects { + side_effect.apply().await?; + } + Ok(()) + }, + )); + ongoing_side_effects.lock().push_back(Arc::new( + tokio::sync::Mutex::new(Some(join_handle)), + )); + } + Ok(response) + }) + .await + }; + async move { + match future.await { + Ok(r) => Ok::<_, hyper::http::Error>(r), + Err(e) => { + println!( + "[500] error ({}): {}", + FormatDuration(start.elapsed()), + PrettyPrintError(&e), + ); + Ok(Response::builder() + .status(500) + .body(hyper::Body::from(format!("{}", PrettyPrintError(&e))))?) + } + } + } + .instrument(request_span) + }; + anyhow::Ok(service_fn(handler)) + } + }); + let server = self.server.serve(make_svc); + + DevServer { + addr: self.addr, + future: Box::pin(async move { + server.await?; + Ok(()) + }), + } + } +} + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_bytes::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_cli_utils::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/asset_graph.rs b/turbopack/crates/turbopack-dev-server/src/source/asset_graph.rs new file mode 100644 index 0000000000000..9d95aa7d644ca --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/asset_graph.rs @@ -0,0 +1,380 @@ +use std::{ + collections::{HashSet, VecDeque}, + iter::once, +}; + +use anyhow::Result; +use indexmap::{indexset, IndexMap, IndexSet}; +use turbo_tasks::{Completion, RcStr, State, TryJoinIterExt, Value, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + asset::Asset, + introspect::{output_asset::IntrospectableOutputAsset, Introspectable, IntrospectableChildren}, + output::{OutputAsset, OutputAssetsSet}, +}; + +use super::{ + route_tree::{BaseSegment, RouteTree, RouteTrees, RouteType}, + ContentSource, ContentSourceContent, ContentSourceData, ContentSourceSideEffect, + GetContentSourceContent, +}; + +#[turbo_tasks::value(transparent)] +struct OutputAssetsMap(IndexMap>>); + +type ExpandedState = State>; + +#[turbo_tasks::value(serialization = "none", eq = "manual", cell = "new")] +pub struct AssetGraphContentSource { + root_path: Vc, + root_assets: Vc, + expanded: Option, +} + +#[turbo_tasks::value_impl] +impl AssetGraphContentSource { + /// Serves all assets references by root_asset. + #[turbo_tasks::function] + pub fn new_eager( + root_path: Vc, + root_asset: Vc>, + ) -> Vc { + Self::cell(AssetGraphContentSource { + root_path, + root_assets: Vc::cell(indexset! { root_asset }), + expanded: None, + }) + } + + /// Serves all assets references by root_asset. Only serve references of an + /// asset when it has served its content before. + #[turbo_tasks::function] + pub fn new_lazy( + root_path: Vc, + root_asset: Vc>, + ) -> Vc { + Self::cell(AssetGraphContentSource { + root_path, + root_assets: Vc::cell(indexset! { root_asset }), + expanded: Some(State::new(HashSet::new())), + }) + } + + /// Serves all assets references by all root_assets. + #[turbo_tasks::function] + pub fn new_eager_multiple( + root_path: Vc, + root_assets: Vc, + ) -> Vc { + Self::cell(AssetGraphContentSource { + root_path, + root_assets, + expanded: None, + }) + } + + /// Serves all assets references by all root_assets. Only serve references + /// of an asset when it has served its content before. + #[turbo_tasks::function] + pub fn new_lazy_multiple( + root_path: Vc, + root_assets: Vc, + ) -> Vc { + Self::cell(AssetGraphContentSource { + root_path, + root_assets, + expanded: Some(State::new(HashSet::new())), + }) + } + + #[turbo_tasks::function] + async fn all_assets_map(self: Vc) -> Result> { + let this = self.await?; + Ok(Vc::cell( + expand( + &*this.root_assets.await?, + &*this.root_path.await?, + this.expanded.as_ref(), + ) + .await?, + )) + } +} + +async fn expand( + root_assets: &IndexSet>>, + root_path: &FileSystemPath, + expanded: Option<&ExpandedState>, +) -> Result>>> { + let mut map = IndexMap::new(); + let mut assets = Vec::new(); + let mut queue = VecDeque::with_capacity(32); + let mut assets_set = HashSet::new(); + let root_assets_with_path = root_assets + .iter() + .map(|&asset| async move { + let path = asset.ident().path().await?; + Ok((path, asset)) + }) + .try_join() + .await?; + + if let Some(expanded) = &expanded { + let expanded = expanded.get(); + for (path, root_asset) in root_assets_with_path.into_iter() { + if let Some(sub_path) = root_path.get_path_to(&path) { + let (sub_paths_buffer, sub_paths) = get_sub_paths(sub_path); + let expanded = sub_paths_buffer + .iter() + .take(sub_paths) + .any(|sub_path| expanded.contains(sub_path)); + for sub_path in sub_paths_buffer.into_iter().take(sub_paths) { + assets.push((sub_path, root_asset)); + } + assets_set.insert(root_asset); + if expanded { + queue.push_back(root_asset.references()); + } + } + } + } else { + for (path, root_asset) in root_assets_with_path.into_iter() { + if let Some(sub_path) = root_path.get_path_to(&path) { + let (sub_paths_buffer, sub_paths) = get_sub_paths(sub_path); + for sub_path in sub_paths_buffer.into_iter().take(sub_paths) { + assets.push((sub_path, root_asset)); + } + queue.push_back(root_asset.references()); + assets_set.insert(root_asset); + } + } + } + + while let Some(references) = queue.pop_front() { + for asset in references.await?.iter() { + if assets_set.insert(*asset) { + let path = asset.ident().path().await?; + if let Some(sub_path) = root_path.get_path_to(&path) { + let (sub_paths_buffer, sub_paths) = get_sub_paths(sub_path); + let expanded = if let Some(expanded) = &expanded { + let expanded = expanded.get(); + sub_paths_buffer + .iter() + .take(sub_paths) + .any(|sub_path| expanded.contains(sub_path)) + } else { + true + }; + if expanded { + queue.push_back(asset.references()); + } + for sub_path in sub_paths_buffer.into_iter().take(sub_paths) { + assets.push((sub_path, *asset)); + } + } + } + } + } + for (sub_path, asset) in assets { + let asset = asset.resolve().await?; + if &*sub_path == "index.html" { + map.insert("".into(), asset); + } else if let Some(p) = sub_path.strip_suffix("/index.html") { + map.insert(p.into(), asset); + map.insert(format!("{p}/").into(), asset); + } else if let Some(p) = sub_path.strip_suffix(".html") { + map.insert(p.into(), asset); + } + map.insert(sub_path, asset); + } + Ok(map) +} + +fn get_sub_paths(sub_path: &str) -> ([RcStr; 3], usize) { + let sub_paths_buffer: [RcStr; 3]; + let n = if sub_path == "index.html" { + sub_paths_buffer = ["".into(), sub_path.into(), Default::default()]; + 2 + } else if let Some(p) = sub_path.strip_suffix("/index.html") { + sub_paths_buffer = [p.into(), format!("{p}/").into(), sub_path.into()]; + 3 + } else if let Some(p) = sub_path.strip_suffix(".html") { + sub_paths_buffer = [p.into(), sub_path.into(), Default::default()]; + 2 + } else { + sub_paths_buffer = [sub_path.into(), Default::default(), Default::default()]; + 1 + }; + (sub_paths_buffer, n) +} + +#[turbo_tasks::value_impl] +impl ContentSource for AssetGraphContentSource { + #[turbo_tasks::function] + async fn get_routes(self: Vc) -> Result> { + let assets = self.all_assets_map().strongly_consistent().await?; + let mut paths = Vec::new(); + let routes = assets + .iter() + .map(|(path, asset)| { + paths.push(path.as_str()); + RouteTree::new_route( + BaseSegment::from_static_pathname(path).collect(), + RouteType::Exact, + Vc::upcast(AssetGraphGetContentSourceContent::new( + self, + path.clone(), + *asset, + )), + ) + }) + .collect(); + Ok(Vc::::cell(routes).merge()) + } +} + +#[turbo_tasks::value] +struct AssetGraphGetContentSourceContent { + source: Vc, + path: RcStr, + asset: Vc>, +} + +#[turbo_tasks::value_impl] +impl AssetGraphGetContentSourceContent { + #[turbo_tasks::function] + pub fn new( + source: Vc, + path: RcStr, + asset: Vc>, + ) -> Vc { + Self::cell(AssetGraphGetContentSourceContent { + source, + path, + asset, + }) + } +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for AssetGraphGetContentSourceContent { + #[turbo_tasks::function] + async fn get( + self: Vc, + _path: RcStr, + _data: Value, + ) -> Result> { + let this = self.await?; + turbo_tasks::emit(Vc::upcast::>(self)); + Ok(ContentSourceContent::static_content( + this.asset.versioned_content(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ContentSourceSideEffect for AssetGraphGetContentSourceContent { + #[turbo_tasks::function] + async fn apply(&self) -> Result> { + let source = self.source.await?; + + if let Some(expanded) = &source.expanded { + expanded.update_conditionally(|expanded| expanded.insert(self.path.clone())); + } + Ok(Completion::new()) + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("asset graph content source".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for AssetGraphContentSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + self.root_path.to_string() + } + + #[turbo_tasks::function] + fn details(&self) -> Vc { + Vc::cell(if let Some(expanded) = &self.expanded { + format!("{} assets expanded", expanded.get().len()).into() + } else { + "eager".into() + }) + } + + #[turbo_tasks::function] + async fn children(self: Vc) -> Result> { + let this = self.await?; + let key = Vc::cell("root".into()); + let inner_key = Vc::cell("inner".into()); + let expanded_key = Vc::cell("expanded".into()); + + let root_assets = this.root_assets.await?; + let root_asset_children = root_assets + .iter() + .map(|&asset| (key, IntrospectableOutputAsset::new(Vc::upcast(asset)))); + + let expanded_assets = self.all_assets_map().await?; + let expanded_asset_children = expanded_assets + .values() + .filter(|a| !root_assets.contains(*a)) + .map(|asset| { + ( + inner_key, + IntrospectableOutputAsset::new(Vc::upcast(*asset)), + ) + }); + + Ok(Vc::cell( + root_asset_children + .chain(expanded_asset_children) + .chain(once((expanded_key, Vc::upcast(FullyExpaned(self).cell())))) + .collect(), + )) + } +} + +#[turbo_tasks::function] +fn fully_expaned_introspectable_type() -> Vc { + Vc::cell("fully expanded asset graph content source".into()) +} + +#[turbo_tasks::value] +struct FullyExpaned(Vc); + +#[turbo_tasks::value_impl] +impl Introspectable for FullyExpaned { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + fully_expaned_introspectable_type() + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + Ok(self.0.await?.root_path.to_string()) + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + let source = self.0.await?; + let key = Vc::cell("asset".into()); + + let expanded_assets = + expand(&*source.root_assets.await?, &*source.root_path.await?, None).await?; + let children = expanded_assets + .iter() + .map(|(_k, &v)| (key, IntrospectableOutputAsset::new(v))) + .collect(); + + Ok(Vc::cell(children)) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/combined.rs b/turbopack/crates/turbopack-dev-server/src/source/combined.rs new file mode 100644 index 0000000000000..f466d898b612f --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/combined.rs @@ -0,0 +1,97 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, TryJoinIterExt, Vc}; +use turbopack_core::introspect::{Introspectable, IntrospectableChildren}; + +use super::{ + route_tree::{RouteTree, RouteTrees}, + ContentSource, +}; +use crate::source::ContentSources; + +/// Combines multiple [ContentSource]s by trying all content sources in order. +/// The content source which responds with the most specific response (that is +/// not a [ContentSourceContent::NotFound]) will be returned. +#[turbo_tasks::value(shared)] +pub struct CombinedContentSource { + pub sources: Vec>>, +} + +impl CombinedContentSource { + pub fn new(sources: Vec>>) -> Vc { + CombinedContentSource { sources }.cell() + } +} + +#[turbo_tasks::value_impl] +impl ContentSource for CombinedContentSource { + #[turbo_tasks::function] + fn get_routes(&self) -> Vc { + let all_routes = self.sources.iter().map(|s| s.get_routes()).collect(); + Vc::::cell(all_routes).merge() + } + + #[turbo_tasks::function] + fn get_children(&self) -> Vc { + Vc::cell(self.sources.clone()) + } +} + +#[turbo_tasks::value_impl] +impl Introspectable for CombinedContentSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + Vc::cell("combined content source".into()) + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + let titles = self + .sources + .iter() + .map(|&source| async move { + Ok( + if let Some(source) = + Vc::try_resolve_sidecast::>(source).await? + { + Some(source.title().await?) + } else { + None + }, + ) + }) + .try_join() + .await?; + let mut titles = titles.into_iter().flatten().collect::>(); + titles.sort(); + const NUMBER_OF_TITLES_TO_DISPLAY: usize = 5; + let mut titles = titles + .iter() + .map(|t| t.as_str()) + .filter(|t| !t.is_empty()) + .take(NUMBER_OF_TITLES_TO_DISPLAY + 1) + .collect::>(); + if titles.len() > NUMBER_OF_TITLES_TO_DISPLAY { + titles[NUMBER_OF_TITLES_TO_DISPLAY] = "..."; + } + Ok(Vc::cell(titles.join(", ").into())) + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + let source = Vc::cell("source".into()); + Ok(Vc::cell( + self.sources + .iter() + .copied() + .map(|s| async move { + Ok(Vc::try_resolve_sidecast::>(s).await?) + }) + .try_join() + .await? + .into_iter() + .flatten() + .map(|i| (source, i)) + .collect(), + )) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/conditional.rs b/turbopack/crates/turbopack-dev-server/src/source/conditional.rs new file mode 100644 index 0000000000000..6638ef21a6235 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/conditional.rs @@ -0,0 +1,182 @@ +use anyhow::Result; +use turbo_tasks::{Completion, RcStr, State, Value, Vc}; +use turbopack_core::introspect::{Introspectable, IntrospectableChildren}; + +use super::{ + route_tree::{MapGetContentSourceContent, RouteTree, RouteTrees}, + ContentSource, ContentSourceData, ContentSourceDataVary, ContentSourceSideEffect, + GetContentSourceContent, +}; +use crate::source::{ContentSourceContent, ContentSources}; + +/// Combines two [ContentSource]s like the [CombinedContentSource], but only +/// allows to serve from the second source when the first source has +/// successfully served something once. +/// This is a laziness optimization when the content of the second source can +/// only be reached via references from the first source. +/// +/// For example, we use that in the content source that handles SSR rendering of +/// pages. Here HTML and "other assets" are in different content sources. So we +/// use this source to only serve (and process) "other assets" when the HTML was +/// served once. +#[turbo_tasks::value(serialization = "none", eq = "manual", cell = "new")] +pub struct ConditionalContentSource { + activator: Vc>, + action: Vc>, + activated: State, +} + +#[turbo_tasks::value_impl] +impl ConditionalContentSource { + #[turbo_tasks::function] + pub fn new( + activator: Vc>, + action: Vc>, + ) -> Vc { + ConditionalContentSource { + activator, + action, + activated: State::new(false), + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl ContentSource for ConditionalContentSource { + #[turbo_tasks::function] + async fn get_routes(self: Vc) -> Result> { + let this = self.await?; + Ok(if !*this.activated.get() { + this.activator.get_routes().map_routes(Vc::upcast( + ConditionalContentSourceMapper { source: self }.cell(), + )) + } else { + Vc::::cell(vec![this.activator.get_routes(), this.action.get_routes()]) + .merge() + }) + } + + #[turbo_tasks::function] + fn get_children(&self) -> Vc { + Vc::cell(vec![self.activator, self.action]) + } +} + +#[turbo_tasks::value] +struct ConditionalContentSourceMapper { + source: Vc, +} + +#[turbo_tasks::value_impl] +impl MapGetContentSourceContent for ConditionalContentSourceMapper { + #[turbo_tasks::function] + fn map_get_content( + &self, + get_content: Vc>, + ) -> Vc> { + Vc::upcast( + ActivateOnGetContentSource { + source: self.source, + get_content, + } + .cell(), + ) + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("conditional content source".into()) +} + +#[turbo_tasks::function] +fn activator_key() -> Vc { + Vc::cell("activator".into()) +} + +#[turbo_tasks::function] +fn action_key() -> Vc { + Vc::cell("action".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for ConditionalContentSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + async fn details(&self) -> Result> { + Ok(Vc::cell( + if *self.activated.get() { + "activated" + } else { + "not activated" + } + .into(), + )) + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + if let Some(activator) = + Vc::try_resolve_sidecast::>(self.activator).await? + { + Ok(activator.title()) + } else { + Ok(Vc::::default()) + } + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + Ok(Vc::cell( + [ + Vc::try_resolve_sidecast::>(self.activator) + .await? + .map(|i| (activator_key(), i)), + Vc::try_resolve_sidecast::>(self.action) + .await? + .map(|i| (action_key(), i)), + ] + .into_iter() + .flatten() + .collect(), + )) + } +} + +#[turbo_tasks::value(serialization = "none", eq = "manual", cell = "new")] +struct ActivateOnGetContentSource { + source: Vc, + get_content: Vc>, +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for ActivateOnGetContentSource { + #[turbo_tasks::function] + fn vary(&self) -> Vc { + self.get_content.vary() + } + + #[turbo_tasks::function] + async fn get( + self: Vc, + path: RcStr, + data: Value, + ) -> Result> { + turbo_tasks::emit(Vc::upcast::>(self)); + Ok(self.await?.get_content.get(path, data)) + } +} + +#[turbo_tasks::value_impl] +impl ContentSourceSideEffect for ActivateOnGetContentSource { + #[turbo_tasks::function] + async fn apply(&self) -> Result> { + self.source.await?.activated.set(true); + Ok(Completion::new()) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/headers.rs b/turbopack/crates/turbopack-dev-server/src/source/headers.rs new file mode 100644 index 0000000000000..55699bf070fcf --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/headers.rs @@ -0,0 +1,77 @@ +use std::{collections::BTreeMap, hash::Hash, mem::replace, ops::DerefMut}; + +use serde::{Deserialize, Serialize}; +use turbo_tasks::trace::TraceRawVcs; + +/// A parsed query string from a http request +#[derive(Clone, Debug, PartialEq, Eq, Default, Hash, TraceRawVcs, Serialize, Deserialize)] +#[serde(transparent)] +pub struct Headers(BTreeMap); + +/// The value of an http header. HTTP headers might contain non-utf-8 bytes. An +/// header might also occur multiple times. +#[derive(Clone, Debug, PartialEq, Eq, Hash, TraceRawVcs, Serialize, Deserialize)] +#[serde(untagged)] +pub enum HeaderValue { + SingleString(String), + SingleBytes(Vec), + MultiStrings(Vec), + MultiBytes(Vec>), +} + +impl std::ops::Deref for Headers { + type Target = BTreeMap; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Headers { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +impl HeaderValue { + /// Extends the current value with another occurrence of that header which + /// is a string + pub fn extend_with_string(&mut self, new: String) { + *self = match replace(self, HeaderValue::SingleBytes(Vec::new())) { + HeaderValue::SingleString(s) => HeaderValue::MultiStrings(vec![s, new]), + HeaderValue::SingleBytes(b) => HeaderValue::MultiBytes(vec![b, new.into()]), + HeaderValue::MultiStrings(mut v) => { + v.push(new); + HeaderValue::MultiStrings(v) + } + HeaderValue::MultiBytes(mut v) => { + v.push(new.into()); + HeaderValue::MultiBytes(v) + } + } + } + /// Extends the current value with another occurrence of that header which + /// is a non-utf-8 valid byte sequence + pub fn extend_with_bytes(&mut self, new: Vec) { + *self = match replace(self, HeaderValue::SingleBytes(Vec::new())) { + HeaderValue::SingleString(s) => HeaderValue::MultiBytes(vec![s.into(), new]), + HeaderValue::SingleBytes(b) => HeaderValue::MultiBytes(vec![b, new]), + HeaderValue::MultiStrings(v) => { + let mut v: Vec> = v.into_iter().map(|s| s.into()).collect(); + v.push(new); + HeaderValue::MultiBytes(v) + } + HeaderValue::MultiBytes(mut v) => { + v.push(new); + HeaderValue::MultiBytes(v) + } + } + } + + pub fn contains(&self, string_value: &str) -> bool { + match self { + HeaderValue::SingleString(s) => s.contains(string_value), + HeaderValue::MultiStrings(s) => s.iter().any(|s| s.contains(string_value)), + _ => false, + } + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/issue_context.rs b/turbopack/crates/turbopack-dev-server/src/source/issue_context.rs new file mode 100644 index 0000000000000..e127955c19c73 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/issue_context.rs @@ -0,0 +1,181 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + introspect::{Introspectable, IntrospectableChildren}, + issue::IssueDescriptionExt, +}; + +use super::{ + route_tree::{MapGetContentSourceContent, RouteTree}, + ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataVary, ContentSources, + GetContentSourceContent, +}; + +#[turbo_tasks::value] +pub struct IssueFilePathContentSource { + file_path: Option>, + description: RcStr, + source: Vc>, +} + +#[turbo_tasks::value_impl] +impl IssueFilePathContentSource { + #[turbo_tasks::function] + pub fn new_file_path( + file_path: Vc, + description: RcStr, + source: Vc>, + ) -> Vc { + IssueFilePathContentSource { + file_path: Some(file_path), + description, + source, + } + .cell() + } + + #[turbo_tasks::function] + pub fn new_description(description: RcStr, source: Vc>) -> Vc { + IssueFilePathContentSource { + file_path: None, + description, + source, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl ContentSource for IssueFilePathContentSource { + #[turbo_tasks::function] + async fn get_routes(self: Vc) -> Result> { + let this = self.await?; + let routes = this + .source + .get_routes() + .issue_file_path(this.file_path, &*this.description) + .await?; + Ok(routes.map_routes(Vc::upcast( + IssueContextContentSourceMapper { source: self }.cell(), + ))) + } + + #[turbo_tasks::function] + fn get_children(&self) -> Vc { + Vc::cell(vec![self.source]) + } +} + +#[turbo_tasks::value] +struct IssueContextContentSourceMapper { + source: Vc, +} + +#[turbo_tasks::value_impl] +impl MapGetContentSourceContent for IssueContextContentSourceMapper { + #[turbo_tasks::function] + fn map_get_content( + &self, + get_content: Vc>, + ) -> Vc> { + Vc::upcast( + IssueContextGetContentSourceContent { + get_content, + source: self.source, + } + .cell(), + ) + } +} + +#[turbo_tasks::value] +struct IssueContextGetContentSourceContent { + get_content: Vc>, + source: Vc, +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for IssueContextGetContentSourceContent { + #[turbo_tasks::function] + async fn vary(&self) -> Result> { + let source = self.source.await?; + let result = self + .get_content + .vary() + .issue_file_path(source.file_path, &*source.description) + .await?; + Ok(result) + } + + #[turbo_tasks::function] + async fn get( + &self, + path: RcStr, + data: Value, + ) -> Result> { + let source = self.source.await?; + let result = self + .get_content + .get(path, data) + .issue_file_path(source.file_path, &*source.description) + .await?; + Ok(result) + } +} + +#[turbo_tasks::value_impl] +impl Introspectable for IssueFilePathContentSource { + #[turbo_tasks::function] + async fn ty(&self) -> Result> { + Ok( + if let Some(source) = + Vc::try_resolve_sidecast::>(self.source).await? + { + source.ty() + } else { + Vc::cell("IssueContextContentSource".into()) + }, + ) + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + Ok( + if let Some(source) = + Vc::try_resolve_sidecast::>(self.source).await? + { + let title = source.title().await?; + Vc::cell(format!("{}: {}", self.description, title).into()) + } else { + Vc::cell(self.description.clone()) + }, + ) + } + + #[turbo_tasks::function] + async fn details(&self) -> Result> { + Ok( + if let Some(source) = + Vc::try_resolve_sidecast::>(self.source).await? + { + source.details() + } else { + Vc::cell(RcStr::default()) + }, + ) + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + Ok( + if let Some(source) = + Vc::try_resolve_sidecast::>(self.source).await? + { + source.children() + } else { + Vc::cell(Default::default()) + }, + ) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/lazy_instantiated.rs b/turbopack/crates/turbopack-dev-server/src/source/lazy_instantiated.rs new file mode 100644 index 0000000000000..4841da72aa9c8 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/lazy_instantiated.rs @@ -0,0 +1,62 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::introspect::{Introspectable, IntrospectableChildren}; + +use super::{route_tree::RouteTree, ContentSource}; + +/// A functor to get a [ContentSource]. Will be invoked when needed when using +/// [LazyInstantiatedContentSource]. +#[turbo_tasks::value_trait] +pub trait GetContentSource { + /// Returns the [ContentSource] + fn content_source(self: Vc) -> Vc>; +} + +/// Wraps the [ContentSource] creation in a way that only creates it when +/// actually used. +#[turbo_tasks::value(shared)] +pub struct LazyInstantiatedContentSource { + pub get_source: Vc>, +} + +#[turbo_tasks::value_impl] +impl ContentSource for LazyInstantiatedContentSource { + #[turbo_tasks::function] + fn get_routes(&self) -> Vc { + self.get_source.content_source().get_routes() + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("lazy instantiated content source".into()) +} + +#[turbo_tasks::function] +fn source_key() -> Vc { + Vc::cell("source".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for LazyInstantiatedContentSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + Ok(Vc::cell( + [ + Vc::try_resolve_sidecast::>( + self.get_source.content_source(), + ) + .await? + .map(|i| (source_key(), i)), + ] + .into_iter() + .flatten() + .collect(), + )) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/mod.rs b/turbopack/crates/turbopack-dev-server/src/source/mod.rs new file mode 100644 index 0000000000000..0518db659f071 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/mod.rs @@ -0,0 +1,571 @@ +pub mod asset_graph; +pub mod combined; +pub mod conditional; +pub mod headers; +pub mod issue_context; +pub mod lazy_instantiated; +pub mod query; +pub mod request; +pub(crate) mod resolve; +pub mod route_tree; +pub mod router; +pub mod static_assets; +pub mod wrapping_source; + +use std::collections::BTreeSet; + +use anyhow::Result; +use futures::{stream::Stream as StreamTrait, TryStreamExt}; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{ + trace::TraceRawVcs, util::SharedError, Completion, RcStr, Upcast, Value, ValueDefault, Vc, +}; +use turbo_tasks_bytes::{Bytes, Stream, StreamRead}; +use turbo_tasks_fs::FileSystemPath; +use turbo_tasks_hash::{DeterministicHash, DeterministicHasher, Xxh3Hash64Hasher}; +use turbopack_core::version::{Version, VersionedContent}; + +use self::{ + headers::Headers, issue_context::IssueFilePathContentSource, query::Query, + route_tree::RouteTree, +}; + +/// The result of proxying a request to another HTTP server. +#[turbo_tasks::value(shared)] +pub struct ProxyResult { + /// The HTTP status code to return. + pub status: u16, + /// Headers arranged as contiguous (name, value) pairs. + pub headers: Vec<(RcStr, RcStr)>, + /// The body to return. + pub body: Body, +} + +#[turbo_tasks::value_impl] +impl Version for ProxyResult { + #[turbo_tasks::function] + async fn id(&self) -> Result> { + let mut hash = Xxh3Hash64Hasher::new(); + hash.write_u16(self.status); + for (name, value) in &self.headers { + name.deterministic_hash(&mut hash); + value.deterministic_hash(&mut hash); + } + let mut read = self.body.read(); + while let Some(chunk) = read.try_next().await? { + hash.write_bytes(&chunk); + } + Ok(Vc::cell(hash.finish().to_string().into())) + } +} + +/// A functor to receive the actual content of a content source result. +#[turbo_tasks::value_trait] +pub trait GetContentSourceContent { + /// Specifies data requirements for the get function. Restricting data + /// passed allows to cache the get method. + fn vary(self: Vc) -> Vc { + ContentSourceDataVary::default().cell() + } + + /// Get the content + fn get(self: Vc, path: RcStr, data: Value) + -> Vc; +} + +#[turbo_tasks::value(transparent)] +pub struct GetContentSourceContents(Vec>>); + +#[turbo_tasks::value] +pub struct StaticContent { + pub content: Vc>, + pub status_code: u16, + pub headers: Vc, +} + +#[turbo_tasks::value(shared)] +// TODO add Dynamic variant in future to allow streaming and server responses +/// The content of a result that is returned by a content source. +pub enum ContentSourceContent { + NotFound, + Static(Vc), + HttpProxy(Vc), + Rewrite(Vc), + /// Continue with the next route + Next, +} + +/// This trait can be emitted as collectible and will be applied after the +/// request is handled and it's ensured that it finishes before the next request +/// is handled. +#[turbo_tasks::value_trait] +pub trait ContentSourceSideEffect { + fn apply(self: Vc) -> Vc; +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for ContentSourceContent { + #[turbo_tasks::function] + fn get( + self: Vc, + _path: RcStr, + _data: Value, + ) -> Vc { + self + } +} + +#[turbo_tasks::value_impl] +impl ContentSourceContent { + #[turbo_tasks::function] + pub fn static_content(content: Vc>) -> Vc { + ContentSourceContent::Static( + StaticContent { + content, + status_code: 200, + headers: HeaderList::empty(), + } + .cell(), + ) + .cell() + } + + #[turbo_tasks::function] + pub fn static_with_headers( + content: Vc>, + status_code: u16, + headers: Vc, + ) -> Vc { + ContentSourceContent::Static( + StaticContent { + content, + status_code, + headers, + } + .cell(), + ) + .cell() + } + + #[turbo_tasks::function] + pub fn not_found() -> Vc { + ContentSourceContent::NotFound.cell() + } +} + +/// A list of headers arranged as contiguous (name, value) pairs. +#[turbo_tasks::value(transparent)] +pub struct HeaderList(Vec<(RcStr, RcStr)>); + +#[turbo_tasks::value_impl] +impl HeaderList { + #[turbo_tasks::function] + pub fn new(headers: Vec<(RcStr, RcStr)>) -> Vc { + HeaderList(headers).cell() + } + + #[turbo_tasks::function] + pub fn empty() -> Vc { + HeaderList(vec![]).cell() + } +} + +/// Additional info passed to the ContentSource. It was extracted from the http +/// request. +/// +/// Note that you might not receive information that has not been requested via +/// `ContentSource::vary()`. So make sure to request all information that's +/// needed. +#[turbo_tasks::value(shared, serialization = "auto_for_input")] +#[derive(Clone, Debug, Hash, Default)] +pub struct ContentSourceData { + /// HTTP method, if requested. + pub method: Option, + /// The full url (including query string), if requested. + pub url: Option, + /// The full url (including query string) before rewrites where applied, if + /// requested. + pub original_url: Option, + /// Query string items, if requested. + pub query: Option, + /// raw query string, if requested. Does not include the `?`. + pub raw_query: Option, + /// HTTP headers, might contain multiple headers with the same name, if + /// requested. + pub headers: Option, + /// Raw HTTP headers, might contain multiple headers with the same name, if + /// requested. + pub raw_headers: Option>, + /// Request body, if requested. + pub body: Option>, + /// See [ContentSourceDataVary::cache_buster]. + pub cache_buster: u64, +} + +pub type BodyChunk = Result; + +/// A request body. +#[turbo_tasks::value(shared)] +#[derive(Default, Clone, Debug)] +pub struct Body { + #[turbo_tasks(trace_ignore)] + chunks: Stream, +} + +impl Body { + /// Creates a new body from a list of chunks. + pub fn new(chunks: Vec) -> Self { + Self { + chunks: Stream::new_closed(chunks), + } + } + + /// Returns an iterator over the body's chunks. + pub fn read(&self) -> StreamRead { + self.chunks.read() + } + + pub fn from_stream + Send + Unpin + 'static>( + source: T, + ) -> Self { + Self { + chunks: Stream::from(source), + } + } +} + +impl> From for Body { + fn from(value: T) -> Self { + Body::new(vec![Ok(value.into())]) + } +} + +impl ValueDefault for Body { + fn value_default() -> Vc { + Body::default().cell() + } +} + +/// Filter function that describes which information is required. +#[derive(Debug, Clone, PartialEq, Eq, TraceRawVcs, Hash, Serialize, Deserialize)] +pub enum ContentSourceDataFilter { + All, + Subset(BTreeSet), +} + +impl ContentSourceDataFilter { + /// Merges the filtering to get a filter that covers both filters. + pub fn extend(&mut self, other: &ContentSourceDataFilter) { + match self { + ContentSourceDataFilter::All => {} + ContentSourceDataFilter::Subset(set) => match other { + ContentSourceDataFilter::All => *self = ContentSourceDataFilter::All, + ContentSourceDataFilter::Subset(set2) => set.extend(set2.iter().cloned()), + }, + } + } + + /// Merges the filtering to get a filter that covers both filters. Works on + /// Option where None is considers as empty filter. + pub fn extend_options( + this: &mut Option, + other: &Option, + ) { + if let Some(this) = this.as_mut() { + if let Some(other) = other.as_ref() { + this.extend(other); + } + } else { + this.clone_from(other); + } + } + + /// Returns true if the filter contains the given key. + pub fn contains(&self, key: &str) -> bool { + match self { + ContentSourceDataFilter::All => true, + ContentSourceDataFilter::Subset(set) => set.contains(key), + } + } + + /// Returns true if the first argument at least contains all values that the + /// second argument would contain. + pub fn fulfills( + this: &Option, + other: &Option, + ) -> bool { + match (this, other) { + (_, None) => true, + (None, Some(_)) => false, + (Some(this), Some(other)) => match (this, other) { + (ContentSourceDataFilter::All, _) => true, + (_, ContentSourceDataFilter::All) => false, + (ContentSourceDataFilter::Subset(this), ContentSourceDataFilter::Subset(other)) => { + this.is_superset(other) + } + }, + } + } +} + +/// Describes additional information that need to be sent to requests to +/// ContentSource. By sending these information ContentSource responses are +/// cached-keyed by them and they can access them. +#[turbo_tasks::value(shared, serialization = "auto_for_input")] +#[derive(Debug, Default, Clone, Hash)] +pub struct ContentSourceDataVary { + pub method: bool, + pub url: bool, + pub original_url: bool, + pub query: Option, + pub raw_query: bool, + pub headers: Option, + pub raw_headers: bool, + pub body: bool, + /// When true, a `cache_buster` value is added to the [ContentSourceData]. + /// This value will be different on every request, which ensures the + /// content is never cached. + pub cache_buster: bool, + pub placeholder_for_future_extensions: (), +} + +impl ContentSourceDataVary { + /// Merges two vary specification to create a combination of both that cover + /// all information requested by either one + pub fn extend(&mut self, other: &ContentSourceDataVary) { + let ContentSourceDataVary { + method, + url, + original_url, + query, + raw_query, + headers, + raw_headers, + body, + cache_buster, + placeholder_for_future_extensions: _, + } = self; + *method = *method || other.method; + *url = *url || other.url; + *original_url = *original_url || other.original_url; + *body = *body || other.body; + *cache_buster = *cache_buster || other.cache_buster; + *raw_query = *raw_query || other.raw_query; + *raw_headers = *raw_headers || other.raw_headers; + ContentSourceDataFilter::extend_options(query, &other.query); + ContentSourceDataFilter::extend_options(headers, &other.headers); + } + + /// Returns true if `self` at least contains all values that the + /// argument would contain. + pub fn fulfills(&self, other: &ContentSourceDataVary) -> bool { + // All fields must be used! + let ContentSourceDataVary { + method, + url, + original_url, + query, + raw_query, + headers, + raw_headers, + body, + cache_buster, + placeholder_for_future_extensions: _, + } = self; + if other.method && !method { + return false; + } + if other.url && !url { + return false; + } + if other.original_url && !original_url { + return false; + } + if other.body && !body { + return false; + } + if other.raw_query && !raw_query { + return false; + } + if other.raw_headers && !raw_headers { + return false; + } + if other.cache_buster && !cache_buster { + return false; + } + if !ContentSourceDataFilter::fulfills(query, &other.query) { + return false; + } + if !ContentSourceDataFilter::fulfills(headers, &other.headers) { + return false; + } + true + } +} + +/// A source of content that the dev server uses to respond to http requests. +#[turbo_tasks::value_trait] +pub trait ContentSource { + fn get_routes(self: Vc) -> Vc; + + /// Gets any content sources wrapped in this content source. + fn get_children(self: Vc) -> Vc { + ContentSources::empty() + } +} + +pub trait ContentSourceExt: Send { + fn issue_file_path( + self: Vc, + file_path: Vc, + description: RcStr, + ) -> Vc>; +} + +impl ContentSourceExt for T +where + T: Upcast>, +{ + fn issue_file_path( + self: Vc, + file_path: Vc, + description: RcStr, + ) -> Vc> { + Vc::upcast(IssueFilePathContentSource::new_file_path( + file_path, + description, + Vc::upcast(self), + )) + } +} + +#[turbo_tasks::value(transparent)] +pub struct ContentSources(Vec>>); + +#[turbo_tasks::value_impl] +impl ContentSources { + #[turbo_tasks::function] + pub fn empty() -> Vc { + Vc::cell(Vec::new()) + } +} + +/// An empty ContentSource implementation that responds with NotFound for every +/// request. +#[turbo_tasks::value] +pub struct NoContentSource; + +#[turbo_tasks::value_impl] +impl NoContentSource { + #[turbo_tasks::function] + pub fn new() -> Vc { + NoContentSource.cell() + } +} +#[turbo_tasks::value_impl] +impl ContentSource for NoContentSource { + #[turbo_tasks::function] + fn get_routes(&self) -> Vc { + RouteTree::empty() + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)] +pub enum RewriteType { + Location { + /// The new path and query used to lookup content. This _does not_ need + /// to be the original path or query. + path_and_query: RcStr, + }, + ContentSource { + /// [Vc>]s from which to restart the lookup + /// process. This _does not_ need to be the original content + /// source. + source: Vc>, + /// The new path and query used to lookup content. This _does not_ need + /// to be the original path or query. + path_and_query: RcStr, + }, + Sources { + /// [GetContentSourceContent]s from which to restart the lookup + /// process. This _does not_ need to be the original content + /// source. + sources: Vc, + }, +} + +/// A rewrite returned from a [ContentSource]. This tells the dev server to +/// update its parsed url, path, and queries with this new information. +#[turbo_tasks::value(shared)] +#[derive(Debug)] +pub struct Rewrite { + pub ty: RewriteType, + + /// A [Headers] which will be appended to the eventual, fully resolved + /// content result. This overwrites any previous matching headers. + pub response_headers: Option>, + + /// A [HeaderList] which will overwrite the values used during the lookup + /// process. All headers not present in this list will be deleted. + pub request_headers: Option>, +} + +pub struct RewriteBuilder { + rewrite: Rewrite, +} + +impl RewriteBuilder { + pub fn new(path_and_query: RcStr) -> Self { + Self { + rewrite: Rewrite { + ty: RewriteType::Location { path_and_query }, + response_headers: None, + request_headers: None, + }, + } + } + + pub fn new_source_with_path_and_query( + source: Vc>, + path_and_query: RcStr, + ) -> Self { + Self { + rewrite: Rewrite { + ty: RewriteType::ContentSource { + source, + path_and_query, + }, + response_headers: None, + request_headers: None, + }, + } + } + + pub fn new_sources(sources: Vc) -> Self { + Self { + rewrite: Rewrite { + ty: RewriteType::Sources { sources }, + response_headers: None, + request_headers: None, + }, + } + } + + /// Sets response headers to append to the eventual, fully resolved content + /// result. + pub fn response_headers(mut self, headers: Vc) -> Self { + self.rewrite.response_headers = Some(headers); + self + } + + /// Sets request headers to overwrite the headers used during the lookup + /// process. + pub fn request_headers(mut self, headers: Vc) -> Self { + self.rewrite.request_headers = Some(headers); + self + } + + pub fn build(self) -> Vc { + self.rewrite.cell() + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/query.rs b/turbopack/crates/turbopack-dev-server/src/source/query.rs new file mode 100644 index 0000000000000..372985ae7619b --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/query.rs @@ -0,0 +1,46 @@ +use std::{collections::BTreeMap, hash::Hash, ops::DerefMut}; + +use serde::{Deserialize, Serialize}; +use turbo_tasks::trace::TraceRawVcs; + +use super::ContentSourceDataFilter; + +/// A parsed query string from a http request +#[derive(Clone, Debug, PartialEq, Eq, Default, Hash, TraceRawVcs, Serialize, Deserialize)] +#[serde(transparent)] +pub struct Query(BTreeMap); + +impl Query { + pub fn filter_with(&mut self, filter: &ContentSourceDataFilter) { + match filter { + ContentSourceDataFilter::All => { + // fast path without iterating query + } + _ => self.0.retain(|k, _| filter.contains(k)), + } + } +} + +impl std::ops::Deref for Query { + type Target = BTreeMap; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Query { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash, TraceRawVcs, Serialize, Deserialize)] +#[serde(untagged)] +pub enum QueryValue { + /// Simple string value, might be an empty string when there is no value + String(String), + /// An array of values + Array(Vec), + /// A nested structure + Nested(Query), +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/request.rs b/turbopack/crates/turbopack-dev-server/src/source/request.rs new file mode 100644 index 0000000000000..23ba2395fe7dd --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/request.rs @@ -0,0 +1,16 @@ +use hyper::{HeaderMap, Uri}; + +use super::Body; + +/// A request to a content source. +#[derive(Debug, Clone)] +pub struct SourceRequest { + /// The HTTP method to use. + pub method: String, + /// The URI to request. + pub uri: Uri, + /// The headers to send. + pub headers: HeaderMap, + /// The body to send. + pub body: Body, +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/resolve.rs b/turbopack/crates/turbopack-dev-server/src/source/resolve.rs new file mode 100644 index 0000000000000..8b56aa7c6c4e0 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/resolve.rs @@ -0,0 +1,201 @@ +use std::{ + collections::btree_map::Entry, + sync::atomic::{AtomicU64, Ordering}, +}; + +use anyhow::Result; +use hyper::{ + header::{HeaderName as HyperHeaderName, HeaderValue as HyperHeaderValue}, + Uri, +}; +use turbo_tasks::{RcStr, TransientInstance, Value, Vc}; + +use super::{ + headers::{HeaderValue, Headers}, + query::Query, + request::SourceRequest, + ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataVary, + GetContentSourceContent, HeaderList, ProxyResult, RewriteType, StaticContent, +}; + +/// The result of [`resolve_source_request`]. Similar to a +/// `ContentSourceContent`, but without the `Rewrite` variant as this is taken +/// care in the function. +#[turbo_tasks::value(serialization = "none")] +pub enum ResolveSourceRequestResult { + NotFound, + Static(Vc, Vc), + HttpProxy(Vc), +} + +/// Resolves a [SourceRequest] within a [super::ContentSource], returning the +/// corresponding content. +/// +/// This function is the boundary of consistency. All invoked methods should be +/// invoked strongly consistent. This ensures that all requests serve the latest +/// version of the content. We don't make resolve_source_request strongly +/// consistent as we want get_routes and get to be independent consistent and +/// any side effect in get should not wait for recomputing of get_routes. +#[turbo_tasks::function] +pub async fn resolve_source_request( + source: Vc>, + request: TransientInstance, +) -> Result> { + let original_path = request.uri.path().to_string(); + // Remove leading slash. + let mut current_asset_path: RcStr = urlencoding::decode(&original_path[1..])?.into(); + let mut request_overwrites = (*request).clone(); + let mut response_header_overwrites = Vec::new(); + let mut route_tree = source.get_routes().resolve_strongly_consistent().await?; + 'routes: loop { + let mut sources = route_tree.get(current_asset_path.clone()); + 'sources: loop { + for get_content in sources.strongly_consistent().await?.iter() { + let content_vary = get_content.vary().strongly_consistent().await?; + let content_data = + request_to_data(&request_overwrites, &request, &content_vary).await?; + let content = get_content.get(current_asset_path.clone(), Value::new(content_data)); + match &*content.strongly_consistent().await? { + ContentSourceContent::Rewrite(rewrite) => { + let rewrite = rewrite.await?; + // apply rewrite extras + if let Some(headers) = &rewrite.response_headers { + response_header_overwrites.extend(headers.await?.iter().cloned()); + } + if let Some(headers) = &rewrite.request_headers { + request_overwrites.headers.clear(); + for (name, value) in &*headers.await? { + request_overwrites.headers.insert( + HyperHeaderName::try_from(name.as_str())?, + HyperHeaderValue::try_from(value.as_str())?, + ); + } + } + // do the rewrite + match &rewrite.ty { + RewriteType::Location { path_and_query } => { + let new_uri = Uri::try_from(path_and_query.as_str())?; + let new_asset_path = + urlencoding::decode(&new_uri.path()[1..])?.into_owned(); + request_overwrites.uri = new_uri; + current_asset_path = new_asset_path.into(); + continue 'routes; + } + RewriteType::ContentSource { + source, + path_and_query, + } => { + let new_uri = Uri::try_from(path_and_query.as_str())?; + let new_asset_path = + urlencoding::decode(&new_uri.path()[1..])?.into_owned(); + request_overwrites.uri = new_uri; + current_asset_path = new_asset_path.into(); + route_tree = + source.get_routes().resolve_strongly_consistent().await?; + continue 'routes; + } + RewriteType::Sources { + sources: new_sources, + } => { + sources = *new_sources; + continue 'sources; + } + } + } + ContentSourceContent::NotFound => { + return Ok(ResolveSourceRequestResult::NotFound.cell()); + } + ContentSourceContent::Static(static_content) => { + return Ok(ResolveSourceRequestResult::Static( + *static_content, + HeaderList::new(response_header_overwrites), + ) + .cell()); + } + ContentSourceContent::HttpProxy(proxy_result) => { + return Ok(ResolveSourceRequestResult::HttpProxy(*proxy_result).cell()); + } + ContentSourceContent::Next => continue, + } + } + break; + } + break; + } + Ok(ResolveSourceRequestResult::NotFound.cell()) +} + +static CACHE_BUSTER: AtomicU64 = AtomicU64::new(0); + +async fn request_to_data( + request: &SourceRequest, + original_request: &SourceRequest, + vary: &ContentSourceDataVary, +) -> Result { + let mut data = ContentSourceData::default(); + if vary.method { + data.method = Some(request.method.clone().into()); + } + if vary.url { + data.url = Some(request.uri.to_string().into()); + } + if vary.original_url { + data.original_url = Some(original_request.uri.to_string().into()); + } + if vary.body { + data.body = Some(request.body.clone().into()); + } + if vary.raw_query { + data.raw_query = Some(request.uri.query().unwrap_or("").into()); + } + if vary.raw_headers { + data.raw_headers = Some( + request + .headers + .iter() + .map(|(name, value)| { + Ok((name.to_string().into(), value.to_str()?.to_string().into())) + }) + .collect::>>()?, + ); + } + if let Some(filter) = vary.query.as_ref() { + if let Some(query) = request.uri.query() { + let mut query: Query = serde_qs::from_str(query)?; + query.filter_with(filter); + data.query = Some(query); + } else { + data.query = Some(Query::default()) + } + } + if let Some(filter) = vary.headers.as_ref() { + let mut headers = Headers::default(); + for (header_name, header_value) in request.headers.iter() { + if !filter.contains(header_name.as_str()) { + continue; + } + match headers.entry(header_name.to_string()) { + Entry::Vacant(e) => { + if let Ok(s) = header_value.to_str() { + e.insert(HeaderValue::SingleString(s.to_string())); + } else { + e.insert(HeaderValue::SingleBytes(header_value.as_bytes().to_vec())); + } + } + Entry::Occupied(mut e) => { + if let Ok(s) = header_value.to_str() { + e.get_mut().extend_with_string(s.to_string()); + } else { + e.get_mut() + .extend_with_bytes(header_value.as_bytes().to_vec()); + } + } + } + } + data.headers = Some(headers); + } + if vary.cache_buster { + data.cache_buster = CACHE_BUSTER.fetch_add(1, Ordering::SeqCst); + } + Ok(data) +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/route_tree.rs b/turbopack/crates/turbopack-dev-server/src/source/route_tree.rs new file mode 100644 index 0000000000000..2e29ee5df2117 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/route_tree.rs @@ -0,0 +1,396 @@ +use std::{fmt::Write, mem::replace}; + +use anyhow::Result; +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, RcStr, TaskInput, TryJoinIterExt, ValueToString, Vc}; + +use super::{GetContentSourceContent, GetContentSourceContents}; + +/// The type of the route. THis will decide about the remaining segements of the +/// route after the base. +#[derive(TaskInput, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, TraceRawVcs)] +pub enum RouteType { + Exact, + CatchAll, + Fallback, + NotFound, +} + +/// Some normal segment of a route. +#[derive(TaskInput, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, TraceRawVcs)] +pub enum BaseSegment { + Static(RcStr), + Dynamic, +} + +impl BaseSegment { + pub fn from_static_pathname(str: &str) -> impl Iterator + '_ { + str.split('/') + .filter(|s| !s.is_empty()) + .map(|s| BaseSegment::Static(s.into())) + } +} + +/// This struct allows to cell a list of RouteTrees and merge them into one. +/// This can't be a single method `fn merge(Vec>)` as this would +/// lead to creating new tasks over and over. A celled list leads to task reuse +/// and faster operation. +#[turbo_tasks::value(transparent)] +pub struct RouteTrees(Vec>); + +#[turbo_tasks::value_impl] +impl RouteTrees { + /// Merges the list of RouteTrees into one RouteTree. + #[turbo_tasks::function] + pub async fn merge(self: Vc) -> Result> { + let trees = &*self.await?; + if trees.is_empty() { + return Ok(RouteTree::default().cell()); + } + if trees.len() == 1 { + return Ok(*trees.iter().next().unwrap()); + } + + // Find common base + let mut tree_values = trees.iter().try_join().await?; + let mut common_base = 0; + let last_tree = tree_values.pop().unwrap(); + 'outer: while common_base < last_tree.base.len() { + for tree in tree_values.iter() { + if tree.base.len() <= common_base { + break 'outer; + } + if tree.base[common_base] != last_tree.base[common_base] { + break 'outer; + } + } + common_base += 1; + } + tree_values.push(last_tree); + + // Normalize bases to common base + let trees = trees + .iter() + .enumerate() + .map(|(i, tree)| { + if tree_values[i].base.len() > common_base { + tree.with_base_len(common_base) + } else { + *tree + } + }) + .collect::>(); + + // Flat merge trees + let tree_values = trees.into_iter().try_join().await?; + let mut iter = tree_values.iter().map(|rr| &**rr); + let mut merged = iter.next().unwrap().clone(); + merged.flat_merge(iter).await?; + + Ok(merged.cell()) + } +} + +/// The prefix tree of routes. Also handling dynamic and catch all segments. +#[turbo_tasks::value] +#[derive(Default, Clone, Debug)] +pub struct RouteTree { + base: Vec, + sources: Vec>>, + static_segments: IndexMap>, + dynamic_segments: Vec>, + catch_all_sources: Vec>>, + fallback_sources: Vec>>, + not_found_sources: Vec>>, +} + +impl RouteTree { + /// Creates a route tree for a single route. + pub fn new_route_ref( + base_segments: Vec, + route_type: RouteType, + source: Vc>, + ) -> Self { + match route_type { + RouteType::Exact => Self { + base: base_segments, + sources: vec![source], + ..Default::default() + }, + RouteType::CatchAll => Self { + base: base_segments, + catch_all_sources: vec![source], + ..Default::default() + }, + RouteType::Fallback => Self { + base: base_segments, + fallback_sources: vec![source], + ..Default::default() + }, + RouteType::NotFound => Self { + base: base_segments, + not_found_sources: vec![source], + ..Default::default() + }, + } + } + + async fn flat_merge(&mut self, others: impl IntoIterator + '_) -> Result<()> { + let mut static_segments = IndexMap::new(); + for other in others { + debug_assert_eq!(self.base, other.base); + self.sources.extend(other.sources.iter().copied()); + self.catch_all_sources + .extend(other.catch_all_sources.iter().copied()); + self.fallback_sources + .extend(other.fallback_sources.iter().copied()); + self.not_found_sources + .extend(other.not_found_sources.iter().copied()); + for (key, value) in other.static_segments.iter() { + if let Some((key, self_value)) = self.static_segments.remove_entry(key) { + static_segments.insert(key, vec![self_value, *value]); + } else if let Some(list) = static_segments.get_mut(key) { + list.push(*value); + } else { + static_segments.insert(key.clone(), vec![*value]); + } + } + self.dynamic_segments + .extend(other.dynamic_segments.iter().copied()); + } + self.static_segments.extend( + static_segments + .into_iter() + .map(|(key, value)| async { + Ok(( + key, + if value.len() == 1 { + value.into_iter().next().unwrap() + } else { + Vc::::cell(value).merge().resolve().await? + }, + )) + }) + .try_join() + .await?, + ); + Ok(()) + } + + fn prepend_base(&mut self, segments: Vec) { + self.base.splice(..0, segments); + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for RouteTree { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + let RouteTree { + base, + sources, + static_segments, + dynamic_segments, + catch_all_sources, + fallback_sources, + not_found_sources, + } = self; + let mut result = "RouteTree(".to_string(); + for segment in base { + match segment { + BaseSegment::Static(str) => write!(result, "/{}", str)?, + BaseSegment::Dynamic => result.push_str("/[dynamic]"), + } + } + if !base.is_empty() { + result.push_str(", "); + } + for (key, tree) in static_segments { + let tree = tree.to_string().await?; + write!(result, "{}: {}, ", key, tree)?; + } + if !sources.is_empty() { + write!(result, "{} x source, ", sources.len())?; + } + if !dynamic_segments.is_empty() { + write!(result, "{} x dynamic, ", dynamic_segments.len())?; + } + if !catch_all_sources.is_empty() { + write!(result, "{} x catch-all, ", catch_all_sources.len())?; + } + if !fallback_sources.is_empty() { + write!(result, "{} x fallback, ", fallback_sources.len())?; + } + if !not_found_sources.is_empty() { + write!(result, "{} x not-found, ", not_found_sources.len())?; + } + if result.ends_with(", ") { + result.truncate(result.len() - 2); + } + result.push(')'); + Ok(Vc::cell(result.into())) + } +} + +#[turbo_tasks::value_impl] +impl RouteTree { + /// Creates an empty route tree. + #[turbo_tasks::function] + pub fn empty() -> Vc { + RouteTree::default().cell() + } + + /// Creates a route tree for a single route. + #[turbo_tasks::function] + pub fn new_route( + base_segments: Vec, + route_type: RouteType, + source: Vc>, + ) -> Vc { + RouteTree::new_route_ref(base_segments, route_type, source).cell() + } + + /// Gets the [`GetContentSourceContent`]s for the given path. + // TODO(WEB-1252) It's unneccesary to compute all [`GetContentSourceContent`]s at once, we could + // return some lazy iterator to make it more efficient. + #[turbo_tasks::function] + pub async fn get(self: Vc, path: RcStr) -> Result> { + let RouteTree { + base, + sources, + static_segments, + dynamic_segments, + catch_all_sources, + fallback_sources, + not_found_sources, + } = &*self.await?; + let mut results = Vec::new(); + if path.is_empty() { + if !base.is_empty() { + return Ok(Vc::cell(vec![])); + } + results.extend(sources.iter().copied()); + } else { + let mut segments = path.split('/'); + for base in base.iter() { + let Some(segment) = segments.next() else { + return Ok(Vc::cell(vec![])); + }; + match base { + BaseSegment::Static(str) => { + if str != segment { + return Ok(Vc::cell(vec![])); + } + } + BaseSegment::Dynamic => { + // always matching + } + } + } + + if let Some(segment) = segments.next() { + let remainder = segments.remainder().unwrap_or(""); + if let Some(tree) = static_segments.get(segment) { + results.extend(tree.get(remainder.into()).await?.iter().copied()); + } + for tree in dynamic_segments.iter() { + results.extend(tree.get(remainder.into()).await?.iter().copied()); + } + } else { + results.extend(sources.iter().copied()); + }; + } + results.extend(catch_all_sources.iter().copied()); + results.extend(fallback_sources.iter().copied()); + results.extend(not_found_sources.iter().copied()); + Ok(Vc::cell(results)) + } + + /// Prepends a base path to all routes. + #[turbo_tasks::function] + pub async fn with_prepended_base( + self: Vc, + segments: Vec, + ) -> Result> { + let mut this = self.await?.clone_value(); + this.prepend_base(segments); + Ok(this.cell()) + } + + #[turbo_tasks::function] + async fn with_base_len(self: Vc, base_len: usize) -> Result> { + let this = self.await?; + if this.base.len() > base_len { + let mut inner = this.clone_value(); + let mut drain = inner.base.drain(base_len..); + let selector_segment = drain.next().unwrap(); + let inner_base = drain.collect(); + let base = replace(&mut inner.base, inner_base); + debug_assert!(base.len() == base_len); + match selector_segment { + BaseSegment::Static(value) => Ok(RouteTree { + base, + static_segments: IndexMap::from([(value, inner.cell())]), + ..Default::default() + } + .cell()), + BaseSegment::Dynamic => Ok(RouteTree { + base, + dynamic_segments: vec![inner.cell()], + ..Default::default() + } + .cell()), + } + } else { + Ok(self) + } + } + + /// Applies a transformation on all [`GetContentSourceContent`]s in the + /// tree. + #[turbo_tasks::function] + pub async fn map_routes( + self: Vc, + mapper: Vc>, + ) -> Result> { + let mut this = self.await?.clone_value(); + let RouteTree { + base: _, + static_segments, + dynamic_segments, + sources, + catch_all_sources, + fallback_sources, + not_found_sources, + } = &mut this; + sources + .iter_mut() + .for_each(|s| *s = mapper.map_get_content(*s)); + catch_all_sources + .iter_mut() + .for_each(|s| *s = mapper.map_get_content(*s)); + fallback_sources + .iter_mut() + .for_each(|s| *s = mapper.map_get_content(*s)); + not_found_sources + .iter_mut() + .for_each(|s| *s = mapper.map_get_content(*s)); + static_segments + .values_mut() + .for_each(|r| *r = r.map_routes(mapper)); + dynamic_segments + .iter_mut() + .for_each(|r| *r = r.map_routes(mapper)); + Ok(this.cell()) + } +} + +/// Transformation functor +#[turbo_tasks::value_trait] +pub trait MapGetContentSourceContent { + fn map_get_content( + self: Vc, + get_content: Vc>, + ) -> Vc>; +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/router.rs b/turbopack/crates/turbopack-dev-server/src/source/router.rs new file mode 100644 index 0000000000000..d62db2a1f891f --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/router.rs @@ -0,0 +1,193 @@ +use std::iter::once; + +use anyhow::Result; +use turbo_tasks::{RcStr, TryJoinIterExt, Value, Vc}; +use turbopack_core::introspect::{Introspectable, IntrospectableChildren}; + +use super::{ + route_tree::{BaseSegment, RouteTree, RouteTrees}, + ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataVary, + GetContentSourceContent, +}; +use crate::source::{route_tree::MapGetContentSourceContent, ContentSources}; + +/// Binds different ContentSources to different subpaths. The request path must +/// begin with the prefix, which will be stripped (along with the subpath) +/// before querying the ContentSource. A fallback ContentSource will serve all +/// other subpaths, including if the request path does not include the prefix. +#[turbo_tasks::value(shared)] +pub struct PrefixedRouterContentSource { + pub prefix: Vc, + pub routes: Vec<(RcStr, Vc>)>, + pub fallback: Vc>, +} + +#[turbo_tasks::value_impl] +impl PrefixedRouterContentSource { + #[turbo_tasks::function] + pub async fn new( + prefix: Vc, + routes: Vec<(RcStr, Vc>)>, + fallback: Vc>, + ) -> Result> { + Ok(PrefixedRouterContentSource { + prefix, + routes, + fallback, + } + .cell()) + } +} + +fn get_children( + routes: &[(RcStr, Vc>)], + fallback: &Vc>, +) -> Vc { + Vc::cell( + routes + .iter() + .map(|r| r.1) + .chain(std::iter::once(*fallback)) + .collect(), + ) +} + +async fn get_introspection_children( + routes: &[(RcStr, Vc>)], + fallback: &Vc>, +) -> Result> { + Ok(Vc::cell( + routes + .iter() + .cloned() + .chain(std::iter::once((RcStr::default(), *fallback))) + .map(|(path, source)| async move { + Ok(Vc::try_resolve_sidecast::>(source) + .await? + .map(|i| (Vc::cell(path), i))) + }) + .try_join() + .await? + .into_iter() + .flatten() + .collect(), + )) +} + +#[turbo_tasks::value_impl] +impl ContentSource for PrefixedRouterContentSource { + #[turbo_tasks::function] + async fn get_routes(&self) -> Result> { + let prefix = &*self.prefix.await?; + if cfg!(debug_assertions) { + debug_assert!(prefix.is_empty() || prefix.ends_with('/')); + debug_assert!(!prefix.starts_with('/')); + } + let prefix = (!prefix.is_empty()) + .then(|| BaseSegment::from_static_pathname(prefix.as_str()).collect()) + .unwrap_or(Vec::new()); + let inner_trees = self.routes.iter().map(|(path, source)| { + let prepended_base = prefix + .iter() + .cloned() + .chain(BaseSegment::from_static_pathname(path)) + .collect(); + source + .get_routes() + .with_prepended_base(prepended_base) + .map_routes(Vc::upcast( + PrefixedRouterContentSourceMapper { + prefix: self.prefix, + path: path.clone(), + } + .cell(), + )) + }); + Ok(Vc::::cell( + inner_trees + .chain(once(self.fallback.get_routes())) + .collect(), + ) + .merge()) + } + + #[turbo_tasks::function] + fn get_children(&self) -> Vc { + get_children(&self.routes, &self.fallback) + } +} + +#[turbo_tasks::value] +struct PrefixedRouterContentSourceMapper { + prefix: Vc, + path: RcStr, +} + +#[turbo_tasks::value_impl] +impl MapGetContentSourceContent for PrefixedRouterContentSourceMapper { + #[turbo_tasks::function] + fn map_get_content( + self: Vc, + get_content: Vc>, + ) -> Vc> { + Vc::upcast( + PrefixedRouterGetContentSourceContent { + mapper: self, + get_content, + } + .cell(), + ) + } +} + +#[turbo_tasks::value] +struct PrefixedRouterGetContentSourceContent { + mapper: Vc, + get_content: Vc>, +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for PrefixedRouterGetContentSourceContent { + #[turbo_tasks::function] + fn vary(&self) -> Vc { + self.get_content.vary() + } + + #[turbo_tasks::function] + async fn get( + &self, + path: RcStr, + data: Value, + ) -> Result> { + let prefix = self.mapper.await?.prefix.await?; + if let Some(path) = path.strip_prefix(&**prefix) { + if path.is_empty() { + return Ok(self.get_content.get("".into(), data)); + } else if prefix.is_empty() { + return Ok(self.get_content.get(path.into(), data)); + } else if let Some(path) = path.strip_prefix('/') { + return Ok(self.get_content.get(path.into(), data)); + } + } + Ok(ContentSourceContent::not_found()) + } +} + +#[turbo_tasks::value_impl] +impl Introspectable for PrefixedRouterContentSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + Vc::cell("prefixed router content source".into()) + } + + #[turbo_tasks::function] + async fn details(&self) -> Result> { + let prefix = self.prefix.await?; + Ok(Vc::cell(format!("prefix: '{}'", prefix).into())) + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + get_introspection_children(&self.routes, &self.fallback).await + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/static_assets.rs b/turbopack/crates/turbopack-dev-server/src/source/static_assets.rs new file mode 100644 index 0000000000000..dc8ef38e3984f --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/static_assets.rs @@ -0,0 +1,140 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, FileSystemPath}; +use turbopack_core::{ + asset::Asset, + file_source::FileSource, + introspect::{source::IntrospectableSource, Introspectable, IntrospectableChildren}, + version::VersionedContentExt, +}; + +use super::{ + route_tree::{BaseSegment, RouteTree, RouteTrees, RouteType}, + ContentSource, ContentSourceContent, ContentSourceData, GetContentSourceContent, +}; + +#[turbo_tasks::value(shared)] +pub struct StaticAssetsContentSource { + pub prefix: Vc, + pub dir: Vc, +} + +#[turbo_tasks::value_impl] +impl StaticAssetsContentSource { + // TODO(WEB-1151): Remove this method and migrate users to `with_prefix`. + #[turbo_tasks::function] + pub fn new(prefix: RcStr, dir: Vc) -> Vc { + StaticAssetsContentSource::with_prefix(Vc::cell(prefix), dir) + } + + #[turbo_tasks::function] + pub async fn with_prefix( + prefix: Vc, + dir: Vc, + ) -> Result> { + if cfg!(debug_assertions) { + let prefix_string = prefix.await?; + debug_assert!(prefix_string.is_empty() || prefix_string.ends_with('/')); + debug_assert!(!prefix_string.starts_with('/')); + } + Ok(StaticAssetsContentSource { prefix, dir }.cell()) + } +} + +// TODO(WEB-1251) It would be better to lazily enumerate the directory +#[turbo_tasks::function] +async fn get_routes_from_directory(dir: Vc) -> Result> { + let dir = dir.read_dir().await?; + let DirectoryContent::Entries(entries) = &*dir else { + return Ok(RouteTree::empty()); + }; + + let routes = entries + .iter() + .flat_map(|(name, entry)| match entry { + DirectoryEntry::File(path) | DirectoryEntry::Symlink(path) => { + Some(RouteTree::new_route( + vec![BaseSegment::Static(name.clone())], + RouteType::Exact, + Vc::upcast(StaticAssetsContentSourceItem::new(*path)), + )) + } + DirectoryEntry::Directory(path) => Some( + get_routes_from_directory(*path) + .with_prepended_base(vec![BaseSegment::Static(name.clone())]), + ), + _ => None, + }) + .collect(); + Ok(Vc::::cell(routes).merge()) +} + +#[turbo_tasks::value_impl] +impl ContentSource for StaticAssetsContentSource { + #[turbo_tasks::function] + async fn get_routes(&self) -> Result> { + let prefix = self.prefix.await?; + let prefix = BaseSegment::from_static_pathname(prefix.as_str()).collect::>(); + Ok(get_routes_from_directory(self.dir).with_prepended_base(prefix)) + } +} + +#[turbo_tasks::value] +struct StaticAssetsContentSourceItem { + path: Vc, +} + +#[turbo_tasks::value_impl] +impl StaticAssetsContentSourceItem { + #[turbo_tasks::function] + pub fn new(path: Vc) -> Vc { + StaticAssetsContentSourceItem { path }.cell() + } +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for StaticAssetsContentSourceItem { + #[turbo_tasks::function] + fn get(&self, _path: RcStr, _data: Value) -> Vc { + let content = Vc::upcast::>(FileSource::new(self.path)).content(); + ContentSourceContent::static_content(content.versioned()) + } +} + +#[turbo_tasks::value_impl] +impl Introspectable for StaticAssetsContentSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + Vc::cell("static assets directory content source".into()) + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + let dir = self.dir.read_dir().await?; + let DirectoryContent::Entries(entries) = &*dir else { + return Ok(Vc::cell(Default::default())); + }; + + let prefix = self.prefix.await?; + let children = entries + .iter() + .map(|(name, entry)| { + let child = match entry { + DirectoryEntry::File(path) | DirectoryEntry::Symlink(path) => { + IntrospectableSource::new(Vc::upcast(FileSource::new(*path))) + } + DirectoryEntry::Directory(path) => { + Vc::upcast(StaticAssetsContentSource::with_prefix( + Vc::cell(format!("{}{name}/", &*prefix).into()), + *path, + )) + } + DirectoryEntry::Other(_) => todo!("what's DirectoryContent::Other?"), + DirectoryEntry::Error => todo!(), + }; + (Vc::cell(name.clone()), child) + }) + .collect(); + Ok(Vc::cell(children)) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/source/wrapping_source.rs b/turbopack/crates/turbopack-dev-server/src/source/wrapping_source.rs new file mode 100644 index 0000000000000..513e1704bf602 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/source/wrapping_source.rs @@ -0,0 +1,88 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, Vc}; + +use super::{ + ContentSourceContent, ContentSourceData, ContentSourceDataVary, GetContentSourceContent, + Rewrite, RewriteType, +}; + +/// A ContentSourceProcessor handles the final processing of an eventual +/// [ContentSourceContent]. +/// +/// Used in conjunction with [WrappedGetContentSourceContent], this allows a +/// [ContentSource] implementation to easily register a final process step over +/// some inner ContentSource's fully resolved [ContentSourceResult] and +/// [ContentSourceContent]. +#[turbo_tasks::value_trait] +pub trait ContentSourceProcessor { + fn process(self: Vc, content: Vc) -> Vc; +} + +/// A WrappedGetContentSourceContent simply wraps the get_content of a +/// [ContentSourceResult], allowing us to process whatever +/// [ContentSourceContent] it would have returned. + +#[turbo_tasks::value] +pub struct WrappedGetContentSourceContent { + inner: Vc>, + processor: Vc>, +} + +#[turbo_tasks::value_impl] +impl WrappedGetContentSourceContent { + #[turbo_tasks::function] + pub async fn new( + inner: Vc>, + processor: Vc>, + ) -> Vc { + WrappedGetContentSourceContent { inner, processor }.cell() + } +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for WrappedGetContentSourceContent { + #[turbo_tasks::function] + fn vary(&self) -> Vc { + self.inner.vary() + } + + #[turbo_tasks::function] + async fn get( + &self, + path: RcStr, + data: Value, + ) -> Result> { + let res = self.inner.get(path, data); + if let ContentSourceContent::Rewrite(rewrite) = &*res.await? { + let rewrite = rewrite.await?; + return Ok(ContentSourceContent::Rewrite( + Rewrite { + ty: match &rewrite.ty { + RewriteType::Location { .. } | RewriteType::ContentSource { .. } => todo!( + "Rewrites for WrappedGetContentSourceContent are not implemented yet" + ), + RewriteType::Sources { sources } => RewriteType::Sources { + sources: Vc::cell( + sources + .await? + .iter() + .map(|s| { + Vc::upcast(WrappedGetContentSourceContent::new( + *s, + self.processor, + )) + }) + .collect(), + ), + }, + }, + response_headers: rewrite.response_headers, + request_headers: rewrite.request_headers, + } + .cell(), + ) + .cell()); + } + Ok(self.processor.process(res)) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/update/mod.rs b/turbopack/crates/turbopack-dev-server/src/update/mod.rs new file mode 100644 index 0000000000000..f07e04a8f32de --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/update/mod.rs @@ -0,0 +1,4 @@ +pub mod server; +pub mod stream; + +pub(super) use server::UpdateServer; diff --git a/turbopack/crates/turbopack-dev-server/src/update/server.rs b/turbopack/crates/turbopack-dev-server/src/update/server.rs new file mode 100644 index 0000000000000..04e41444ef0e9 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/update/server.rs @@ -0,0 +1,284 @@ +use std::{ + pin::Pin, + task::{Context, Poll}, +}; + +use anyhow::{Context as _, Error, Result}; +use futures::{prelude::*, ready, stream::FusedStream, SinkExt}; +use hyper::{upgrade::Upgraded, HeaderMap, Uri}; +use hyper_tungstenite::{tungstenite::Message, HyperWebsocket, WebSocketStream}; +use pin_project_lite::pin_project; +use tokio::select; +use tokio_stream::StreamMap; +use tracing::{instrument, Level}; +use turbo_tasks::{TransientInstance, TurboTasksApi, Vc}; +use turbo_tasks_fs::json::parse_json_with_source_context; +use turbopack_core::{error::PrettyPrintError, issue::IssueReporter, version::Update}; +use turbopack_ecmascript_hmr_protocol::{ + ClientMessage, ClientUpdateInstruction, Issue, ResourceIdentifier, +}; + +use super::stream::UpdateStream; +use crate::{ + source::{request::SourceRequest, resolve::resolve_source_request, Body}, + update::stream::UpdateStreamItem, + SourceProvider, +}; + +/// A server that listens for updates and sends them to connected clients. +pub(crate) struct UpdateServer { + source_provider: P, + #[allow(dead_code)] + issue_reporter: Vc>, +} + +impl UpdateServer

    { + /// Create a new update server with the given websocket and content source. + pub fn new(source_provider: P, issue_reporter: Vc>) -> Self { + Self { + source_provider, + issue_reporter, + } + } + + /// Run the update server loop. + pub fn run(self, tt: &dyn TurboTasksApi, ws: HyperWebsocket) { + tt.run_once_process(Box::pin(async move { + if let Err(err) = self.run_internal(ws).await { + println!("[UpdateServer]: error {:#}", err); + } + Ok(()) + })); + } + + #[instrument(level = Level::TRACE, skip_all, name = "UpdateServer::run_internal")] + async fn run_internal(self, ws: HyperWebsocket) -> Result<()> { + let mut client: UpdateClient = ws.await?.into(); + + let mut streams = StreamMap::new(); + + loop { + select! { + message = client.try_next() => { + match message? { + Some(ClientMessage::Subscribe { resource }) => { + let get_content = { + let source_provider = self.source_provider.clone(); + let request = resource_to_request(&resource)?; + move || { + let request = request.clone(); + let source = source_provider.get_source(); + resolve_source_request( + source, + TransientInstance::new(request) + ) + } + }; + match UpdateStream::new(resource.to_string().into(), TransientInstance::new(Box::new(get_content))).await { + Ok(stream) => { + streams.insert(resource, stream); + } + Err(err) => { + eprintln!("Failed to create update stream for {resource}: {}", PrettyPrintError(&err)); + client + .send(ClientUpdateInstruction::not_found(&resource)) + .await?; + } + } + } + Some(ClientMessage::Unsubscribe { resource }) => { + streams.remove(&resource); + } + None => { + // WebSocket was closed, stop sending updates + break; + } + } + } + Some((resource, update)) = streams.next() => { + match update { + Ok(update) => { + Self::send_update(&mut client, &mut streams, resource, &update).await?; + } + Err(err) => { + eprintln!("Failed to get update for {resource}: {}", PrettyPrintError(&err)); + } + } + } + else => break + } + } + + Ok(()) + } + + async fn send_update( + client: &mut UpdateClient, + streams: &mut StreamMap, + resource: ResourceIdentifier, + item: &UpdateStreamItem, + ) -> Result<()> { + match item { + UpdateStreamItem::NotFound => { + // If the resource was not found, we remove the stream and indicate that to the + // client. + streams.remove(&resource); + client + .send(ClientUpdateInstruction::not_found(&resource)) + .await?; + } + UpdateStreamItem::Found { update, issues } => { + let issues = issues + .iter() + .map(|p| (&**p).into()) + .collect::>>(); + match &**update { + Update::Partial(partial) => { + let partial_instruction = &partial.instruction; + client + .send(ClientUpdateInstruction::partial( + &resource, + partial_instruction, + &issues, + )) + .await?; + } + Update::Total(_total) => { + client + .send(ClientUpdateInstruction::restart(&resource, &issues)) + .await?; + } + Update::None => { + client + .send(ClientUpdateInstruction::issues(&resource, &issues)) + .await?; + } + } + } + } + + Ok(()) + } +} + +fn resource_to_request(resource: &ResourceIdentifier) -> Result { + let mut headers = HeaderMap::new(); + + if let Some(res_headers) = &resource.headers { + for (name, value) in res_headers { + headers.append( + hyper::header::HeaderName::from_bytes(name.as_bytes()).unwrap(), + hyper::header::HeaderValue::from_bytes(value.as_bytes()).unwrap(), + ); + } + } + + Ok(SourceRequest { + uri: Uri::try_from(format!("/{}", resource.path))?, + headers, + method: "GET".to_string(), + body: Body::new(vec![]), + }) +} + +pin_project! { + struct UpdateClient { + #[pin] + ws: WebSocketStream, + ended: bool, + } +} + +impl Stream for UpdateClient { + type Item = Result; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + if self.ended { + return Poll::Ready(None); + } + + let this = self.project(); + let item = ready!(this.ws.poll_next(cx)); + + let msg = match item { + Some(Ok(Message::Text(msg))) => msg, + Some(Err(err)) => { + *this.ended = true; + + let err = Error::new(err).context("reading from websocket"); + return Poll::Ready(Some(Err(err))); + } + _ => { + *this.ended = true; + return Poll::Ready(None); + } + }; + + match parse_json_with_source_context(&msg).context("deserializing websocket message") { + Ok(msg) => Poll::Ready(Some(Ok(msg))), + Err(err) => { + *this.ended = true; + + Poll::Ready(Some(Err(err))) + } + } + } +} + +impl FusedStream for UpdateClient { + fn is_terminated(&self) -> bool { + self.ended || self.ws.is_terminated() + } +} + +impl<'a> Sink> for UpdateClient { + type Error = Error; + + fn poll_ready( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + self.project() + .ws + .poll_ready(cx) + .map(|res| res.context("polling WebSocket ready")) + } + + fn start_send( + self: Pin<&mut Self>, + item: ClientUpdateInstruction<'a>, + ) -> std::result::Result<(), Self::Error> { + let msg = Message::text(serde_json::to_string(&item)?); + + self.project() + .ws + .start_send(msg) + .context("sending to WebSocket") + } + + fn poll_flush( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + self.project() + .ws + .poll_flush(cx) + .map(|res| res.context("flushing WebSocket")) + } + + fn poll_close( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + ) -> Poll> { + self.project() + .ws + .poll_close(cx) + .map(|res| res.context("closing WebSocket")) + } +} + +impl From> for UpdateClient { + fn from(ws: WebSocketStream) -> Self { + Self { ws, ended: false } + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/update/stream.rs b/turbopack/crates/turbopack-dev-server/src/update/stream.rs new file mode 100644 index 0000000000000..a287e7ed7c1f1 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/update/stream.rs @@ -0,0 +1,314 @@ +use std::pin::Pin; + +use anyhow::Result; +use futures::prelude::*; +use tokio::sync::mpsc::Sender; +use tokio_stream::wrappers::ReceiverStream; +use tracing::Instrument; +use turbo_tasks::{IntoTraitRef, RcStr, ReadRef, TransientInstance, Vc}; +use turbo_tasks_fs::{FileSystem, FileSystemPath}; +use turbopack_core::{ + error::PrettyPrintError, + issue::{ + Issue, IssueDescriptionExt, IssueSeverity, IssueStage, OptionIssueProcessingPathItems, + OptionStyledString, PlainIssue, StyledString, + }, + server_fs::ServerFileSystem, + version::{ + NotFoundVersion, PartialUpdate, TotalUpdate, Update, Version, VersionState, + VersionedContent, + }, +}; + +use crate::source::{resolve::ResolveSourceRequestResult, ProxyResult}; + +type GetContentFn = Box Vc + Send + Sync>; + +async fn peek_issues(source: Vc) -> Result>> { + let captured = source.peek_issues_with_path().await?; + + captured.get_plain_issues().await +} + +fn extend_issues(issues: &mut Vec>, new_issues: Vec>) { + for issue in new_issues { + if issues.contains(&issue) { + continue; + } + + issues.push(issue); + } +} + +#[turbo_tasks::function] +async fn get_update_stream_item( + resource: RcStr, + from: Vc, + get_content: TransientInstance, +) -> Result> { + let content = get_content(); + let _ = content.resolve_strongly_consistent().await?; + let mut plain_issues = peek_issues(content).await?; + + let content_value = match content.await { + Ok(content) => content, + Err(e) => { + plain_issues.push( + FatalStreamIssue { + resource, + description: StyledString::Text(format!("{}", PrettyPrintError(&e)).into()) + .cell(), + } + .cell() + .into_plain(OptionIssueProcessingPathItems::none()) + .await?, + ); + + let update = Update::Total(TotalUpdate { + to: Vc::upcast::>(NotFoundVersion::new()) + .into_trait_ref() + .await?, + }) + .cell(); + return Ok(UpdateStreamItem::Found { + update: update.await?, + issues: plain_issues, + } + .cell()); + } + }; + + match *content_value { + ResolveSourceRequestResult::Static(static_content_vc, _) => { + let static_content = static_content_vc.await?; + + // This can happen when a chunk is removed from the asset graph. + if static_content.status_code == 404 { + return Ok(UpdateStreamItem::NotFound.cell()); + } + + let resolved_content = static_content.content; + let from = from.get(); + let update = resolved_content.update(from); + + extend_issues(&mut plain_issues, peek_issues(update).await?); + + let update = update.await?; + + Ok(UpdateStreamItem::Found { + update, + issues: plain_issues, + } + .cell()) + } + ResolveSourceRequestResult::HttpProxy(proxy_result) => { + let proxy_result_value = proxy_result.await?; + + if proxy_result_value.status == 404 { + return Ok(UpdateStreamItem::NotFound.cell()); + } + + extend_issues(&mut plain_issues, peek_issues(proxy_result).await?); + + let from = from.get(); + if let Some(from) = Vc::try_resolve_downcast_type::(from).await? { + if from.await? == proxy_result_value { + return Ok(UpdateStreamItem::Found { + update: Update::None.cell().await?, + issues: plain_issues, + } + .cell()); + } + } + + Ok(UpdateStreamItem::Found { + update: Update::Total(TotalUpdate { + to: Vc::upcast::>(proxy_result) + .into_trait_ref() + .await?, + }) + .cell() + .await?, + issues: plain_issues, + } + .cell()) + } + _ => { + let update = if plain_issues.is_empty() { + // Client requested a non-existing asset + // It might be removed in meantime, reload client + // TODO add special instructions for removed assets to handled it in a better + // way + Update::Total(TotalUpdate { + to: Vc::upcast::>(NotFoundVersion::new()) + .into_trait_ref() + .await?, + }) + .cell() + } else { + Update::None.cell() + }; + + Ok(UpdateStreamItem::Found { + update: update.await?, + issues: plain_issues, + } + .cell()) + } + } +} + +#[turbo_tasks::function] +async fn compute_update_stream( + resource: RcStr, + from: Vc, + get_content: TransientInstance, + sender: TransientInstance>>>, +) -> Result> { + let item = get_update_stream_item(resource, from, get_content) + .strongly_consistent() + .await; + + // Send update. Ignore channel closed error. + let _ = sender.send(item).await; + + Ok(Default::default()) +} + +pub(super) struct UpdateStream( + Pin>> + Send + Sync>>, +); + +impl UpdateStream { + #[tracing::instrument(skip(get_content), name = "UpdateStream::new")] + pub async fn new( + resource: RcStr, + get_content: TransientInstance, + ) -> Result { + let (sx, rx) = tokio::sync::mpsc::channel(32); + + let content = get_content(); + // We can ignore issues reported in content here since [compute_update_stream] + // will handle them + let version = match *content.await? { + ResolveSourceRequestResult::Static(static_content, _) => { + static_content.await?.content.version() + } + ResolveSourceRequestResult::HttpProxy(proxy_result) => Vc::upcast(proxy_result), + _ => Vc::upcast(NotFoundVersion::new()), + }; + let version_state = VersionState::new(version.into_trait_ref().await?).await?; + + let _ = compute_update_stream( + resource, + version_state, + get_content, + TransientInstance::new(sx), + ); + + let mut last_had_issues = false; + + let stream = ReceiverStream::new(rx).filter_map(move |item| { + { + let (has_issues, issues_changed) = + if let Ok(UpdateStreamItem::Found { issues, .. }) = item.as_deref() { + let has_issues = !issues.is_empty(); + let issues_changed = has_issues != last_had_issues; + last_had_issues = has_issues; + (has_issues, issues_changed) + } else { + (false, false) + }; + + async move { + match item.as_deref() { + Ok(UpdateStreamItem::Found { update, .. }) => { + match &**update { + Update::Partial(PartialUpdate { to, .. }) + | Update::Total(TotalUpdate { to }) => { + version_state + .set(to.clone()) + .await + .expect("failed to update version"); + + Some(item) + } + // Do not propagate empty updates. + Update::None => { + if has_issues || issues_changed { + Some(item) + } else { + None + } + } + } + } + _ => { + // Propagate other updates + Some(item) + } + } + } + .in_current_span() + } + .in_current_span() + }); + + Ok(UpdateStream(Box::pin(stream))) + } +} + +impl Stream for UpdateStream { + type Item = Result>; + + fn poll_next( + self: Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + Pin::new(&mut self.get_mut().0).poll_next(cx) + } +} + +#[turbo_tasks::value(serialization = "none")] +#[derive(Debug)] +pub enum UpdateStreamItem { + NotFound, + Found { + update: ReadRef, + issues: Vec>, + }, +} + +#[turbo_tasks::value(serialization = "none")] +struct FatalStreamIssue { + description: Vc, + resource: RcStr, +} + +#[turbo_tasks::value_impl] +impl Issue for FatalStreamIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Fatal.into() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Other("websocket".into()).cell() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + ServerFileSystem::new().root().join(self.resource.clone()) + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Fatal error while getting content to stream".into()).cell() + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some(self.description)) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-hmr-protocol/Cargo.toml b/turbopack/crates/turbopack-ecmascript-hmr-protocol/Cargo.toml new file mode 100644 index 0000000000000..ff12a5786cc81 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-hmr-protocol/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "turbopack-ecmascript-hmr-protocol" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +serde = { workspace = true } +serde_json = { workspace = true } + +turbopack-cli-utils = { workspace = true } +turbopack-core = { workspace = true } diff --git a/turbopack/crates/turbopack-ecmascript-hmr-protocol/src/lib.rs b/turbopack/crates/turbopack-ecmascript-hmr-protocol/src/lib.rs new file mode 100644 index 0000000000000..51eba9ddbf535 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-hmr-protocol/src/lib.rs @@ -0,0 +1,190 @@ +use std::{collections::BTreeMap, fmt::Display, ops::Deref, path::PathBuf}; + +use serde::{Deserialize, Serialize}; +use serde_json::Value; +use turbopack_cli_utils::issue::{format_issue, LogOptions}; +use turbopack_core::{ + issue::{IssueSeverity, IssueStage, PlainIssue, StyledString}, + source_pos::SourcePos, +}; + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +pub struct ResourceIdentifier { + pub path: String, + pub headers: Option>, +} + +impl Display for ResourceIdentifier { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.path)?; + if let Some(headers) = &self.headers { + for (key, value) in headers.iter() { + write!(f, " [{}: {}]", key, value)?; + } + } + Ok(()) + } +} + +#[derive(Deserialize)] +#[serde(tag = "type")] +pub enum ClientMessage { + #[serde(rename = "turbopack-subscribe")] + Subscribe { + #[serde(flatten)] + resource: ResourceIdentifier, + }, + #[serde(rename = "turbopack-unsubscribe")] + Unsubscribe { + #[serde(flatten)] + resource: ResourceIdentifier, + }, +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct ClientUpdateInstruction<'a> { + pub resource: &'a ResourceIdentifier, + #[serde(flatten)] + pub ty: ClientUpdateInstructionType<'a>, + pub issues: &'a [Issue<'a>], +} + +pub const EMPTY_ISSUES: &[Issue<'static>] = &[]; + +impl<'a> ClientUpdateInstruction<'a> { + pub fn new( + resource: &'a ResourceIdentifier, + ty: ClientUpdateInstructionType<'a>, + issues: &'a [Issue<'a>], + ) -> Self { + Self { + resource, + ty, + issues, + } + } + + pub fn restart(resource: &'a ResourceIdentifier, issues: &'a [Issue<'a>]) -> Self { + Self::new(resource, ClientUpdateInstructionType::Restart, issues) + } + + /// Returns a [`ClientUpdateInstruction`] that indicates that the resource + /// was not found. + pub fn not_found(resource: &'a ResourceIdentifier) -> Self { + Self::new(resource, ClientUpdateInstructionType::NotFound, &[]) + } + + pub fn partial( + resource: &'a ResourceIdentifier, + instruction: &'a Value, + issues: &'a [Issue<'a>], + ) -> Self { + Self::new( + resource, + ClientUpdateInstructionType::Partial { instruction }, + issues, + ) + } + + pub fn issues(resource: &'a ResourceIdentifier, issues: &'a [Issue<'a>]) -> Self { + Self::new(resource, ClientUpdateInstructionType::Issues, issues) + } + + pub fn with_issues(self, issues: &'a [Issue<'a>]) -> Self { + Self { + resource: self.resource, + ty: self.ty, + issues, + } + } +} + +#[derive(Serialize)] +#[serde(tag = "type", rename_all = "camelCase")] +pub enum ClientUpdateInstructionType<'a> { + Restart, + NotFound, + Partial { instruction: &'a Value }, + Issues, +} + +#[derive(Serialize)] +#[serde(tag = "type", rename_all = "camelCase")] +pub enum ServerError { + SSR(String), + Turbo(String), +} + +#[derive(Serialize)] +pub struct Asset<'a> { + pub path: &'a str, +} + +#[derive(Serialize)] +pub struct IssueSource<'a> { + pub asset: Asset<'a>, + pub range: Option, +} + +#[derive(Serialize)] +pub struct IssueSourceRange { + pub start: SourcePos, + pub end: SourcePos, +} + +#[derive(Serialize)] +pub struct Issue<'a> { + pub severity: IssueSeverity, + pub file_path: &'a str, + pub stage: &'a IssueStage, + + pub title: &'a StyledString, + pub description: Option<&'a StyledString>, + pub detail: Option<&'a StyledString>, + pub documentation_link: &'a str, + + pub source: Option>, + pub sub_issues: Vec>, + + pub formatted: String, +} + +impl<'a> From<&'a PlainIssue> for Issue<'a> { + fn from(plain: &'a PlainIssue) -> Self { + let source = plain.source.as_deref().map(|source| IssueSource { + asset: Asset { + path: &source.asset.ident, + }, + range: source + .range + .map(|(start, end)| IssueSourceRange { start, end }), + }); + + Issue { + severity: plain.severity, + file_path: &plain.file_path, + stage: &plain.stage, + title: &plain.title, + description: plain.description.as_ref(), + documentation_link: &plain.documentation_link, + detail: plain.detail.as_ref(), + source, + sub_issues: plain.sub_issues.iter().map(|p| p.deref().into()).collect(), + // TODO(WEB-691) formatting the issue should be handled by the error overlay. + // The browser could handle error formatting in a better way than the text only + // formatting here + formatted: format_issue( + plain, + None, + &LogOptions { + current_dir: PathBuf::new(), + project_dir: PathBuf::new(), + show_all: true, + log_detail: true, + log_level: IssueSeverity::Info, + }, + ), + } + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/Cargo.toml b/turbopack/crates/turbopack-ecmascript-plugins/Cargo.toml new file mode 100644 index 0000000000000..9b7c1771bfbbf --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/Cargo.toml @@ -0,0 +1,46 @@ +[package] +name = "turbopack-ecmascript-plugins" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[features] +default = ["swc_ecma_transform_plugin"] +transform_emotion = [] +# [NOTE]: Be careful to explicitly enable this only for the supported platform / targets. +swc_ecma_transform_plugin = [ + "swc_core/plugin_transform_host_native", + "swc_core/plugin_transform_host_native_shared_runtime", +] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +async-trait = { workspace = true } +indexmap = { workspace = true } +lightningcss = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +tracing = { workspace = true } + +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } + +modularize_imports = { workspace = true } +styled_components = { workspace = true } +styled_jsx = { workspace = true } +swc_core = { workspace = true, features = ["ecma_ast", "ecma_visit", "common"] } +swc_emotion = { workspace = true } +swc_relay = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-ecmascript-plugins/build.rs b/turbopack/crates/turbopack-ecmascript-plugins/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/lib.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/lib.rs new file mode 100644 index 0000000000000..98caae26182cb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/lib.rs @@ -0,0 +1,9 @@ +#![feature(arbitrary_self_types)] + +pub mod transform; + +pub fn register() { + turbo_tasks::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/client.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/client.rs new file mode 100644 index 0000000000000..3b9432cb48caa --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/client.rs @@ -0,0 +1,36 @@ +use anyhow::Result; +use async_trait::async_trait; +use swc_core::ecma::{ast::Program, transforms::base::resolver, visit::VisitMutWith}; +use turbo_tasks::{RcStr, Vc}; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +use super::{is_client_module, server_to_client_proxy::create_proxy_module}; + +#[derive(Debug)] +pub struct ClientDirectiveTransformer { + transition_name: Vc, +} + +impl ClientDirectiveTransformer { + pub fn new(transition_name: Vc) -> Self { + Self { transition_name } + } +} + +#[async_trait] +impl CustomTransformer for ClientDirectiveTransformer { + #[tracing::instrument(level = tracing::Level::TRACE, name = "client_directive", skip_all)] + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + if is_client_module(program) { + let transition_name = &*self.transition_name.await?; + *program = create_proxy_module(transition_name, &format!("./{}", ctx.file_name_str)); + program.visit_mut_with(&mut resolver( + ctx.unresolved_mark, + ctx.top_level_mark, + false, + )); + } + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/client_disallowed.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/client_disallowed.rs new file mode 100644 index 0000000000000..4b3f04667ce7d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/client_disallowed.rs @@ -0,0 +1,33 @@ +use anyhow::Result; +use async_trait::async_trait; +use swc_core::ecma::{ast::Program, transforms::base::resolver, visit::VisitMutWith}; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +use super::{is_client_module, server_to_client_proxy::create_error_proxy_module}; + +#[derive(Debug)] +pub struct ClientDisallowedDirectiveTransformer { + error_proxy_module: String, +} + +impl ClientDisallowedDirectiveTransformer { + pub fn new(error_proxy_module: String) -> Self { + Self { error_proxy_module } + } +} + +#[async_trait] +impl CustomTransformer for ClientDisallowedDirectiveTransformer { + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + if is_client_module(program) { + *program = create_error_proxy_module(&self.error_proxy_module); + program.visit_mut_with(&mut resolver( + ctx.unresolved_mark, + ctx.top_level_mark, + false, + )); + } + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/mod.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/mod.rs new file mode 100644 index 0000000000000..2b5e745c9eb2f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/mod.rs @@ -0,0 +1,40 @@ +use swc_core::ecma::ast::{Lit, Program}; + +pub mod client; +pub mod client_disallowed; +pub mod server; +mod server_to_client_proxy; + +macro_rules! has_directive { + ($stmts:expr, $name:literal) => { + $stmts + .map(|item| { + if let Lit::Str(str) = item?.as_expr()?.expr.as_lit()? { + Some(str) + } else { + None + } + }) + .take_while(Option::is_some) + .map(Option::unwrap) + .any(|s| &*s.value == $name) + }; +} + +fn is_client_module(program: &Program) -> bool { + match program { + Program::Module(m) => { + has_directive!(m.body.iter().map(|item| item.as_stmt()), "use client") + } + Program::Script(s) => has_directive!(s.body.iter().map(Some), "use client"), + } +} + +fn is_server_module(program: &Program) -> bool { + match program { + Program::Module(m) => { + has_directive!(m.body.iter().map(|item| item.as_stmt()), "use server") + } + Program::Script(s) => has_directive!(s.body.iter().map(Some), "use server"), + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/server.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/server.rs new file mode 100644 index 0000000000000..dac7afad1bab2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/server.rs @@ -0,0 +1,51 @@ +use anyhow::Result; +use async_trait::async_trait; +use swc_core::{ + ecma::ast::{ModuleItem, Program}, + quote, +}; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::issue::IssueExt; +use turbopack_ecmascript::{CustomTransformer, TransformContext, UnsupportedServerActionIssue}; + +use super::is_server_module; + +#[derive(Debug)] +pub struct ServerDirectiveTransformer { + // ServerDirective is not implemented yet and always reports an issue. + // We don't have to pass a valid transition name yet, but the API is prepared. + #[allow(unused)] + transition_name: Vc, +} + +impl ServerDirectiveTransformer { + pub fn new(transition_name: &Vc) -> Self { + Self { + transition_name: *transition_name, + } + } +} + +#[async_trait] +impl CustomTransformer for ServerDirectiveTransformer { + #[tracing::instrument(level = tracing::Level::TRACE, name = "server_directive", skip_all)] + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + if is_server_module(program) { + let stmt = quote!( + "throw new Error('Server actions (\"use server\") are not yet supported in \ + Turbopack');" as Stmt + ); + match program { + Program::Module(m) => m.body = vec![ModuleItem::Stmt(stmt)], + Program::Script(s) => s.body = vec![stmt], + } + UnsupportedServerActionIssue { + file_path: ctx.file_path, + } + .cell() + .emit(); + } + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs new file mode 100644 index 0000000000000..b031e3dc65c90 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/directives/server_to_client_proxy.rs @@ -0,0 +1,68 @@ +use swc_core::{ + common::DUMMY_SP, + ecma::{ + ast::{ + ImportDecl, ImportDefaultSpecifier, ImportSpecifier, ImportStarAsSpecifier, Module, + ModuleDecl, ModuleItem, Program, + }, + utils::private_ident, + }, + quote, +}; +use turbopack_ecmascript::{ + annotations::{with_clause, ANNOTATION_TRANSITION}, + TURBOPACK_HELPER, +}; + +pub fn create_proxy_module(transition_name: &str, target_import: &str) -> Program { + let ident = private_ident!("clientProxy"); + Program::Module(Module { + body: vec![ + ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + specifiers: vec![ImportSpecifier::Namespace(ImportStarAsSpecifier { + local: ident.clone(), + span: DUMMY_SP, + })], + src: Box::new(target_import.into()), + type_only: false, + with: Some(with_clause(&[ + (TURBOPACK_HELPER.as_str(), "true"), + (ANNOTATION_TRANSITION, transition_name), + ])), + span: DUMMY_SP, + phase: Default::default(), + })), + ModuleItem::Stmt(quote!( + "__turbopack_export_namespace__($proxy);" as Stmt, + proxy = ident, + )), + ], + shebang: None, + span: DUMMY_SP, + }) +} + +pub fn create_error_proxy_module(error_proxy_module: &str) -> Program { + let ident = private_ident!("errorProxy"); + Program::Module(Module { + body: vec![ + ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + specifiers: vec![ImportSpecifier::Default(ImportDefaultSpecifier { + local: ident.clone(), + span: DUMMY_SP, + })], + src: Box::new(error_proxy_module.into()), + type_only: false, + with: Some(with_clause(&[(TURBOPACK_HELPER.as_str(), "true")])), + span: DUMMY_SP, + phase: Default::default(), + })), + ModuleItem::Stmt(quote!( + "__turbopack_export_namespace__($proxy);" as Stmt, + proxy = ident, + )), + ], + shebang: None, + span: DUMMY_SP, + }) +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/emotion.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/emotion.rs new file mode 100644 index 0000000000000..469b77c4ed781 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/emotion.rs @@ -0,0 +1,119 @@ +#![allow(unused)] +use std::{ + hash::{Hash, Hasher}, + path::Path, +}; + +use anyhow::Result; +use async_trait::async_trait; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::util::take::Take, + ecma::{ + ast::{Module, Program}, + visit::FoldWith, + }, +}; +use turbo_tasks::{trace::TraceRawVcs, ValueDefault, Vc}; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +pub enum EmotionLabelKind { + DevOnly, + Always, + Never, +} + +#[turbo_tasks::value(transparent)] +pub struct OptionEmotionTransformConfig(Option>); + +//[TODO]: need to support importmap, there are type mismatch between +//next.config.js to swc's emotion options +#[turbo_tasks::value(shared)] +#[derive(Default, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct EmotionTransformConfig { + pub sourcemap: Option, + pub label_format: Option, + pub auto_label: Option, +} + +#[turbo_tasks::value_impl] +impl EmotionTransformConfig { + #[turbo_tasks::function] + pub fn default_private() -> Vc { + Self::cell(Default::default()) + } +} + +impl ValueDefault for EmotionTransformConfig { + fn value_default() -> Vc { + EmotionTransformConfig::default_private() + } +} + +#[derive(Debug)] +pub struct EmotionTransformer { + #[cfg(feature = "transform_emotion")] + config: swc_emotion::EmotionOptions, +} + +#[cfg(feature = "transform_emotion")] +impl EmotionTransformer { + pub fn new(config: &EmotionTransformConfig) -> Option { + let config = swc_emotion::EmotionOptions { + // When you create a transformer structure, it is assumed that you are performing an + // emotion transform. + enabled: Some(true), + sourcemap: config.sourcemap, + label_format: config.label_format.clone(), + auto_label: if let Some(auto_label) = config.auto_label.as_ref() { + match auto_label { + EmotionLabelKind::Always => Some(true), + EmotionLabelKind::Never => Some(false), + // [TODO]: this is not correct coerece, need to be fixed + EmotionLabelKind::DevOnly => None, + } + } else { + None + }, + ..Default::default() + }; + + Some(EmotionTransformer { config }) + } +} + +#[cfg(not(feature = "transform_emotion"))] +impl EmotionTransformer { + pub fn new(_config: &EmotionTransformConfig) -> Option { + None + } +} + +#[async_trait] +impl CustomTransformer for EmotionTransformer { + #[tracing::instrument(level = tracing::Level::TRACE, name = "emotion", skip_all)] + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + #[cfg(feature = "transform_emotion")] + { + let p = std::mem::replace(program, Program::Module(Module::dummy())); + let hash = { + #[allow(clippy::disallowed_types)] + let mut hasher = std::collections::hash_map::DefaultHasher::new(); + p.hash(&mut hasher); + hasher.finish() + }; + *program = p.fold_with(&mut swc_emotion::emotion( + self.config.clone(), + Path::new(ctx.file_name_str), + hash as u32, + ctx.source_map.clone(), + ctx.comments.clone(), + )); + } + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/mod.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/mod.rs new file mode 100644 index 0000000000000..620985013c091 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/mod.rs @@ -0,0 +1,7 @@ +pub mod directives; +pub mod emotion; +pub mod modularize_imports; +pub mod relay; +pub mod styled_components; +pub mod styled_jsx; +pub mod swc_ecma_transform_plugins; diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/modularize_imports.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/modularize_imports.rs new file mode 100644 index 0000000000000..368e36dd4786c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/modularize_imports.rs @@ -0,0 +1,66 @@ +use std::collections::HashMap; + +use anyhow::Result; +use async_trait::async_trait; +use indexmap::IndexMap; +use modularize_imports::{modularize_imports, Config, PackageConfig}; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::util::take::Take, + ecma::{ + ast::{Module, Program}, + visit::FoldWith, + }, +}; +use turbo_tasks::trace::TraceRawVcs; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, TraceRawVcs)] +#[serde(rename_all = "camelCase")] +pub struct ModularizeImportPackageConfig { + pub transform: String, + #[serde(default)] + pub prevent_full_import: bool, + #[serde(default)] + pub skip_default_conversion: bool, +} + +#[derive(Debug)] +pub struct ModularizeImportsTransformer { + packages: HashMap, +} + +impl ModularizeImportsTransformer { + pub fn new(packages: &IndexMap) -> Self { + Self { + packages: packages + .iter() + .map(|(k, v)| { + ( + k.clone(), + PackageConfig { + transform: modularize_imports::Transform::String(v.transform.clone()), + prevent_full_import: v.prevent_full_import, + skip_default_conversion: v.skip_default_conversion, + handle_default_import: false, + handle_namespace_import: false, + }, + ) + }) + .collect(), + } + } +} + +#[async_trait] +impl CustomTransformer for ModularizeImportsTransformer { + #[tracing::instrument(level = tracing::Level::TRACE, name = "modularize_imports", skip_all)] + async fn transform(&self, program: &mut Program, _ctx: &TransformContext<'_>) -> Result<()> { + let p = std::mem::replace(program, Program::Module(Module::dummy())); + *program = p.fold_with(&mut modularize_imports(Config { + packages: self.packages.clone(), + })); + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/relay.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/relay.rs new file mode 100644 index 0000000000000..3baf3cc58a74b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/relay.rs @@ -0,0 +1,89 @@ +use std::{path::PathBuf, sync::Arc}; + +use anyhow::{Context, Result}; +use async_trait::async_trait; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::{util::take::Take, FileName}, + ecma::{ + ast::{Module, Program}, + visit::FoldWith, + }, +}; +use swc_relay::RelayLanguageConfig; +use turbo_tasks::trace::TraceRawVcs; +use turbo_tasks_fs::FileSystemPath; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TraceRawVcs)] +#[serde(rename_all = "camelCase")] +pub struct RelayConfig { + pub src: String, + pub artifact_directory: Option, + pub language: Option, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, TraceRawVcs)] +#[serde(rename_all = "lowercase")] +pub enum RelayLanguage { + TypeScript, + Flow, + JavaScript, +} + +#[derive(Debug)] +pub struct RelayTransformer { + config: Arc, + project_path: FileSystemPath, +} + +impl RelayTransformer { + pub fn new(config: &RelayConfig, project_path: &FileSystemPath) -> Self { + let options = swc_relay::Config { + artifact_directory: config.artifact_directory.as_ref().map(PathBuf::from), + language: config.language.as_ref().map_or( + RelayLanguageConfig::TypeScript, + |v| match v { + RelayLanguage::JavaScript => RelayLanguageConfig::JavaScript, + RelayLanguage::TypeScript => RelayLanguageConfig::TypeScript, + RelayLanguage::Flow => RelayLanguageConfig::Flow, + }, + ), + ..Default::default() + }; + + Self { + config: options.into(), + project_path: project_path.clone(), + } + } +} + +#[async_trait] +impl CustomTransformer for RelayTransformer { + #[tracing::instrument(level = tracing::Level::TRACE, name = "relay", skip_all)] + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + // If user supplied artifact_directory, it should be resolvable already. + // Otherwise, supply default relative path (./__generated__) + let path_to_proj = PathBuf::from( + ctx.file_path + .parent() + .await? + .get_relative_path_to(&self.project_path) + .context("Expected relative path to relay artifact")?, + ); + + let p = std::mem::replace(program, Program::Module(Module::dummy())); + *program = p.fold_with(&mut swc_relay::relay( + self.config.clone(), + FileName::Real(PathBuf::from(ctx.file_name_str)), + path_to_proj, + // [TODO]: pages_dir comes through next-swc-loader + // https://github.com/vercel/next.js/blob/ea472e8058faea8ebdab2ef6d3aab257a1f0d11c/packages/next/src/build/webpack-config.ts#L792 + None, + Some(ctx.unresolved_mark), + )); + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/styled_components.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/styled_components.rs new file mode 100644 index 0000000000000..b3a32ef6fd358 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/styled_components.rs @@ -0,0 +1,106 @@ +use std::path::PathBuf; + +use anyhow::Result; +use async_trait::async_trait; +use swc_core::{ + common::{comments::NoopComments, FileName}, + ecma::{ast::Program, atoms::JsWord, visit::VisitMutWith}, +}; +use turbo_tasks::{ValueDefault, Vc}; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +#[turbo_tasks::value(transparent)] +pub struct OptionStyledComponentsTransformConfig(Option>); + +#[turbo_tasks::value(shared)] +#[derive(Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct StyledComponentsTransformConfig { + pub display_name: bool, + pub ssr: bool, + pub file_name: bool, + pub top_level_import_paths: Vec, + pub meaningless_file_names: Vec, + pub css_prop: bool, + pub namespace: Option, +} + +impl Default for StyledComponentsTransformConfig { + fn default() -> Self { + StyledComponentsTransformConfig { + display_name: true, + ssr: true, + file_name: true, + top_level_import_paths: vec![], + meaningless_file_names: vec!["index".to_string()], + css_prop: true, + namespace: None, + } + } +} + +#[turbo_tasks::value_impl] +impl StyledComponentsTransformConfig { + #[turbo_tasks::function] + fn default_private() -> Vc { + Self::cell(Default::default()) + } +} + +impl ValueDefault for StyledComponentsTransformConfig { + fn value_default() -> Vc { + StyledComponentsTransformConfig::default_private() + } +} + +#[derive(Debug)] +pub struct StyledComponentsTransformer { + config: styled_components::Config, +} + +impl StyledComponentsTransformer { + pub fn new(config: &StyledComponentsTransformConfig) -> Self { + let mut options = styled_components::Config { + display_name: config.display_name, + ssr: config.ssr, + file_name: config.file_name, + css_prop: config.css_prop, + ..Default::default() + }; + + if let Some(namespace) = &config.namespace { + options.namespace.clone_from(namespace); + } + + let top_level_import_paths = &config.top_level_import_paths; + if !top_level_import_paths.is_empty() { + options.top_level_import_paths = top_level_import_paths + .iter() + .map(|s| JsWord::from(s.clone())) + .collect(); + } + let meaningless_file_names = &config.meaningless_file_names; + if !meaningless_file_names.is_empty() { + options + .meaningless_file_names + .clone_from(meaningless_file_names); + } + + Self { config: options } + } +} + +#[async_trait] +impl CustomTransformer for StyledComponentsTransformer { + #[tracing::instrument(level = tracing::Level::TRACE, name = "styled_components", skip_all)] + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + program.visit_mut_with(&mut styled_components::styled_components( + FileName::Real(PathBuf::from(ctx.file_path_str)), + ctx.file_name_hash, + self.config.clone(), + NoopComments, + )); + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/styled_jsx.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/styled_jsx.rs new file mode 100644 index 0000000000000..254b841ba4567 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/styled_jsx.rs @@ -0,0 +1,98 @@ +use anyhow::{bail, Result}; +use async_trait::async_trait; +use lightningcss::{ + stylesheet::{PrinterOptions, StyleSheet}, + targets::{Browsers, Targets}, +}; +use swc_core::{ + common::{util::take::Take, FileName}, + ecma::{ + ast::{Module, Program}, + preset_env::{Version, Versions}, + visit::FoldWith, + }, +}; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +#[derive(Debug)] +pub struct StyledJsxTransformer { + use_lightningcss: bool, + target_browsers: Versions, +} + +impl StyledJsxTransformer { + pub fn new(use_lightningcss: bool, target_browsers: Versions) -> Self { + Self { + use_lightningcss, + target_browsers, + } + } +} + +#[async_trait] +impl CustomTransformer for StyledJsxTransformer { + #[tracing::instrument(level = tracing::Level::TRACE, name = "styled_jsx", skip_all)] + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + let p = std::mem::replace(program, Program::Module(Module::dummy())); + *program = p.fold_with(&mut styled_jsx::visitor::styled_jsx( + ctx.source_map.clone(), + // styled_jsx don't really use that in a relevant way + FileName::Anon, + styled_jsx::visitor::Config { + use_lightningcss: self.use_lightningcss, + browsers: self.target_browsers, + }, + styled_jsx::visitor::NativeConfig { + process_css: if self.use_lightningcss || self.target_browsers.is_any_target() { + None + } else { + let targets = Targets { + browsers: Some(convert_browsers(&self.target_browsers)), + ..Default::default() + }; + + Some(Box::new(move |css| { + let ss = StyleSheet::parse(css, Default::default()); + + let ss = match ss { + Ok(v) => v, + Err(err) => { + bail!("failed to parse css using lightningcss: {}", err) + } + }; + + let output = ss.to_css(PrinterOptions { + minify: true, + source_map: None, + project_root: None, + targets, + analyze_dependencies: None, + pseudo_classes: None, + })?; + Ok(output.code) + })) + }, + }, + )); + + Ok(()) + } +} + +fn convert_browsers(browsers: &Versions) -> Browsers { + fn convert(v: Option) -> Option { + v.map(|v| v.major << 16 | v.minor << 8 | v.patch) + } + + Browsers { + android: convert(browsers.android), + chrome: convert(browsers.chrome), + edge: convert(browsers.edge), + firefox: convert(browsers.firefox), + ie: convert(browsers.ie), + ios_saf: convert(browsers.ios), + opera: convert(browsers.opera), + safari: convert(browsers.safari), + samsung: convert(browsers.samsung), + } +} diff --git a/turbopack/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs new file mode 100644 index 0000000000000..359c89433c3cc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-plugins/src/transform/swc_ecma_transform_plugins.rs @@ -0,0 +1,236 @@ +use anyhow::Result; +use async_trait::async_trait; +use swc_core::ecma::ast::Program; +use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::issue::{Issue, IssueSeverity, IssueStage, OptionStyledString, StyledString}; +use turbopack_ecmascript::{CustomTransformer, TransformContext}; + +/// A wrapper around an SWC's ecma transform wasm plugin module bytes, allowing +/// it to operate with the turbo_tasks caching requirements. +/// Internally this contains a `CompiledPluginModuleBytes`, which points to the +/// compiled, serialized wasmer::Module instead of raw file bytes to reduce the +/// cost of the compilation. +#[turbo_tasks::value(serialization = "none", eq = "manual", into = "new", cell = "new")] +pub struct SwcPluginModule( + #[turbo_tasks(trace_ignore)] + #[cfg(feature = "swc_ecma_transform_plugin")] + pub swc_core::plugin_runner::plugin_module_bytes::CompiledPluginModuleBytes, + // Dummy field to avoid turbo_tasks macro complaining about empty struct. + // This is because we can't import CompiledPluginModuleBytes by default, it should be only + // available for the target / platforms that support swc plugins (which can build wasmer) + #[cfg(not(feature = "swc_ecma_transform_plugin"))] pub (), +); + +impl SwcPluginModule { + pub fn new(plugin_name: &str, plugin_bytes: Vec) -> Self { + #[cfg(feature = "swc_ecma_transform_plugin")] + { + Self({ + use swc_core::plugin_runner::plugin_module_bytes::{ + CompiledPluginModuleBytes, RawPluginModuleBytes, + }; + CompiledPluginModuleBytes::from(RawPluginModuleBytes::new( + plugin_name.to_string(), + plugin_bytes, + )) + }) + } + + #[cfg(not(feature = "swc_ecma_transform_plugin"))] + { + let _ = plugin_name; + let _ = plugin_bytes; + Self(()) + } + } +} + +#[turbo_tasks::value(shared)] +struct UnsupportedSwcEcmaTransformPluginsIssue { + pub file_path: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for UnsupportedSwcEcmaTransformPluginsIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Warning.into() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Transform.cell() + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + Ok(StyledString::Text( + "Unsupported SWC EcmaScript transform plugins on this platform.".into(), + ) + .cell()) + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.file_path + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some( + StyledString::Text( + "Turbopack does not yet support running SWC EcmaScript transform plugins on this \ + platform." + .into(), + ) + .cell(), + )) + } +} + +/// A custom transformer plugin to execute SWC's transform plugins. +#[derive(Debug)] +pub struct SwcEcmaTransformPluginsTransformer { + #[cfg(feature = "swc_ecma_transform_plugin")] + plugins: Vec<(Vc, serde_json::Value)>, +} + +impl SwcEcmaTransformPluginsTransformer { + #[cfg(feature = "swc_ecma_transform_plugin")] + pub fn new(plugins: Vec<(Vc, serde_json::Value)>) -> Self { + Self { plugins } + } + + // [TODO] Due to WEB-1102 putting this module itself behind compile time feature + // doesn't work. Instead allow to instantiate dummy instance. + #[cfg(not(feature = "swc_ecma_transform_plugin"))] + #[allow(clippy::new_without_default)] + pub fn new() -> Self { + Self {} + } +} + +#[async_trait] +impl CustomTransformer for SwcEcmaTransformPluginsTransformer { + #[cfg_attr(not(feature = "swc_ecma_transform_plugin"), allow(unused))] + #[tracing::instrument(level = tracing::Level::TRACE, name = "swc_ecma_transform_plugin", skip_all)] + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + #[cfg(feature = "swc_ecma_transform_plugin")] + { + use std::{cell::RefCell, rc::Rc, sync::Arc}; + + use swc_core::{ + common::{ + comments::SingleThreadedComments, + plugin::{ + metadata::TransformPluginMetadataContext, serialized::PluginSerializedBytes, + }, + util::take::Take, + }, + ecma::ast::Module, + plugin::proxies::{HostCommentsStorage, COMMENTS}, + plugin_runner::plugin_module_bytes::PluginModuleBytes, + }; + + let mut plugins = vec![]; + for (plugin_module, config) in &self.plugins { + let plugin_module = &plugin_module.await?.0; + + plugins.push(( + plugin_module.get_module_name().to_string(), + config.clone(), + Box::new(plugin_module.clone()), + )); + } + + let should_enable_comments_proxy = + !ctx.comments.leading.is_empty() && !ctx.comments.trailing.is_empty(); + + //[TODO]: as same as swc/core does, we should set should_enable_comments_proxy + // depends on the src's comments availability. For now, check naively if leading + // / trailing comments are empty. + let comments = if should_enable_comments_proxy { + // Plugin only able to accept singlethreaded comments, interop from + // multithreaded comments. + let mut leading = + swc_core::common::comments::SingleThreadedCommentsMapInner::default(); + ctx.comments.leading.as_ref().into_iter().for_each(|c| { + leading.insert(*c.key(), c.value().clone()); + }); + + let mut trailing = + swc_core::common::comments::SingleThreadedCommentsMapInner::default(); + ctx.comments.trailing.as_ref().into_iter().for_each(|c| { + trailing.insert(*c.key(), c.value().clone()); + }); + + Some(SingleThreadedComments::from_leading_and_trailing( + Rc::new(RefCell::new(leading)), + Rc::new(RefCell::new(trailing)), + )) + } else { + None + }; + + let transformed_program = + COMMENTS.set(&HostCommentsStorage { inner: comments }, || { + let module_program = + std::mem::replace(program, Program::Module(Module::dummy())); + let module_program = + swc_core::common::plugin::serialized::VersionedSerializable::new( + module_program, + ); + let mut serialized_program = + PluginSerializedBytes::try_serialize(&module_program)?; + + let transform_metadata_context = Arc::new(TransformPluginMetadataContext::new( + Some(ctx.file_name_str.to_string()), + //[TODO]: Support env-related variable injection, i.e process.env.NODE_ENV + "development".to_string(), + None, + )); + + // Run plugin transformation against current program. + // We do not serialize / deserialize between each plugin execution but + // copies raw transformed bytes directly into plugin's memory space. + // Note: This doesn't mean plugin won't perform any se/deserialization: it + // still have to construct from raw bytes internally to perform actual + // transform. + for (_plugin_name, plugin_config, plugin_module) in plugins.drain(..) { + let runtime = + swc_core::plugin_runner::wasix_runtime::build_wasi_runtime(None); + let mut transform_plugin_executor = + swc_core::plugin_runner::create_plugin_transform_executor( + ctx.source_map, + &ctx.unresolved_mark, + &transform_metadata_context, + plugin_module, + Some(plugin_config), + runtime, + ); + + serialized_program = transform_plugin_executor + .transform(&serialized_program, Some(should_enable_comments_proxy))?; + } + + serialized_program.deserialize().map(|v| v.into_inner()) + })?; + + *program = transformed_program; + } + + #[cfg(not(feature = "swc_ecma_transform_plugin"))] + { + use turbopack_core::issue::IssueExt; + + UnsupportedSwcEcmaTransformPluginsIssue { + file_path: ctx.file_path, + } + .cell() + .emit(); + } + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/Cargo.toml b/turbopack/crates/turbopack-ecmascript-runtime/Cargo.toml new file mode 100644 index 0000000000000..a9899deabda2c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "turbopack-ecmascript-runtime" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[features] +# enable "HMR" for embedded assets +dynamic_embed_contents = ["turbo-tasks-fs/dynamic_embed_contents"] +# enable test utilities such as `RuntimeType::Dummy` +test = [] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +indoc = { workspace = true } +serde = { workspace = true } + +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-ecmascript-runtime/README.md b/turbopack/crates/turbopack-ecmascript-runtime/README.md new file mode 100644 index 0000000000000..736d12f36368a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/README.md @@ -0,0 +1,34 @@ +# turbopack-ecmascript-runtime + +This crate contains Turbopack's ECMAScript runtimes. These include: + +- Development runtimes for the browser, Node.js, and Edge-like runtimes; +- Production runtimes for the browser, Node.js, and Edge-like runtimes (only Node.js is implemented for now). + +## `` + +The TypeScript files corresponding to the runtime itself all use `` instead of `import`/`export` +to import dependencies. This is because the runtime doesn't use a module system. Instead, the files are concatenated +together in a specific order. + +As such, the `` statements more closely map to the way the runtime is actually built. They also +allow us to refer to top-level declarations in another file without having to `import`/`export` them, which makes no +sense in the context of a runtime. + +## Why is everything in one crate? + +The runtime-agnostic code (`js/src/shared`) was originally placed in `turbopack-ecmascript`, and the runtime-specific +code (`js/src/{build,dev}`) in `turbopack-{build,dev}`. + +However, `` statements only support relative paths. You can't refer to a file in a dependency. For +the typings to work properly, and for them to be usable from outside of this repo (e.g. in the Next.js repo), it's much +easier to have everything in one package. + +## Why so many `tsconfig.json`? + +Since different runtimes are meant to run in different environments, they use different `tsconfig.json` files to +customize what APIs are available to them. For example, the browser runtime can use `window` and `document`, but the +Node.js runtime can't. + +All of these `tsconfig.json` files extend `tsconfig.base.json`, which contains the common configuration for all +runtimes. diff --git a/turbopack/crates/turbopack-ecmascript-runtime/build.rs b/turbopack/crates/turbopack-ecmascript-runtime/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/package.json b/turbopack/crates/turbopack-ecmascript-runtime/js/package.json new file mode 100644 index 0000000000000..e54594d1bb1d2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/package.json @@ -0,0 +1,26 @@ +{ + "name": "@vercel/turbopack-ecmascript-runtime", + "version": "0.0.0", + "description": "Turbopack EcmaScript runtime code and utilities", + "license": "UNLICENSED", + "private": true, + "scripts": { + "check": "run-p check:*", + "check:nodejs": "tsc -p src/nodejs", + "check:browser-dev-client": "tsc -p src/browser/dev/hmr-client", + "check:browser-dev-runtime-base": "tsc -p src/browser/dev/runtime/base", + "check:browser-dev-runtime-dom": "tsc -p src/browser/dev/runtime/dom", + "check:browser-dev-runtime-edge": "tsc -p src/browser/dev/runtime/edge" + }, + "exports": { + ".": "./src/main.js", + "./*": "./src/*.ts" + }, + "dependencies": { + "@types/node": "^18.11.11" + }, + "devDependencies": { + "@next/react-refresh-utils": "^14.1.0", + "npm-run-all": "^4.1.5" + } +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/hmr-client.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/hmr-client.ts new file mode 100644 index 0000000000000..fc011843a752c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/hmr-client.ts @@ -0,0 +1,601 @@ +/// +/// +/// +/// + +import { + addMessageListener as turboSocketAddMessageListener, + sendMessage as turboSocketSendMessage, +} from "./websocket"; +type SendMessage = typeof import("./websocket").sendMessage; + +export type ClientOptions = { + addMessageListener: typeof import("./websocket").addMessageListener; + sendMessage: SendMessage; + onUpdateError: (err: unknown) => void; +}; + +export function connect({ + // TODO(WEB-1465) Remove this backwards compat fallback once + // vercel/next.js#54586 is merged. + addMessageListener = turboSocketAddMessageListener, + // TODO(WEB-1465) Remove this backwards compat fallback once + // vercel/next.js#54586 is merged. + sendMessage = turboSocketSendMessage, + onUpdateError = console.error, +}: ClientOptions) { + addMessageListener((msg) => { + switch (msg.type) { + case "turbopack-connected": + handleSocketConnected(sendMessage); + break; + default: + try { + if (Array.isArray(msg.data)) { + for (let i = 0; i < msg.data.length; i++) { + handleSocketMessage(msg.data[i] as ServerMessage); + } + } else { + handleSocketMessage(msg.data as ServerMessage); + } + applyAggregatedUpdates(); + } catch (e: unknown) { + console.warn( + "[Fast Refresh] performing full reload\n\n" + + "Fast Refresh will perform a full reload when you edit a file that's imported by modules outside of the React rendering tree.\n" + + "You might have a file which exports a React component but also exports a value that is imported by a non-React component file.\n" + + "Consider migrating the non-React component export to a separate file and importing it into both files.\n\n" + + "It is also possible the parent component of the component you edited is a class component, which disables Fast Refresh.\n" + + "Fast Refresh requires at least one parent function component in your React tree." + ); + onUpdateError(e); + location.reload(); + } + break; + } + }); + + const queued = globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS; + if (queued != null && !Array.isArray(queued)) { + throw new Error("A separate HMR handler was already registered"); + } + globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS = { + push: ([chunkPath, callback]: [ChunkPath, UpdateCallback]) => { + subscribeToChunkUpdate(chunkPath, sendMessage, callback); + }, + }; + + if (Array.isArray(queued)) { + for (const [chunkPath, callback] of queued) { + subscribeToChunkUpdate(chunkPath, sendMessage, callback); + } + } +} + +type UpdateCallbackSet = { + callbacks: Set; + unsubscribe: () => void; +}; + +const updateCallbackSets: Map = new Map(); + +function sendJSON(sendMessage: SendMessage, message: ClientMessage) { + sendMessage(JSON.stringify(message)); +} + +type ResourceKey = string; + +function resourceKey(resource: ResourceIdentifier): ResourceKey { + return JSON.stringify({ + path: resource.path, + headers: resource.headers || null, + }); +} + +function subscribeToUpdates( + sendMessage: SendMessage, + resource: ResourceIdentifier +): () => void { + sendJSON(sendMessage, { + type: "turbopack-subscribe", + ...resource, + }); + + return () => { + sendJSON(sendMessage, { + type: "turbopack-unsubscribe", + ...resource, + }); + }; +} + +function handleSocketConnected(sendMessage: SendMessage) { + for (const key of updateCallbackSets.keys()) { + subscribeToUpdates(sendMessage, JSON.parse(key)); + } +} + +// we aggregate all pending updates until the issues are resolved +const chunkListsWithPendingUpdates: Map = + new Map(); + +function aggregateUpdates(msg: PartialServerMessage) { + const key = resourceKey(msg.resource); + let aggregated = chunkListsWithPendingUpdates.get(key); + + if (aggregated) { + aggregated.instruction = mergeChunkListUpdates( + aggregated.instruction, + msg.instruction + ); + } else { + chunkListsWithPendingUpdates.set(key, msg); + } +} + +function applyAggregatedUpdates() { + if (chunkListsWithPendingUpdates.size === 0) return; + hooks.beforeRefresh(); + for (const msg of chunkListsWithPendingUpdates.values()) { + triggerUpdate(msg); + } + chunkListsWithPendingUpdates.clear(); + finalizeUpdate(); +} + +function mergeChunkListUpdates( + updateA: ChunkListUpdate, + updateB: ChunkListUpdate +): ChunkListUpdate { + let chunks; + if (updateA.chunks != null) { + if (updateB.chunks == null) { + chunks = updateA.chunks; + } else { + chunks = mergeChunkListChunks(updateA.chunks, updateB.chunks); + } + } else if (updateB.chunks != null) { + chunks = updateB.chunks; + } + + let merged; + if (updateA.merged != null) { + if (updateB.merged == null) { + merged = updateA.merged; + } else { + // Since `merged` is an array of updates, we need to merge them all into + // one, consistent update. + // Since there can only be `EcmascriptMergeUpdates` in the array, there is + // no need to key on the `type` field. + let update = updateA.merged[0]; + for (let i = 1; i < updateA.merged.length; i++) { + update = mergeChunkListEcmascriptMergedUpdates( + update, + updateA.merged[i] + ); + } + + for (let i = 0; i < updateB.merged.length; i++) { + update = mergeChunkListEcmascriptMergedUpdates( + update, + updateB.merged[i] + ); + } + + merged = [update]; + } + } else if (updateB.merged != null) { + merged = updateB.merged; + } + + return { + type: "ChunkListUpdate", + chunks, + merged, + }; +} + +function mergeChunkListChunks( + chunksA: Record, + chunksB: Record +): Record { + const chunks: Record = {}; + + for (const [chunkPath, chunkUpdateA] of Object.entries(chunksA)) { + const chunkUpdateB = chunksB[chunkPath]; + if (chunkUpdateB != null) { + const mergedUpdate = mergeChunkUpdates(chunkUpdateA, chunkUpdateB); + if (mergedUpdate != null) { + chunks[chunkPath] = mergedUpdate; + } + } else { + chunks[chunkPath] = chunkUpdateA; + } + } + + for (const [chunkPath, chunkUpdateB] of Object.entries(chunksB)) { + if (chunks[chunkPath] == null) { + chunks[chunkPath] = chunkUpdateB; + } + } + + return chunks; +} + +function mergeChunkUpdates( + updateA: ChunkUpdate, + updateB: ChunkUpdate +): ChunkUpdate | undefined { + if ( + (updateA.type === "added" && updateB.type === "deleted") || + (updateA.type === "deleted" && updateB.type === "added") + ) { + return undefined; + } + + if (updateA.type === "partial") { + invariant(updateA.instruction, "Partial updates are unsupported"); + } + + if (updateB.type === "partial") { + invariant(updateB.instruction, "Partial updates are unsupported"); + } + + return undefined; +} + +function mergeChunkListEcmascriptMergedUpdates( + mergedA: EcmascriptMergedUpdate, + mergedB: EcmascriptMergedUpdate +): EcmascriptMergedUpdate { + const entries = mergeEcmascriptChunkEntries(mergedA.entries, mergedB.entries); + const chunks = mergeEcmascriptChunksUpdates(mergedA.chunks, mergedB.chunks); + + return { + type: "EcmascriptMergedUpdate", + entries, + chunks, + }; +} + +function mergeEcmascriptChunkEntries( + entriesA: Record | undefined, + entriesB: Record | undefined +): Record { + return { ...entriesA, ...entriesB }; +} + +function mergeEcmascriptChunksUpdates( + chunksA: Record | undefined, + chunksB: Record | undefined +): Record | undefined { + if (chunksA == null) { + return chunksB; + } + + if (chunksB == null) { + return chunksA; + } + + const chunks: Record = {}; + + for (const [chunkPath, chunkUpdateA] of Object.entries(chunksA)) { + const chunkUpdateB = chunksB[chunkPath]; + if (chunkUpdateB != null) { + const mergedUpdate = mergeEcmascriptChunkUpdates( + chunkUpdateA, + chunkUpdateB + ); + if (mergedUpdate != null) { + chunks[chunkPath] = mergedUpdate; + } + } else { + chunks[chunkPath] = chunkUpdateA; + } + } + + for (const [chunkPath, chunkUpdateB] of Object.entries(chunksB)) { + if (chunks[chunkPath] == null) { + chunks[chunkPath] = chunkUpdateB; + } + } + + if (Object.keys(chunks).length === 0) { + return undefined; + } + + return chunks; +} + +function mergeEcmascriptChunkUpdates( + updateA: EcmascriptMergedChunkUpdate, + updateB: EcmascriptMergedChunkUpdate +): EcmascriptMergedChunkUpdate | undefined { + if (updateA.type === "added" && updateB.type === "deleted") { + // These two completely cancel each other out. + return undefined; + } + + if (updateA.type === "deleted" && updateB.type === "added") { + const added = []; + const deleted = []; + const deletedModules = new Set(updateA.modules ?? []); + const addedModules = new Set(updateB.modules ?? []); + + for (const moduleId of addedModules) { + if (!deletedModules.has(moduleId)) { + added.push(moduleId); + } + } + + for (const moduleId of deletedModules) { + if (!addedModules.has(moduleId)) { + deleted.push(moduleId); + } + } + + if (added.length === 0 && deleted.length === 0) { + return undefined; + } + + return { + type: "partial", + added, + deleted, + }; + } + + if (updateA.type === "partial" && updateB.type === "partial") { + const added = new Set([...(updateA.added ?? []), ...(updateB.added ?? [])]); + const deleted = new Set([ + ...(updateA.deleted ?? []), + ...(updateB.deleted ?? []), + ]); + + if (updateB.added != null) { + for (const moduleId of updateB.added) { + deleted.delete(moduleId); + } + } + + if (updateB.deleted != null) { + for (const moduleId of updateB.deleted) { + added.delete(moduleId); + } + } + + return { + type: "partial", + added: [...added], + deleted: [...deleted], + }; + } + + if (updateA.type === "added" && updateB.type === "partial") { + const modules = new Set([ + ...(updateA.modules ?? []), + ...(updateB.added ?? []), + ]); + + for (const moduleId of updateB.deleted ?? []) { + modules.delete(moduleId); + } + + return { + type: "added", + modules: [...modules], + }; + } + + if (updateA.type === "partial" && updateB.type === "deleted") { + // We could eagerly return `updateB` here, but this would potentially be + // incorrect if `updateA` has added modules. + + const modules = new Set(updateB.modules ?? []); + + if (updateA.added != null) { + for (const moduleId of updateA.added) { + modules.delete(moduleId); + } + } + + return { + type: "deleted", + modules: [...modules], + }; + } + + // Any other update combination is invalid. + + return undefined; +} + +function invariant(_: never, message: string): never { + throw new Error(`Invariant: ${message}`); +} + +const CRITICAL = ["bug", "error", "fatal"]; + +function compareByList(list: any[], a: any, b: any) { + const aI = list.indexOf(a) + 1 || list.length; + const bI = list.indexOf(b) + 1 || list.length; + return aI - bI; +} + +const chunksWithIssues: Map = new Map(); + +function emitIssues() { + const issues = []; + const deduplicationSet = new Set(); + + for (const [_, chunkIssues] of chunksWithIssues) { + for (const chunkIssue of chunkIssues) { + if (deduplicationSet.has(chunkIssue.formatted)) continue; + + issues.push(chunkIssue); + deduplicationSet.add(chunkIssue.formatted); + } + } + + sortIssues(issues); + + hooks.issues(issues); +} + +function handleIssues(msg: ServerMessage): boolean { + const key = resourceKey(msg.resource); + let hasCriticalIssues = false; + + for (const issue of msg.issues) { + if (CRITICAL.includes(issue.severity)) { + hasCriticalIssues = true; + } + } + + if (msg.issues.length > 0) { + chunksWithIssues.set(key, msg.issues); + } else if (chunksWithIssues.has(key)) { + chunksWithIssues.delete(key); + } + + emitIssues(); + + return hasCriticalIssues; +} + +const SEVERITY_ORDER = ["bug", "fatal", "error", "warning", "info", "log"]; +const CATEGORY_ORDER = [ + "parse", + "resolve", + "code generation", + "rendering", + "typescript", + "other", +]; + +function sortIssues(issues: Issue[]) { + issues.sort((a, b) => { + const first = compareByList(SEVERITY_ORDER, a.severity, b.severity); + if (first !== 0) return first; + return compareByList(CATEGORY_ORDER, a.category, b.category); + }); +} + +const hooks = { + beforeRefresh: () => {}, + refresh: () => {}, + buildOk: () => {}, + issues: (_issues: Issue[]) => {}, +}; + +export function setHooks(newHooks: typeof hooks) { + Object.assign(hooks, newHooks); +} + +function handleSocketMessage(msg: ServerMessage) { + sortIssues(msg.issues); + + handleIssues(msg); + + switch (msg.type) { + case "issues": + // issues are already handled + break; + case "partial": + // aggregate updates + aggregateUpdates(msg); + break; + default: + // run single update + const runHooks = chunkListsWithPendingUpdates.size === 0; + if (runHooks) hooks.beforeRefresh(); + triggerUpdate(msg); + if (runHooks) finalizeUpdate(); + break; + } +} + +function finalizeUpdate() { + hooks.refresh(); + hooks.buildOk(); + + // This is used by the Next.js integration test suite to notify it when HMR + // updates have been completed. + // TODO: Only run this in test environments (gate by `process.env.__NEXT_TEST_MODE`) + if (globalThis.__NEXT_HMR_CB) { + globalThis.__NEXT_HMR_CB(); + globalThis.__NEXT_HMR_CB = null; + } +} + +function subscribeToChunkUpdate( + chunkPath: ChunkPath, + sendMessage: SendMessage, + callback: UpdateCallback +): () => void { + return subscribeToUpdate( + { + path: chunkPath, + }, + sendMessage, + callback + ); +} + +export function subscribeToUpdate( + resource: ResourceIdentifier, + sendMessage: SendMessage, + callback: UpdateCallback +) { + // TODO(WEB-1465) Remove this backwards compat fallback once + // vercel/next.js#54586 is merged. + if (callback === undefined) { + callback = sendMessage; + sendMessage = turboSocketSendMessage; + } + + const key = resourceKey(resource); + let callbackSet: UpdateCallbackSet; + const existingCallbackSet = updateCallbackSets.get(key); + if (!existingCallbackSet) { + callbackSet = { + callbacks: new Set([callback]), + unsubscribe: subscribeToUpdates(sendMessage, resource), + }; + updateCallbackSets.set(key, callbackSet); + } else { + existingCallbackSet.callbacks.add(callback); + callbackSet = existingCallbackSet; + } + + return () => { + callbackSet.callbacks.delete(callback); + + if (callbackSet.callbacks.size === 0) { + callbackSet.unsubscribe(); + updateCallbackSets.delete(key); + } + }; +} + +function triggerUpdate(msg: ServerMessage) { + const key = resourceKey(msg.resource); + const callbackSet = updateCallbackSets.get(key); + if (!callbackSet) { + return; + } + + for (const callback of callbackSet.callbacks) { + callback(msg); + } + + if (msg.type === "notFound") { + // This indicates that the resource which we subscribed to either does not exist or + // has been deleted. In either case, we should clear all update callbacks, so if a + // new subscription is created for the same resource, it will send a new "subscribe" + // message to the server. + // No need to send an "unsubscribe" message to the server, it will have already + // dropped the update stream before sending the "notFound" message. + updateCallbackSets.delete(key); + } +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/index.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/index.ts new file mode 100644 index 0000000000000..6b455222c37eb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/index.ts @@ -0,0 +1,2 @@ +export * from "./hmr-client"; +export * from "./websocket"; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/tsconfig.json b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/tsconfig.json new file mode 100644 index 0000000000000..7ce726cb8210c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "skipLibCheck": true, + + // environment + "lib": ["ESNext", "DOM"], + "target": "esnext" + }, + "include": ["*.ts"] +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/websocket.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/websocket.ts new file mode 100644 index 0000000000000..d7da330bb8173 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/hmr-client/websocket.ts @@ -0,0 +1,101 @@ +// Adapted from https://github.com/vercel/next.js/blob/canary/packages/next/client/dev/error-overlay/websocket.ts + +let source: WebSocket; +const eventCallbacks: ((msg: WebSocketMessage) => void)[] = []; + +// TODO: add timeout again +// let lastActivity = Date.now() + +function getSocketProtocol(assetPrefix: string): string { + let protocol = location.protocol; + + try { + // assetPrefix is a url + protocol = new URL(assetPrefix).protocol; + } catch (_) {} + + return protocol === "http:" ? "ws" : "wss"; +} + +export type WebSocketMessage = + | { + type: "turbopack-connected"; + } + | { + type: "turbopack-message"; + data: Record; + }; + +export function addMessageListener(cb: (msg: WebSocketMessage) => void) { + eventCallbacks.push(cb); +} + +export function sendMessage(data: any) { + if (!source || source.readyState !== source.OPEN) return; + return source.send(data); +} + +export type HMROptions = { + path: string; + assetPrefix: string; + timeout?: number; + log?: boolean; +}; + +export function connectHMR(options: HMROptions) { + const { timeout = 5 * 1000 } = options; + + function init() { + if (source) source.close(); + + console.log("[HMR] connecting..."); + + function handleOnline() { + const connected = { type: "turbopack-connected" as const }; + eventCallbacks.forEach((cb) => { + cb(connected); + }); + + if (options.log) console.log("[HMR] connected"); + // lastActivity = Date.now() + } + + function handleMessage(event: MessageEvent) { + // lastActivity = Date.now() + + const message = { + type: "turbopack-message" as const, + data: JSON.parse(event.data), + }; + eventCallbacks.forEach((cb) => { + cb(message); + }); + } + + // let timer: NodeJS.Timeout + + function handleDisconnect() { + source.close(); + setTimeout(init, timeout); + } + + const { hostname, port } = location; + const protocol = getSocketProtocol(options.assetPrefix || ""); + const assetPrefix = options.assetPrefix.replace(/^\/+/, ""); + + let url = `${protocol}://${hostname}:${port}${ + assetPrefix ? `/${assetPrefix}` : "" + }`; + + if (assetPrefix.startsWith("http")) { + url = `${protocol}://${assetPrefix.split("://")[1]}`; + } + + source = new window.WebSocket(`${url}${options.path}`); + source.onopen = handleOnline; + source.onerror = handleDisconnect; + source.onmessage = handleMessage; + } + + init(); +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/dummy.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/dummy.ts new file mode 100644 index 0000000000000..eabcfaa5a5bc8 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/dummy.ts @@ -0,0 +1,27 @@ +/** + * This file acts as a dummy implementor for the interface that + * `runtime-base.ts` expects to be available in the global scope. + * + * This interface will be implemented by runtime backends. + */ + +/// + +declare var BACKEND: RuntimeBackend; +declare var _eval: (code: EcmascriptModuleEntry) => any; +/** + * Adds additional properties to the `TurbopackDevBaseContext` interface. + */ +declare var augmentContext: ( + context: TurbopackDevBaseContext +) => TurbopackDevContext; +declare var loadWebAssembly: ( + source: SourceInfo, + wasmChunkPath: ChunkPath, + imports: WebAssembly.Imports +) => Exports; +declare var loadWebAssemblyModule: ( + source: SourceInfo, + wasmChunkPath: ChunkPath +) => WebAssembly.Module; +declare var relativeURL: (inputUrl: string) => void; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/extensions.d.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/extensions.d.ts new file mode 100644 index 0000000000000..a6f011eb863b2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/extensions.d.ts @@ -0,0 +1,65 @@ +/** + * Extensions to the shared runtime types that are specific to the development + * runtime (e.g. `module.hot`). + */ + +declare const enum HotUpdateStatus { + idle = "idle", +} + +type HotUpdateStatusHandler = (status: HotUpdateStatus) => void; + +interface HotData { + prevExports?: Exports; +} + +interface HotState { + selfAccepted: boolean | Function; + selfDeclined: boolean; + selfInvalidated: boolean; + disposeHandlers: ((data: object) => void)[]; +} + +type AcceptErrorHandler = ( + err: Error, + context: { moduleId: ModuleId; dependencyId: string | number } +) => void; +type AcceptCallback = (outdatedDependencies: string[]) => void; + +interface AcceptFunction { + // accept updates for self + (errorHandler?: AcceptErrorHandler): void; + + // accept updates for the given modules + ( + modules?: string | string[], + callback?: AcceptCallback, + errorHandler?: AcceptErrorHandler + ): void; +} + +interface Hot { + active: boolean; + data: HotData; + + accept: AcceptFunction; + + decline: (module?: string | string[]) => void; + + dispose: (callback: (data: HotData) => void) => void; + + addDisposeHandler: (callback: (data: object) => void) => void; + + removeDisposeHandler: (callback: (data: object) => void) => void; + + invalidate: () => void; + + status: () => keyof typeof HotUpdateStatus; + addStatusHandler: (handler: HotUpdateStatusHandler) => void; + removeStatusHandler: (handler: HotUpdateStatusHandler) => void; + check: (autoApply: boolean) => Promise; +} + +interface Module { + hot: Hot; +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/globals.d.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/globals.d.ts new file mode 100644 index 0000000000000..eae4e2323ee6c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/globals.d.ts @@ -0,0 +1,30 @@ +/** + * Definitions for globals that are injected by the Turbopack runtime. + * + * These are available from every module, but should only be used by Turbopack + * code, not by user code. + */ + +type UpdateCallback = (update: ServerMessage) => void; + +type ChunkRegistry = { + push: (registration: ChunkRegistration) => void; +}; + +type ChunkListProvider = { + push: (registration: ChunkList) => void; +}; + +type ChunkUpdateProvider = { + push: (registration: [ChunkPath, UpdateCallback]) => void; +}; + +declare var TURBOPACK: ChunkRegistry | ChunkRegistration[] | undefined; +declare var TURBOPACK_CHUNK_LISTS: ChunkListProvider | ChunkList[] | undefined; +declare var TURBOPACK_CHUNK_UPDATE_LISTENERS: + | ChunkUpdateProvider + | [ChunkPath, UpdateCallback][] + | undefined; +// This is used by the Next.js integration test suite to notify it when HMR +// updates have been completed. +declare var __NEXT_HMR_CB: undefined | null | (() => void); diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/protocol.d.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/protocol.d.ts new file mode 100644 index 0000000000000..2123ac8e8e888 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/protocol.d.ts @@ -0,0 +1,148 @@ +/** + * Definitions for the protocol that is used to communicate between the + * Turbopack runtime and the Turbopack server for issue reporting and HMR. + */ +type PartialServerMessage = { + resource: ResourceIdentifier; + issues: Issue[]; + type: "partial"; + instruction: PartialUpdate; +}; + +type ServerMessage = { + resource: ResourceIdentifier; + issues: Issue[]; +} & ( + | { + type: "restart"; + } + | { + type: "notFound"; + } + | PartialServerMessage + | { + type: "issues"; + } + | UnknownType +); + +type UnknownType = { + type: "future-type-marker-do-not-use-or-you-will-be-fired"; +}; + +type PartialUpdate = + | ChunkListUpdate + | { + type: never; + }; + +type ChunkListUpdate = { + type: "ChunkListUpdate"; + chunks?: Record; + merged?: MergedChunkUpdate[]; +}; + +type ChunkUpdate = + | { + type: "added"; + } + | { type: "deleted" } + | { type: "total" } + // We currently don't have any chunks that can be updated partially that can't + // be merged either. So these updates would go into `MergedChunkUpdate` instead. + | { type: "partial"; instruction: never }; + +type MergedChunkUpdate = + | EcmascriptMergedUpdate + | { + type: never; + }; + +type EcmascriptMergedUpdate = { + type: "EcmascriptMergedUpdate"; + entries?: Record; + chunks?: Record; +}; + +type EcmascriptMergedChunkUpdate = + | { + type: "added"; + modules?: ModuleId[]; + } + | { + type: "deleted"; + modules?: ModuleId[]; + } + | { + type: "partial"; + added?: ModuleId[]; + deleted?: ModuleId[]; + } + | { + type: never; + }; + +type EcmascriptModuleEntry = { + code: ModuleFactoryString; + url: string; + map?: string; +}; + +type ResourceIdentifier = { + path: string; + headers?: { [key: string]: string }; +}; + +type ClientMessageSubscribe = { + type: "turbopack-subscribe"; +} & ResourceIdentifier; + +type ClientMessageUnsubscribe = { + type: "turbopack-unsubscribe"; +} & ResourceIdentifier; + +type ClientMessage = ClientMessageSubscribe | ClientMessageUnsubscribe; + +type IssueSeverity = + | "bug" + | "fatal" + | "error" + | "warning" + | "hint" + | "note" + | "suggestion" + | "info"; + +type IssueAsset = { + path: string; +}; + +type SourcePos = { + line: number; + column: number; +}; + +type IssueSource = { + asset: IssueAsset; + range?: IssueSourceRange; +}; + +type IssueSourceRange = { + start: SourcePos; + end: SourcePos; +}; + +type Issue = { + severity: IssueSeverity; + file_path: string; + category: string; + + title: string; + description: string; + detail: string; + documentation_link: string; + + source: IssueSource | null; + sub_issues: Issue[]; + formatted: string; +}; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/runtime-base.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/runtime-base.ts new file mode 100644 index 0000000000000..7896fe904d28d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/runtime-base.ts @@ -0,0 +1,1398 @@ +/** + * This file contains runtime types and functions that are shared between all + * Turbopack *development* ECMAScript runtimes. + * + * It will be appended to the runtime code of each runtime right after the + * shared runtime utils. + */ + +/* eslint-disable @next/next/no-assign-module-variable */ + +/// +/// +/// +/// + +// This file must not use `import` and `export` statements. Otherwise, it +// becomes impossible to augment interfaces declared in ``d files +// (e.g. `Module`). Hence, the need for `import()` here. +type RefreshRuntimeGlobals = + import("@next/react-refresh-utils/dist/runtime").RefreshRuntimeGlobals; + +declare var CHUNK_BASE_PATH: string; +declare var $RefreshHelpers$: RefreshRuntimeGlobals["$RefreshHelpers$"]; +declare var $RefreshReg$: RefreshRuntimeGlobals["$RefreshReg$"]; +declare var $RefreshSig$: RefreshRuntimeGlobals["$RefreshSig$"]; +declare var $RefreshInterceptModuleExecution$: + | RefreshRuntimeGlobals["$RefreshInterceptModuleExecution$"]; + +type RefreshContext = { + register: RefreshRuntimeGlobals["$RefreshReg$"]; + signature: RefreshRuntimeGlobals["$RefreshSig$"]; + registerExports: typeof registerExportsAndSetupBoundaryForReactRefresh; +}; + +type RefreshHelpers = RefreshRuntimeGlobals["$RefreshHelpers$"]; + +interface TurbopackDevBaseContext extends TurbopackBaseContext { + k: RefreshContext; + R: ResolvePathFromModule; +} + +interface TurbopackDevContext extends TurbopackDevBaseContext {} + +// string encoding of a module factory (used in hmr updates) +type ModuleFactoryString = string; + +type ModuleFactory = ( + this: Module["exports"], + context: TurbopackDevContext +) => undefined; + +type DevRuntimeParams = { + otherChunks: ChunkData[]; + runtimeModuleIds: ModuleId[]; +}; + +type ChunkRegistration = [ + chunkPath: ChunkPath, + chunkModules: ModuleFactories, + params: DevRuntimeParams | undefined +]; +type ChunkList = { + path: ChunkPath; + chunks: ChunkData[]; + source: "entry" | "dynamic"; +}; + +enum SourceType { + /** + * The module was instantiated because it was included in an evaluated chunk's + * runtime. + */ + Runtime = 0, + /** + * The module was instantiated because a parent module imported it. + */ + Parent = 1, + /** + * The module was instantiated because it was included in a chunk's hot module + * update. + */ + Update = 2, +} + +type SourceInfo = + | { + type: SourceType.Runtime; + chunkPath: ChunkPath; + } + | { + type: SourceType.Parent; + parentId: ModuleId; + } + | { + type: SourceType.Update; + parents?: ModuleId[]; + }; + +interface RuntimeBackend { + registerChunk: (chunkPath: ChunkPath, params?: DevRuntimeParams) => void; + loadChunk: (chunkPath: ChunkPath, source: SourceInfo) => Promise; + reloadChunk?: (chunkPath: ChunkPath) => Promise; + unloadChunk?: (chunkPath: ChunkPath) => void; + + restart: () => void; +} + +class UpdateApplyError extends Error { + name = "UpdateApplyError"; + + dependencyChain: string[]; + + constructor(message: string, dependencyChain: string[]) { + super(message); + this.dependencyChain = dependencyChain; + } +} + +const moduleFactories: ModuleFactories = Object.create(null); +const moduleCache: ModuleCache = Object.create(null); +/** + * Maps module IDs to persisted data between executions of their hot module + * implementation (`hot.data`). + */ +const moduleHotData: Map = new Map(); +/** + * Maps module instances to their hot module state. + */ +const moduleHotState: Map = new Map(); +/** + * Modules that call `module.hot.invalidate()` (while being updated). + */ +const queuedInvalidatedModules: Set = new Set(); +/** + * Module IDs that are instantiated as part of the runtime of a chunk. + */ +const runtimeModules: Set = new Set(); +/** + * Map from module ID to the chunks that contain this module. + * + * In HMR, we need to keep track of which modules are contained in which so + * chunks. This is so we don't eagerly dispose of a module when it is removed + * from chunk A, but still exists in chunk B. + */ +const moduleChunksMap: Map> = new Map(); +/** + * Map from a chunk path to all modules it contains. + */ +const chunkModulesMap: Map> = new Map(); +/** + * Chunk lists that contain a runtime. When these chunk lists receive an update + * that can't be reconciled with the current state of the page, we need to + * reload the runtime entirely. + */ +const runtimeChunkLists: Set = new Set(); +/** + * Map from a chunk list to the chunk paths it contains. + */ +const chunkListChunksMap: Map> = new Map(); +/** + * Map from a chunk path to the chunk lists it belongs to. + */ +const chunkChunkListsMap: Map> = new Map(); + +const availableModules: Map | true> = new Map(); + +const availableModuleChunks: Map | true> = new Map(); + +async function loadChunk( + source: SourceInfo, + chunkData: ChunkData +): Promise { + if (typeof chunkData === "string") { + return loadChunkPath(source, chunkData); + } + + const includedList = chunkData.included || []; + const modulesPromises = includedList.map((included) => { + if (moduleFactories[included]) return true; + return availableModules.get(included); + }); + if (modulesPromises.length > 0 && modulesPromises.every((p) => p)) { + // When all included items are already loaded or loading, we can skip loading ourselves + return Promise.all(modulesPromises); + } + + const includedModuleChunksList = chunkData.moduleChunks || []; + const moduleChunksPromises = includedModuleChunksList + .map((included) => { + // TODO(alexkirsz) Do we need this check? + // if (moduleFactories[included]) return true; + return availableModuleChunks.get(included); + }) + .filter((p) => p); + + let promise; + if (moduleChunksPromises.length > 0) { + // Some module chunks are already loaded or loading. + + if (moduleChunksPromises.length == includedModuleChunksList.length) { + // When all included module chunks are already loaded or loading, we can skip loading ourselves + return Promise.all(moduleChunksPromises); + } + + const moduleChunksToLoad: Set = new Set(); + for (const moduleChunk of includedModuleChunksList) { + if (!availableModuleChunks.has(moduleChunk)) { + moduleChunksToLoad.add(moduleChunk); + } + } + + for (const moduleChunkToLoad of moduleChunksToLoad) { + const promise = loadChunkPath(source, moduleChunkToLoad); + + availableModuleChunks.set(moduleChunkToLoad, promise); + + moduleChunksPromises.push(promise); + } + + promise = Promise.all(moduleChunksPromises); + } else { + promise = loadChunkPath(source, chunkData.path); + + // Mark all included module chunks as loading if they are not already loaded or loading. + for (const includedModuleChunk of includedModuleChunksList) { + if (!availableModuleChunks.has(includedModuleChunk)) { + availableModuleChunks.set(includedModuleChunk, promise); + } + } + } + + for (const included of includedList) { + if (!availableModules.has(included)) { + // It might be better to race old and new promises, but it's rare that the new promise will be faster than a request started earlier. + // In production it's even more rare, because the chunk optimization tries to deduplicate modules anyway. + availableModules.set(included, promise); + } + } + + return promise; +} + +async function loadChunkPath( + source: SourceInfo, + chunkPath: ChunkPath +): Promise { + try { + await BACKEND.loadChunk(chunkPath, source); + } catch (error) { + let loadReason; + switch (source.type) { + case SourceType.Runtime: + loadReason = `as a runtime dependency of chunk ${source.chunkPath}`; + break; + case SourceType.Parent: + loadReason = `from module ${source.parentId}`; + break; + case SourceType.Update: + loadReason = "from an HMR update"; + break; + } + throw new Error( + `Failed to load chunk ${chunkPath} ${loadReason}${ + error ? `: ${error}` : "" + }`, + error + ? { + cause: error, + } + : undefined + ); + } +} + +/** + * Returns an absolute url to an asset. + */ +function createResolvePathFromModule( + resolver: (moduleId: string) => Exports +): (moduleId: string) => string { + return function resolvePathFromModule(moduleId: string): string { + const exported = resolver(moduleId); + return exported?.default ?? exported; + }; +} + +function instantiateModule(id: ModuleId, source: SourceInfo): Module { + const moduleFactory = moduleFactories[id]; + if (typeof moduleFactory !== "function") { + // This can happen if modules incorrectly handle HMR disposes/updates, + // e.g. when they keep a `setTimeout` around which still executes old code + // and contains e.g. a `require("something")` call. + let instantiationReason; + switch (source.type) { + case SourceType.Runtime: + instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`; + break; + case SourceType.Parent: + instantiationReason = `because it was required from module ${source.parentId}`; + break; + case SourceType.Update: + instantiationReason = "because of an HMR update"; + break; + } + throw new Error( + `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.` + ); + } + + const hotData = moduleHotData.get(id)!; + const { hot, hotState } = createModuleHot(id, hotData); + + let parents: ModuleId[]; + switch (source.type) { + case SourceType.Runtime: + runtimeModules.add(id); + parents = []; + break; + case SourceType.Parent: + // No need to add this module as a child of the parent module here, this + // has already been taken care of in `getOrInstantiateModuleFromParent`. + parents = [source.parentId]; + break; + case SourceType.Update: + parents = source.parents || []; + break; + } + const module: Module = { + exports: {}, + error: undefined, + loaded: false, + id, + parents, + children: [], + namespaceObject: undefined, + hot, + }; + + moduleCache[id] = module; + moduleHotState.set(module, hotState); + + // NOTE(alexkirsz) This can fail when the module encounters a runtime error. + try { + const sourceInfo: SourceInfo = { type: SourceType.Parent, parentId: id }; + + runModuleExecutionHooks(module, (refresh) => { + const r = commonJsRequire.bind(null, module); + moduleFactory.call( + module.exports, + augmentContext({ + a: asyncModule.bind(null, module), + e: module.exports, + r: commonJsRequire.bind(null, module), + t: runtimeRequire, + f: moduleContext, + i: esmImport.bind(null, module), + s: esmExport.bind(null, module, module.exports), + j: dynamicExport.bind(null, module, module.exports), + v: exportValue.bind(null, module), + n: exportNamespace.bind(null, module), + m: module, + c: moduleCache, + M: moduleFactories, + l: loadChunk.bind(null, sourceInfo), + w: loadWebAssembly.bind(null, sourceInfo), + u: loadWebAssemblyModule.bind(null, sourceInfo), + g: globalThis, + P: resolveAbsolutePath, + U: relativeURL, + k: refresh, + R: createResolvePathFromModule(r), + __dirname: module.id.replace(/(^|\/)\/+$/, ""), + }) + ); + }); + } catch (error) { + module.error = error as any; + throw error; + } + + module.loaded = true; + if (module.namespaceObject && module.exports !== module.namespaceObject) { + // in case of a circular dependency: cjs1 -> esm2 -> cjs1 + interopEsm(module.exports, module.namespaceObject); + } + + return module; +} + +/** + * no-op for browser + * @param modulePath + */ +function resolveAbsolutePath(modulePath?: string): string { + return `/ROOT/${modulePath ?? ""}`; +} + +/** + * NOTE(alexkirsz) Webpack has a "module execution" interception hook that + * Next.js' React Refresh runtime hooks into to add module context to the + * refresh registry. + */ +function runModuleExecutionHooks( + module: Module, + executeModule: (ctx: RefreshContext) => void +) { + const cleanupReactRefreshIntercept = + typeof globalThis.$RefreshInterceptModuleExecution$ === "function" + ? globalThis.$RefreshInterceptModuleExecution$(module.id) + : () => {}; + + try { + executeModule({ + register: globalThis.$RefreshReg$, + signature: globalThis.$RefreshSig$, + registerExports: registerExportsAndSetupBoundaryForReactRefresh, + }); + } catch (e) { + throw e; + } finally { + // Always cleanup the intercept, even if module execution failed. + cleanupReactRefreshIntercept(); + } +} + +/** + * Retrieves a module from the cache, or instantiate it if it is not cached. + */ +const getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent = ( + id, + sourceModule +) => { + if (!sourceModule.hot.active) { + console.warn( + `Unexpected import of module ${id} from module ${sourceModule.id}, which was deleted by an HMR update` + ); + } + + const module = moduleCache[id]; + + if (sourceModule.children.indexOf(id) === -1) { + sourceModule.children.push(id); + } + + if (module) { + if (module.parents.indexOf(sourceModule.id) === -1) { + module.parents.push(sourceModule.id); + } + + return module; + } + + return instantiateModule(id, { + type: SourceType.Parent, + parentId: sourceModule.id, + }); +}; + +/** + * This is adapted from https://github.com/vercel/next.js/blob/3466862d9dc9c8bb3131712134d38757b918d1c0/packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts + */ +function registerExportsAndSetupBoundaryForReactRefresh( + module: Module, + helpers: RefreshHelpers +) { + const currentExports = module.exports; + const prevExports = module.hot.data.prevExports ?? null; + + helpers.registerExportsForReactRefresh(currentExports, module.id); + + // A module can be accepted automatically based on its exports, e.g. when + // it is a Refresh Boundary. + if (helpers.isReactRefreshBoundary(currentExports)) { + // Save the previous exports on update, so we can compare the boundary + // signatures. + module.hot.dispose((data) => { + data.prevExports = currentExports; + }); + // Unconditionally accept an update to this module, we'll check if it's + // still a Refresh Boundary later. + module.hot.accept(); + + // This field is set when the previous version of this module was a + // Refresh Boundary, letting us know we need to check for invalidation or + // enqueue an update. + if (prevExports !== null) { + // A boundary can become ineligible if its exports are incompatible + // with the previous exports. + // + // For example, if you add/remove/change exports, we'll want to + // re-execute the importing modules, and force those components to + // re-render. Similarly, if you convert a class component to a + // function, we want to invalidate the boundary. + if ( + helpers.shouldInvalidateReactRefreshBoundary( + helpers.getRefreshBoundarySignature(prevExports), + helpers.getRefreshBoundarySignature(currentExports) + ) + ) { + module.hot.invalidate(); + } else { + helpers.scheduleUpdate(); + } + } + } else { + // Since we just executed the code for the module, it's possible that the + // new exports made it ineligible for being a boundary. + // We only care about the case when we were _previously_ a boundary, + // because we already accepted this update (accidental side effect). + const isNoLongerABoundary = prevExports !== null; + if (isNoLongerABoundary) { + module.hot.invalidate(); + } + } +} + +function formatDependencyChain(dependencyChain: ModuleId[]): string { + return `Dependency chain: ${dependencyChain.join(" -> ")}`; +} + +function computeOutdatedModules( + added: Map, + modified: Map +): { + outdatedModules: Set; + newModuleFactories: Map; +} { + const newModuleFactories = new Map(); + + for (const [moduleId, entry] of added) { + if (entry != null) { + newModuleFactories.set(moduleId, _eval(entry)); + } + } + + const outdatedModules = computedInvalidatedModules(modified.keys()); + + for (const [moduleId, entry] of modified) { + newModuleFactories.set(moduleId, _eval(entry)); + } + + return { outdatedModules, newModuleFactories }; +} + +function computedInvalidatedModules( + invalidated: Iterable +): Set { + const outdatedModules = new Set(); + + for (const moduleId of invalidated) { + const effect = getAffectedModuleEffects(moduleId); + + switch (effect.type) { + case "unaccepted": + throw new UpdateApplyError( + `cannot apply update: unaccepted module. ${formatDependencyChain( + effect.dependencyChain + )}.`, + effect.dependencyChain + ); + case "self-declined": + throw new UpdateApplyError( + `cannot apply update: self-declined module. ${formatDependencyChain( + effect.dependencyChain + )}.`, + effect.dependencyChain + ); + case "accepted": + for (const outdatedModuleId of effect.outdatedModules) { + outdatedModules.add(outdatedModuleId); + } + break; + // TODO(alexkirsz) Dependencies: handle dependencies effects. + } + } + + return outdatedModules; +} + +function computeOutdatedSelfAcceptedModules( + outdatedModules: Iterable +): { moduleId: ModuleId; errorHandler: true | Function }[] { + const outdatedSelfAcceptedModules = []; + for (const moduleId of outdatedModules) { + const module = moduleCache[moduleId]; + const hotState = moduleHotState.get(module)!; + if (module && hotState.selfAccepted && !hotState.selfInvalidated) { + outdatedSelfAcceptedModules.push({ + moduleId, + errorHandler: hotState.selfAccepted, + }); + } + } + return outdatedSelfAcceptedModules; +} + +/** + * Adds, deletes, and moves modules between chunks. This must happen before the + * dispose phase as it needs to know which modules were removed from all chunks, + * which we can only compute *after* taking care of added and moved modules. + */ +function updateChunksPhase( + chunksAddedModules: Map>, + chunksDeletedModules: Map> +): { disposedModules: Set } { + for (const [chunkPath, addedModuleIds] of chunksAddedModules) { + for (const moduleId of addedModuleIds) { + addModuleToChunk(moduleId, chunkPath); + } + } + + const disposedModules: Set = new Set(); + for (const [chunkPath, addedModuleIds] of chunksDeletedModules) { + for (const moduleId of addedModuleIds) { + if (removeModuleFromChunk(moduleId, chunkPath)) { + disposedModules.add(moduleId); + } + } + } + + return { disposedModules }; +} + +function disposePhase( + outdatedModules: Iterable, + disposedModules: Iterable +): { outdatedModuleParents: Map> } { + for (const moduleId of outdatedModules) { + disposeModule(moduleId, "replace"); + } + + for (const moduleId of disposedModules) { + disposeModule(moduleId, "clear"); + } + + // Removing modules from the module cache is a separate step. + // We also want to keep track of previous parents of the outdated modules. + const outdatedModuleParents = new Map(); + for (const moduleId of outdatedModules) { + const oldModule = moduleCache[moduleId]; + outdatedModuleParents.set(moduleId, oldModule?.parents); + delete moduleCache[moduleId]; + } + + // TODO(alexkirsz) Dependencies: remove outdated dependency from module + // children. + + return { outdatedModuleParents }; +} + +/** + * Disposes of an instance of a module. + * + * Returns the persistent hot data that should be kept for the next module + * instance. + * + * NOTE: mode = "replace" will not remove modules from the moduleCache. + * This must be done in a separate step afterwards. + * This is important because all modules need to be disposed to update the + * parent/child relationships before they are actually removed from the moduleCache. + * If this was done in this method, the following disposeModule calls won't find + * the module from the module id in the cache. + */ +function disposeModule(moduleId: ModuleId, mode: "clear" | "replace") { + const module = moduleCache[moduleId]; + if (!module) { + return; + } + + const hotState = moduleHotState.get(module)!; + const data = {}; + + // Run the `hot.dispose` handler, if any, passing in the persistent + // `hot.data` object. + for (const disposeHandler of hotState.disposeHandlers) { + disposeHandler(data); + } + + // This used to warn in `getOrInstantiateModuleFromParent` when a disposed + // module is still importing other modules. + module.hot.active = false; + + moduleHotState.delete(module); + + // TODO(alexkirsz) Dependencies: delete the module from outdated deps. + + // Remove the disposed module from its children's parent list. + // It will be added back once the module re-instantiates and imports its + // children again. + for (const childId of module.children) { + const child = moduleCache[childId]; + if (!child) { + continue; + } + + const idx = child.parents.indexOf(module.id); + if (idx >= 0) { + child.parents.splice(idx, 1); + } + } + + switch (mode) { + case "clear": + delete moduleCache[module.id]; + moduleHotData.delete(module.id); + break; + case "replace": + moduleHotData.set(module.id, data); + break; + default: + invariant(mode, (mode) => `invalid mode: ${mode}`); + } +} + +function applyPhase( + outdatedSelfAcceptedModules: { + moduleId: ModuleId; + errorHandler: true | Function; + }[], + newModuleFactories: Map, + outdatedModuleParents: Map>, + reportError: (err: any) => void +) { + // Update module factories. + for (const [moduleId, factory] of newModuleFactories.entries()) { + moduleFactories[moduleId] = factory; + } + + // TODO(alexkirsz) Run new runtime entries here. + + // TODO(alexkirsz) Dependencies: call accept handlers for outdated deps. + + // Re-instantiate all outdated self-accepted modules. + for (const { moduleId, errorHandler } of outdatedSelfAcceptedModules) { + try { + instantiateModule(moduleId, { + type: SourceType.Update, + parents: outdatedModuleParents.get(moduleId), + }); + } catch (err) { + if (typeof errorHandler === "function") { + try { + errorHandler(err, { moduleId, module: moduleCache[moduleId] }); + } catch (err2) { + reportError(err2); + reportError(err); + } + } else { + reportError(err); + } + } + } +} + +/** + * Utility function to ensure all variants of an enum are handled. + */ +function invariant(never: never, computeMessage: (arg: any) => string): never { + throw new Error(`Invariant: ${computeMessage(never)}`); +} + +function applyUpdate(update: PartialUpdate) { + switch (update.type) { + case "ChunkListUpdate": + applyChunkListUpdate(update); + break; + default: + invariant(update, (update) => `Unknown update type: ${update.type}`); + } +} + +function applyChunkListUpdate(update: ChunkListUpdate) { + if (update.merged != null) { + for (const merged of update.merged) { + switch (merged.type) { + case "EcmascriptMergedUpdate": + applyEcmascriptMergedUpdate(merged); + break; + default: + invariant(merged, (merged) => `Unknown merged type: ${merged.type}`); + } + } + } + + if (update.chunks != null) { + for (const [chunkPath, chunkUpdate] of Object.entries(update.chunks)) { + switch (chunkUpdate.type) { + case "added": + BACKEND.loadChunk(chunkPath, { type: SourceType.Update }); + break; + case "total": + BACKEND.reloadChunk?.(chunkPath); + break; + case "deleted": + BACKEND.unloadChunk?.(chunkPath); + break; + case "partial": + invariant( + chunkUpdate.instruction, + (instruction) => + `Unknown partial instruction: ${JSON.stringify(instruction)}.` + ); + default: + invariant( + chunkUpdate, + (chunkUpdate) => `Unknown chunk update type: ${chunkUpdate.type}` + ); + } + } + } +} + +function applyEcmascriptMergedUpdate(update: EcmascriptMergedUpdate) { + const { entries = {}, chunks = {} } = update; + const { added, modified, chunksAdded, chunksDeleted } = computeChangedModules( + entries, + chunks + ); + const { outdatedModules, newModuleFactories } = computeOutdatedModules( + added, + modified + ); + const { disposedModules } = updateChunksPhase(chunksAdded, chunksDeleted); + + applyInternal(outdatedModules, disposedModules, newModuleFactories); +} + +function applyInvalidatedModules(outdatedModules: Set) { + if (queuedInvalidatedModules.size > 0) { + computedInvalidatedModules(queuedInvalidatedModules).forEach((moduleId) => { + outdatedModules.add(moduleId); + }); + + queuedInvalidatedModules.clear(); + } + + return outdatedModules; +} + +function applyInternal( + outdatedModules: Set, + disposedModules: Iterable, + newModuleFactories: Map +) { + outdatedModules = applyInvalidatedModules(outdatedModules); + + const outdatedSelfAcceptedModules = + computeOutdatedSelfAcceptedModules(outdatedModules); + + const { outdatedModuleParents } = disposePhase( + outdatedModules, + disposedModules + ); + + // we want to continue on error and only throw the error after we tried applying all updates + let error: any; + + function reportError(err: any) { + if (!error) error = err; + } + + applyPhase( + outdatedSelfAcceptedModules, + newModuleFactories, + outdatedModuleParents, + reportError + ); + + if (error) { + throw error; + } + + if (queuedInvalidatedModules.size > 0) { + applyInternal(new Set(), [], new Map()); + } +} + +function computeChangedModules( + entries: Record, + updates: Record +): { + added: Map; + modified: Map; + deleted: Set; + chunksAdded: Map>; + chunksDeleted: Map>; +} { + const chunksAdded = new Map(); + const chunksDeleted = new Map(); + const added: Map = new Map(); + const modified = new Map(); + const deleted: Set = new Set(); + + for (const [chunkPath, mergedChunkUpdate] of Object.entries(updates)) { + switch (mergedChunkUpdate.type) { + case "added": { + const updateAdded = new Set(mergedChunkUpdate.modules); + for (const moduleId of updateAdded) { + added.set(moduleId, entries[moduleId]); + } + chunksAdded.set(chunkPath, updateAdded); + break; + } + case "deleted": { + // We could also use `mergedChunkUpdate.modules` here. + const updateDeleted = new Set(chunkModulesMap.get(chunkPath)); + for (const moduleId of updateDeleted) { + deleted.add(moduleId); + } + chunksDeleted.set(chunkPath, updateDeleted); + break; + } + case "partial": { + const updateAdded = new Set(mergedChunkUpdate.added); + const updateDeleted = new Set(mergedChunkUpdate.deleted); + for (const moduleId of updateAdded) { + added.set(moduleId, entries[moduleId]); + } + for (const moduleId of updateDeleted) { + deleted.add(moduleId); + } + chunksAdded.set(chunkPath, updateAdded); + chunksDeleted.set(chunkPath, updateDeleted); + break; + } + default: + invariant( + mergedChunkUpdate, + (mergedChunkUpdate) => + `Unknown merged chunk update type: ${mergedChunkUpdate.type}` + ); + } + } + + // If a module was added from one chunk and deleted from another in the same update, + // consider it to be modified, as it means the module was moved from one chunk to another + // AND has new code in a single update. + for (const moduleId of added.keys()) { + if (deleted.has(moduleId)) { + added.delete(moduleId); + deleted.delete(moduleId); + } + } + + for (const [moduleId, entry] of Object.entries(entries)) { + // Modules that haven't been added to any chunk but have new code are considered + // to be modified. + // This needs to be under the previous loop, as we need it to get rid of modules + // that were added and deleted in the same update. + if (!added.has(moduleId)) { + modified.set(moduleId, entry); + } + } + + return { added, deleted, modified, chunksAdded, chunksDeleted }; +} + +type ModuleEffect = + | { + type: "unaccepted"; + dependencyChain: ModuleId[]; + } + | { + type: "self-declined"; + dependencyChain: ModuleId[]; + moduleId: ModuleId; + } + | { + type: "accepted"; + moduleId: ModuleId; + outdatedModules: Set; + }; + +function getAffectedModuleEffects(moduleId: ModuleId): ModuleEffect { + const outdatedModules: Set = new Set(); + + type QueueItem = { moduleId?: ModuleId; dependencyChain: ModuleId[] }; + + const queue: QueueItem[] = [ + { + moduleId, + dependencyChain: [], + }, + ]; + + let nextItem; + while ((nextItem = queue.shift())) { + const { moduleId, dependencyChain } = nextItem; + + if (moduleId != null) { + if (outdatedModules.has(moduleId)) { + // Avoid infinite loops caused by cycles between modules in the dependency chain. + continue; + } + + outdatedModules.add(moduleId); + } + + // We've arrived at the runtime of the chunk, which means that nothing + // else above can accept this update. + if (moduleId === undefined) { + return { + type: "unaccepted", + dependencyChain, + }; + } + + const module = moduleCache[moduleId]; + const hotState = moduleHotState.get(module)!; + + if ( + // The module is not in the cache. Since this is a "modified" update, + // it means that the module was never instantiated before. + !module || // The module accepted itself without invalidating globalThis. + // TODO is that right? + (hotState.selfAccepted && !hotState.selfInvalidated) + ) { + continue; + } + + if (hotState.selfDeclined) { + return { + type: "self-declined", + dependencyChain, + moduleId, + }; + } + + if (runtimeModules.has(moduleId)) { + queue.push({ + moduleId: undefined, + dependencyChain: [...dependencyChain, moduleId], + }); + continue; + } + + for (const parentId of module.parents) { + const parent = moduleCache[parentId]; + + if (!parent) { + // TODO(alexkirsz) Is this even possible? + continue; + } + + // TODO(alexkirsz) Dependencies: check accepted and declined + // dependencies here. + + queue.push({ + moduleId: parentId, + dependencyChain: [...dependencyChain, moduleId], + }); + } + } + + return { + type: "accepted", + moduleId, + outdatedModules, + }; +} + +function handleApply(chunkListPath: ChunkPath, update: ServerMessage) { + switch (update.type) { + case "partial": { + // This indicates that the update is can be applied to the current state of the application. + applyUpdate(update.instruction); + break; + } + case "restart": { + // This indicates that there is no way to apply the update to the + // current state of the application, and that the application must be + // restarted. + BACKEND.restart(); + break; + } + case "notFound": { + // This indicates that the chunk list no longer exists: either the dynamic import which created it was removed, + // or the page itself was deleted. + // If it is a dynamic import, we simply discard all modules that the chunk has exclusive access to. + // If it is a runtime chunk list, we restart the application. + if (runtimeChunkLists.has(chunkListPath)) { + BACKEND.restart(); + } else { + disposeChunkList(chunkListPath); + } + break; + } + default: + throw new Error(`Unknown update type: ${update.type}`); + } +} + +function createModuleHot( + moduleId: ModuleId, + hotData: HotData +): { hot: Hot; hotState: HotState } { + const hotState: HotState = { + selfAccepted: false, + selfDeclined: false, + selfInvalidated: false, + disposeHandlers: [], + }; + + const hot: Hot = { + // TODO(alexkirsz) This is not defined in the HMR API. It was used to + // decide whether to warn whenever an HMR-disposed module required other + // modules. We might want to remove it. + active: true, + + data: hotData ?? {}, + + // TODO(alexkirsz) Support full (dep, callback, errorHandler) form. + accept: ( + modules?: string | string[] | AcceptErrorHandler, + _callback?: AcceptCallback, + _errorHandler?: AcceptErrorHandler + ) => { + if (modules === undefined) { + hotState.selfAccepted = true; + } else if (typeof modules === "function") { + hotState.selfAccepted = modules; + } else { + throw new Error("unsupported `accept` signature"); + } + }, + + decline: (dep) => { + if (dep === undefined) { + hotState.selfDeclined = true; + } else { + throw new Error("unsupported `decline` signature"); + } + }, + + dispose: (callback) => { + hotState.disposeHandlers.push(callback); + }, + + addDisposeHandler: (callback) => { + hotState.disposeHandlers.push(callback); + }, + + removeDisposeHandler: (callback) => { + const idx = hotState.disposeHandlers.indexOf(callback); + if (idx >= 0) { + hotState.disposeHandlers.splice(idx, 1); + } + }, + + invalidate: () => { + hotState.selfInvalidated = true; + queuedInvalidatedModules.add(moduleId); + }, + + // NOTE(alexkirsz) This is part of the management API, which we don't + // implement, but the Next.js React Refresh runtime uses this to decide + // whether to schedule an update. + status: () => "idle", + + // NOTE(alexkirsz) Since we always return "idle" for now, these are no-ops. + addStatusHandler: (_handler) => {}, + removeStatusHandler: (_handler) => {}, + + // NOTE(jridgewell) Check returns the list of updated modules, but we don't + // want the webpack code paths to ever update (the turbopack paths handle + // this already). + check: () => Promise.resolve(null), + }; + + return { hot, hotState }; +} + +/** + * Adds a module to a chunk. + */ +function addModuleToChunk(moduleId: ModuleId, chunkPath: ChunkPath) { + let moduleChunks = moduleChunksMap.get(moduleId); + if (!moduleChunks) { + moduleChunks = new Set([chunkPath]); + moduleChunksMap.set(moduleId, moduleChunks); + } else { + moduleChunks.add(chunkPath); + } + + let chunkModules = chunkModulesMap.get(chunkPath); + if (!chunkModules) { + chunkModules = new Set([moduleId]); + chunkModulesMap.set(chunkPath, chunkModules); + } else { + chunkModules.add(moduleId); + } +} + +/** + * Returns the first chunk that included a module. + * This is used by the Node.js backend, hence why it's marked as unused in this + * file. + */ +function getFirstModuleChunk(moduleId: ModuleId) { + const moduleChunkPaths = moduleChunksMap.get(moduleId); + if (moduleChunkPaths == null) { + return null; + } + + return moduleChunkPaths.values().next().value; +} + +/** + * Removes a module from a chunk. + * Returns `true` if there are no remaining chunks including this module. + */ +function removeModuleFromChunk( + moduleId: ModuleId, + chunkPath: ChunkPath +): boolean { + const moduleChunks = moduleChunksMap.get(moduleId)!; + moduleChunks.delete(chunkPath); + + const chunkModules = chunkModulesMap.get(chunkPath)!; + chunkModules.delete(moduleId); + + const noRemainingModules = chunkModules.size === 0; + if (noRemainingModules) { + chunkModulesMap.delete(chunkPath); + } + + const noRemainingChunks = moduleChunks.size === 0; + if (noRemainingChunks) { + moduleChunksMap.delete(moduleId); + } + + return noRemainingChunks; +} + +/** + * Disposes of a chunk list and its corresponding exclusive chunks. + */ +function disposeChunkList(chunkListPath: ChunkPath): boolean { + const chunkPaths = chunkListChunksMap.get(chunkListPath); + if (chunkPaths == null) { + return false; + } + chunkListChunksMap.delete(chunkListPath); + + for (const chunkPath of chunkPaths) { + const chunkChunkLists = chunkChunkListsMap.get(chunkPath)!; + chunkChunkLists.delete(chunkListPath); + + if (chunkChunkLists.size === 0) { + chunkChunkListsMap.delete(chunkPath); + disposeChunk(chunkPath); + } + } + + // We must also dispose of the chunk list's chunk itself to ensure it may + // be reloaded properly in the future. + BACKEND.unloadChunk?.(chunkListPath); + + return true; +} + +/** + * Disposes of a chunk and its corresponding exclusive modules. + * + * @returns Whether the chunk was disposed of. + */ +function disposeChunk(chunkPath: ChunkPath): boolean { + // This should happen whether the chunk has any modules in it or not. + // For instance, CSS chunks have no modules in them, but they still need to be unloaded. + BACKEND.unloadChunk?.(chunkPath); + + const chunkModules = chunkModulesMap.get(chunkPath); + if (chunkModules == null) { + return false; + } + chunkModules.delete(chunkPath); + + for (const moduleId of chunkModules) { + const moduleChunks = moduleChunksMap.get(moduleId)!; + moduleChunks.delete(chunkPath); + + const noRemainingChunks = moduleChunks.size === 0; + if (noRemainingChunks) { + moduleChunksMap.delete(moduleId); + disposeModule(moduleId, "clear"); + availableModules.delete(moduleId); + } + } + + return true; +} + +/** + * Instantiates a runtime module. + */ +function instantiateRuntimeModule( + moduleId: ModuleId, + chunkPath: ChunkPath +): Module { + return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath }); +} + +/** + * Gets or instantiates a runtime module. + */ +function getOrInstantiateRuntimeModule( + moduleId: ModuleId, + chunkPath: ChunkPath +): Module { + const module = moduleCache[moduleId]; + if (module) { + if (module.error) { + throw module.error; + } + return module; + } + + return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath }); +} + +/** + * Returns the URL relative to the origin where a chunk can be fetched from. + */ +function getChunkRelativeUrl(chunkPath: ChunkPath): string { + return `${CHUNK_BASE_PATH}${chunkPath + .split("/") + .map((p) => encodeURIComponent(p)) + .join("/")}`; +} + +/** + * Subscribes to chunk list updates from the update server and applies them. + */ +function registerChunkList( + chunkUpdateProvider: ChunkUpdateProvider, + chunkList: ChunkList +) { + chunkUpdateProvider.push([ + chunkList.path, + handleApply.bind(null, chunkList.path), + ]); + + // Adding chunks to chunk lists and vice versa. + const chunks = new Set(chunkList.chunks.map(getChunkPath)); + chunkListChunksMap.set(chunkList.path, chunks); + for (const chunkPath of chunks) { + let chunkChunkLists = chunkChunkListsMap.get(chunkPath); + if (!chunkChunkLists) { + chunkChunkLists = new Set([chunkList.path]); + chunkChunkListsMap.set(chunkPath, chunkChunkLists); + } else { + chunkChunkLists.add(chunkList.path); + } + } + + if (chunkList.source === "entry") { + markChunkListAsRuntime(chunkList.path); + } +} + +/** + * Marks a chunk list as a runtime chunk list. There can be more than one + * runtime chunk list. For instance, integration tests can have multiple chunk + * groups loaded at runtime, each with its own chunk list. + */ +function markChunkListAsRuntime(chunkListPath: ChunkPath) { + runtimeChunkLists.add(chunkListPath); +} + +function registerChunk([ + chunkPath, + chunkModules, + runtimeParams, +]: ChunkRegistration) { + for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) { + if (!moduleFactories[moduleId]) { + moduleFactories[moduleId] = moduleFactory; + } + addModuleToChunk(moduleId, chunkPath); + } + + return BACKEND.registerChunk(chunkPath, runtimeParams); +} + +globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS ??= []; + +const chunkListsToRegister = globalThis.TURBOPACK_CHUNK_LISTS; +if (Array.isArray(chunkListsToRegister)) { + for (const chunkList of chunkListsToRegister) { + registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS, chunkList); + } +} + +globalThis.TURBOPACK_CHUNK_LISTS = { + push: (chunkList) => { + registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS!, chunkList); + }, +} satisfies ChunkListProvider; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/tsconfig.json b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/tsconfig.json new file mode 100644 index 0000000000000..cc70058649bb6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/base/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + // environment, we need WebWorker for WebAssembly types + "lib": ["ESNext", "WebWorker"] + }, + "include": ["runtime-base.ts", "dummy.ts"] +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/dom/runtime-backend-dom.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/dom/runtime-backend-dom.ts new file mode 100644 index 0000000000000..17295aec962db --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/dom/runtime-backend-dom.ts @@ -0,0 +1,303 @@ +/** + * This file contains the runtime code specific to the Turbopack development + * ECMAScript DOM runtime. + * + * It will be appended to the base development runtime code. + */ + +/// +/// + +type ChunkResolver = { + resolved: boolean; + resolve: () => void; + reject: (error?: Error) => void; + promise: Promise; +}; + +let BACKEND: RuntimeBackend; + +function augmentContext(context: TurbopackDevBaseContext): TurbopackDevContext { + return context; +} + +function fetchWebAssembly(wasmChunkPath: ChunkPath) { + return fetch(getChunkRelativeUrl(wasmChunkPath)); +} + +async function loadWebAssembly( + _source: SourceInfo, + wasmChunkPath: ChunkPath, + importsObj: WebAssembly.Imports +): Promise { + const req = fetchWebAssembly(wasmChunkPath); + + const { instance } = await WebAssembly.instantiateStreaming(req, importsObj); + + return instance.exports; +} + +async function loadWebAssemblyModule( + _source: SourceInfo, + wasmChunkPath: ChunkPath +): Promise { + const req = fetchWebAssembly(wasmChunkPath); + + return await WebAssembly.compileStreaming(req); +} + +(() => { + BACKEND = { + async registerChunk(chunkPath, params) { + const resolver = getOrCreateResolver(chunkPath); + resolver.resolve(); + + if (params == null) { + return; + } + + for (const otherChunkData of params.otherChunks) { + const otherChunkPath = getChunkPath(otherChunkData); + // Chunk might have started loading, so we want to avoid triggering another load. + getOrCreateResolver(otherChunkPath); + } + + // This waits for chunks to be loaded, but also marks included items as available. + await Promise.all( + params.otherChunks.map((otherChunkData) => + loadChunk({ type: SourceType.Runtime, chunkPath }, otherChunkData) + ) + ); + + if (params.runtimeModuleIds.length > 0) { + for (const moduleId of params.runtimeModuleIds) { + getOrInstantiateRuntimeModule(moduleId, chunkPath); + } + } + }, + + loadChunk(chunkPath, source) { + return doLoadChunk(chunkPath, source); + }, + + unloadChunk(chunkPath) { + deleteResolver(chunkPath); + + const chunkUrl = getChunkRelativeUrl(chunkPath); + // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped. + const decodedChunkUrl = decodeURI(chunkUrl); + + if (chunkPath.endsWith(".css")) { + const links = document.querySelectorAll( + `link[href="${chunkUrl}"],link[href^="${chunkUrl}?"],link[href="${decodedChunkUrl}"],link[href^="${decodedChunkUrl}?"]` + ); + for (const link of Array.from(links)) { + link.remove(); + } + } else if (chunkPath.endsWith(".js")) { + // Unloading a JS chunk would have no effect, as it lives in the JS + // runtime once evaluated. + // However, we still want to remove the script tag from the DOM to keep + // the HTML somewhat consistent from the user's perspective. + const scripts = document.querySelectorAll( + `script[src="${chunkUrl}"],script[src^="${chunkUrl}?"],script[src="${decodedChunkUrl}"],script[src^="${decodedChunkUrl}?"]` + ); + for (const script of Array.from(scripts)) { + script.remove(); + } + } else { + throw new Error(`can't infer type of chunk from path ${chunkPath}`); + } + }, + + reloadChunk(chunkPath) { + return new Promise((resolve, reject) => { + if (!chunkPath.endsWith(".css")) { + reject(new Error("The DOM backend can only reload CSS chunks")); + return; + } + + const chunkUrl = getChunkRelativeUrl(chunkPath); + const decodedChunkUrl = decodeURI(chunkUrl); + + const previousLinks = document.querySelectorAll( + `link[rel=stylesheet][href="${chunkUrl}"],link[rel=stylesheet][href^="${chunkUrl}?"],link[rel=stylesheet][href="${decodedChunkUrl}"],link[rel=stylesheet][href^="${decodedChunkUrl}?"]` + ); + + if (previousLinks.length == 0) { + reject(new Error(`No link element found for chunk ${chunkPath}`)); + return; + } + + const link = document.createElement("link"); + link.rel = "stylesheet"; + + if (navigator.userAgent.includes("Firefox")) { + // Firefox won't reload CSS files that were previously loaded on the current page, + // we need to add a query param to make sure CSS is actually reloaded from the server. + // + // I believe this is this issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1037506 + // + // Safari has a similar issue, but only if you have a `` tag + // pointing to the same URL as the stylesheet: https://bugs.webkit.org/show_bug.cgi?id=187726 + link.href = `${chunkUrl}?ts=${Date.now()}`; + } else { + link.href = chunkUrl; + } + + link.onerror = () => { + reject(); + }; + link.onload = () => { + // First load the new CSS, then remove the old ones. This prevents visible + // flickering that would happen in-between removing the previous CSS and + // loading the new one. + for (const previousLink of Array.from(previousLinks)) + previousLink.remove(); + + // CSS chunks do not register themselves, and as such must be marked as + // loaded instantly. + resolve(); + }; + + // Make sure to insert the new CSS right after the previous one, so that + // its precedence is higher. + previousLinks[0].parentElement!.insertBefore( + link, + previousLinks[0].nextSibling + ); + }); + }, + + restart: () => self.location.reload(), + }; + + /** + * Maps chunk paths to the corresponding resolver. + */ + const chunkResolvers: Map = new Map(); + + function getOrCreateResolver(chunkPath: ChunkPath): ChunkResolver { + let resolver = chunkResolvers.get(chunkPath); + if (!resolver) { + let resolve: () => void; + let reject: (error?: Error) => void; + const promise = new Promise((innerResolve, innerReject) => { + resolve = innerResolve; + reject = innerReject; + }); + resolver = { + resolved: false, + promise, + resolve: () => { + resolver!.resolved = true; + resolve(); + }, + reject: reject!, + }; + chunkResolvers.set(chunkPath, resolver); + } + return resolver; + } + + function deleteResolver(chunkPath: ChunkPath) { + chunkResolvers.delete(chunkPath); + } + + /** + * Loads the given chunk, and returns a promise that resolves once the chunk + * has been loaded. + */ + async function doLoadChunk(chunkPath: ChunkPath, source: SourceInfo) { + const resolver = getOrCreateResolver(chunkPath); + if (resolver.resolved) { + return resolver.promise; + } + + if (source.type === SourceType.Runtime) { + // We don't need to load chunks references from runtime code, as they're already + // present in the DOM. + + if (chunkPath.endsWith(".css")) { + // CSS chunks do not register themselves, and as such must be marked as + // loaded instantly. + resolver.resolve(); + } + + // We need to wait for JS chunks to register themselves within `registerChunk` + // before we can start instantiating runtime modules, hence the absence of + // `resolver.resolve()` in this branch. + + return resolver.promise; + } + + const chunkUrl = getChunkRelativeUrl(chunkPath); + const decodedChunkUrl = decodeURI(chunkUrl); + + if (chunkPath.endsWith(".css")) { + const previousLinks = document.querySelectorAll( + `link[rel=stylesheet][href="${chunkUrl}"],link[rel=stylesheet][href^="${chunkUrl}?"],link[rel=stylesheet][href="${decodedChunkUrl}"],link[rel=stylesheet][href^="${decodedChunkUrl}?"]` + ); + if (previousLinks.length > 0) { + // CSS chunks do not register themselves, and as such must be marked as + // loaded instantly. + resolver.resolve(); + } else { + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = chunkUrl; + link.onerror = () => { + resolver.reject(); + }; + link.onload = () => { + // CSS chunks do not register themselves, and as such must be marked as + // loaded instantly. + resolver.resolve(); + }; + document.body.appendChild(link); + } + } else if (chunkPath.endsWith(".js")) { + const previousScripts = document.querySelectorAll( + `script[src="${chunkUrl}"],script[src^="${chunkUrl}?"],script[src="${decodedChunkUrl}"],script[src^="${decodedChunkUrl}?"]` + ); + if (previousScripts.length > 0) { + // There is this edge where the script already failed loading, but we + // can't detect that. The Promise will never resolve in this case. + for (const script of Array.from(previousScripts)) { + script.addEventListener("error", () => { + resolver.reject(); + }); + } + } else { + const script = document.createElement("script"); + script.src = chunkUrl; + // We'll only mark the chunk as loaded once the script has been executed, + // which happens in `registerChunk`. Hence the absence of `resolve()` in + // this branch. + script.onerror = () => { + resolver.reject(); + }; + document.body.appendChild(script); + } + } else { + throw new Error(`can't infer type of chunk from path ${chunkPath}`); + } + + return resolver.promise; + } +})(); + +function _eval({ code, url, map }: EcmascriptModuleEntry): ModuleFactory { + code += `\n\n//# sourceURL=${encodeURI( + location.origin + CHUNK_BASE_PATH + url + )}`; + if (map) { + code += `\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa( + // btoa doesn't handle nonlatin characters, so escape them as \x sequences + // See https://stackoverflow.com/a/26603875 + unescape(encodeURIComponent(map)) + )}`; + } + + return eval(code); +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/dom/tsconfig.json b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/dom/tsconfig.json new file mode 100644 index 0000000000000..802c6823e3451 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/dom/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + // environment + "lib": ["ESNext", "DOM"] + }, + "include": ["*.ts"] +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/edge/runtime-backend-edge.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/edge/runtime-backend-edge.ts new file mode 100644 index 0000000000000..0f4851977a735 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/edge/runtime-backend-edge.ts @@ -0,0 +1,202 @@ +/** + * This file contains the runtime code specific to the Turbopack development + * ECMAScript "None" runtime (e.g. for Edge). + * + * It will be appended to the base development runtime code. + */ + +/// +/// +/// + +type ChunkRunner = { + requiredChunks: Set; + chunkPath: ChunkPath; + runtimeModuleIds: ModuleId[]; +}; + +let BACKEND: RuntimeBackend; + +type ExternalRequire = ( + id: ModuleId, + esm?: boolean +) => Exports | EsmNamespaceObject; +type ExternalImport = (id: ModuleId) => Promise; + +interface TurbopackDevContext extends TurbopackDevBaseContext { + x: ExternalRequire; + y: ExternalImport; +} + +function augmentContext(context: TurbopackDevBaseContext): TurbopackDevContext { + const nodejsContext = context as TurbopackDevContext; + nodejsContext.x = externalRequire; + nodejsContext.y = externalImport; + return nodejsContext; +} + +async function loadWebAssembly( + source: SourceInfo, + chunkPath: ChunkPath, + imports: WebAssembly.Imports +): Promise { + const module = await loadWebAssemblyModule(source, chunkPath); + + return await WebAssembly.instantiate(module, imports); +} + +function getFileStem(path: string): string { + const fileName = path.split("/").pop()!; + + const stem = fileName.split(".").shift()!; + + if (stem == "") { + return fileName; + } + + return stem; +} + +type GlobalWithInjectedWebAssembly = typeof globalThis & { + [key: `wasm_${string}`]: WebAssembly.Module; +}; + +async function loadWebAssemblyModule( + _source: SourceInfo, + chunkPath: ChunkPath +): Promise { + const stem = getFileStem(chunkPath); + + // very simple escaping just replacing unsupported characters with `_` + const escaped = stem.replace(/[^a-zA-Z0-9$_]/gi, "_"); + + const identifier: `wasm_${string}` = `wasm_${escaped}`; + + const module = (globalThis as GlobalWithInjectedWebAssembly)[identifier]; + + if (!module) { + throw new Error( + `dynamically loading WebAssembly is not supported in this runtime and global \`${identifier}\` was not injected` + ); + } + + return module; +} + +(() => { + BACKEND = { + // The "none" runtime expects all chunks within the same chunk group to be + // registered before any of them are instantiated. + // Furthermore, modules must be instantiated synchronously, hence we don't + // use promises here. + registerChunk(chunkPath, params) { + registeredChunks.add(chunkPath); + instantiateDependentChunks(chunkPath); + + if (params == null) { + return; + } + + if (params.otherChunks.length === 0) { + // The current chunk does not depend on any other chunks, it can be + // instantiated immediately. + instantiateRuntimeModules(params.runtimeModuleIds, chunkPath); + } else { + // The current chunk depends on other chunks, so we need to wait for + // those chunks to be registered before instantiating the runtime + // modules. + registerChunkRunner( + chunkPath, + params.otherChunks.filter((chunk) => + // The none runtime can only handle JS chunks, so we only wait for these + getChunkPath(chunk).endsWith(".js") + ), + params.runtimeModuleIds + ); + } + }, + + loadChunk(_chunkPath, _fromChunkPath) { + throw new Error("chunk loading is not supported"); + }, + + restart: () => { + throw new Error("restart is not supported"); + }, + }; + + const registeredChunks: Set = new Set(); + const runners: Map> = new Map(); + + /** + * Registers a chunk runner that will be instantiated once all of the + * dependencies of the chunk have been registered. + */ + function registerChunkRunner( + chunkPath: ChunkPath, + otherChunks: ChunkData[], + runtimeModuleIds: ModuleId[] + ) { + const requiredChunks: Set = new Set(); + const runner = { + runtimeModuleIds, + chunkPath, + requiredChunks, + }; + + for (const otherChunkData of otherChunks) { + const otherChunkPath = getChunkPath(otherChunkData); + if (registeredChunks.has(otherChunkPath)) { + continue; + } + + requiredChunks.add(otherChunkPath); + let runnersForChunk = runners.get(otherChunkPath); + if (runnersForChunk == null) { + runnersForChunk = new Set(); + runners.set(otherChunkPath, runnersForChunk); + } + runnersForChunk.add(runner); + } + // When all chunks are already registered, we can instantiate the runtime module + if (runner.requiredChunks.size === 0) { + instantiateRuntimeModules(runner.runtimeModuleIds, runner.chunkPath); + } + } + + /** + * Instantiates any chunk runners that were waiting for the given chunk to be + * registered. + */ + function instantiateDependentChunks(chunkPath: ChunkPath) { + // Run any chunk runners that were waiting for this chunk to be + // registered. + const runnersForChunk = runners.get(chunkPath); + if (runnersForChunk != null) { + for (const runner of runnersForChunk) { + runner.requiredChunks.delete(chunkPath); + + if (runner.requiredChunks.size === 0) { + instantiateRuntimeModules(runner.runtimeModuleIds, runner.chunkPath); + } + } + runners.delete(chunkPath); + } + } + + /** + * Instantiates the runtime modules for the given chunk. + */ + function instantiateRuntimeModules( + runtimeModuleIds: ModuleId[], + chunkPath: ChunkPath + ) { + for (const moduleId of runtimeModuleIds) { + getOrInstantiateRuntimeModule(moduleId, chunkPath); + } + } +})(); + +function _eval(_: EcmascriptModuleEntry): ModuleFactory { + throw new Error("HMR evaluation is not implemented on this backend"); +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/edge/tsconfig.json b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/edge/tsconfig.json new file mode 100644 index 0000000000000..fabb2ed16dbbb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/browser/dev/runtime/edge/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../../../tsconfig.base.json", + "compilerOptions": { + // environment, we need WebWorker for WebAssembly types + "lib": ["ESNext", "WebWorker"] + }, + "include": ["*.ts"] +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/main.js b/turbopack/crates/turbopack-ecmascript-runtime/js/src/main.js new file mode 100644 index 0000000000000..dddce0ffc51a2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/main.js @@ -0,0 +1 @@ +// required for NCC to work diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts new file mode 100644 index 0000000000000..54a0244f524fd --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/runtime.ts @@ -0,0 +1,319 @@ +/// +/// +/// +/// + +enum SourceType { + /** + * The module was instantiated because it was included in an evaluated chunk's + * runtime. + */ + Runtime = 0, + /** + * The module was instantiated because a parent module imported it. + */ + Parent = 1, +} + +type SourceInfo = + | { + type: SourceType.Runtime; + chunkPath: ChunkPath; + } + | { + type: SourceType.Parent; + parentId: ModuleId; + }; + +function stringifySourceInfo(source: SourceInfo): string { + switch (source.type) { + case SourceType.Runtime: + return `runtime for chunk ${source.chunkPath}`; + case SourceType.Parent: + return `parent module ${source.parentId}`; + } +} + +type ExternalRequire = (id: ModuleId) => Exports | EsmNamespaceObject; +type ExternalImport = (id: ModuleId) => Promise; + +interface TurbopackNodeBuildContext extends TurbopackBaseContext { + R: ResolvePathFromModule; + x: ExternalRequire; + y: ExternalImport; +} + +type ModuleFactory = ( + this: Module["exports"], + context: TurbopackNodeBuildContext +) => undefined; + +const url = require("url"); +const fs = require("fs/promises"); +const vm = require("vm"); + +const moduleFactories: ModuleFactories = Object.create(null); +const moduleCache: ModuleCache = Object.create(null); + +/** + * Returns an absolute path to the given module's id. + */ +function createResolvePathFromModule( + resolver: (moduleId: string) => Exports +): (moduleId: string) => string { + return function resolvePathFromModule(moduleId: string): string { + const exported = resolver(moduleId); + const exportedPath = exported?.default ?? exported; + if (typeof exportedPath !== "string") { + return exported as any; + } + + const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length); + const resolved = path.resolve( + ABSOLUTE_ROOT, + OUTPUT_ROOT, + strippedAssetPrefix + ); + + return url.pathToFileURL(resolved); + }; +} + +function loadChunk(chunkData: ChunkData, source?: SourceInfo): void { + if (typeof chunkData === "string") { + return loadChunkPath(chunkData, source); + } else { + return loadChunkPath(chunkData.path, source); + } +} + +function loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void { + if (!chunkPath.endsWith(".js")) { + // We only support loading JS chunks in Node.js. + // This branch can be hit when trying to load a CSS chunk. + return; + } + + try { + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + const chunkModules: ModuleFactories = require(resolved); + + for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) { + if (!moduleFactories[moduleId]) { + moduleFactories[moduleId] = moduleFactory; + } + } + } catch (e) { + let errorMessage = `Failed to load chunk ${chunkPath}`; + + if (source) { + errorMessage += ` from ${stringifySourceInfo(source)}`; + } + + throw new Error(errorMessage, { + cause: e, + }); + } +} + +async function loadChunkAsync( + source: SourceInfo, + chunkData: ChunkData +): Promise { + const chunkPath = typeof chunkData === "string" ? chunkData : chunkData.path; + if (!chunkPath.endsWith(".js")) { + // We only support loading JS chunks in Node.js. + // This branch can be hit when trying to load a CSS chunk. + return; + } + + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + + try { + const contents = await fs.readFile(resolved, "utf-8"); + + const module = { + exports: {}, + }; + vm.runInThisContext( + "(function(module, exports, require, __dirname, __filename) {" + + contents + + "\n})", + resolved + )(module, module.exports, require, path.dirname(resolved), resolved); + + const chunkModules: ModuleFactories = module.exports; + for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) { + if (!moduleFactories[moduleId]) { + moduleFactories[moduleId] = moduleFactory; + } + } + } catch (e) { + let errorMessage = `Failed to load chunk ${chunkPath}`; + + if (source) { + errorMessage += ` from ${stringifySourceInfo(source)}`; + } + + throw new Error(errorMessage, { + cause: e, + }); + } +} + +function loadWebAssembly(chunkPath: ChunkPath, imports: WebAssembly.Imports) { + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + + return instantiateWebAssemblyFromPath(resolved, imports); +} + +function loadWebAssemblyModule(chunkPath: ChunkPath) { + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + + return compileWebAssemblyFromPath(resolved); +} + +function instantiateModule(id: ModuleId, source: SourceInfo): Module { + const moduleFactory = moduleFactories[id]; + if (typeof moduleFactory !== "function") { + // This can happen if modules incorrectly handle HMR disposes/updates, + // e.g. when they keep a `setTimeout` around which still executes old code + // and contains e.g. a `require("something")` call. + let instantiationReason; + switch (source.type) { + case SourceType.Runtime: + instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`; + break; + case SourceType.Parent: + instantiationReason = `because it was required from module ${source.parentId}`; + break; + } + throw new Error( + `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.` + ); + } + + let parents: ModuleId[]; + switch (source.type) { + case SourceType.Runtime: + parents = []; + break; + case SourceType.Parent: + // No need to add this module as a child of the parent module here, this + // has already been taken care of in `getOrInstantiateModuleFromParent`. + parents = [source.parentId]; + break; + } + + const module: Module = { + exports: {}, + error: undefined, + loaded: false, + id, + parents, + children: [], + namespaceObject: undefined, + }; + moduleCache[id] = module; + + // NOTE(alexkirsz) This can fail when the module encounters a runtime error. + try { + const r = commonJsRequire.bind(null, module); + moduleFactory.call(module.exports, { + a: asyncModule.bind(null, module), + e: module.exports, + r, + t: runtimeRequire, + x: externalRequire, + y: externalImport, + f: moduleContext, + i: esmImport.bind(null, module), + s: esmExport.bind(null, module, module.exports), + j: dynamicExport.bind(null, module, module.exports), + v: exportValue.bind(null, module), + n: exportNamespace.bind(null, module), + m: module, + c: moduleCache, + M: moduleFactories, + l: loadChunkAsync.bind(null, { type: SourceType.Parent, parentId: id }), + w: loadWebAssembly, + u: loadWebAssemblyModule, + g: globalThis, + P: resolveAbsolutePath, + U: relativeURL, + R: createResolvePathFromModule(r), + __dirname: module.id.replace(/(^|\/)[\/]+$/, ""), + }); + } catch (error) { + module.error = error as any; + throw error; + } + + module.loaded = true; + if (module.namespaceObject && module.exports !== module.namespaceObject) { + // in case of a circular dependency: cjs1 -> esm2 -> cjs1 + interopEsm(module.exports, module.namespaceObject); + } + + return module; +} + +/** + * Retrieves a module from the cache, or instantiate it if it is not cached. + */ +function getOrInstantiateModuleFromParent( + id: ModuleId, + sourceModule: Module +): Module { + const module = moduleCache[id]; + + if (sourceModule.children.indexOf(id) === -1) { + sourceModule.children.push(id); + } + + if (module) { + if (module.parents.indexOf(sourceModule.id) === -1) { + module.parents.push(sourceModule.id); + } + + return module; + } + + return instantiateModule(id, { + type: SourceType.Parent, + parentId: sourceModule.id, + }); +} + +/** + * Instantiates a runtime module. + */ +function instantiateRuntimeModule( + moduleId: ModuleId, + chunkPath: ChunkPath +): Module { + return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath }); +} + +/** + * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached. + */ +function getOrInstantiateRuntimeModule( + moduleId: ModuleId, + chunkPath: ChunkPath +): Module { + const module = moduleCache[moduleId]; + if (module) { + if (module.error) { + throw module.error; + } + return module; + } + + return instantiateRuntimeModule(moduleId, chunkPath); +} + +module.exports = { + getOrInstantiateRuntimeModule, + loadChunk, +}; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/tsconfig.json b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/tsconfig.json new file mode 100644 index 0000000000000..fbc393330f47e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/nodejs/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + // environment, we need WebWorker for WebAssembly types (not part of @types/node yet) + "lib": ["ESNext", "WebWorker"], + "types": ["node"] + }, + "include": ["*.ts"] +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/base-externals-utils.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/base-externals-utils.ts new file mode 100644 index 0000000000000..a47faf56fe65a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/base-externals-utils.ts @@ -0,0 +1,55 @@ +/// + +/// A 'base' utilities to support runtime can have externals. +/// Currently this is for node.js / edge runtime both. +/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead. + +async function externalImport(id: ModuleId) { + let raw; + try { + raw = await import(id); + } catch (err) { + // TODO(alexkirsz) This can happen when a client-side module tries to load + // an external module we don't provide a shim for (e.g. querystring, url). + // For now, we fail semi-silently, but in the future this should be a + // compilation error. + throw new Error(`Failed to load external module ${id}: ${err}`); + } + + if (raw && raw.__esModule && raw.default && "default" in raw.default) { + return interopEsm(raw.default, createNS(raw), true); + } + + return raw; +} + +function externalRequire( + id: ModuleId, + esm: boolean = false +): Exports | EsmNamespaceObject { + let raw; + try { + raw = require(id); + } catch (err) { + // TODO(alexkirsz) This can happen when a client-side module tries to load + // an external module we don't provide a shim for (e.g. querystring, url). + // For now, we fail semi-silently, but in the future this should be a + // compilation error. + throw new Error(`Failed to load external module ${id}: ${err}`); + } + + if (!esm || raw.__esModule) { + return raw; + } + + return interopEsm(raw, createNS(raw), true); +} + +externalRequire.resolve = ( + id: string, + options?: { + paths?: string[]; + } +) => { + return require.resolve(id, options); +}; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/node-externals-utils.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/node-externals-utils.ts new file mode 100644 index 0000000000000..ce2e1d5da5535 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/node-externals-utils.ts @@ -0,0 +1,30 @@ +declare var RUNTIME_PUBLIC_PATH: string; +declare var OUTPUT_ROOT: string; +declare var ASSET_PREFIX: string; + +const path = require("path"); + +const relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, "."); +// Compute the relative path to the `distDir`. +const relativePathToDistRoot = path.relative( + path.join(OUTPUT_ROOT, RUNTIME_PUBLIC_PATH), + "." +); +const RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot); +// Compute the absolute path to the root, by stripping distDir from the absolute path to this file. +const ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot); + +/** + * Returns an absolute path to the given module path. + * Module path should be relative, either path to a file or a directory. + * + * This fn allows to calculate an absolute path for some global static values, such as + * `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time. + * See ImportMetaBinding::code_generation for the usage. + */ +function resolveAbsolutePath(modulePath?: string): string { + if (modulePath) { + return path.join(ABSOLUTE_ROOT, modulePath); + } + return ABSOLUTE_ROOT; +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/node-wasm-utils.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/node-wasm-utils.ts new file mode 100644 index 0000000000000..1baa2fc01c0c3 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/node-wasm-utils.ts @@ -0,0 +1,37 @@ +/// + +function readWebAssemblyAsResponse(path: string) { + const { createReadStream } = require("fs") as typeof import("fs"); + const { Readable } = require("stream") as typeof import("stream"); + + const stream = createReadStream(path); + + // @ts-ignore unfortunately there's a slight type mismatch with the stream. + return new Response(Readable.toWeb(stream), { + headers: { + "content-type": "application/wasm", + }, + }); +} + +async function compileWebAssemblyFromPath( + path: string +): Promise { + const response = readWebAssemblyAsResponse(path); + + return await WebAssembly.compileStreaming(response); +} + +async function instantiateWebAssemblyFromPath( + path: string, + importsObj: WebAssembly.Imports +): Promise { + const response = readWebAssemblyAsResponse(path); + + const { instance } = await WebAssembly.instantiateStreaming( + response, + importsObj + ); + + return instance.exports; +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/tsconfig.json b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/tsconfig.json new file mode 100644 index 0000000000000..fbc393330f47e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared-node/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + // environment, we need WebWorker for WebAssembly types (not part of @types/node yet) + "lib": ["ESNext", "WebWorker"], + "types": ["node"] + }, + "include": ["*.ts"] +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/dummy.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/dummy.ts new file mode 100644 index 0000000000000..a3aea592da891 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/dummy.ts @@ -0,0 +1,8 @@ +/** + * This file acts as a dummy implementor for the interface that + * `runtime-utils.ts` expects to be available in the global scope. + * + * This interface will be implemented by runtimes. + */ + +declare var getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/require-type.d.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/require-type.d.ts new file mode 100644 index 0000000000000..b28e19778e877 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/require-type.d.ts @@ -0,0 +1,9 @@ +// Make sure that `require` is available for runtime-utils.ts. +declare var require: ((moduleId: ModuleId) => Exports) & { + resolve: ( + moduleId: ModuleId, + options?: { + paths?: string[]; + } + ) => ModuleId; +}; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts new file mode 100644 index 0000000000000..5681f99b73d41 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-types.d.ts @@ -0,0 +1,79 @@ +/** + * This file contains runtime types that are shared between all TurboPack + * ECMAScript runtimes. + * + * It is separate from `runtime-utils.ts` because it can be used outside of + * runtime code, hence it should not contain any function declarations that are + * specific to the runtime context. + */ + +type ChunkPath = string; +type ModuleId = string; + +type ChunkData = + | ChunkPath + | { + path: ChunkPath; + included: ModuleId[]; + excluded: ModuleId[]; + moduleChunks: ChunkPath[]; + }; + +type CommonJsRequire = (moduleId: ModuleId) => Exports; +type ModuleContextFactory = (map: ModuleContextMap) => ModuleContext; +type EsmImport = ( + moduleId: ModuleId, + allowExportDefault: boolean +) => EsmNamespaceObject | Promise; +type EsmExport = (exportGetters: Record any>) => void; +type ExportValue = (value: any) => void; +type ExportNamespace = (namespace: any) => void; +type DynamicExport = (object: Record) => void; + +type LoadChunk = (chunkPath: ChunkPath) => Promise | undefined; +type LoadWebAssembly = ( + wasmChunkPath: ChunkPath, + imports: WebAssembly.Imports +) => Exports; +type LoadWebAssemblyModule = (wasmChunkPath: ChunkPath) => WebAssembly.Module; + +type ModuleCache = Record; +type ModuleFactories = Record; + +type RelativeURL = (inputUrl: string) => void; +type ResolvePathFromModule = (moduleId: string) => string; + +type AsyncModule = ( + body: ( + handleAsyncDependencies: ( + deps: Dep[] + ) => Exports[] | Promise<() => Exports[]>, + asyncResult: (err?: any) => void + ) => void, + hasAwait: boolean +) => void; + +type ResolveAbsolutePath = (modulePath?: string) => string; + +interface TurbopackBaseContext { + a: AsyncModule; + e: Module["exports"]; + r: CommonJsRequire; + t: CommonJsRequire; + f: ModuleContextFactory; + i: EsmImport; + s: EsmExport; + j: DynamicExport; + v: ExportValue; + n: ExportNamespace; + m: Module; + c: ModuleCache; + M: ModuleFactories; + l: LoadChunk; + w: LoadWebAssembly; + u: LoadWebAssemblyModule; + g: typeof globalThis; + P: ResolveAbsolutePath; + U: RelativeURL; + __dirname: string; +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts new file mode 100644 index 0000000000000..b79197790fd74 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/runtime-utils.ts @@ -0,0 +1,516 @@ +/** + * This file contains runtime types and functions that are shared between all + * TurboPack ECMAScript runtimes. + * + * It will be prepended to the runtime code of each runtime. + */ + +/* eslint-disable @next/next/no-assign-module-variable */ + +/// + +interface Exports { + __esModule?: boolean; + + [key: string]: any; +} + +type EsmNamespaceObject = Record; + +const REEXPORTED_OBJECTS = Symbol("reexported objects"); + +interface BaseModule { + exports: Function | Exports | Promise | AsyncModulePromise; + error: Error | undefined; + loaded: boolean; + id: ModuleId; + children: ModuleId[]; + parents: ModuleId[]; + namespaceObject?: + | EsmNamespaceObject + | Promise + | AsyncModulePromise; + [REEXPORTED_OBJECTS]?: any[]; +} + +interface Module extends BaseModule {} + +type ModuleContextMap = Record; + +interface ModuleContextEntry { + id: () => ModuleId; + module: () => any; +} + +interface ModuleContext { + // require call + (moduleId: ModuleId): Exports | EsmNamespaceObject; + + // async import call + import(moduleId: ModuleId): Promise; + + keys(): ModuleId[]; + + resolve(moduleId: ModuleId): ModuleId; +} + +type GetOrInstantiateModuleFromParent = ( + moduleId: ModuleId, + parentModule: Module +) => Module; + +const hasOwnProperty = Object.prototype.hasOwnProperty; +const toStringTag = typeof Symbol !== "undefined" && Symbol.toStringTag; + +function defineProp( + obj: any, + name: PropertyKey, + options: PropertyDescriptor & ThisType +) { + if (!hasOwnProperty.call(obj, name)) + Object.defineProperty(obj, name, options); +} + +/** + * Adds the getters to the exports object. + */ +function esm( + exports: Exports, + getters: Record any) | [() => any, (v: any) => void]> +) { + defineProp(exports, "__esModule", { value: true }); + if (toStringTag) defineProp(exports, toStringTag, { value: "Module" }); + for (const key in getters) { + const item = getters[key]; + if (Array.isArray(item)) { + defineProp(exports, key, { + get: item[0], + set: item[1], + enumerable: true, + }); + } else { + defineProp(exports, key, { get: item, enumerable: true }); + } + } + Object.seal(exports); +} + +/** + * Makes the module an ESM with exports + */ +function esmExport( + module: Module, + exports: Exports, + getters: Record any> +) { + module.namespaceObject = module.exports; + esm(exports, getters); +} + +function ensureDynamicExports(module: Module, exports: Exports) { + let reexportedObjects = module[REEXPORTED_OBJECTS]; + + if (!reexportedObjects) { + reexportedObjects = module[REEXPORTED_OBJECTS] = []; + module.exports = module.namespaceObject = new Proxy(exports, { + get(target, prop) { + if ( + hasOwnProperty.call(target, prop) || + prop === "default" || + prop === "__esModule" + ) { + return Reflect.get(target, prop); + } + for (const obj of reexportedObjects!) { + const value = Reflect.get(obj, prop); + if (value !== undefined) return value; + } + return undefined; + }, + ownKeys(target) { + const keys = Reflect.ownKeys(target); + for (const obj of reexportedObjects!) { + for (const key of Reflect.ownKeys(obj)) { + if (key !== "default" && !keys.includes(key)) keys.push(key); + } + } + return keys; + }, + }); + } +} + +/** + * Dynamically exports properties from an object + */ +function dynamicExport( + module: Module, + exports: Exports, + object: Record +) { + ensureDynamicExports(module, exports); + + if (typeof object === "object" && object !== null) { + module[REEXPORTED_OBJECTS]!.push(object); + } +} + +function exportValue(module: Module, value: any) { + module.exports = value; +} + +function exportNamespace(module: Module, namespace: any) { + module.exports = module.namespaceObject = namespace; +} + +function createGetter(obj: Record, key: string | symbol) { + return () => obj[key]; +} + +/** + * @returns prototype of the object + */ +const getProto: (obj: any) => any = Object.getPrototypeOf + ? (obj) => Object.getPrototypeOf(obj) + : (obj) => obj.__proto__; + +/** Prototypes that are not expanded for exports */ +const LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)]; + +/** + * @param raw + * @param ns + * @param allowExportDefault + * * `false`: will have the raw module as default export + * * `true`: will have the default property as default export + */ +function interopEsm( + raw: Exports, + ns: EsmNamespaceObject, + allowExportDefault?: boolean +) { + const getters: { [s: string]: () => any } = Object.create(null); + for ( + let current = raw; + (typeof current === "object" || typeof current === "function") && + !LEAF_PROTOTYPES.includes(current); + current = getProto(current) + ) { + for (const key of Object.getOwnPropertyNames(current)) { + getters[key] = createGetter(raw, key); + } + } + + // this is not really correct + // we should set the `default` getter if the imported module is a `.cjs file` + if (!(allowExportDefault && "default" in getters)) { + getters["default"] = () => raw; + } + + esm(ns, getters); + return ns; +} + +function createNS(raw: BaseModule["exports"]): EsmNamespaceObject { + if (typeof raw === "function") { + return function (this: any, ...args: any[]) { + return raw.apply(this, args); + }; + } else { + return Object.create(null); + } +} + +function esmImport( + sourceModule: Module, + id: ModuleId +): Exclude { + const module = getOrInstantiateModuleFromParent(id, sourceModule); + if (module.error) throw module.error; + + // any ES module has to have `module.namespaceObject` defined. + if (module.namespaceObject) return module.namespaceObject; + + // only ESM can be an async module, so we don't need to worry about exports being a promise here. + const raw = module.exports; + return (module.namespaceObject = interopEsm( + raw, + createNS(raw), + raw && (raw as any).__esModule + )); +} + +// Add a simple runtime require so that environments without one can still pass +// `typeof require` CommonJS checks so that exports are correctly registered. +const runtimeRequire = + typeof require === "function" + ? require + : function require() { + throw new Error("Unexpected use of runtime require"); + }; + +function commonJsRequire(sourceModule: Module, id: ModuleId): Exports { + const module = getOrInstantiateModuleFromParent(id, sourceModule); + if (module.error) throw module.error; + return module.exports; +} + +/** + * `require.context` and require/import expression runtime. + */ +function moduleContext(map: ModuleContextMap): ModuleContext { + function moduleContext(id: ModuleId): Exports { + if (hasOwnProperty.call(map, id)) { + return map[id].module(); + } + + const e = new Error(`Cannot find module '${name}'`); + (e as any).code = "MODULE_NOT_FOUND"; + throw e; + } + + moduleContext.keys = (): ModuleId[] => { + return Object.keys(map); + }; + + moduleContext.resolve = (id: ModuleId): ModuleId => { + if (hasOwnProperty.call(map, id)) { + return map[id].id(); + } + + const e = new Error(`Cannot find module '${name}'`); + (e as any).code = "MODULE_NOT_FOUND"; + throw e; + }; + + moduleContext.import = async (id: ModuleId) => { + return await (moduleContext(id) as Promise); + }; + + return moduleContext; +} + +/** + * Returns the path of a chunk defined by its data. + */ +function getChunkPath(chunkData: ChunkData): ChunkPath { + return typeof chunkData === "string" ? chunkData : chunkData.path; +} + +function isPromise(maybePromise: any): maybePromise is Promise { + return ( + maybePromise != null && + typeof maybePromise === "object" && + "then" in maybePromise && + typeof maybePromise.then === "function" + ); +} + +function isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T { + return turbopackQueues in obj; +} + +function createPromise() { + let resolve: (value: T | PromiseLike) => void; + let reject: (reason?: any) => void; + + const promise = new Promise((res, rej) => { + reject = rej; + resolve = res; + }); + + return { + promise, + resolve: resolve!, + reject: reject!, + }; +} + +// everything below is adapted from webpack +// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13 + +const turbopackQueues = Symbol("turbopack queues"); +const turbopackExports = Symbol("turbopack exports"); +const turbopackError = Symbol("turbopack error"); + +const enum QueueStatus { + Unknown = -1, + Unresolved = 0, + Resolved = 1, +} + +type AsyncQueueFn = (() => void) & { queueCount: number }; +type AsyncQueue = AsyncQueueFn[] & { + status: QueueStatus; +}; + +function resolveQueue(queue?: AsyncQueue) { + if (queue && queue.status !== QueueStatus.Resolved) { + queue.status = QueueStatus.Resolved; + queue.forEach((fn) => fn.queueCount--); + queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn())); + } +} + +type Dep = Exports | AsyncModulePromise | Promise; + +type AsyncModuleExt = { + [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void; + [turbopackExports]: Exports; + [turbopackError]?: any; +}; + +type AsyncModulePromise = Promise & AsyncModuleExt; + +function wrapDeps(deps: Dep[]): AsyncModuleExt[] { + return deps.map((dep): AsyncModuleExt => { + if (dep !== null && typeof dep === "object") { + if (isAsyncModuleExt(dep)) return dep; + if (isPromise(dep)) { + const queue: AsyncQueue = Object.assign([], { + status: QueueStatus.Unresolved, + }); + + const obj: AsyncModuleExt = { + [turbopackExports]: {}, + [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue), + }; + + dep.then( + (res) => { + obj[turbopackExports] = res; + resolveQueue(queue); + }, + (err) => { + obj[turbopackError] = err; + resolveQueue(queue); + } + ); + + return obj; + } + } + + return { + [turbopackExports]: dep, + [turbopackQueues]: () => {}, + }; + }); +} + +function asyncModule( + module: Module, + body: ( + handleAsyncDependencies: ( + deps: Dep[] + ) => Exports[] | Promise<() => Exports[]>, + asyncResult: (err?: any) => void + ) => void, + hasAwait: boolean +) { + const queue: AsyncQueue | undefined = hasAwait + ? Object.assign([], { status: QueueStatus.Unknown }) + : undefined; + + const depQueues: Set = new Set(); + + const { resolve, reject, promise: rawPromise } = createPromise(); + + const promise: AsyncModulePromise = Object.assign(rawPromise, { + [turbopackExports]: module.exports, + [turbopackQueues]: (fn) => { + queue && fn(queue); + depQueues.forEach(fn); + promise["catch"](() => {}); + }, + } satisfies AsyncModuleExt); + + const attributes: PropertyDescriptor = { + get(): any { + return promise; + }, + set(v: any) { + // Calling `esmExport` leads to this. + if (v !== promise) { + promise[turbopackExports] = v; + } + }, + }; + + Object.defineProperty(module, "exports", attributes); + Object.defineProperty(module, "namespaceObject", attributes); + + function handleAsyncDependencies(deps: Dep[]) { + const currentDeps = wrapDeps(deps); + + const getResult = () => + currentDeps.map((d) => { + if (d[turbopackError]) throw d[turbopackError]; + return d[turbopackExports]; + }); + + const { promise, resolve } = createPromise<() => Exports[]>(); + + const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), { + queueCount: 0, + }); + + function fnQueue(q: AsyncQueue) { + if (q !== queue && !depQueues.has(q)) { + depQueues.add(q); + if (q && q.status === QueueStatus.Unresolved) { + fn.queueCount++; + q.push(fn); + } + } + } + + currentDeps.map((dep) => dep[turbopackQueues](fnQueue)); + + return fn.queueCount ? promise : getResult(); + } + + function asyncResult(err?: any) { + if (err) { + reject((promise[turbopackError] = err)); + } else { + resolve(promise[turbopackExports]); + } + + resolveQueue(queue); + } + + body(handleAsyncDependencies, asyncResult); + + if (queue && queue.status === QueueStatus.Unknown) { + queue.status = QueueStatus.Unresolved; + } +} + +/** + * A pseudo "fake" URL object to resolve to its relative path. + * + * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this + * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid + * hydration mismatch. + * + * This is based on webpack's existing implementation: + * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js + */ +const relativeURL = function relativeURL(this: any, inputUrl: string) { + const realUrl = new URL(inputUrl, "x:/"); + const values: Record = {}; + for (const key in realUrl) values[key] = (realUrl as any)[key]; + values.href = inputUrl; + values.pathname = inputUrl.replace(/[?#].*/, ""); + values.origin = values.protocol = ""; + values.toString = values.toJSON = (..._args: Array) => inputUrl; + for (const key in values) + Object.defineProperty(this, key, { + enumerable: true, + configurable: true, + value: values[key], + }); +}; + +relativeURL.prototype = URL.prototype; diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/tsconfig.json b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/tsconfig.json new file mode 100644 index 0000000000000..c255a6ca179fc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/shared/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + // environment, we need WebWorker for WebAssembly types + "lib": ["ESNext", "WebWorker"] + }, + "include": ["*.ts"] +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/js/src/tsconfig.base.json b/turbopack/crates/turbopack-ecmascript-runtime/js/src/tsconfig.base.json new file mode 100644 index 0000000000000..978189abece60 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/js/src/tsconfig.base.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + // type checking + "strict": true, + "noFallthroughCasesInSwitch": true, + "noImplicitAny": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + + // environment + "target": "ESNext", + + // modules + "baseUrl": ".", + "module": "CommonJS", + "types": [], // disable implicit types. + + // emit + "noEmit": true, + "stripInternal": true + } +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/src/asset_context.rs b/turbopack/crates/turbopack-ecmascript-runtime/src/asset_context.rs new file mode 100644 index 0000000000000..cef6c325e339d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/src/asset_context.rs @@ -0,0 +1,30 @@ +use turbo_tasks::Vc; +use turbopack::{ + module_options::{ModuleOptionsContext, TypescriptTransformOptions}, + ModuleAssetContext, +}; +use turbopack_core::{ + compile_time_info::CompileTimeInfo, context::AssetContext, environment::Environment, +}; +use turbopack_ecmascript::TreeShakingMode; + +/// Returns the runtime asset context to use to process runtime code assets. +pub fn get_runtime_asset_context(environment: Vc) -> Vc> { + let module_options_context = ModuleOptionsContext { + enable_typescript_transform: Some(TypescriptTransformOptions::default().cell()), + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), + ..Default::default() + } + .cell(); + let compile_time_info = CompileTimeInfo::builder(environment).cell(); + + let asset_context: Vc> = Vc::upcast(ModuleAssetContext::new( + Vc::cell(Default::default()), + compile_time_info, + module_options_context, + Vc::default(), + Vc::cell("runtime".into()), + )); + + asset_context +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/src/browser_runtime.rs b/turbopack/crates/turbopack-ecmascript-runtime/src/browser_runtime.rs new file mode 100644 index 0000000000000..3ef6e5f8f01e5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/src/browser_runtime.rs @@ -0,0 +1,107 @@ +use std::io::Write; + +use anyhow::Result; +use indoc::writedoc; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::{ + code_builder::{Code, CodeBuilder}, + context::AssetContext, + environment::{ChunkLoading, Environment}, +}; +use turbopack_ecmascript::utils::StringifyJs; + +use crate::{asset_context::get_runtime_asset_context, embed_js::embed_static_code}; + +/// Returns the code for the development ECMAScript runtime. +#[turbo_tasks::function] +pub async fn get_browser_runtime_code( + environment: Vc, + chunk_base_path: Vc>, + output_root: Vc, +) -> Result> { + let asset_context = get_runtime_asset_context(environment); + + let shared_runtime_utils_code = + embed_static_code(asset_context, "shared/runtime-utils.ts".into()); + let runtime_base_code = embed_static_code( + asset_context, + "browser/dev/runtime/base/runtime-base.ts".into(), + ); + + let chunk_loading = &*asset_context + .compile_time_info() + .environment() + .chunk_loading() + .await?; + + let runtime_backend_code = embed_static_code( + asset_context, + match chunk_loading { + ChunkLoading::Edge => "browser/dev/runtime/edge/runtime-backend-edge.ts".into(), + // This case should never be hit. + ChunkLoading::NodeJs => { + panic!("Node.js runtime is not supported in the browser runtime!") + } + ChunkLoading::Dom => "browser/dev/runtime/dom/runtime-backend-dom.ts".into(), + }, + ); + + let mut code: CodeBuilder = CodeBuilder::default(); + let output_root = output_root.await?.to_string(); + let chunk_base_path = &*chunk_base_path.await?; + let chunk_base_path = chunk_base_path.as_ref().map_or_else(|| "", |f| f.as_str()); + + writedoc!( + code, + r#" + (() => {{ + if (!Array.isArray(globalThis.TURBOPACK)) {{ + return; + }} + + const CHUNK_BASE_PATH = {}; + const RUNTIME_PUBLIC_PATH = {}; + const OUTPUT_ROOT = {}; + "#, + StringifyJs(chunk_base_path), + StringifyJs(chunk_base_path), + StringifyJs(output_root.as_str()), + )?; + + code.push_code(&*shared_runtime_utils_code.await?); + code.push_code(&*runtime_base_code.await?); + + if *environment.supports_commonjs_externals().await? { + code.push_code( + &*embed_static_code(asset_context, "shared-node/base-externals-utils.ts".into()) + .await?, + ); + } + if *environment.node_externals().await? { + code.push_code( + &*embed_static_code(asset_context, "shared-node/node-externals-utils.ts".into()) + .await?, + ); + } + if *environment.supports_wasm().await? { + code.push_code( + &*embed_static_code(asset_context, "shared-node/node-wasm-utils.ts".into()).await?, + ); + } + + code.push_code(&*runtime_backend_code.await?); + + // Registering chunks depends on the BACKEND variable, which is set by the + // specific runtime code, hence it must be appended after it. + writedoc!( + code, + r#" + const chunksToRegister = globalThis.TURBOPACK; + globalThis.TURBOPACK = {{ push: registerChunk }}; + chunksToRegister.forEach(registerChunk); + }})(); + "# + )?; + + Ok(Code::cell(code.build())) +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/src/dummy_runtime.rs b/turbopack/crates/turbopack-ecmascript-runtime/src/dummy_runtime.rs new file mode 100644 index 0000000000000..e9662b67f304f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/src/dummy_runtime.rs @@ -0,0 +1,10 @@ +use turbopack_core::code_builder::{Code, CodeBuilder}; + +/// Returns the code for the dummy runtime, which is used for snapshots. +pub fn get_dummy_runtime_code() -> Code { + let mut code = CodeBuilder::default(); + + code += "// Dummy runtime\n"; + + code.build() +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/src/embed_js.rs b/turbopack/crates/turbopack-ecmascript-runtime/src/embed_js.rs new file mode 100644 index 0000000000000..fda4e89341c62 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/src/embed_js.rs @@ -0,0 +1,24 @@ +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::{embed_directory, FileContent, FileSystem, FileSystemPath}; +use turbopack_core::{code_builder::Code, context::AssetContext}; +use turbopack_ecmascript::StaticEcmascriptCode; + +#[turbo_tasks::function] +pub fn embed_fs() -> Vc> { + embed_directory!("turbopack", "$CARGO_MANIFEST_DIR/js/src") +} + +#[turbo_tasks::function] +pub fn embed_file(path: RcStr) -> Vc { + embed_fs().root().join(path).read() +} + +#[turbo_tasks::function] +pub fn embed_file_path(path: RcStr) -> Vc { + embed_fs().root().join(path) +} + +#[turbo_tasks::function] +pub fn embed_static_code(asset_context: Vc>, path: RcStr) -> Vc { + StaticEcmascriptCode::new(asset_context, embed_file_path(path)).code() +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/src/lib.rs b/turbopack/crates/turbopack-ecmascript-runtime/src/lib.rs new file mode 100644 index 0000000000000..b1ebef84c9aab --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/src/lib.rs @@ -0,0 +1,24 @@ +#![feature(arbitrary_self_types)] + +pub(crate) mod asset_context; +pub(crate) mod browser_runtime; +#[cfg(feature = "test")] +pub(crate) mod dummy_runtime; +pub(crate) mod embed_js; +pub(crate) mod nodejs_runtime; +pub(crate) mod runtime_type; + +pub use browser_runtime::get_browser_runtime_code; +#[cfg(feature = "test")] +pub use dummy_runtime::get_dummy_runtime_code; +pub use embed_js::{embed_file, embed_file_path, embed_fs}; +pub use nodejs_runtime::get_nodejs_runtime_code; +pub use runtime_type::RuntimeType; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/src/nodejs_runtime.rs b/turbopack/crates/turbopack-ecmascript-runtime/src/nodejs_runtime.rs new file mode 100644 index 0000000000000..a7aab2d7a6b3d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/src/nodejs_runtime.rs @@ -0,0 +1,33 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbopack_core::{ + code_builder::{Code, CodeBuilder}, + environment::Environment, +}; + +use crate::{asset_context::get_runtime_asset_context, embed_js::embed_static_code}; + +/// Returns the code for the Node.js production ECMAScript runtime. +#[turbo_tasks::function] +pub async fn get_nodejs_runtime_code(environment: Vc) -> Result> { + let asset_context = get_runtime_asset_context(environment); + + let shared_runtime_utils_code = + embed_static_code(asset_context, "shared/runtime-utils.ts".into()); + let shared_base_external_utils_code = + embed_static_code(asset_context, "shared-node/base-externals-utils.ts".into()); + let shared_node_external_utils_code = + embed_static_code(asset_context, "shared-node/node-externals-utils.ts".into()); + let shared_node_wasm_utils_code = + embed_static_code(asset_context, "shared-node/node-wasm-utils.ts".into()); + let runtime_code = embed_static_code(asset_context, "nodejs/runtime.ts".into()); + + let mut code = CodeBuilder::default(); + code.push_code(&*shared_runtime_utils_code.await?); + code.push_code(&*shared_base_external_utils_code.await?); + code.push_code(&*shared_node_external_utils_code.await?); + code.push_code(&*shared_node_wasm_utils_code.await?); + code.push_code(&*runtime_code.await?); + + Ok(Code::cell(code.build())) +} diff --git a/turbopack/crates/turbopack-ecmascript-runtime/src/runtime_type.rs b/turbopack/crates/turbopack-ecmascript-runtime/src/runtime_type.rs new file mode 100644 index 0000000000000..b44bcb69aa4c7 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript-runtime/src/runtime_type.rs @@ -0,0 +1,11 @@ +use serde::{Deserialize, Serialize}; +use turbo_tasks::trace::TraceRawVcs; + +#[derive(Serialize, Deserialize, Debug, Clone, Copy, Hash, PartialEq, Eq, TraceRawVcs)] +pub enum RuntimeType { + Development, + Production, + #[cfg(feature = "test")] + /// Dummy runtime for snapshot tests. + Dummy, +} diff --git a/turbopack/crates/turbopack-ecmascript/Cargo.toml b/turbopack/crates/turbopack-ecmascript/Cargo.toml new file mode 100644 index 0000000000000..8142da8f863bb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/Cargo.toml @@ -0,0 +1,80 @@ +[package] +name = "turbopack-ecmascript" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +async-trait = { workspace = true } +either = { workspace = true } +indexmap = { workspace = true } +indoc = { workspace = true } +lazy_static = { workspace = true } +num-bigint = "0.4" +num-traits = "0.2.15" +once_cell = { workspace = true } +parking_lot = { workspace = true } +petgraph = { workspace = true } +regex = { workspace = true } +rustc-hash = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +sourcemap = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-hash = { workspace = true } +turbopack-core = { workspace = true } +turbopack-resolve = { workspace = true } +turbopack-swc-utils = { workspace = true } +url = { workspace = true } +urlencoding = { workspace = true } + +swc_core = { workspace = true, features = [ + "ecma_ast", + "ecma_ast_serde", + "common", + "common_concurrent", + "common_sourcemap", + "ecma_codegen", + "ecma_lints", + "ecma_minifier", + "ecma_minifier_concurrent", + "ecma_parser", + "ecma_preset_env", + "ecma_transforms", + "ecma_transforms_module", + "ecma_transforms_react", + "ecma_transforms_optimization", + "ecma_transforms_typescript", + "ecma_transforms_proposal", + "ecma_quote", + "ecma_visit", + "ecma_visit_path", + "ecma_utils", + "testing", + "base", +] } + +[dev-dependencies] +criterion = { workspace = true, features = ["async_tokio"] } +rstest = { workspace = true } +turbo-tasks-memory = { workspace = true } +turbo-tasks-testing = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } + +[[bench]] +name = "mod" +harness = false diff --git a/turbopack/crates/turbopack-ecmascript/benches/analyzer.rs b/turbopack/crates/turbopack-ecmascript/benches/analyzer.rs new file mode 100644 index 0000000000000..0a94684f5ed9b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/benches/analyzer.rs @@ -0,0 +1,120 @@ +use std::{fs, path::PathBuf, sync::Arc, time::Duration}; + +use criterion::{Bencher, BenchmarkId, Criterion}; +use swc_core::{ + common::{FilePathMapping, Mark, SourceMap, GLOBALS}, + ecma::{ + ast::{EsVersion, Program}, + parser::parse_file_as_program, + transforms::base::resolver, + visit::VisitMutWith, + }, +}; +use turbo_tasks::Value; +use turbo_tasks_testing::VcStorage; +use turbopack_core::{ + compile_time_info::CompileTimeInfo, + environment::{Environment, ExecutionEnvironment, NodeJsEnvironment}, + target::CompileTarget, +}; +use turbopack_ecmascript::analyzer::{ + graph::{create_graph, EvalContext, VarGraph}, + linker::link, + test_utils::{early_visitor, visitor}, +}; + +pub fn benchmark(c: &mut Criterion) { + turbopack_ecmascript::register(); + + let tests_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests/analyzer/graph"); + let results = fs::read_dir(tests_dir).unwrap(); + + let mut group = c.benchmark_group("analyzer"); + group.warm_up_time(Duration::from_secs(1)); + group.measurement_time(Duration::from_secs(3)); + + for result in results { + let entry = result.unwrap(); + if entry.file_type().unwrap().is_dir() { + let name = entry.file_name().into_string().unwrap(); + let input = entry.path().join("input.js"); + + let cm = Arc::new(SourceMap::new(FilePathMapping::empty())); + let fm = cm.load_file(&input).unwrap(); + GLOBALS.set(&swc_core::common::Globals::new(), || { + let mut program = parse_file_as_program( + &fm, + Default::default(), + EsVersion::latest(), + None, + &mut vec![], + ) + .unwrap(); + + let unresolved_mark = Mark::new(); + let top_level_mark = Mark::new(); + program.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false)); + + let eval_context = + EvalContext::new(&program, unresolved_mark, top_level_mark, None); + let var_graph = create_graph(&program, &eval_context); + + let input = BenchInput { + program, + eval_context, + var_graph, + }; + + group.bench_with_input( + BenchmarkId::new("create_graph", &name), + &input, + bench_create_graph, + ); + group.bench_with_input(BenchmarkId::new("link", &name), &input, bench_link); + }); + } + } +} + +struct BenchInput { + program: Program, + eval_context: EvalContext, + var_graph: VarGraph, +} + +fn bench_create_graph(b: &mut Bencher, input: &BenchInput) { + b.iter(|| create_graph(&input.program, &input.eval_context)); +} + +fn bench_link(b: &mut Bencher, input: &BenchInput) { + let rt = tokio::runtime::Builder::new_current_thread() + .build() + .unwrap(); + + b.to_async(rt).iter(|| async { + for val in input.var_graph.values.values() { + VcStorage::with(async { + let compile_time_info = CompileTimeInfo::builder(Environment::new(Value::new( + ExecutionEnvironment::NodeJsLambda( + NodeJsEnvironment { + compile_target: CompileTarget::unknown(), + ..Default::default() + } + .into(), + ), + ))) + .cell(); + link( + &input.var_graph, + val.clone(), + &early_visitor, + &(|val| visitor(val, compile_time_info)), + Default::default(), + ) + .await + }) + .await + .unwrap(); + } + }); +} diff --git a/turbopack/crates/turbopack-ecmascript/benches/mod.rs b/turbopack/crates/turbopack-ecmascript/benches/mod.rs new file mode 100644 index 0000000000000..48208446e41e4 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/benches/mod.rs @@ -0,0 +1,6 @@ +use criterion::{criterion_group, criterion_main}; + +mod analyzer; + +criterion_group!(analyzer_benches, analyzer::benchmark); +criterion_main!(analyzer_benches); diff --git a/turbopack/crates/turbopack-ecmascript/build.rs b/turbopack/crates/turbopack-ecmascript/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/builtin.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/builtin.rs new file mode 100644 index 0000000000000..781aaf79fd433 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/builtin.rs @@ -0,0 +1,569 @@ +use std::mem::take; + +use swc_core::ecma::atoms::js_word; + +use super::{ConstantNumber, ConstantValue, JsValue, LogicalOperator, ObjectPart}; + +/// Replaces some builtin values with their resulting values. Called early +/// without lazy nested values. This allows to skip a lot of work to process the +/// arguments. +pub fn early_replace_builtin(value: &mut JsValue) -> bool { + match value { + // matching calls like `callee(arg1, arg2, ...)` + JsValue::Call(_, box ref mut callee, args) => { + let args_have_side_effects = || args.iter().any(|arg| arg.has_side_effects()); + match callee { + // We don't know what the callee is, so we can early return + &mut JsValue::Unknown { + original_value: _, + reason: _, + has_side_effects, + } => { + let has_side_effects = has_side_effects || args_have_side_effects(); + value.make_unknown(has_side_effects, "unknown callee"); + true + } + // We known that these callee will lead to an error at runtime, so we can skip + // processing them + JsValue::Constant(_) + | JsValue::Url(_) + | JsValue::WellKnownObject(_) + | JsValue::Array { .. } + | JsValue::Object { .. } + | JsValue::Alternatives(_, _) + | JsValue::Concat(_, _) + | JsValue::Add(_, _) + | JsValue::Not(_, _) => { + let has_side_effects = args_have_side_effects(); + value.make_unknown(has_side_effects, "non-function callee"); + true + } + _ => false, + } + } + // matching calls with this context like `obj.prop(arg1, arg2, ...)` + JsValue::MemberCall(_, box ref mut obj, box ref mut prop, args) => { + let args_have_side_effects = || args.iter().any(|arg| arg.has_side_effects()); + match obj { + // We don't know what the callee is, so we can early return + &mut JsValue::Unknown { + original_value: _, + reason: _, + has_side_effects, + } => { + let side_effects = + has_side_effects || prop.has_side_effects() || args_have_side_effects(); + value.make_unknown(side_effects, "unknown callee object"); + true + } + // otherwise we need to look at the property + _ => match prop { + // We don't know what the property is, so we can early return + &mut JsValue::Unknown { + original_value: _, + reason: _, + has_side_effects, + } => { + let side_effects = has_side_effects || args_have_side_effects(); + value.make_unknown(side_effects, "unknown callee property"); + true + } + _ => false, + }, + } + } + // matching property access like `obj.prop` when we don't know what the obj is. + // We can early return here + &mut JsValue::Member( + _, + box JsValue::Unknown { + original_value: _, + reason: _, + has_side_effects, + }, + box ref mut prop, + ) => { + let side_effects = has_side_effects || prop.has_side_effects(); + value.make_unknown(side_effects, "unknown object"); + true + } + _ => false, + } +} + +/// Replaces some builtin functions and values with their resulting values. In +/// contrast to early_replace_builtin this has all inner values already +/// processed. +pub fn replace_builtin(value: &mut JsValue) -> bool { + match value { + // matching property access like `obj.prop` + // Accessing a property on something can be handled in some cases + JsValue::Member(_, box ref mut obj, ref mut prop) => match obj { + // matching property access when obj is a bunch of alternatives + // like `(obj1 | obj2 | obj3).prop` + // We expand these to `obj1.prop | obj2.prop | obj3.prop` + JsValue::Alternatives(_, alts) => { + *value = JsValue::alternatives( + take(alts) + .into_iter() + .map(|alt| JsValue::member(Box::new(alt), prop.clone())) + .collect(), + ); + true + } + // matching property access on an array like `[1,2,3].prop` or `[1,2,3][1]` + &mut JsValue::Array { + ref mut items, + mutable, + .. + } => { + fn items_to_alternatives(items: &mut Vec, prop: &mut JsValue) -> JsValue { + items.push(JsValue::unknown( + JsValue::member(Box::new(JsValue::array(Vec::new())), Box::new(take(prop))), + false, + "unknown array prototype methods or values", + )); + JsValue::alternatives(take(items)) + } + match &mut **prop { + // accessing a numeric property on an array like `[1,2,3][1]` + // We can replace this with the value at the index + JsValue::Constant(ConstantValue::Num(num @ ConstantNumber(_))) => { + if let Some(index) = num.as_u32_index() { + if index < items.len() { + *value = items.swap_remove(index); + if mutable { + value.add_unknown_mutations(true); + } + true + } else { + *value = JsValue::unknown( + JsValue::member(Box::new(take(obj)), Box::new(take(prop))), + false, + "invalid index", + ); + true + } + } else { + value.make_unknown(false, "non-num constant property on array"); + true + } + } + // accessing a non-numeric property on an array like `[1,2,3].length` + // We don't know what happens here + JsValue::Constant(_) => { + value.make_unknown(false, "non-num constant property on array"); + true + } + // accessing multiple alternative properties on an array like `[1,2,3][(1 | 2 | + // prop3)]` + JsValue::Alternatives(_, alts) => { + *value = JsValue::alternatives( + take(alts) + .into_iter() + .map(|alt| JsValue::member(Box::new(obj.clone()), Box::new(alt))) + .collect(), + ); + true + } + // otherwise we can say that this might gives an item of the array + // but we also add an unknown value to the alternatives for other properties + _ => { + *value = items_to_alternatives(items, prop); + true + } + } + } + // matching property access on an object like `{a: 1, b: 2}.a` + &mut JsValue::Object { + ref mut parts, + mutable, + .. + } => { + fn parts_to_alternatives( + parts: &mut Vec, + prop: &mut Box, + include_unknown: bool, + ) -> JsValue { + let mut values = Vec::new(); + for part in parts { + match part { + ObjectPart::KeyValue(_, value) => { + values.push(take(value)); + } + ObjectPart::Spread(_) => { + values.push(JsValue::unknown( + JsValue::member( + Box::new(JsValue::object(vec![take(part)])), + prop.clone(), + ), + true, + "spreaded object", + )); + } + } + } + if include_unknown { + values.push(JsValue::unknown( + JsValue::member( + Box::new(JsValue::object(Vec::new())), + Box::new(take(prop)), + ), + true, + "unknown object prototype methods or values", + )); + } + JsValue::alternatives(values) + } + + /// Convert a list of potential values into + /// JsValue::Alternatives Optionally add a + /// unknown value to the alternatives for object prototype + /// methods + fn potential_values_to_alternatives( + mut potential_values: Vec, + parts: &mut Vec, + prop: &mut Box, + include_unknown: bool, + ) -> JsValue { + // Note: potential_values are already in reverse order + let mut potential_values = take(parts) + .into_iter() + .enumerate() + .filter(|(i, _)| { + if potential_values.last() == Some(i) { + potential_values.pop(); + true + } else { + false + } + }) + .map(|(_, part)| part) + .collect(); + parts_to_alternatives(&mut potential_values, prop, include_unknown) + } + + match &mut **prop { + // matching constant string property access on an object like `{a: 1, b: + // 2}["a"]` + JsValue::Constant(ConstantValue::Str(_)) => { + let prop_str = prop.as_str().unwrap(); + let mut potential_values = Vec::new(); + for (i, part) in parts.iter_mut().enumerate().rev() { + match part { + ObjectPart::KeyValue(key, val) => { + if let Some(key) = key.as_str() { + if key == prop_str { + if potential_values.is_empty() { + *value = take(val); + } else { + potential_values.push(i); + *value = potential_values_to_alternatives( + potential_values, + parts, + prop, + false, + ); + } + if mutable { + value.add_unknown_mutations(true); + } + return true; + } + } else { + potential_values.push(i); + } + } + ObjectPart::Spread(_) => { + value.make_unknown(true, "spread object"); + return true; + } + } + } + if potential_values.is_empty() { + *value = JsValue::FreeVar(js_word!("undefined")); + } else { + *value = potential_values_to_alternatives( + potential_values, + parts, + prop, + true, + ); + } + if mutable { + value.add_unknown_mutations(true); + } + true + } + // matching mutliple alternative properties on an object like `{a: 1, b: 2}[(a | + // b)]` + JsValue::Alternatives(_, alts) => { + *value = JsValue::alternatives( + take(alts) + .into_iter() + .map(|alt| JsValue::member(Box::new(obj.clone()), Box::new(alt))) + .collect(), + ); + true + } + _ => { + *value = parts_to_alternatives(parts, prop, true); + true + } + } + } + _ => false, + }, + // matching calls with this context like `obj.prop(arg1, arg2, ...)` + JsValue::MemberCall(_, box ref mut obj, box ref mut prop, ref mut args) => { + match obj { + // matching calls on an array like `[1,2,3].concat([4,5,6])` + JsValue::Array { items, mutable, .. } => { + // matching cases where the property is a const string + if let Some(str) = prop.as_str() { + match str { + // The Array.prototype.concat method + "concat" => { + if args.iter().all(|arg| { + matches!( + arg, + JsValue::Array { .. } + | JsValue::Constant(_) + | JsValue::Url(_) + | JsValue::Concat(..) + | JsValue::Add(..) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) + | JsValue::Function(..) + ) + }) { + for arg in args { + match arg { + JsValue::Array { + items: inner, + mutable: inner_mutable, + .. + } => { + items.extend(take(inner)); + *mutable |= *inner_mutable; + } + JsValue::Constant(_) + | JsValue::Url(_) + | JsValue::Concat(..) + | JsValue::Add(..) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) + | JsValue::Function(..) => { + items.push(take(arg)); + } + _ => { + unreachable!(); + } + } + } + obj.update_total_nodes(); + *value = take(obj); + return true; + } + } + // The Array.prototype.map method + "map" => { + if let Some(func) = args.first() { + *value = JsValue::array( + take(items) + .into_iter() + .enumerate() + .map(|(i, item)| { + JsValue::call( + Box::new(func.clone()), + vec![ + item, + JsValue::Constant(ConstantValue::Num( + ConstantNumber(i as f64), + )), + ], + ) + }) + .collect(), + ); + return true; + } + } + _ => {} + } + } + } + // matching calls on multiple alternative objects like `(obj1 | obj2).prop(arg1, + // arg2, ...)` + JsValue::Alternatives(_, alts) => { + *value = JsValue::alternatives( + take(alts) + .into_iter() + .map(|alt| { + JsValue::member_call( + Box::new(alt), + Box::new(prop.clone()), + args.clone(), + ) + }) + .collect(), + ); + return true; + } + _ => {} + } + + // matching calls on strings like `"dayjs/locale/".concat(userLocale, ".js")` + if obj.is_string() == Some(true) { + if let Some(str) = prop.as_str() { + // The String.prototype.concat method + if str == "concat" { + let mut values = vec![take(obj)]; + values.extend(take(args)); + + *value = JsValue::concat(values); + return true; + } + } + } + + // without special handling, we convert it into a normal call like + // `(obj.prop)(arg1, arg2, ...)` + *value = JsValue::call( + Box::new(JsValue::member(Box::new(take(obj)), Box::new(take(prop)))), + take(args), + ); + true + } + // match calls when the callee are multiple alternative functions like `(func1 | + // func2)(arg1, arg2, ...)` + JsValue::Call(_, box JsValue::Alternatives(_, alts), ref mut args) => { + *value = JsValue::alternatives( + take(alts) + .into_iter() + .map(|alt| JsValue::call(Box::new(alt), args.clone())) + .collect(), + ); + true + } + // match object literals + JsValue::Object { parts, mutable, .. } => { + // If the object contains any spread, we might be able to flatten that + if parts + .iter() + .any(|part| matches!(part, ObjectPart::Spread(JsValue::Object { .. }))) + { + let old_parts = take(parts); + for part in old_parts { + if let ObjectPart::Spread(JsValue::Object { + parts: inner_parts, + mutable: inner_mutable, + .. + }) = part + { + parts.extend(inner_parts); + *mutable |= inner_mutable; + } else { + parts.push(part); + } + } + value.update_total_nodes(); + true + } else { + false + } + } + // match logical expressions like `a && b` or `a || b || c` or `a ?? b` + // Reduce logical expressions to their final value(s) + JsValue::Logical(_, op, ref mut parts) => { + let len = parts.len(); + for (i, part) in take(parts).into_iter().enumerate() { + // The last part is never skipped. + if i == len - 1 { + parts.push(part); + break; + } + // We might know at compile-time if a part is skipped or the final value. + let skip_part = match op { + LogicalOperator::And => part.is_truthy(), + LogicalOperator::Or => part.is_falsy(), + LogicalOperator::NullishCoalescing => part.is_nullish(), + }; + match skip_part { + Some(true) => { + // We known this part is skipped, so we can remove it. + continue; + } + Some(false) => { + // We known this part is the final value, so we can remove the rest. + parts.push(part); + break; + } + None => { + // We don't know if this part is skipped or the final value, so we keep it. + parts.push(part); + continue; + } + } + } + // If we reduced the expression to a single value, we can replace it. + if parts.len() == 1 { + *value = parts.pop().unwrap(); + true + } else { + // If not, we know that it will be one of the remaining values. + *value = JsValue::alternatives(take(parts)); + true + } + } + JsValue::Tenary(_, test, cons, alt) => { + if test.is_truthy() == Some(true) { + *value = take(cons); + true + } else if test.is_falsy() == Some(true) { + *value = take(alt); + true + } else { + false + } + } + // match a binary operator like `a == b` + JsValue::Binary(..) => { + if let Some(v) = value.is_truthy() { + let v = if v { + ConstantValue::True + } else { + ConstantValue::False + }; + *value = JsValue::Constant(v); + true + } else { + false + } + } + // match the not operator like `!a` + // Evaluate not when the inner value is truthy or falsy + JsValue::Not(_, ref inner) => match inner.is_truthy() { + Some(true) => { + *value = JsValue::Constant(ConstantValue::False); + true + } + Some(false) => { + *value = JsValue::Constant(ConstantValue::True); + true + } + None => false, + }, + + JsValue::Iterated(_, iterable) => { + if let JsValue::Array { items, .. } = &mut **iterable { + *value = JsValue::alternatives(take(items)); + true + } else { + false + } + } + + _ => false, + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/graph.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/graph.rs new file mode 100644 index 0000000000000..8105ae870289f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/graph.rs @@ -0,0 +1,1932 @@ +use std::{ + collections::HashMap, + iter, + mem::{replace, take}, +}; + +use swc_core::{ + common::{pass::AstNodePath, Mark, Span, Spanned, SyntaxContext, GLOBALS}, + ecma::{ + ast::*, + atoms::js_word, + visit::{fields::*, *}, + }, +}; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::source::Source; + +use super::{ConstantNumber, ConstantValue, ImportMap, JsValue, ObjectPart, WellKnownFunctionKind}; +use crate::{analyzer::is_unresolved, utils::unparen}; + +#[derive(Debug, Clone, Default)] +pub struct EffectsBlock { + pub effects: Vec, + /// The ast path to the block or expression. + pub ast_path: Vec, +} + +impl EffectsBlock { + pub fn is_empty(&self) -> bool { + self.effects.is_empty() + } +} + +#[derive(Debug, Clone)] +pub enum ConditionalKind { + /// The blocks of an `if` statement without an `else` block. + If { then: EffectsBlock }, + /// The blocks of an `if ... else` statement. + IfElse { + then: EffectsBlock, + r#else: EffectsBlock, + }, + /// The expressions on the right side of the `?:` operator. + Ternary { + then: EffectsBlock, + r#else: EffectsBlock, + }, + /// The expression on the right side of the `&&` operator. + And { expr: EffectsBlock }, + /// The expression on the right side of the `||` operator. + Or { expr: EffectsBlock }, + /// The expression on the right side of the `??` operator. + NullishCoalescing { expr: EffectsBlock }, +} + +impl ConditionalKind { + /// Normalizes all contained values. + pub fn normalize(&mut self) { + match self { + ConditionalKind::If { then, .. } => { + for effect in &mut then.effects { + effect.normalize(); + } + } + ConditionalKind::IfElse { then, r#else, .. } + | ConditionalKind::Ternary { then, r#else, .. } => { + for effect in &mut then.effects { + effect.normalize(); + } + for effect in &mut r#else.effects { + effect.normalize(); + } + } + ConditionalKind::And { expr, .. } + | ConditionalKind::Or { expr, .. } + | ConditionalKind::NullishCoalescing { expr, .. } => { + for effect in &mut expr.effects { + effect.normalize(); + } + } + } + } +} + +#[derive(Debug, Clone)] +pub enum EffectArg { + Value(JsValue), + Closure(JsValue, EffectsBlock), + Spread, +} + +impl EffectArg { + /// Normalizes all contained values. + pub fn normalize(&mut self) { + match self { + EffectArg::Value(value) => value.normalize(), + EffectArg::Closure(value, effects) => { + value.normalize(); + for effect in &mut effects.effects { + effect.normalize(); + } + } + EffectArg::Spread => {} + } + } +} + +#[derive(Debug, Clone)] +pub enum Effect { + /// Some condition which affects which effects might be executed. If the + /// condition evaluates to some compile-time constant, we can use that + /// to determine which effects are executed and remove the others. + Conditional { + condition: JsValue, + kind: Box, + /// The ast path to the condition. + ast_path: Vec, + span: Span, + in_try: bool, + }, + /// A function call. + Call { + func: JsValue, + args: Vec, + ast_path: Vec, + span: Span, + in_try: bool, + }, + /// A function call of a property of an object. + MemberCall { + obj: JsValue, + prop: JsValue, + args: Vec, + ast_path: Vec, + span: Span, + in_try: bool, + }, + /// A property access. + Member { + obj: JsValue, + prop: JsValue, + ast_path: Vec, + span: Span, + in_try: bool, + }, + /// A reference to an imported binding. + ImportedBinding { + esm_reference_index: usize, + export: Option, + ast_path: Vec, + span: Span, + in_try: bool, + }, + /// A reference to a free var access. + FreeVar { + var: JsValue, + ast_path: Vec, + span: Span, + in_try: bool, + }, + // TODO ImportMeta should be replaced with Member + /// A reference to `import.meta`. + ImportMeta { + ast_path: Vec, + span: Span, + in_try: bool, + }, + /// A reference to `new URL(..., import.meta.url)`. + Url { + input: JsValue, + ast_path: Vec, + span: Span, + in_try: bool, + }, +} + +impl Effect { + /// Normalizes all contained values. + pub fn normalize(&mut self) { + match self { + Effect::Conditional { + condition, kind, .. + } => { + condition.normalize(); + kind.normalize(); + } + Effect::Call { func, args, .. } => { + func.normalize(); + for arg in args.iter_mut() { + arg.normalize(); + } + } + Effect::MemberCall { + obj, prop, args, .. + } => { + obj.normalize(); + prop.normalize(); + for arg in args.iter_mut() { + arg.normalize(); + } + } + Effect::Member { obj, prop, .. } => { + obj.normalize(); + prop.normalize(); + } + Effect::FreeVar { var, .. } => { + var.normalize(); + } + Effect::ImportedBinding { .. } => {} + Effect::ImportMeta { .. } => {} + Effect::Url { input, .. } => { + input.normalize(); + } + } + } +} + +#[derive(Debug)] +pub struct VarGraph { + pub values: HashMap, + + pub effects: Vec, +} + +impl VarGraph { + pub fn normalize(&mut self) { + for value in self.values.values_mut() { + value.normalize(); + } + for effect in self.effects.iter_mut() { + effect.normalize(); + } + } +} + +/// You should use same [Mark] for this function and +/// [swc_ecma_transforms_base::resolver::resolver_with_mark] +pub fn create_graph(m: &Program, eval_context: &EvalContext) -> VarGraph { + let mut graph = VarGraph { + values: Default::default(), + effects: Default::default(), + }; + + m.visit_with_path( + &mut Analyzer { + data: &mut graph, + eval_context, + effects: Default::default(), + var_decl_kind: Default::default(), + current_value: Default::default(), + cur_fn_return_values: Default::default(), + cur_fn_ident: Default::default(), + }, + &mut Default::default(), + ); + + graph.normalize(); + + graph +} + +pub struct EvalContext { + pub(crate) unresolved_mark: Mark, + pub(crate) top_level_mark: Mark, + pub(crate) imports: ImportMap, +} + +impl EvalContext { + pub fn new( + module: &Program, + unresolved_mark: Mark, + top_level_mark: Mark, + source: Option>>, + ) -> Self { + Self { + unresolved_mark, + top_level_mark, + imports: ImportMap::analyze(module, source), + } + } + + pub fn is_esm(&self) -> bool { + self.imports.is_esm() + } + + fn eval_prop_name(&self, prop: &PropName) -> JsValue { + match prop { + PropName::Ident(ident) => ident.sym.clone().into(), + PropName::Str(str) => str.value.clone().into(), + PropName::Num(num) => num.value.into(), + PropName::Computed(ComputedPropName { expr, .. }) => self.eval(expr), + PropName::BigInt(bigint) => (*bigint.value.clone()).into(), + } + } + + fn eval_tpl(&self, e: &Tpl, raw: bool) -> JsValue { + debug_assert!(e.quasis.len() == e.exprs.len() + 1); + + let mut values = vec![]; + + for idx in 0..(e.quasis.len() + e.exprs.len()) { + if idx % 2 == 0 { + let idx = idx / 2; + let e = &e.quasis[idx]; + + if raw { + values.push(JsValue::from(e.raw.clone())); + } else { + match &e.cooked { + Some(v) => { + values.push(JsValue::from(v.clone())); + } + // This is actually unreachable + None => return JsValue::unknown_empty(true, ""), + } + } + } else { + let idx = idx / 2; + let e = &e.exprs[idx]; + + values.push(self.eval(e)); + } + } + + if values.len() == 1 { + return values.into_iter().next().unwrap(); + } + + JsValue::concat(values) + } + + fn eval_ident(&self, i: &Ident) -> JsValue { + let id = i.to_id(); + if let Some(imported) = self.imports.get_import(&id) { + return imported; + } + if is_unresolved(i, self.unresolved_mark) { + JsValue::FreeVar(i.sym.clone()) + } else { + JsValue::Variable(id) + } + } + + pub fn eval(&self, e: &Expr) -> JsValue { + debug_assert!( + GLOBALS.is_set(), + "Eval requires globals from its parsed result" + ); + match e { + Expr::Paren(e) => self.eval(&e.expr), + Expr::Lit(e) => JsValue::Constant(e.clone().into()), + Expr::Ident(i) => self.eval_ident(i), + + Expr::Unary(UnaryExpr { + op: op!("!"), arg, .. + }) => { + let arg = self.eval(arg); + + JsValue::logical_not(Box::new(arg)) + } + + Expr::Unary(UnaryExpr { + op: op!("typeof"), + arg, + .. + }) => { + let arg = self.eval(arg); + + JsValue::type_of(Box::new(arg)) + } + + Expr::Bin(BinExpr { + op: op!(bin, "+"), + left, + right, + .. + }) => { + let l = self.eval(left); + let r = self.eval(right); + + match (l, r) { + (JsValue::Add(c, l), r) => JsValue::Add( + c + r.total_nodes(), + l.into_iter().chain(iter::once(r)).collect(), + ), + (l, r) => JsValue::add(vec![l, r]), + } + } + + Expr::Bin(BinExpr { + op: op!("&&"), + left, + right, + .. + }) => JsValue::logical_and(vec![self.eval(left), self.eval(right)]), + + Expr::Bin(BinExpr { + op: op!("||"), + left, + right, + .. + }) => JsValue::logical_or(vec![self.eval(left), self.eval(right)]), + + Expr::Bin(BinExpr { + op: op!("??"), + left, + right, + .. + }) => JsValue::nullish_coalescing(vec![self.eval(left), self.eval(right)]), + + Expr::Bin(BinExpr { + op: op!("=="), + left, + right, + .. + }) => JsValue::equal(self.eval(left), self.eval(right)), + + Expr::Bin(BinExpr { + op: op!("!="), + left, + right, + .. + }) => JsValue::not_equal(self.eval(left), self.eval(right)), + + Expr::Bin(BinExpr { + op: op!("==="), + left, + right, + .. + }) => JsValue::strict_equal(self.eval(left), self.eval(right)), + + Expr::Bin(BinExpr { + op: op!("!=="), + left, + right, + .. + }) => JsValue::strict_not_equal(self.eval(left), self.eval(right)), + + &Expr::Cond(CondExpr { + box ref cons, + box ref alt, + box ref test, + .. + }) => { + let test = self.eval(test); + if let Some(truthy) = test.is_truthy() { + if truthy { + self.eval(cons) + } else { + self.eval(alt) + } + } else { + JsValue::tenary( + Box::new(test), + Box::new(self.eval(cons)), + Box::new(self.eval(alt)), + ) + } + } + + Expr::Tpl(e) => self.eval_tpl(e, false), + + Expr::TaggedTpl(TaggedTpl { + tag: + box Expr::Member(MemberExpr { + obj: box Expr::Ident(tag_obj), + prop: MemberProp::Ident(tag_prop), + .. + }), + tpl, + .. + }) => { + if &*tag_obj.sym == "String" + && &*tag_prop.sym == "raw" + && is_unresolved(tag_obj, self.unresolved_mark) + { + self.eval_tpl(tpl, true) + } else { + JsValue::unknown_empty(true, "tagged template literal is not supported yet") + } + } + + Expr::Fn(expr) => { + if let Some(ident) = &expr.ident { + JsValue::Variable(ident.to_id()) + } else { + JsValue::Variable(( + format!("*anonymous function {}*", expr.function.span.lo.0).into(), + SyntaxContext::empty(), + )) + } + } + Expr::Arrow(expr) => JsValue::Variable(( + format!("*arrow function {}*", expr.span.lo.0).into(), + SyntaxContext::empty(), + )), + + Expr::Await(AwaitExpr { arg, .. }) => self.eval(arg), + + Expr::New(..) => JsValue::unknown_empty(true, "unknown new expression"), + + Expr::Seq(e) => { + let mut seq = e.exprs.iter().map(|e| self.eval(e)).peekable(); + let mut side_effects = false; + let mut last = seq.next().unwrap(); + for e in seq { + side_effects |= last.has_side_effects(); + last = e; + } + if side_effects { + last.make_unknown(true, "sequence with side effects"); + } + last + } + + Expr::Member(MemberExpr { + obj, + prop: MemberProp::Ident(prop), + .. + }) => { + let obj = self.eval(obj); + JsValue::member(Box::new(obj), Box::new(prop.sym.clone().into())) + } + + Expr::Member(MemberExpr { + obj, + prop: MemberProp::Computed(computed), + .. + }) => { + let obj = self.eval(obj); + let prop = self.eval(&computed.expr); + JsValue::member(Box::new(obj), Box::new(prop)) + } + + Expr::Call(CallExpr { + callee: Callee::Expr(box callee), + args, + .. + }) => { + // We currently do not handle spreads. + if args.iter().any(|arg| arg.spread.is_some()) { + return JsValue::unknown_empty( + true, + "spread in function calls is not supported", + ); + } + + let args = args.iter().map(|arg| self.eval(&arg.expr)).collect(); + if let Expr::Member(MemberExpr { obj, prop, .. }) = unparen(callee) { + let obj = Box::new(self.eval(obj)); + let prop = Box::new(match prop { + // TODO avoid clone + MemberProp::Ident(i) => i.sym.clone().into(), + MemberProp::PrivateName(_) => { + return JsValue::unknown_empty( + false, + "private names in function calls is not supported", + ); + } + MemberProp::Computed(ComputedPropName { expr, .. }) => self.eval(expr), + }); + JsValue::member_call(obj, prop, args) + } else { + let callee = Box::new(self.eval(callee)); + + JsValue::call(callee, args) + } + } + + Expr::Call(CallExpr { + callee: Callee::Super(_), + args, + .. + }) => { + // We currently do not handle spreads. + if args.iter().any(|arg| arg.spread.is_some()) { + return JsValue::unknown_empty( + true, + "spread in function calls is not supported", + ); + } + + let args = args.iter().map(|arg| self.eval(&arg.expr)).collect(); + + JsValue::super_call(args) + } + + Expr::Call(CallExpr { + callee: Callee::Import(_), + args, + .. + }) => { + // We currently do not handle spreads. + if args.iter().any(|arg| arg.spread.is_some()) { + return JsValue::unknown_empty(true, "spread in import() is not supported"); + } + let args = args.iter().map(|arg| self.eval(&arg.expr)).collect(); + + let callee = Box::new(JsValue::FreeVar(js_word!("import"))); + + JsValue::call(callee, args) + } + + Expr::Array(arr) => { + if arr.elems.iter().flatten().any(|v| v.spread.is_some()) { + return JsValue::unknown_empty(true, "spread is not supported"); + } + + let arr = arr + .elems + .iter() + .map(|e| match e { + Some(e) => self.eval(&e.expr), + _ => JsValue::FreeVar(js_word!("undefined")), + }) + .collect(); + JsValue::array(arr) + } + + Expr::Object(obj) => { + return JsValue::object( + obj.props + .iter() + .map(|prop| match prop { + PropOrSpread::Spread(SpreadElement { expr, .. }) => { + ObjectPart::Spread(self.eval(expr)) + } + PropOrSpread::Prop(box Prop::KeyValue(KeyValueProp { + key, + box value, + })) => ObjectPart::KeyValue(self.eval_prop_name(key), self.eval(value)), + PropOrSpread::Prop(box Prop::Shorthand(ident)) => ObjectPart::KeyValue( + ident.sym.clone().into(), + self.eval(&Expr::Ident(ident.clone())), + ), + _ => ObjectPart::Spread(JsValue::unknown_empty( + true, + "unsupported object part", + )), + }) + .collect(), + ) + } + + _ => JsValue::unknown_empty(true, "unsupported expression"), + } + } +} + +struct Analyzer<'a> { + data: &'a mut VarGraph, + + effects: Vec, + + eval_context: &'a EvalContext, + + var_decl_kind: Option, + + /// Used for patterns + current_value: Option, + + /// Return values of the current function. + /// + /// This is configured to [Some] by function handlers and filled by the + /// return statement handler. + cur_fn_return_values: Option>, + + cur_fn_ident: u32, +} + +pub fn as_parent_path(ast_path: &AstNodePath>) -> Vec { + ast_path.iter().map(|n| n.kind()).collect() +} + +pub fn as_parent_path_with( + ast_path: &AstNodePath>, + additional: AstParentKind, +) -> Vec { + ast_path + .iter() + .map(|n| n.kind()) + .chain([additional]) + .collect() +} + +pub fn is_in_try(ast_path: &AstNodePath>) -> bool { + ast_path + .iter() + .rev() + .find_map(|ast_ref| match ast_ref.kind() { + AstParentKind::ArrowExpr(ArrowExprField::Body) => Some(false), + AstParentKind::Function(FunctionField::Body) => Some(false), + AstParentKind::TryStmt(TryStmtField::Block) => Some(true), + _ => None, + }) + .unwrap_or(false) +} + +impl Analyzer<'_> { + fn add_value(&mut self, id: Id, value: JsValue) { + if let Some(prev) = self.data.values.get_mut(&id) { + prev.add_alt(value); + } else { + self.data.values.insert(id, value); + } + // TODO(kdy1): We may need to report an error for this. + // Variables declared with `var` are hoisted, but using undefined as its + // value does not seem like a good idea. + } + + fn add_value_from_expr(&mut self, id: Id, value: &Expr) { + let value = self.eval_context.eval(value); + + self.add_value(id, value); + } + + fn add_effect(&mut self, effect: Effect) { + self.effects.push(effect); + } + + fn check_iife<'ast: 'r, 'r>( + &mut self, + n: &'ast CallExpr, + ast_path: &mut AstNodePath>, + ) -> bool { + fn unparen<'ast: 'r, 'r, T>( + expr: &'ast Expr, + ast_path: &mut AstNodePath>, + f: impl FnOnce(&'ast Expr, &mut AstNodePath>) -> T, + ) -> T { + if let Some(inner_expr) = expr.as_paren() { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::Expr(expr, ExprField::Paren)); + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ParenExpr( + inner_expr, + ParenExprField::Expr, + )); + unparen(&inner_expr.expr, &mut ast_path, f) + } else { + f(expr, ast_path) + } + } + + if n.args.iter().any(|arg| arg.spread.is_some()) { + return false; + } + + let Some(expr) = n.callee.as_expr() else { + return false; + }; + + let fn_expr = { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::CallExpr(n, CallExprField::Callee)); + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::Callee(&n.callee, CalleeField::Expr)); + unparen(expr, &mut ast_path, |expr, ast_path| match expr { + Expr::Fn(fn_expr @ FnExpr { function, ident }) => { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::Expr(expr, ExprField::Fn)); + { + let mut ast_path = ast_path + .with_guard(AstParentNodeRef::FnExpr(fn_expr, FnExprField::Ident)); + self.visit_opt_ident(ident.as_ref(), &mut ast_path); + } + + { + let mut ast_path = ast_path + .with_guard(AstParentNodeRef::FnExpr(fn_expr, FnExprField::Function)); + self.handle_iife_function(function, &mut ast_path, &n.args); + } + + true + } + + Expr::Arrow(arrow_expr) => { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::Expr(expr, ExprField::Arrow)); + let args = &n.args; + self.handle_iife_arrow(arrow_expr, args, &mut ast_path); + true + } + _ => false, + }) + }; + + if !fn_expr { + return false; + } + + let mut ast_path = ast_path.with_guard(AstParentNodeRef::CallExpr( + n, + CallExprField::Args(usize::MAX), + )); + + self.visit_expr_or_spreads(&n.args, &mut ast_path); + + true + } + + fn handle_iife_arrow<'ast: 'r, 'r>( + &mut self, + arrow_expr: &'ast ArrowExpr, + args: &[ExprOrSpread], + ast_path: &mut AstNodePath>, + ) { + let ArrowExpr { + params, + body, + is_async: _, + is_generator: _, + return_type, + span: _, + type_params, + } = arrow_expr; + let mut iter = args.iter(); + for (i, param) in params.iter().enumerate() { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ArrowExpr( + arrow_expr, + ArrowExprField::Params(i), + )); + if let Some(arg) = iter.next() { + self.current_value = Some(self.eval_context.eval(&arg.expr)); + self.visit_pat(param, &mut ast_path); + self.current_value = None; + } else { + self.visit_pat(param, &mut ast_path); + } + } + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ArrowExpr( + arrow_expr, + ArrowExprField::Body, + )); + self.visit_block_stmt_or_expr(body, &mut ast_path); + } + + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ArrowExpr( + arrow_expr, + ArrowExprField::ReturnType, + )); + self.visit_opt_ts_type_ann(return_type.as_ref(), &mut ast_path); + } + + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ArrowExpr( + arrow_expr, + ArrowExprField::TypeParams, + )); + self.visit_opt_ts_type_param_decl(type_params.as_ref(), &mut ast_path); + } + } + + fn handle_iife_function<'ast: 'r, 'r>( + &mut self, + function: &'ast Function, + ast_path: &mut AstNodePath>, + args: &[ExprOrSpread], + ) { + let mut iter = args.iter(); + let Function { + body, + decorators, + is_async: _, + is_generator: _, + params, + return_type, + span: _, + type_params, + } = function; + for (i, param) in params.iter().enumerate() { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::Function( + function, + FunctionField::Params(i), + )); + if let Some(arg) = iter.next() { + self.current_value = Some(self.eval_context.eval(&arg.expr)); + self.visit_param(param, &mut ast_path); + self.current_value = None; + } else { + self.visit_param(param, &mut ast_path); + } + } + + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::Function(function, FunctionField::Body)); + + self.visit_opt_block_stmt(body.as_ref(), &mut ast_path); + } + + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::Function( + function, + FunctionField::Decorators(usize::MAX), + )); + + self.visit_decorators(decorators, &mut ast_path); + } + + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::Function( + function, + FunctionField::ReturnType, + )); + + self.visit_opt_ts_type_ann(return_type.as_ref(), &mut ast_path); + } + + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::Function( + function, + FunctionField::TypeParams, + )); + + self.visit_opt_ts_type_param_decl(type_params.as_ref(), &mut ast_path); + } + } + + fn check_call_expr_for_effects<'ast: 'r, 'r>( + &mut self, + n: &'ast CallExpr, + args: Vec, + ast_path: &AstNodePath>, + ) { + match &n.callee { + Callee::Import(_) => { + self.add_effect(Effect::Call { + func: JsValue::FreeVar(js_word!("import")), + args, + ast_path: as_parent_path(ast_path), + span: n.span(), + in_try: is_in_try(ast_path), + }); + } + Callee::Expr(box expr) => { + if let Expr::Member(MemberExpr { obj, prop, .. }) = unparen(expr) { + let obj_value = self.eval_context.eval(obj); + let prop_value = match prop { + // TODO avoid clone + MemberProp::Ident(i) => i.sym.clone().into(), + MemberProp::PrivateName(_) => { + return; + } + MemberProp::Computed(ComputedPropName { expr, .. }) => { + self.eval_context.eval(expr) + } + }; + self.add_effect(Effect::MemberCall { + obj: obj_value, + prop: prop_value, + args, + ast_path: as_parent_path(ast_path), + span: n.span(), + in_try: is_in_try(ast_path), + }); + } else { + let fn_value = self.eval_context.eval(expr); + self.add_effect(Effect::Call { + func: fn_value, + args, + ast_path: as_parent_path(ast_path), + span: n.span(), + in_try: is_in_try(ast_path), + }); + } + } + Callee::Super(_) => self.add_effect(Effect::Call { + func: self.eval_context.eval(&Expr::Call(n.clone())), + args, + ast_path: as_parent_path(ast_path), + span: n.span(), + in_try: is_in_try(ast_path), + }), + } + } + + fn check_member_expr_for_effects<'ast: 'r, 'r>( + &mut self, + member_expr: &'ast MemberExpr, + ast_path: &AstNodePath>, + ) { + let obj_value = self.eval_context.eval(&member_expr.obj); + let prop_value = match &member_expr.prop { + // TODO avoid clone + MemberProp::Ident(i) => i.sym.clone().into(), + MemberProp::PrivateName(_) => { + return; + } + MemberProp::Computed(ComputedPropName { expr, .. }) => self.eval_context.eval(expr), + }; + self.add_effect(Effect::Member { + obj: obj_value, + prop: prop_value, + ast_path: as_parent_path(ast_path), + span: member_expr.span(), + in_try: is_in_try(ast_path), + }); + } + + fn take_return_values(&mut self) -> Box { + let values = self.cur_fn_return_values.take().unwrap(); + + Box::new(match values.len() { + 0 => JsValue::FreeVar(js_word!("undefined")), + 1 => values.into_iter().next().unwrap(), + _ => JsValue::alternatives(values), + }) + } +} + +impl VisitAstPath for Analyzer<'_> { + fn visit_assign_expr<'ast: 'r, 'r>( + &mut self, + n: &'ast AssignExpr, + ast_path: &mut AstNodePath>, + ) { + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::AssignExpr(n, AssignExprField::Left)); + + match n.op { + AssignOp::Assign => { + self.current_value = Some(self.eval_context.eval(&n.right)); + n.left.visit_children_with_path(self, &mut ast_path); + self.current_value = None; + } + + _ => { + if let Some(key) = n.left.as_ident() { + let value = match n.op { + AssignOp::AndAssign | AssignOp::OrAssign | AssignOp::NullishAssign => { + let right = self.eval_context.eval(&n.right); + // We can handle the right value as alternative to the existing + // value + Some(right) + } + AssignOp::AddAssign => { + let left = self.eval_context.eval(&Expr::Ident(key.clone())); + + let right = self.eval_context.eval(&n.right); + + Some(JsValue::add(vec![left, right])) + } + _ => Some(JsValue::unknown_empty(true, "unsupported assign operation")), + }; + if let Some(value) = value { + // We should visit this to handle `+=` like + // + // clientComponentLoadTimes += performance.now() - startTime + + self.current_value = Some(value); + n.left.visit_children_with_path(self, &mut ast_path); + self.current_value = None; + } + } + + if n.left.as_ident().is_none() { + n.left.visit_children_with_path(self, &mut ast_path); + } + } + } + } + + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::AssignExpr(n, AssignExprField::Right)); + self.visit_expr(&n.right, &mut ast_path); + } + } + + fn visit_update_expr<'ast: 'r, 'r>( + &mut self, + n: &'ast UpdateExpr, + ast_path: &mut AstNodePath>, + ) { + if let Some(key) = n.arg.as_ident() { + self.add_value( + key.to_id(), + JsValue::unknown_empty(true, "updated with update expression"), + ); + } + + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::UpdateExpr(n, UpdateExprField::Arg)); + self.visit_expr(&n.arg, &mut ast_path); + } + + fn visit_call_expr<'ast: 'r, 'r>( + &mut self, + n: &'ast CallExpr, + ast_path: &mut AstNodePath>, + ) { + // We handle `define(function (require) {})` here. + if let Callee::Expr(callee) = &n.callee { + if n.args.len() == 1 { + if let Some(require_var_id) = extract_var_from_umd_factory(callee, &n.args) { + self.add_value( + require_var_id, + JsValue::WellKnownFunction(WellKnownFunctionKind::Require), + ); + } + } + } + + // special behavior of IIFEs + if !self.check_iife(n, ast_path) { + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::CallExpr(n, CallExprField::Callee)); + n.callee.visit_with_path(self, &mut ast_path); + } + let args = n + .args + .iter() + .enumerate() + .map(|(i, arg)| { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::CallExpr(n, CallExprField::Args(i))); + if arg.spread.is_none() { + let value = self.eval_context.eval(&arg.expr); + + let block_path = match &*arg.expr { + Expr::Fn(FnExpr { .. }) => { + let mut path = as_parent_path(&ast_path); + path.push(AstParentKind::ExprOrSpread(ExprOrSpreadField::Expr)); + path.push(AstParentKind::Expr(ExprField::Fn)); + path.push(AstParentKind::FnExpr(FnExprField::Function)); + path.push(AstParentKind::Function(FunctionField::Body)); + Some(path) + } + Expr::Arrow(ArrowExpr { + body: box BlockStmtOrExpr::BlockStmt(_), + .. + }) => { + let mut path = as_parent_path(&ast_path); + path.push(AstParentKind::ExprOrSpread(ExprOrSpreadField::Expr)); + path.push(AstParentKind::Expr(ExprField::Arrow)); + path.push(AstParentKind::ArrowExpr(ArrowExprField::Body)); + path.push(AstParentKind::BlockStmtOrExpr( + BlockStmtOrExprField::BlockStmt, + )); + Some(path) + } + Expr::Arrow(ArrowExpr { + body: box BlockStmtOrExpr::Expr(_), + .. + }) => { + let mut path = as_parent_path(&ast_path); + path.push(AstParentKind::ExprOrSpread(ExprOrSpreadField::Expr)); + path.push(AstParentKind::Expr(ExprField::Arrow)); + path.push(AstParentKind::ArrowExpr(ArrowExprField::Body)); + path.push(AstParentKind::BlockStmtOrExpr( + BlockStmtOrExprField::Expr, + )); + Some(path) + } + _ => None, + }; + if let Some(path) = block_path { + let old_effects = take(&mut self.effects); + arg.visit_with_path(self, &mut ast_path); + let effects = replace(&mut self.effects, old_effects); + EffectArg::Closure( + value, + EffectsBlock { + effects, + ast_path: path, + }, + ) + } else { + arg.visit_with_path(self, &mut ast_path); + EffectArg::Value(value) + } + } else { + arg.visit_with_path(self, &mut ast_path); + EffectArg::Spread + } + }) + .collect(); + self.check_call_expr_for_effects(n, args, ast_path); + } + } + + fn visit_new_expr<'ast: 'r, 'r>( + &mut self, + new_expr: &'ast NewExpr, + ast_path: &mut AstNodePath>, + ) { + // new URL("path", import.meta.url) + if let box Expr::Ident(ref callee) = &new_expr.callee { + if &*callee.sym == "URL" && is_unresolved(callee, self.eval_context.unresolved_mark) { + if let Some(args) = &new_expr.args { + if args.len() == 2 { + if let Expr::Member(MemberExpr { + obj: + box Expr::MetaProp(MetaPropExpr { + kind: MetaPropKind::ImportMeta, + .. + }), + prop: MemberProp::Ident(prop), + .. + }) = &*args[1].expr + { + if &*prop.sym == "url" { + self.add_effect(Effect::Url { + input: self.eval_context.eval(&args[0].expr), + ast_path: as_parent_path(ast_path), + span: new_expr.span(), + in_try: is_in_try(ast_path), + }); + } + } + } + } + } + } + new_expr.visit_children_with_path(self, ast_path); + } + + fn visit_member_expr<'ast: 'r, 'r>( + &mut self, + member_expr: &'ast MemberExpr, + ast_path: &mut AstNodePath>, + ) { + self.check_member_expr_for_effects(member_expr, ast_path); + member_expr.visit_children_with_path(self, ast_path); + } + + fn visit_expr<'ast: 'r, 'r>( + &mut self, + n: &'ast Expr, + ast_path: &mut AstNodePath>, + ) { + let old = self.var_decl_kind; + self.var_decl_kind = None; + n.visit_children_with_path(self, ast_path); + self.var_decl_kind = old; + } + + fn visit_params<'ast: 'r, 'r>( + &mut self, + n: &'ast [Param], + ast_path: &mut AstNodePath>, + ) { + let value = self.current_value.take(); + for (index, p) in n.iter().enumerate() { + self.current_value = Some(JsValue::Argument(self.cur_fn_ident, index)); + let mut ast_path = ast_path.with_index_guard(index); + p.visit_with_path(self, &mut ast_path); + } + self.current_value = value; + } + + fn visit_param<'ast: 'r, 'r>( + &mut self, + n: &'ast Param, + ast_path: &mut AstNodePath>, + ) { + let old = self.var_decl_kind; + let Param { + decorators, + pat, + span: _, + } = n; + self.var_decl_kind = None; + let value = self.current_value.take(); + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::Param( + n, + ParamField::Decorators(usize::MAX), + )); + self.visit_decorators(decorators, &mut ast_path); + } + self.current_value = value; + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::Param(n, ParamField::Pat)); + self.visit_pat(pat, &mut ast_path); + } + self.current_value = None; + self.var_decl_kind = old; + } + + fn visit_fn_decl<'ast: 'r, 'r>( + &mut self, + decl: &'ast FnDecl, + ast_path: &mut AstNodePath>, + ) { + let old = replace( + &mut self.cur_fn_return_values, + Some(get_fn_init_return_vals(decl.function.body.as_ref())), + ); + let old_ident = self.cur_fn_ident; + self.cur_fn_ident = decl.function.span.lo.0; + decl.visit_children_with_path(self, ast_path); + let return_value = self.take_return_values(); + + self.add_value( + decl.ident.to_id(), + JsValue::function(self.cur_fn_ident, return_value), + ); + + self.cur_fn_ident = old_ident; + self.cur_fn_return_values = old; + } + + fn visit_fn_expr<'ast: 'r, 'r>( + &mut self, + expr: &'ast FnExpr, + ast_path: &mut AstNodePath>, + ) { + let old = replace( + &mut self.cur_fn_return_values, + Some(get_fn_init_return_vals(expr.function.body.as_ref())), + ); + let old_ident = self.cur_fn_ident; + self.cur_fn_ident = expr.function.span.lo.0; + expr.visit_children_with_path(self, ast_path); + let return_value = self.take_return_values(); + + if let Some(ident) = &expr.ident { + self.add_value( + ident.to_id(), + JsValue::function(self.cur_fn_ident, return_value), + ); + } else { + self.add_value( + ( + format!("*anonymous function {}*", expr.function.span.lo.0).into(), + SyntaxContext::empty(), + ), + JsValue::function(self.cur_fn_ident, return_value), + ); + } + + self.cur_fn_ident = old_ident; + self.cur_fn_return_values = old; + } + + fn visit_arrow_expr<'ast: 'r, 'r>( + &mut self, + expr: &'ast ArrowExpr, + ast_path: &mut AstNodePath>, + ) { + let old_return_values = replace( + &mut self.cur_fn_return_values, + expr.body + .as_block_stmt() + .map(|block| get_fn_init_return_vals(Some(block))), + ); + let old_ident = self.cur_fn_ident; + self.cur_fn_ident = expr.span.lo.0; + + let value = self.current_value.take(); + for (index, p) in expr.params.iter().enumerate() { + self.current_value = Some(JsValue::Argument(self.cur_fn_ident, index)); + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ArrowExpr( + expr, + ArrowExprField::Params(index), + )); + p.visit_with_path(self, &mut ast_path); + } + self.current_value = value; + + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::ArrowExpr(expr, ArrowExprField::Body)); + expr.body.visit_with_path(self, &mut ast_path); + } + + let return_value = match &*expr.body { + BlockStmtOrExpr::BlockStmt(_) => self.take_return_values(), + BlockStmtOrExpr::Expr(inner_expr) => Box::new(self.eval_context.eval(inner_expr)), + }; + + self.add_value( + ( + format!("*arrow function {}*", expr.span.lo.0).into(), + SyntaxContext::empty(), + ), + JsValue::function(self.cur_fn_ident, return_value), + ); + + self.cur_fn_ident = old_ident; + self.cur_fn_return_values = old_return_values; + } + + fn visit_class_decl<'ast: 'r, 'r>( + &mut self, + decl: &'ast ClassDecl, + ast_path: &mut AstNodePath>, + ) { + self.add_value_from_expr( + decl.ident.to_id(), + // TODO avoid clone + &Expr::Class(ClassExpr { + ident: Some(decl.ident.clone()), + class: decl.class.clone(), + }), + ); + decl.visit_children_with_path(self, ast_path); + } + + fn visit_var_decl<'ast: 'r, 'r>( + &mut self, + n: &'ast VarDecl, + ast_path: &mut AstNodePath>, + ) { + let old = self.var_decl_kind; + self.var_decl_kind = Some(n.kind); + n.visit_children_with_path(self, ast_path); + self.var_decl_kind = old; + } + + fn visit_var_declarator<'ast: 'r, 'r>( + &mut self, + n: &'ast VarDeclarator, + ast_path: &mut AstNodePath>, + ) { + if self.var_decl_kind.is_some() { + if let Some(init) = &n.init { + self.current_value = Some(self.eval_context.eval(init)); + } + } + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::VarDeclarator(n, VarDeclaratorField::Name)); + + self.visit_pat(&n.name, &mut ast_path); + } + self.current_value = None; + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::VarDeclarator(n, VarDeclaratorField::Init)); + + self.visit_opt_expr(n.init.as_ref(), &mut ast_path); + } + } + + fn visit_for_of_stmt<'ast: 'r, 'r>( + &mut self, + n: &'ast ForOfStmt, + ast_path: &mut swc_core::ecma::visit::AstNodePath<'r>, + ) { + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::ForOfStmt(n, ForOfStmtField::Right)); + self.current_value = None; + self.visit_expr(&n.right, &mut ast_path); + } + + let array = self.eval_context.eval(&n.right); + + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::ForOfStmt(n, ForOfStmtField::Left)); + self.current_value = Some(JsValue::iterated(array)); + self.visit_for_head(&n.left, &mut ast_path); + } + + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::ForOfStmt(n, ForOfStmtField::Body)); + + self.visit_stmt(&n.body, &mut ast_path); + } + + fn visit_simple_assign_target<'ast: 'r, 'r>( + &mut self, + n: &'ast SimpleAssignTarget, + ast_path: &mut swc_core::ecma::visit::AstNodePath<'r>, + ) { + let value = self.current_value.take(); + if let SimpleAssignTarget::Ident(i) = n { + n.visit_children_with_path(self, ast_path); + + self.add_value( + i.to_id(), + value.unwrap_or_else(|| { + JsValue::unknown(JsValue::Variable(i.to_id()), false, "pattern without value") + }), + ); + return; + } + + n.visit_children_with_path(self, ast_path); + } + + fn visit_pat<'ast: 'r, 'r>( + &mut self, + pat: &'ast Pat, + ast_path: &mut AstNodePath>, + ) { + let value = self.current_value.take(); + match pat { + Pat::Ident(i) => { + self.add_value( + i.to_id(), + value.unwrap_or_else(|| { + JsValue::unknown( + JsValue::Variable(i.to_id()), + false, + "pattern without value", + ) + }), + ); + } + + Pat::Array(arr) => { + match &value { + Some(JsValue::Array { items, .. }) => { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::Pat(pat, PatField::Array)); + for (idx, elem) in arr.elems.iter().enumerate() { + self.current_value = items.get(idx).cloned(); + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ArrayPat( + arr, + ArrayPatField::Elems(idx), + )); + elem.visit_with_path(self, &mut ast_path); + } + + // We should not call visit_children_with + return; + } + + Some(value) => { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::Pat(pat, PatField::Array)); + for (idx, elem) in arr.elems.iter().enumerate() { + self.current_value = Some(JsValue::member( + Box::new(value.clone()), + Box::new(JsValue::Constant(ConstantValue::Num(ConstantNumber( + idx as f64, + )))), + )); + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ArrayPat( + arr, + ArrayPatField::Elems(idx), + )); + elem.visit_with_path(self, &mut ast_path); + } + // We should not call visit_children_with + return; + } + + None => {} + } + } + + Pat::Object(obj) => { + let value = + value.unwrap_or_else(|| JsValue::unknown_empty(false, "pattern without value")); + + self.visit_pat_with_value(pat, obj, value, ast_path); + + // We should not call visit_children_with + return; + } + + _ => {} + } + pat.visit_children_with_path(self, ast_path); + } + + fn visit_return_stmt<'ast: 'r, 'r>( + &mut self, + stmt: &'ast ReturnStmt, + ast_path: &mut AstNodePath>, + ) { + stmt.visit_children_with_path(self, ast_path); + + if let Some(values) = &mut self.cur_fn_return_values { + let return_value = stmt + .arg + .as_deref() + .map(|e| self.eval_context.eval(e)) + .unwrap_or(JsValue::FreeVar(js_word!("undefined"))); + + values.push(return_value); + } + } + + fn visit_ident<'ast: 'r, 'r>( + &mut self, + ident: &'ast Ident, + ast_path: &mut AstNodePath>, + ) { + if !(matches!( + ast_path.last(), + Some(AstParentNodeRef::Expr(_, ExprField::Ident)) + | Some(AstParentNodeRef::Prop(_, PropField::Shorthand)) + ) || matches!( + ast_path.get(ast_path.len() - 2), + Some(AstParentNodeRef::SimpleAssignTarget( + _, + SimpleAssignTargetField::Ident, + )) + )) { + return; + } + + if let Some((esm_reference_index, export)) = + self.eval_context.imports.get_binding(&ident.to_id()) + { + self.add_effect(Effect::ImportedBinding { + esm_reference_index, + export, + ast_path: as_parent_path(ast_path), + span: ident.span(), + in_try: is_in_try(ast_path), + }) + } else if is_unresolved(ident, self.eval_context.unresolved_mark) { + self.add_effect(Effect::FreeVar { + var: JsValue::FreeVar(ident.sym.clone()), + ast_path: as_parent_path(ast_path), + span: ident.span(), + in_try: is_in_try(ast_path), + }) + } + } + + fn visit_meta_prop_expr<'ast: 'r, 'r>( + &mut self, + expr: &'ast MetaPropExpr, + ast_path: &mut AstNodePath>, + ) { + if expr.kind == MetaPropKind::ImportMeta { + // MetaPropExpr also covers `new.target`. Only consider `import.meta` + // an effect. + self.add_effect(Effect::ImportMeta { + span: expr.span, + ast_path: as_parent_path(ast_path), + in_try: is_in_try(ast_path), + }) + } + } + + fn visit_program<'ast: 'r, 'r>( + &mut self, + program: &'ast Program, + ast_path: &mut AstNodePath>, + ) { + self.effects = take(&mut self.data.effects); + program.visit_children_with_path(self, ast_path); + self.data.effects = take(&mut self.effects); + } + + fn visit_cond_expr<'ast: 'r, 'r>( + &mut self, + expr: &'ast CondExpr, + ast_path: &mut AstNodePath>, + ) { + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::CondExpr(expr, CondExprField::Test)); + expr.test.visit_with_path(self, &mut ast_path); + } + + let prev_effects = take(&mut self.effects); + let then = { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::CondExpr(expr, CondExprField::Cons)); + expr.cons.visit_with_path(self, &mut ast_path); + EffectsBlock { + effects: take(&mut self.effects), + ast_path: as_parent_path(&ast_path), + } + }; + let r#else = { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::CondExpr(expr, CondExprField::Alt)); + expr.alt.visit_with_path(self, &mut ast_path); + EffectsBlock { + effects: take(&mut self.effects), + ast_path: as_parent_path(&ast_path), + } + }; + self.effects = prev_effects; + + self.add_conditional_effect( + &expr.test, + ast_path, + AstParentKind::CondExpr(CondExprField::Test), + expr.span(), + ConditionalKind::Ternary { then, r#else }, + ); + } + + fn visit_if_stmt<'ast: 'r, 'r>( + &mut self, + stmt: &'ast IfStmt, + ast_path: &mut AstNodePath>, + ) { + { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::IfStmt(stmt, IfStmtField::Test)); + stmt.test.visit_with_path(self, &mut ast_path); + } + let prev_effects = take(&mut self.effects); + let then = { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::IfStmt(stmt, IfStmtField::Cons)); + stmt.cons.visit_with_path(self, &mut ast_path); + EffectsBlock { + effects: take(&mut self.effects), + ast_path: as_parent_path(&ast_path), + } + }; + let r#else = stmt + .alt + .as_ref() + .map(|alt| { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::IfStmt(stmt, IfStmtField::Alt)); + alt.visit_with_path(self, &mut ast_path); + EffectsBlock { + effects: take(&mut self.effects), + ast_path: as_parent_path(&ast_path), + } + }) + .unwrap_or_default(); + self.effects = prev_effects; + match (!then.is_empty(), !r#else.is_empty()) { + (true, false) => { + self.add_conditional_effect( + &stmt.test, + ast_path, + AstParentKind::IfStmt(IfStmtField::Test), + stmt.span(), + ConditionalKind::If { then }, + ); + } + (_, true) => { + self.add_conditional_effect( + &stmt.test, + ast_path, + AstParentKind::IfStmt(IfStmtField::Test), + stmt.span(), + ConditionalKind::IfElse { then, r#else }, + ); + } + (false, false) => { + // no effects, can be ignored + } + } + } +} + +impl<'a> Analyzer<'a> { + fn add_conditional_effect( + &mut self, + test: &Expr, + ast_path: &AstNodePath>, + ast_kind: AstParentKind, + span: Span, + mut cond_kind: ConditionalKind, + ) { + let condition = self.eval_context.eval(test); + if condition.is_unknown() { + match &mut cond_kind { + ConditionalKind::If { then } => { + self.effects.append(&mut then.effects); + } + ConditionalKind::IfElse { then, r#else } + | ConditionalKind::Ternary { then, r#else } => { + self.effects.append(&mut then.effects); + self.effects.append(&mut r#else.effects); + } + ConditionalKind::And { expr } + | ConditionalKind::Or { expr } + | ConditionalKind::NullishCoalescing { expr } => { + self.effects.append(&mut expr.effects); + } + } + } else { + self.add_effect(Effect::Conditional { + condition, + kind: Box::new(cond_kind), + ast_path: as_parent_path_with(ast_path, ast_kind), + span, + in_try: is_in_try(ast_path), + }); + } + } + + fn visit_pat_with_value<'ast: 'r, 'r>( + &mut self, + pat: &'ast Pat, + obj: &'ast ObjectPat, + current_value: JsValue, + ast_path: &mut AstNodePath>, + ) { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::Pat(pat, PatField::Object)); + for (i, prop) in obj.props.iter().enumerate() { + let mut ast_path = + ast_path.with_guard(AstParentNodeRef::ObjectPat(obj, ObjectPatField::Props(i))); + match prop { + ObjectPatProp::KeyValue(kv) => { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ObjectPatProp( + prop, + ObjectPatPropField::KeyValue, + )); + let KeyValuePatProp { key, value } = kv; + let key_value = self.eval_context.eval_prop_name(key); + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::KeyValuePatProp( + kv, + KeyValuePatPropField::Key, + )); + key.visit_with_path(self, &mut ast_path); + } + self.current_value = Some(JsValue::member( + Box::new(current_value.clone()), + Box::new(key_value), + )); + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::KeyValuePatProp( + kv, + KeyValuePatPropField::Value, + )); + value.visit_with_path(self, &mut ast_path); + } + } + ObjectPatProp::Assign(assign) => { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::ObjectPatProp( + prop, + ObjectPatPropField::Assign, + )); + let AssignPatProp { key, value, .. } = assign; + let key_value = key.sym.clone().into(); + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::AssignPatProp( + assign, + AssignPatPropField::Key, + )); + key.visit_with_path(self, &mut ast_path); + } + self.add_value( + key.to_id(), + if let Some(box value) = value { + let value = self.eval_context.eval(value); + JsValue::alternatives(vec![ + JsValue::member( + Box::new(current_value.clone()), + Box::new(key_value), + ), + value, + ]) + } else { + JsValue::member(Box::new(current_value.clone()), Box::new(key_value)) + }, + ); + { + let mut ast_path = ast_path.with_guard(AstParentNodeRef::AssignPatProp( + assign, + AssignPatPropField::Value, + )); + value.visit_with_path(self, &mut ast_path); + } + } + + _ => prop.visit_with_path(self, &mut ast_path), + } + } + } +} + +fn extract_var_from_umd_factory(callee: &Expr, args: &[ExprOrSpread]) -> Option { + match unparen(callee) { + Expr::Ident(Ident { sym, .. }) => { + if &**sym == "define" { + if let Expr::Fn(FnExpr { function, .. }) = &*args[0].expr { + let params = &*function.params; + if params.len() == 1 { + if let Pat::Ident(param) = ¶ms[0].pat { + if &*param.id.sym == "require" { + return Some(param.to_id()); + } + } + } + } + } + } + + // umd may use (function (factory){ + // // Somewhere, define(['require', 'exports'], factory) + // }(function (require, exports){})) + // + // In all module system which has `require`, `require` in the factory function can be + // treated as a well-known require. + Expr::Fn(FnExpr { function, .. }) => { + let params = &*function.params; + if params.len() == 1 { + if let Some(FnExpr { function, .. }) = + args.first().and_then(|arg| arg.expr.as_fn_expr()) + { + let params = &*function.params; + if !params.is_empty() { + if let Pat::Ident(param) = ¶ms[0].pat { + if &*param.id.sym == "require" { + return Some(param.to_id()); + } + } + } + } + } + } + + _ => {} + } + + None +} + +fn get_fn_init_return_vals(fn_body_stmts: Option<&BlockStmt>) -> Vec { + let has_final_return_val = match fn_body_stmts { + Some(fn_body_stmts) => { + matches!( + fn_body_stmts.stmts.last(), + Some(Stmt::Return(ReturnStmt { arg: Some(_), .. })) + ) + } + None => false, + }; + + if has_final_return_val { + vec![] + } else { + vec![JsValue::Constant(ConstantValue::Undefined)] + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/imports.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/imports.rs new file mode 100644 index 0000000000000..e9d797cc62349 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/imports.rs @@ -0,0 +1,458 @@ +use std::{collections::BTreeMap, fmt::Display}; + +use indexmap::{IndexMap, IndexSet}; +use once_cell::sync::Lazy; +use swc_core::{ + common::{source_map::Pos, Span}, + ecma::{ + ast::*, + atoms::{js_word, JsWord}, + visit::{Visit, VisitWith}, + }, +}; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::{issue::IssueSource, source::Source}; + +use super::{top_level_await::has_top_level_await, JsValue, ModuleValue}; +use crate::tree_shake::{find_turbopack_part_id_in_asserts, PartId}; + +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Default, Debug, Clone, Hash)] +pub struct ImportAnnotations { + // TODO store this in more structured way + #[turbo_tasks(trace_ignore)] + map: BTreeMap, +} + +/// Enables a specified transition for the annotated import +static ANNOTATION_TRANSITION: Lazy = + Lazy::new(|| crate::annotations::ANNOTATION_TRANSITION.into()); + +/// Changes the chunking type for the annotated import +static ANNOTATION_CHUNKING_TYPE: Lazy = + Lazy::new(|| crate::annotations::ANNOTATION_CHUNKING_TYPE.into()); + +/// Changes the type of the resolved module (only "json" is supported currently) +static ATTRIBUTE_MODULE_TYPE: Lazy = Lazy::new(|| "type".into()); + +impl ImportAnnotations { + pub fn parse(with: Option<&ObjectLit>) -> ImportAnnotations { + let Some(with) = with else { + return ImportAnnotations::default(); + }; + + let mut map = BTreeMap::new(); + + // The `with` clause is way more restrictive than `ObjectLit`, it only allows + // string -> value and value can only be a string. + // We just ignore everything else here till the SWC ast is more restrictive. + for (key, value) in with.props.iter().filter_map(|prop| { + let kv = prop.as_prop()?.as_key_value()?; + + let Lit::Str(str) = kv.value.as_lit()? else { + return None; + }; + + Some((&kv.key, str)) + }) { + let key = match key { + PropName::Ident(ident) => ident.sym.as_str(), + PropName::Str(str) => str.value.as_str(), + // the rest are invalid, ignore for now till SWC ast is correct + _ => continue, + }; + + map.insert(key.into(), value.value.as_str().into()); + } + + ImportAnnotations { map } + } + + /// Returns the content on the transition annotation + pub fn transition(&self) -> Option<&str> { + self.get(&ANNOTATION_TRANSITION) + } + + /// Returns the content on the chunking-type annotation + pub fn chunking_type(&self) -> Option<&str> { + self.get(&ANNOTATION_CHUNKING_TYPE) + } + + /// Returns the content on the type attribute + pub fn module_type(&self) -> Option<&str> { + self.get(&ATTRIBUTE_MODULE_TYPE) + } + + pub fn get(&self, key: &JsWord) -> Option<&str> { + self.map.get(key).map(|w| w.as_str()) + } +} + +impl Display for ImportAnnotations { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let mut it = self.map.iter(); + if let Some((k, v)) = it.next() { + write!(f, "{{ {k}: {v}")? + } else { + return f.write_str("{}"); + }; + for (k, v) in it { + write!(f, ", {k}: {v}")? + } + f.write_str(" }") + } +} + +#[derive(Debug)] +pub(crate) enum Reexport { + Star, + Namespace { exported: JsWord }, + Named { imported: JsWord, exported: JsWord }, +} + +/// The storage for all kinds of imports. +/// +/// Note that when it's initialized by calling `analyze`, it only contains ESM +/// import/exports. +#[derive(Default, Debug)] +pub(crate) struct ImportMap { + /// Map from identifier to (index in references, exported symbol) + imports: IndexMap, + + /// Map from identifier to index in references + namespace_imports: IndexMap, + + /// List of (index in references, imported symbol, exported symbol) + reexports: Vec<(usize, Reexport)>, + + /// Ordered list of imported symbols + references: IndexSet, + + /// True, when the module has exports + has_exports: bool, + + /// True if the module is an ESM module due to top-level await. + has_top_level_await: bool, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) enum ImportedSymbol { + ModuleEvaluation, + Symbol(JsWord), + Exports, + Part(u32), +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) struct ImportMapReference { + pub module_path: JsWord, + pub imported_symbol: ImportedSymbol, + pub annotations: ImportAnnotations, + pub issue_source: Option>, +} + +impl ImportMap { + pub fn is_esm(&self) -> bool { + self.has_exports + || self.has_top_level_await + || !self.imports.is_empty() + || !self.namespace_imports.is_empty() + } + + pub fn get_import(&self, id: &Id) -> Option { + if let Some((i, i_sym)) = self.imports.get(id) { + let r = &self.references[*i]; + return Some(JsValue::member( + Box::new(JsValue::Module(ModuleValue { + module: r.module_path.clone(), + annotations: r.annotations.clone(), + })), + Box::new(i_sym.clone().into()), + )); + } + if let Some(i) = self.namespace_imports.get(id) { + let r = &self.references[*i]; + return Some(JsValue::Module(ModuleValue { + module: r.module_path.clone(), + annotations: r.annotations.clone(), + })); + } + None + } + + // TODO this could return &str instead of String to avoid cloning + pub fn get_binding(&self, id: &Id) -> Option<(usize, Option)> { + if let Some((i, i_sym)) = self.imports.get(id) { + return Some((*i, Some(i_sym.as_str().into()))); + } + if let Some(i) = self.namespace_imports.get(id) { + return Some((*i, None)); + } + None + } + + pub fn references(&self) -> impl Iterator { + self.references.iter() + } + + pub fn reexports(&self) -> impl Iterator { + self.reexports.iter().map(|(i, r)| (*i, r)) + } + + /// Analyze ES import + pub(super) fn analyze(m: &Program, source: Option>>) -> Self { + let mut data = ImportMap::default(); + + m.visit_with(&mut Analyzer { + data: &mut data, + source, + }); + + data + } +} + +struct Analyzer<'a> { + data: &'a mut ImportMap, + source: Option>>, +} + +impl<'a> Analyzer<'a> { + fn ensure_reference( + &mut self, + span: Span, + module_path: JsWord, + imported_symbol: ImportedSymbol, + annotations: ImportAnnotations, + ) -> Option { + let issue_source = self + .source + .map(|s| IssueSource::from_swc_offsets(s, span.lo.to_usize(), span.hi.to_usize())); + + let r = ImportMapReference { + module_path, + imported_symbol, + issue_source, + annotations, + }; + if let Some(i) = self.data.references.get_index_of(&r) { + Some(i) + } else { + let i = self.data.references.len(); + self.data.references.insert(r); + Some(i) + } + } +} + +fn to_word(name: &ModuleExportName) -> JsWord { + match name { + ModuleExportName::Ident(ident) => ident.sym.clone(), + ModuleExportName::Str(str) => str.value.clone(), + } +} + +impl Visit for Analyzer<'_> { + fn visit_import_decl(&mut self, import: &ImportDecl) { + let annotations = ImportAnnotations::parse(import.with.as_deref()); + + let internal_symbol = parse_with(import.with.as_deref()); + + if internal_symbol.is_none() { + self.ensure_reference( + import.span, + import.src.value.clone(), + ImportedSymbol::ModuleEvaluation, + annotations.clone(), + ); + } + + for s in &import.specifiers { + let symbol = internal_symbol + .clone() + .unwrap_or_else(|| get_import_symbol_from_import(s)); + let i = self.ensure_reference( + import.span, + import.src.value.clone(), + symbol, + annotations.clone(), + ); + let i = match i { + Some(v) => v, + None => continue, + }; + + let (local, orig_sym) = match s { + ImportSpecifier::Named(ImportNamedSpecifier { + local, imported, .. + }) => match imported { + Some(imported) => (local.to_id(), orig_name(imported)), + _ => (local.to_id(), local.sym.clone()), + }, + ImportSpecifier::Default(s) => (s.local.to_id(), "default".into()), + ImportSpecifier::Namespace(s) => { + self.data.namespace_imports.insert(s.local.to_id(), i); + continue; + } + }; + + self.data.imports.insert(local, (i, orig_sym)); + } + + if import.specifiers.is_empty() { + if let Some(internal_symbol) = internal_symbol { + self.ensure_reference( + import.span, + import.src.value.clone(), + internal_symbol, + annotations, + ); + } + } + } + + fn visit_export_all(&mut self, export: &ExportAll) { + self.data.has_exports = true; + + let annotations = ImportAnnotations::parse(export.with.as_deref()); + + self.ensure_reference( + export.span, + export.src.value.clone(), + ImportedSymbol::ModuleEvaluation, + annotations.clone(), + ); + let symbol = parse_with(export.with.as_deref()); + + let i = self.ensure_reference( + export.span, + export.src.value.clone(), + symbol.unwrap_or(ImportedSymbol::Exports), + annotations, + ); + if let Some(i) = i { + self.data.reexports.push((i, Reexport::Star)); + } + } + + fn visit_named_export(&mut self, export: &NamedExport) { + self.data.has_exports = true; + + let Some(ref src) = export.src else { + return; + }; + + let annotations = ImportAnnotations::parse(export.with.as_deref()); + + let internal_symbol = parse_with(export.with.as_deref()); + + if internal_symbol.is_none() || export.specifiers.is_empty() { + self.ensure_reference( + export.span, + src.value.clone(), + ImportedSymbol::ModuleEvaluation, + annotations.clone(), + ); + } + + for spec in export.specifiers.iter() { + let symbol = internal_symbol + .clone() + .unwrap_or_else(|| get_import_symbol_from_export(spec)); + + let i = + self.ensure_reference(export.span, src.value.clone(), symbol, annotations.clone()); + let i = match i { + Some(v) => v, + None => continue, + }; + + match spec { + ExportSpecifier::Namespace(n) => { + self.data.reexports.push(( + i, + Reexport::Namespace { + exported: to_word(&n.name), + }, + )); + } + ExportSpecifier::Default(d) => { + self.data.reexports.push(( + i, + Reexport::Named { + imported: js_word!("default"), + exported: d.exported.sym.clone(), + }, + )); + } + ExportSpecifier::Named(n) => { + self.data.reexports.push(( + i, + Reexport::Named { + imported: to_word(&n.orig), + exported: to_word(n.exported.as_ref().unwrap_or(&n.orig)), + }, + )); + } + } + } + } + + fn visit_export_decl(&mut self, _: &ExportDecl) { + self.data.has_exports = true; + } + fn visit_export_default_decl(&mut self, _: &ExportDefaultDecl) { + self.data.has_exports = true; + } + fn visit_export_default_expr(&mut self, _: &ExportDefaultExpr) { + self.data.has_exports = true; + } + fn visit_stmt(&mut self, _: &Stmt) { + // don't visit children + } + + fn visit_program(&mut self, m: &Program) { + self.data.has_top_level_await = has_top_level_await(m).is_some(); + + m.visit_children_with(self); + } +} + +pub(crate) fn orig_name(n: &ModuleExportName) -> JsWord { + match n { + ModuleExportName::Ident(v) => v.sym.clone(), + ModuleExportName::Str(v) => v.value.clone(), + } +} + +fn parse_with(with: Option<&ObjectLit>) -> Option { + find_turbopack_part_id_in_asserts(with?).map(|v| match v { + PartId::Internal(index) => ImportedSymbol::Part(index), + PartId::ModuleEvaluation => ImportedSymbol::ModuleEvaluation, + PartId::Export(e) => ImportedSymbol::Symbol(e.as_str().into()), + PartId::Exports => ImportedSymbol::Exports, + }) +} + +fn get_import_symbol_from_import(specifier: &ImportSpecifier) -> ImportedSymbol { + match specifier { + ImportSpecifier::Named(ImportNamedSpecifier { + local, imported, .. + }) => ImportedSymbol::Symbol(match imported { + Some(imported) => orig_name(imported), + _ => local.sym.clone(), + }), + ImportSpecifier::Default(..) => ImportedSymbol::Symbol(js_word!("default")), + ImportSpecifier::Namespace(..) => ImportedSymbol::Exports, + } +} + +fn get_import_symbol_from_export(specifier: &ExportSpecifier) -> ImportedSymbol { + match specifier { + ExportSpecifier::Named(ExportNamedSpecifier { orig, .. }) => { + ImportedSymbol::Symbol(orig_name(orig)) + } + ExportSpecifier::Default(..) => ImportedSymbol::Symbol(js_word!("default")), + ExportSpecifier::Namespace(..) => ImportedSymbol::Exports, + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/linker.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/linker.rs new file mode 100644 index 0000000000000..b48329d5d158f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/linker.rs @@ -0,0 +1,343 @@ +use std::{ + collections::{hash_map::Entry, HashMap, HashSet}, + future::Future, + mem::take, +}; + +use anyhow::Result; +use swc_core::ecma::ast::Id; + +use super::{graph::VarGraph, JsValue}; + +pub async fn link<'a, B, RB, F, RF>( + graph: &VarGraph, + mut val: JsValue, + early_visitor: &B, + visitor: &F, + fun_args_values: HashMap>, +) -> Result +where + RB: 'a + Future> + Send, + B: 'a + Fn(JsValue) -> RB + Sync, + RF: 'a + Future> + Send, + F: 'a + Fn(JsValue) -> RF + Sync, +{ + val.normalize(); + let val = link_internal_iterative(graph, val, early_visitor, visitor, fun_args_values).await?; + Ok(val) +} + +const LIMIT_NODE_SIZE: usize = 300; +const LIMIT_IN_PROGRESS_NODES: usize = 1000; +const LIMIT_LINK_STEPS: usize = 1500; + +pub(crate) async fn link_internal_iterative<'a, B, RB, F, RF>( + graph: &'a VarGraph, + val: JsValue, + early_visitor: &'a B, + visitor: &'a F, + mut fun_args_values: HashMap>, +) -> Result +where + RB: 'a + Future> + Send, + B: 'a + Fn(JsValue) -> RB + Sync, + RF: 'a + Future> + Send, + F: 'a + Fn(JsValue) -> RF + Sync, +{ + #[derive(Debug)] + enum Step { + Enter(JsValue), + EarlyVisit(JsValue), + Leave(JsValue), + LeaveVar(Id), + LeaveLate(JsValue), + Visit(JsValue), + LeaveCall(u32), + } + + let mut work_queue_stack: Vec = Vec::new(); + let mut done: Vec = Vec::new(); + // Tracks the number of nodes in the queue and done combined + let mut total_nodes = 0; + let mut cycle_stack: HashSet = HashSet::new(); + // Tracks the number linking steps so far + let mut steps = 0; + + total_nodes += val.total_nodes(); + work_queue_stack.push(Step::Enter(val)); + + while let Some(step) = work_queue_stack.pop() { + steps += 1; + + match step { + // Enter a variable + // - replace it with value from graph + // - process value + // - on leave: cache value + Step::Enter(JsValue::Variable(var)) => { + // Replace with unknown for now + if cycle_stack.contains(&var) { + done.push(JsValue::unknown( + JsValue::Variable(var.clone()), + false, + "circular variable reference", + )); + } else { + total_nodes -= 1; + if let Some(val) = graph.values.get(&var) { + cycle_stack.insert(var.clone()); + work_queue_stack.push(Step::LeaveVar(var)); + total_nodes += val.total_nodes(); + work_queue_stack.push(Step::Enter(val.clone())); + } else { + total_nodes += 1; + done.push(JsValue::unknown( + JsValue::Variable(var.clone()), + false, + "no value of this variable analysed", + )); + }; + } + } + // Leave a variable + Step::LeaveVar(var) => { + cycle_stack.remove(&var); + } + // Enter a function argument + // We want to replace the argument with the value from the function call + Step::Enter(JsValue::Argument(func_ident, index)) => { + total_nodes -= 1; + if let Some(args) = fun_args_values.get(&func_ident) { + if let Some(val) = args.get(index) { + total_nodes += val.total_nodes(); + done.push(val.clone()); + } else { + total_nodes += 1; + done.push(JsValue::unknown_empty( + false, + "unknown function argument (out of bounds)", + )); + } + } else { + total_nodes += 1; + done.push(JsValue::unknown( + JsValue::Argument(func_ident, index), + false, + "function calls are not analysed yet", + )); + } + } + // Visit a function call + // This need special handling, since we want to replace the function call and process + // the function return value after that. + Step::Visit(JsValue::Call( + _, + box JsValue::Function(_, func_ident, return_value), + args, + )) => { + total_nodes -= 2; // Call + Function + if let Entry::Vacant(entry) = fun_args_values.entry(func_ident) { + // Return value will stay in total_nodes + for arg in args.iter() { + total_nodes -= arg.total_nodes(); + } + entry.insert(args); + work_queue_stack.push(Step::LeaveCall(func_ident)); + work_queue_stack.push(Step::Enter(*return_value)); + } else { + total_nodes -= return_value.total_nodes(); + for arg in args.iter() { + total_nodes -= arg.total_nodes(); + } + total_nodes += 1; + done.push(JsValue::unknown( + JsValue::call(Box::new(JsValue::function(func_ident, return_value)), args), + true, + "recursive function call", + )); + } + } + // Leaving a function call evaluation + // - remove function arguments from the map + Step::LeaveCall(func_ident) => { + fun_args_values.remove(&func_ident); + } + // Enter a function + // We don't want to process the function return value yet, this will happen after + // function calls + // - just put it into done + Step::Enter(func @ JsValue::Function(..)) => { + done.push(func); + } + // Enter a value + // - take and queue children for processing + // - on leave: insert children again and optimize + Step::Enter(mut val) => { + let i = work_queue_stack.len(); + work_queue_stack.push(Step::Leave(JsValue::default())); + let mut has_early_children = false; + val.for_each_early_children_mut(&mut |child| { + has_early_children = true; + work_queue_stack.push(Step::Enter(take(child))); + false + }); + if has_early_children { + work_queue_stack[i] = Step::EarlyVisit(val); + } else { + val.for_each_children_mut(&mut |child| { + work_queue_stack.push(Step::Enter(take(child))); + false + }); + work_queue_stack[i] = Step::Leave(val); + } + } + // Early visit a value + // - reconstruct the value from early children + // - visit the value + // - insert late children and process for Leave + Step::EarlyVisit(mut val) => { + val.for_each_early_children_mut(&mut |child| { + let val = done.pop().unwrap(); + *child = val; + true + }); + val.debug_assert_total_nodes_up_to_date(); + total_nodes -= val.total_nodes(); + if val.total_nodes() > LIMIT_NODE_SIZE { + total_nodes += 1; + done.push(JsValue::unknown_empty(true, "node limit reached")); + continue; + } + + let (mut val, visit_modified) = early_visitor(val).await?; + val.debug_assert_total_nodes_up_to_date(); + if visit_modified && val.total_nodes() > LIMIT_NODE_SIZE { + total_nodes += 1; + done.push(JsValue::unknown_empty(true, "node limit reached")); + continue; + } + + let count = val.total_nodes(); + if total_nodes + count > LIMIT_IN_PROGRESS_NODES { + // There is always space for one more node since we just popped at least one + // count + total_nodes += 1; + done.push(JsValue::unknown_empty( + true, + "in progress nodes limit reached", + )); + continue; + } + total_nodes += count; + + if visit_modified { + // When the early visitor has changed the value, we need to enter it again + work_queue_stack.push(Step::Enter(val)); + } else { + // Otherwise we can just process the late children + let i = work_queue_stack.len(); + work_queue_stack.push(Step::LeaveLate(JsValue::default())); + val.for_each_late_children_mut(&mut |child| { + work_queue_stack.push(Step::Enter(take(child))); + false + }); + work_queue_stack[i] = Step::LeaveLate(val); + } + } + // Leave a value + Step::Leave(mut val) => { + val.for_each_children_mut(&mut |child| { + let val = done.pop().unwrap(); + *child = val; + true + }); + val.debug_assert_total_nodes_up_to_date(); + + total_nodes -= val.total_nodes(); + + if val.total_nodes() > LIMIT_NODE_SIZE { + total_nodes += 1; + done.push(JsValue::unknown_empty(true, "node limit reached")); + continue; + } + val.normalize_shallow(); + + val.debug_assert_total_nodes_up_to_date(); + + total_nodes += val.total_nodes(); + work_queue_stack.push(Step::Visit(val)); + } + // Leave a value from EarlyVisit + Step::LeaveLate(mut val) => { + val.for_each_late_children_mut(&mut |child| { + let val = done.pop().unwrap(); + *child = val; + true + }); + val.debug_assert_total_nodes_up_to_date(); + + total_nodes -= val.total_nodes(); + + if val.total_nodes() > LIMIT_NODE_SIZE { + total_nodes += 1; + done.push(JsValue::unknown_empty(true, "node limit reached")); + continue; + } + val.normalize_shallow(); + + val.debug_assert_total_nodes_up_to_date(); + + total_nodes += val.total_nodes(); + work_queue_stack.push(Step::Visit(val)); + } + // Visit a value with the visitor + // - visited value is put into done + Step::Visit(val) => { + total_nodes -= val.total_nodes(); + + let (mut val, visit_modified) = visitor(val).await?; + if visit_modified { + val.normalize_shallow(); + #[cfg(debug_assertions)] + val.debug_assert_total_nodes_up_to_date(); + if val.total_nodes() > LIMIT_NODE_SIZE { + total_nodes += 1; + done.push(JsValue::unknown_empty(true, "node limit reached")); + continue; + } + } + + let count = val.total_nodes(); + if total_nodes + count > LIMIT_IN_PROGRESS_NODES { + // There is always space for one more node since we just popped at least one + // count + total_nodes += 1; + done.push(JsValue::unknown_empty( + true, + "in progress nodes limit reached", + )); + continue; + } + total_nodes += count; + if visit_modified { + work_queue_stack.push(Step::Enter(val)); + } else { + done.push(val); + } + } + } + if steps > LIMIT_LINK_STEPS { + return Ok(JsValue::unknown_empty( + true, + "max number of linking steps reached", + )); + } + } + + let final_value = done.pop().unwrap(); + + debug_assert!(work_queue_stack.is_empty()); + debug_assert_eq!(total_nodes, final_value.total_nodes()); + + Ok(final_value) +} diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs new file mode 100644 index 0000000000000..d397d1873a2c3 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs @@ -0,0 +1,3842 @@ +#![allow(clippy::redundant_closure_call)] + +use std::{ + borrow::Cow, + cmp::Ordering, + fmt::{Display, Write}, + future::Future, + hash::{Hash, Hasher}, + mem::take, + pin::Pin, + sync::Arc, +}; + +use anyhow::{bail, Context, Result}; +use indexmap::{IndexMap, IndexSet}; +use num_bigint::BigInt; +use num_traits::identities::Zero; +use once_cell::sync::Lazy; +use regex::Regex; +use swc_core::{ + common::Mark, + ecma::{ + ast::{Id, Ident, Lit}, + atoms::{Atom, JsWord}, + }, +}; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::compile_time_info::CompileTimeDefineValue; +use url::Url; + +use self::imports::ImportAnnotations; +pub(crate) use self::imports::ImportMap; +use crate::{references::require_context::RequireContextMap, utils::StringifyJs}; + +pub mod builtin; +pub mod graph; +pub mod imports; +pub mod linker; +pub mod top_level_await; +pub mod well_known; + +type PinnedAsyncUntilSettledBox<'a, E> = + Pin> + Send + 'a>>; + +type PinnedAsyncBox<'a, E> = Pin> + 'a>>; + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum ObjectPart { + KeyValue(JsValue, JsValue), + Spread(JsValue), +} + +impl Default for ObjectPart { + fn default() -> Self { + ObjectPart::Spread(Default::default()) + } +} + +#[derive(Debug, Clone)] +pub struct ConstantNumber(pub f64); + +fn integer_decode(val: f64) -> (u64, i16, i8) { + let bits: u64 = val.to_bits(); + let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; + let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; + let mantissa = if exponent == 0 { + (bits & 0xfffffffffffff) << 1 + } else { + (bits & 0xfffffffffffff) | 0x10000000000000 + }; + + exponent -= 1023 + 52; + (mantissa, exponent, sign) +} + +impl ConstantNumber { + pub fn as_u32_index(&self) -> Option { + let index: u32 = self.0 as u32; + (index as f64 == self.0).then_some(index as usize) + } +} + +impl Hash for ConstantNumber { + fn hash(&self, state: &mut H) { + integer_decode(self.0).hash(state); + } +} + +impl PartialEq for ConstantNumber { + fn eq(&self, other: &Self) -> bool { + integer_decode(self.0) == integer_decode(other.0) + } +} + +impl Eq for ConstantNumber {} + +#[derive(Debug, Clone)] +pub enum ConstantString { + Word(JsWord), + Atom(Atom), + RcStr(RcStr), +} + +impl ConstantString { + pub fn as_str(&self) -> &str { + match self { + Self::Word(s) => s, + Self::Atom(s) => s, + Self::RcStr(s) => s, + } + } + + pub fn is_empty(&self) -> bool { + self.as_str().is_empty() + } +} + +impl PartialEq for ConstantString { + fn eq(&self, other: &Self) -> bool { + self.as_str() == other.as_str() + } +} + +impl Eq for ConstantString {} + +impl Hash for ConstantString { + fn hash(&self, state: &mut H) { + self.as_str().hash(state); + } +} + +impl Display for ConstantString { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.as_str().fmt(f) + } +} + +impl From for ConstantString { + fn from(v: Atom) -> Self { + ConstantString::Atom(v) + } +} + +impl From<&'static str> for ConstantString { + fn from(v: &'static str) -> Self { + ConstantString::Word(v.into()) + } +} + +impl From for ConstantString { + fn from(v: String) -> Self { + ConstantString::Atom(v.into()) + } +} + +impl From for ConstantString { + fn from(v: RcStr) -> Self { + ConstantString::RcStr(v) + } +} + +#[derive(Debug, Clone, Hash, PartialEq, Eq, Default)] +pub enum ConstantValue { + #[default] + Undefined, + Str(ConstantString), + Num(ConstantNumber), + True, + False, + Null, + BigInt(BigInt), + Regex(Atom, Atom), +} + +impl ConstantValue { + pub fn as_str(&self) -> Option<&str> { + match self { + Self::Str(s) => Some(s.as_str()), + _ => None, + } + } + + pub fn as_bool(&self) -> Option { + match self { + Self::True => Some(true), + Self::False => Some(false), + _ => None, + } + } + + pub fn is_truthy(&self) -> bool { + match self { + Self::Undefined | Self::False | Self::Null => false, + Self::True | Self::Regex(..) => true, + Self::Str(s) => !s.is_empty(), + Self::Num(ConstantNumber(n)) => *n != 0.0, + Self::BigInt(n) => !n.is_zero(), + } + } + + pub fn is_nullish(&self) -> bool { + match self { + Self::Undefined | Self::Null => true, + Self::Str(..) + | Self::Num(..) + | Self::True + | Self::False + | Self::BigInt(..) + | Self::Regex(..) => false, + } + } + + pub fn is_empty_string(&self) -> bool { + match self { + Self::Str(s) => s.is_empty(), + _ => false, + } + } + + pub fn is_value_type(&self) -> bool { + !matches!(self, Self::Regex(..)) + } +} + +impl From for ConstantValue { + fn from(v: bool) -> Self { + match v { + true => ConstantValue::True, + false => ConstantValue::False, + } + } +} + +impl From<&'_ str> for ConstantValue { + fn from(v: &str) -> Self { + ConstantValue::Str(ConstantString::Word(v.into())) + } +} + +impl From for ConstantValue { + fn from(v: Lit) -> Self { + match v { + Lit::Str(v) => ConstantValue::Str(ConstantString::Word(v.value)), + Lit::Bool(v) => { + if v.value { + ConstantValue::True + } else { + ConstantValue::False + } + } + Lit::Null(_) => ConstantValue::Null, + Lit::Num(v) => ConstantValue::Num(ConstantNumber(v.value)), + Lit::BigInt(v) => ConstantValue::BigInt(*v.value), + Lit::Regex(v) => ConstantValue::Regex(v.exp, v.flags), + Lit::JSXText(v) => ConstantValue::Str(ConstantString::Atom(v.value)), + } + } +} + +impl Display for ConstantValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ConstantValue::Undefined => write!(f, "undefined"), + ConstantValue::Str(str) => write!(f, "{}", StringifyJs(str.as_str())), + ConstantValue::True => write!(f, "true"), + ConstantValue::False => write!(f, "false"), + ConstantValue::Null => write!(f, "null"), + ConstantValue::Num(ConstantNumber(n)) => write!(f, "{n}"), + ConstantValue::BigInt(n) => write!(f, "{n}"), + ConstantValue::Regex(exp, flags) => write!(f, "/{exp}/{flags}"), + } + } +} + +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub struct ModuleValue { + pub module: JsWord, + pub annotations: ImportAnnotations, +} + +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +pub enum LogicalOperator { + And, + Or, + NullishCoalescing, +} + +impl LogicalOperator { + fn joiner(&self) -> &'static str { + match self { + LogicalOperator::And => " && ", + LogicalOperator::Or => " || ", + LogicalOperator::NullishCoalescing => " ?? ", + } + } + fn multi_line_joiner(&self) -> &'static str { + match self { + LogicalOperator::And => "&& ", + LogicalOperator::Or => "|| ", + LogicalOperator::NullishCoalescing => "?? ", + } + } +} + +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +pub enum BinaryOperator { + Equal, + NotEqual, + StrictEqual, + StrictNotEqual, +} + +impl BinaryOperator { + fn joiner(&self) -> &'static str { + match self { + BinaryOperator::Equal => " == ", + BinaryOperator::NotEqual => " != ", + BinaryOperator::StrictEqual => " === ", + BinaryOperator::StrictNotEqual => " !== ", + } + } + + fn positive_op(&self) -> (PositiveBinaryOperator, bool) { + match self { + BinaryOperator::Equal => (PositiveBinaryOperator::Equal, false), + BinaryOperator::NotEqual => (PositiveBinaryOperator::Equal, true), + BinaryOperator::StrictEqual => (PositiveBinaryOperator::StrictEqual, false), + BinaryOperator::StrictNotEqual => (PositiveBinaryOperator::StrictEqual, true), + } + } +} + +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +pub enum PositiveBinaryOperator { + Equal, + StrictEqual, +} + +/// The four categories of [JsValue]s. +enum JsValueMetaKind { + /// Doesn't contain nested values. + Leaf, + /// Contains nested values. Nested values represent some structure and can't + /// be replaced during linking. They might contain placeholders. + Nested, + /// Contains nested values. Operations are replaced during linking. They + /// might contain placeholders. + Operation, + /// These values are replaced during linking. + Placeholder, +} + +/// TODO: Use `Arc` +/// There are 4 kinds of values: Leaves, Nested, Operations, and Placeholders +/// (see [JsValueMetaKind] for details). Values are processed in two phases: +/// - Analyze phase: We convert AST into [JsValue]s. We don't have contextual +/// information so we need to insert placeholders to represent that. +/// - Link phase: We try to reduce a value to a constant value. The link phase +/// has 5 substeps that are executed on each node in the graph depth-first. +/// When a value is modified, we need to visit the new children again. +/// - Replace variables with their values. This replaces [JsValue::Variable]. No +/// variable should be remaining after that. +/// - Replace placeholders with contextual information. This usually replaces +/// [JsValue::FreeVar] and [JsValue::Module]. Some [JsValue::Call] on well- +/// known functions might also be replaced. No free vars or modules should be +/// remaining after that. +/// - Replace operations on well-known objects and functions. This handles +/// [JsValue::Call] and [JsValue::Member] on well-known objects and functions. +/// - Replace all built-in functions with their values when they are +/// compile-time constant. +/// - For optimization, any nested operations are replaced with +/// [JsValue::Unknown]. So only one layer of operation remains. Any remaining +/// operation or placeholder can be treated as unknown. +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum JsValue { + // LEAF VALUES + // ---------------------------- + /// A constant primitive value. + Constant(ConstantValue), + /// An constant URL object. + Url(Box), + /// Some kind of well-known object + /// (must not be an array, otherwise Array.concat needs to be changed) + WellKnownObject(WellKnownObjectKind), + /// Some kind of well-known function + WellKnownFunction(WellKnownFunctionKind), + /// Not-analyzable value. Might contain the original value for additional + /// info. Has a reason string for explanation. + Unknown { + original_value: Option>, + reason: Cow<'static, str>, + has_side_effects: bool, + }, + + // NESTED VALUES + // ---------------------------- + /// An array of nested values + Array { + total_nodes: usize, + items: Vec, + mutable: bool, + }, + /// An object of nested values + Object { + total_nodes: usize, + parts: Vec, + mutable: bool, + }, + /// A list of alternative values + Alternatives(usize, Vec), + /// A function reference. The return value might contain [JsValue::Argument] + /// placeholders that need to be replaced when calling this function. + /// `(total_node_count, func_ident, return_value)` + Function(usize, u32, Box), + + // OPERATIONS + // ---------------------------- + /// A string concatenation of values. + /// `foo.${unknownVar}.js` => 'foo' + Unknown + '.js' + Concat(usize, Vec), + /// An addition of values. + /// This can be converted to [JsValue::Concat] if the type of the variable + /// is string. + Add(usize, Vec), + /// Logical negation `!expr` + Not(usize, Box), + /// Logical operator chain e. g. `expr && expr` + Logical(usize, LogicalOperator, Vec), + /// Binary expression e. g. `expr == expr` + Binary(usize, Box, BinaryOperator, Box), + /// A function call without a this context. + /// `(total_node_count, callee, args)` + Call(usize, Box, Vec), + /// A super call to the parent constructor. + /// `(total_node_count, args)` + SuperCall(usize, Vec), + /// A function call with a this context. + /// `(total_node_count, obj, prop, args)` + MemberCall(usize, Box, Box, Vec), + /// A member access `obj[prop]` + /// `(total_node_count, obj, prop)` + Member(usize, Box, Box), + /// A tenary operator `test ? cons : alt` + /// `(total_node_count, test, cons, alt)` + Tenary(usize, Box, Box, Box), + + /// A for-of loop + /// + /// `(total_node_count, iterable)` + Iterated(usize, Box), + + /// A `typeof` expression. + /// + /// `(total_node_count, operand)` + TypeOf(usize, Box), + + // PLACEHOLDERS + // ---------------------------- + /// A reference to a variable. + Variable(Id), + /// A reference to an function argument. + /// (func_ident, arg_index) + Argument(u32, usize), + // TODO no predefined kinds, only JsWord + /// A reference to a free variable. + FreeVar(JsWord), + /// This is a reference to a imported module. + Module(ModuleValue), +} + +impl From<&'_ str> for JsValue { + fn from(v: &str) -> Self { + ConstantValue::Str(ConstantString::Word(v.into())).into() + } +} + +impl From for JsValue { + fn from(v: Atom) -> Self { + ConstantValue::Str(ConstantString::Atom(v)).into() + } +} + +impl From for JsValue { + fn from(v: BigInt) -> Self { + ConstantValue::BigInt(v).into() + } +} + +impl From for JsValue { + fn from(v: f64) -> Self { + ConstantValue::Num(ConstantNumber(v)).into() + } +} + +impl From for JsValue { + fn from(v: RcStr) -> Self { + ConstantValue::Str(v.into()).into() + } +} + +impl From for JsValue { + fn from(v: String) -> Self { + RcStr::from(v).into() + } +} + +impl From for JsValue { + fn from(v: swc_core::ecma::ast::Str) -> Self { + ConstantValue::Str(v.value.into()).into() + } +} + +impl From for JsValue { + fn from(v: ConstantValue) -> Self { + JsValue::Constant(v) + } +} + +impl From<&CompileTimeDefineValue> for JsValue { + fn from(v: &CompileTimeDefineValue) -> Self { + match v { + CompileTimeDefineValue::String(s) => JsValue::Constant(s.as_str().into()), + CompileTimeDefineValue::Bool(b) => JsValue::Constant((*b).into()), + CompileTimeDefineValue::JSON(_) => { + JsValue::unknown_empty(false, "compile time injected JSON") + } + } + } +} + +impl Default for JsValue { + fn default() -> Self { + JsValue::unknown_empty(false, "") + } +} + +impl Display for ObjectPart { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ObjectPart::KeyValue(key, value) => write!(f, "{key}: {value}"), + ObjectPart::Spread(value) => write!(f, "...{value}"), + } + } +} + +impl Display for JsValue { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + JsValue::Constant(v) => write!(f, "{v}"), + JsValue::Url(url) => write!(f, "{}", url), + JsValue::Array { items, mutable, .. } => write!( + f, + "{}[{}]", + if *mutable { "" } else { "frozen " }, + items + .iter() + .map(|v| v.to_string()) + .collect::>() + .join(", ") + ), + JsValue::Object { parts, mutable, .. } => write!( + f, + "{}{{{}}}", + if *mutable { "" } else { "frozen " }, + parts + .iter() + .map(|v| v.to_string()) + .collect::>() + .join(", ") + ), + JsValue::Alternatives(_, list) => write!( + f, + "({})", + list.iter() + .map(|v| v.to_string()) + .collect::>() + .join(" | ") + ), + JsValue::FreeVar(name) => write!(f, "FreeVar({:?})", name), + JsValue::Variable(name) => write!(f, "Variable({}#{:?})", name.0, name.1), + JsValue::Concat(_, list) => write!( + f, + "`{}`", + list.iter() + .map(|v| v + .as_str() + .map_or_else(|| format!("${{{}}}", v), |str| str.to_string())) + .collect::>() + .join("") + ), + JsValue::Add(_, list) => write!( + f, + "({})", + list.iter() + .map(|v| v.to_string()) + .collect::>() + .join(" + ") + ), + JsValue::Not(_, value) => write!(f, "!({})", value), + JsValue::Logical(_, op, list) => write!( + f, + "({})", + list.iter() + .map(|v| v.to_string()) + .collect::>() + .join(op.joiner()) + ), + JsValue::Binary(_, a, op, b) => write!(f, "({}{}{})", a, op.joiner(), b), + JsValue::Tenary(_, test, cons, alt) => write!(f, "({} ? {} : {})", test, cons, alt), + JsValue::Call(_, callee, list) => write!( + f, + "{}({})", + callee, + list.iter() + .map(|v| v.to_string()) + .collect::>() + .join(", ") + ), + JsValue::SuperCall(_, list) => write!( + f, + "super({})", + list.iter() + .map(|v| v.to_string()) + .collect::>() + .join(", ") + ), + JsValue::MemberCall(_, obj, prop, list) => write!( + f, + "{}[{}]({})", + obj, + prop, + list.iter() + .map(|v| v.to_string()) + .collect::>() + .join(", ") + ), + JsValue::Member(_, obj, prop) => write!(f, "{}[{}]", obj, prop), + JsValue::Module(ModuleValue { + module: name, + annotations, + }) => { + write!(f, "Module({}, {})", name, annotations) + } + JsValue::Unknown { .. } => write!(f, "???"), + JsValue::WellKnownObject(obj) => write!(f, "WellKnownObject({:?})", obj), + JsValue::WellKnownFunction(func) => write!(f, "WellKnownFunction({:?})", func), + JsValue::Function(_, func_ident, return_value) => { + write!(f, "Function#{}(return = {:?})", func_ident, return_value) + } + JsValue::Argument(func_ident, index) => { + write!(f, "arguments[{}#{}]", index, func_ident) + } + JsValue::Iterated(_, iterable) => write!(f, "Iterated({})", iterable), + JsValue::TypeOf(_, operand) => write!(f, "typeof({})", operand), + } + } +} + +fn pretty_join( + items: &[String], + indent_depth: usize, + single_line_separator: &str, + multi_line_separator_end: &str, + multi_line_separator_start: &str, +) -> String { + let multi_line = items + .iter() + .any(|item| item.len() > 50 || item.contains('\n')) + || items + .iter() + .map(|item| item.len() + single_line_separator.len()) + .sum::() + > 100; + if !multi_line { + items.join(single_line_separator) + } else if multi_line_separator_start.is_empty() { + format!( + "\n{}{}\n{}", + " ".repeat(indent_depth + 1), + items.join(&format!( + "{multi_line_separator_end}\n{}", + " ".repeat(indent_depth + 1) + )), + " ".repeat(indent_depth) + ) + } else { + format!( + "\n{}{multi_line_separator_start}{}\n{}", + " ".repeat(indent_depth * 4 + 4 - multi_line_separator_start.len()), + items.join(&format!( + "{multi_line_separator_end}\n{}{multi_line_separator_start}", + " ".repeat(indent_depth * 4 + 4 - multi_line_separator_start.len()) + )), + " ".repeat(indent_depth) + ) + } +} + +fn total_nodes(vec: &[JsValue]) -> usize { + vec.iter().map(|v| v.total_nodes()).sum::() +} + +// Private meta methods +impl JsValue { + fn meta_type(&self) -> JsValueMetaKind { + match self { + JsValue::Constant(..) + | JsValue::Url(..) + | JsValue::WellKnownObject(..) + | JsValue::WellKnownFunction(..) + | JsValue::Unknown { .. } => JsValueMetaKind::Leaf, + JsValue::Array { .. } + | JsValue::Object { .. } + | JsValue::Alternatives(..) + | JsValue::Function(..) + | JsValue::Member(..) => JsValueMetaKind::Nested, + JsValue::Concat(..) + | JsValue::Add(..) + | JsValue::Not(..) + | JsValue::Logical(..) + | JsValue::Binary(..) + | JsValue::Call(..) + | JsValue::SuperCall(..) + | JsValue::Tenary(..) + | JsValue::MemberCall(..) + | JsValue::Iterated(..) + | JsValue::TypeOf(..) => JsValueMetaKind::Operation, + JsValue::Variable(..) + | JsValue::Argument(..) + | JsValue::FreeVar(..) + | JsValue::Module(..) => JsValueMetaKind::Placeholder, + } + } +} + +// Constructors +impl JsValue { + pub fn alternatives(list: Vec) -> Self { + Self::Alternatives(1 + total_nodes(&list), list) + } + + pub fn concat(list: Vec) -> Self { + Self::Concat(1 + total_nodes(&list), list) + } + + pub fn add(list: Vec) -> Self { + Self::Add(1 + total_nodes(&list), list) + } + + pub fn logical_and(list: Vec) -> Self { + Self::Logical(1 + total_nodes(&list), LogicalOperator::And, list) + } + + pub fn logical_or(list: Vec) -> Self { + Self::Logical(1 + total_nodes(&list), LogicalOperator::Or, list) + } + + pub fn nullish_coalescing(list: Vec) -> Self { + Self::Logical( + 1 + total_nodes(&list), + LogicalOperator::NullishCoalescing, + list, + ) + } + + pub fn tenary(test: Box, cons: Box, alt: Box) -> Self { + Self::Tenary( + 1 + test.total_nodes() + cons.total_nodes() + alt.total_nodes(), + test, + cons, + alt, + ) + } + + pub fn iterated(iterable: JsValue) -> Self { + Self::Iterated(1 + iterable.total_nodes(), Box::new(iterable)) + } + + pub fn equal(a: JsValue, b: JsValue) -> Self { + Self::Binary( + 1 + a.total_nodes() + b.total_nodes(), + Box::new(a), + BinaryOperator::Equal, + Box::new(b), + ) + } + + pub fn not_equal(a: JsValue, b: JsValue) -> Self { + Self::Binary( + 1 + a.total_nodes() + b.total_nodes(), + Box::new(a), + BinaryOperator::NotEqual, + Box::new(b), + ) + } + + pub fn strict_equal(a: JsValue, b: JsValue) -> Self { + Self::Binary( + 1 + a.total_nodes() + b.total_nodes(), + Box::new(a), + BinaryOperator::StrictEqual, + Box::new(b), + ) + } + + pub fn strict_not_equal(a: JsValue, b: JsValue) -> Self { + Self::Binary( + 1 + a.total_nodes() + b.total_nodes(), + Box::new(a), + BinaryOperator::StrictNotEqual, + Box::new(b), + ) + } + + pub fn logical_not(inner: Box) -> Self { + Self::Not(1 + inner.total_nodes(), inner) + } + + pub fn type_of(operand: Box) -> Self { + Self::TypeOf(1 + operand.total_nodes(), operand) + } + + pub fn array(items: Vec) -> Self { + Self::Array { + total_nodes: 1 + total_nodes(&items), + items, + mutable: true, + } + } + + pub fn frozen_array(items: Vec) -> Self { + Self::Array { + total_nodes: 1 + total_nodes(&items), + items, + mutable: false, + } + } + + pub fn function(func_ident: u32, return_value: Box) -> Self { + Self::Function(1 + return_value.total_nodes(), func_ident, return_value) + } + + pub fn object(list: Vec) -> Self { + Self::Object { + total_nodes: 1 + list + .iter() + .map(|v| match v { + ObjectPart::KeyValue(k, v) => k.total_nodes() + v.total_nodes(), + ObjectPart::Spread(s) => s.total_nodes(), + }) + .sum::(), + parts: list, + mutable: true, + } + } + + pub fn frozen_object(list: Vec) -> Self { + Self::Object { + total_nodes: 1 + list + .iter() + .map(|v| match v { + ObjectPart::KeyValue(k, v) => k.total_nodes() + v.total_nodes(), + ObjectPart::Spread(s) => s.total_nodes(), + }) + .sum::(), + parts: list, + mutable: false, + } + } + + pub fn call(f: Box, args: Vec) -> Self { + Self::Call(1 + f.total_nodes() + total_nodes(&args), f, args) + } + + pub fn super_call(args: Vec) -> Self { + Self::SuperCall(1 + total_nodes(&args), args) + } + + pub fn member_call(o: Box, p: Box, args: Vec) -> Self { + Self::MemberCall( + 1 + o.total_nodes() + p.total_nodes() + total_nodes(&args), + o, + p, + args, + ) + } + + pub fn member(o: Box, p: Box) -> Self { + Self::Member(1 + o.total_nodes() + p.total_nodes(), o, p) + } + + pub fn unknown( + value: impl Into>, + side_effects: bool, + reason: impl Into>, + ) -> Self { + Self::Unknown { + original_value: Some(value.into()), + reason: reason.into(), + has_side_effects: side_effects, + } + } + + pub fn unknown_empty(side_effects: bool, reason: impl Into>) -> Self { + Self::Unknown { + original_value: None, + reason: reason.into(), + has_side_effects: side_effects, + } + } +} + +// Methods regarding node count +impl JsValue { + pub fn total_nodes(&self) -> usize { + match self { + JsValue::Constant(_) + | JsValue::Url(_) + | JsValue::FreeVar(_) + | JsValue::Variable(_) + | JsValue::Module(..) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) + | JsValue::Unknown { .. } + | JsValue::Argument(..) => 1, + + JsValue::Array { total_nodes: c, .. } + | JsValue::Object { total_nodes: c, .. } + | JsValue::Alternatives(c, _) + | JsValue::Concat(c, _) + | JsValue::Add(c, _) + | JsValue::Not(c, _) + | JsValue::Logical(c, _, _) + | JsValue::Binary(c, _, _, _) + | JsValue::Tenary(c, _, _, _) + | JsValue::Call(c, _, _) + | JsValue::SuperCall(c, _) + | JsValue::MemberCall(c, _, _, _) + | JsValue::Member(c, _, _) + | JsValue::Function(c, _, _) + | JsValue::Iterated(c, ..) + | JsValue::TypeOf(c, ..) => *c, + } + } + + fn update_total_nodes(&mut self) { + match self { + JsValue::Constant(_) + | JsValue::Url(_) + | JsValue::FreeVar(_) + | JsValue::Variable(_) + | JsValue::Module(..) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) + | JsValue::Unknown { .. } + | JsValue::Argument(..) => {} + + JsValue::Array { + total_nodes: c, + items: list, + .. + } + | JsValue::Alternatives(c, list) + | JsValue::Concat(c, list) + | JsValue::Add(c, list) + | JsValue::Logical(c, _, list) => { + *c = 1 + total_nodes(list); + } + + JsValue::Binary(c, a, _, b) => { + *c = 1 + a.total_nodes() + b.total_nodes(); + } + JsValue::Tenary(c, test, cons, alt) => { + *c = 1 + test.total_nodes() + cons.total_nodes() + alt.total_nodes(); + } + JsValue::Not(c, r) => { + *c = 1 + r.total_nodes(); + } + + JsValue::Object { + total_nodes: c, + parts, + mutable: _, + } => { + *c = 1 + parts + .iter() + .map(|v| match v { + ObjectPart::KeyValue(k, v) => k.total_nodes() + v.total_nodes(), + ObjectPart::Spread(s) => s.total_nodes(), + }) + .sum::(); + } + JsValue::Call(c, f, list) => { + *c = 1 + f.total_nodes() + total_nodes(list); + } + JsValue::SuperCall(c, list) => { + *c = 1 + total_nodes(list); + } + JsValue::MemberCall(c, o, m, list) => { + *c = 1 + o.total_nodes() + m.total_nodes() + total_nodes(list); + } + JsValue::Member(c, o, p) => { + *c = 1 + o.total_nodes() + p.total_nodes(); + } + JsValue::Function(c, _, r) => { + *c = 1 + r.total_nodes(); + } + + JsValue::Iterated(c, iterable) => { + *c = 1 + iterable.total_nodes(); + } + + JsValue::TypeOf(c, operand) => { + *c = 1 + operand.total_nodes(); + } + } + } + + #[cfg(debug_assertions)] + pub fn debug_assert_total_nodes_up_to_date(&mut self) { + let old = self.total_nodes(); + self.update_total_nodes(); + assert_eq!( + old, + self.total_nodes(), + "total nodes not up to date {:?}", + self + ); + } + + #[cfg(not(debug_assertions))] + pub fn debug_assert_total_nodes_up_to_date(&mut self) {} + + pub fn ensure_node_limit(&mut self, limit: usize) { + fn cmp_nodes(a: &JsValue, b: &JsValue) -> Ordering { + a.total_nodes().cmp(&b.total_nodes()) + } + fn make_max_unknown<'a>(mut iter: impl Iterator) { + let mut max = iter.next().unwrap(); + let mut side_effects = max.has_side_effects(); + for item in iter { + side_effects |= item.has_side_effects(); + if cmp_nodes(item, max) == Ordering::Greater { + max = item; + } + } + max.make_unknown_without_content(side_effects, "node limit reached"); + } + if self.total_nodes() > limit { + match self { + JsValue::Constant(_) + | JsValue::Url(_) + | JsValue::FreeVar(_) + | JsValue::Variable(_) + | JsValue::Module(..) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) + | JsValue::Argument(..) => { + self.make_unknown_without_content(false, "node limit reached") + } + &mut JsValue::Unknown { + original_value: _, + reason: _, + has_side_effects, + } => self.make_unknown_without_content(has_side_effects, "node limit reached"), + + JsValue::Array { items: list, .. } + | JsValue::Alternatives(_, list) + | JsValue::Concat(_, list) + | JsValue::Logical(_, _, list) + | JsValue::Add(_, list) => { + make_max_unknown(list.iter_mut()); + self.update_total_nodes(); + } + JsValue::Not(_, r) => { + r.make_unknown_without_content(false, "node limit reached"); + } + JsValue::Binary(_, a, _, b) => { + if a.total_nodes() > b.total_nodes() { + a.make_unknown_without_content(b.has_side_effects(), "node limit reached"); + } else { + b.make_unknown_without_content(a.has_side_effects(), "node limit reached"); + } + self.update_total_nodes(); + } + JsValue::Object { parts, .. } => { + make_max_unknown(parts.iter_mut().flat_map(|v| match v { + // TODO this probably can avoid heap allocation somehow + ObjectPart::KeyValue(k, v) => vec![k, v].into_iter(), + ObjectPart::Spread(s) => vec![s].into_iter(), + })); + self.update_total_nodes(); + } + JsValue::Call(_, f, args) => { + make_max_unknown([&mut **f].into_iter().chain(args.iter_mut())); + self.update_total_nodes(); + } + JsValue::SuperCall(_, args) => { + make_max_unknown(args.iter_mut()); + self.update_total_nodes(); + } + JsValue::MemberCall(_, o, p, args) => { + make_max_unknown([&mut **o, &mut **p].into_iter().chain(args.iter_mut())); + self.update_total_nodes(); + } + JsValue::Tenary(_, test, cons, alt) => { + make_max_unknown([&mut **test, &mut **cons, &mut **alt].into_iter()); + self.update_total_nodes(); + } + JsValue::Iterated(_, iterable) => { + iterable.make_unknown_without_content(false, "node limit reached"); + } + JsValue::TypeOf(_, operand) => { + operand.make_unknown_without_content(false, "node limit reached"); + } + JsValue::Member(_, o, p) => { + make_max_unknown([&mut **o, &mut **p].into_iter()); + self.update_total_nodes(); + } + JsValue::Function(_, _, r) => { + r.make_unknown_without_content(false, "node limit reached"); + } + } + } + } +} + +// Methods for explaining a value +impl JsValue { + pub fn explain_args(args: &[JsValue], depth: usize, unknown_depth: usize) -> (String, String) { + let mut hints = Vec::new(); + let args = args + .iter() + .map(|arg| arg.explain_internal(&mut hints, 1, depth, unknown_depth)) + .collect::>(); + let explainer = pretty_join(&args, 0, ", ", ",", ""); + ( + explainer, + hints.into_iter().fold(String::new(), |mut out, h| { + let _ = write!(out, "\n{h}"); + out + }), + ) + } + + pub fn explain(&self, depth: usize, unknown_depth: usize) -> (String, String) { + let mut hints = Vec::new(); + let explainer = self.explain_internal(&mut hints, 0, depth, unknown_depth); + ( + explainer, + hints.into_iter().fold(String::new(), |mut out, h| { + let _ = write!(out, "\n{h}"); + out + }), + ) + } + + fn explain_internal_inner( + &self, + hints: &mut Vec, + indent_depth: usize, + depth: usize, + unknown_depth: usize, + ) -> String { + if depth == 0 { + return "...".to_string(); + } + // let i = hints.len(); + + // if explainer.len() < 100 { + self.explain_internal(hints, indent_depth, depth - 1, unknown_depth) + // } + // hints.truncate(i); + // hints.push(String::new()); + // hints[i] = format!( + // "- *{}* {}", + // i, + // self.explain_internal(hints, 1, depth - 1, unknown_depth) + // ); + // format!("*{}*", i) + } + + fn explain_internal( + &self, + hints: &mut Vec, + indent_depth: usize, + depth: usize, + unknown_depth: usize, + ) -> String { + match self { + JsValue::Constant(v) => format!("{v}"), + JsValue::Array { items, mutable, .. } => format!( + "{}[{}]", + if *mutable { "" } else { "frozen " }, + pretty_join( + &items + .iter() + .map(|v| v.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + )) + .collect::>(), + indent_depth, + ", ", + ",", + "" + ) + ), + JsValue::Object { parts, mutable, .. } => format!( + "{}{{{}}}", + if *mutable { "" } else { "frozen " }, + pretty_join( + &parts + .iter() + .map(|v| match v { + ObjectPart::KeyValue(key, value) => format!( + "{}: {}", + key.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + ), + value.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + ) + ), + ObjectPart::Spread(value) => format!( + "...{}", + value.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + ) + ), + }) + .collect::>(), + indent_depth, + ", ", + ",", + "" + ) + ), + JsValue::Url(url) => format!("{}", url), + JsValue::Alternatives(_, list) => format!( + "({})", + pretty_join( + &list + .iter() + .map(|v| v.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + )) + .collect::>(), + indent_depth, + " | ", + "", + "| " + ) + ), + JsValue::FreeVar(name) => format!("FreeVar({})", name), + JsValue::Variable(name) => { + format!("{}", name.0) + } + JsValue::Argument(_, index) => { + format!("arguments[{}]", index) + } + JsValue::Concat(_, list) => format!( + "`{}`", + list.iter() + .map(|v| v.as_str().map_or_else( + || format!( + "${{{}}}", + v.explain_internal_inner(hints, indent_depth + 1, depth, unknown_depth) + ), + |str| str.to_string() + )) + .collect::>() + .join("") + ), + JsValue::Add(_, list) => format!( + "({})", + pretty_join( + &list + .iter() + .map(|v| v.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + )) + .collect::>(), + indent_depth, + " + ", + "", + "+ " + ) + ), + JsValue::Logical(_, op, list) => format!( + "({})", + pretty_join( + &list + .iter() + .map(|v| v.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + )) + .collect::>(), + indent_depth, + op.joiner(), + "", + op.multi_line_joiner() + ) + ), + JsValue::Binary(_, a, op, b) => format!( + "({}{}{})", + a.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + op.joiner(), + b.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + ), + JsValue::Tenary(_, test, cons, alt) => format!( + "({} ? {} : {})", + test.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + cons.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + alt.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + ), + JsValue::Not(_, value) => format!( + "!({})", + value.explain_internal_inner(hints, indent_depth, depth, unknown_depth) + ), + JsValue::Iterated(_, iterable) => { + format!( + "Iterated({})", + iterable.explain_internal_inner(hints, indent_depth, depth, unknown_depth) + ) + } + JsValue::TypeOf(_, operand) => { + format!( + "typeof({})", + operand.explain_internal_inner(hints, indent_depth, depth, unknown_depth) + ) + } + JsValue::Call(_, callee, list) => { + format!( + "{}({})", + callee.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + pretty_join( + &list + .iter() + .map(|v| v.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + )) + .collect::>(), + indent_depth, + ", ", + ",", + "" + ) + ) + } + JsValue::SuperCall(_, list) => { + format!( + "super({})", + pretty_join( + &list + .iter() + .map(|v| v.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + )) + .collect::>(), + indent_depth, + ", ", + ",", + "" + ) + ) + } + JsValue::MemberCall(_, obj, prop, list) => { + format!( + "{}[{}]({})", + obj.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + prop.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + pretty_join( + &list + .iter() + .map(|v| v.explain_internal_inner( + hints, + indent_depth + 1, + depth, + unknown_depth + )) + .collect::>(), + indent_depth, + ", ", + ",", + "" + ) + ) + } + JsValue::Member(_, obj, prop) => { + format!( + "{}[{}]", + obj.explain_internal_inner(hints, indent_depth, depth, unknown_depth), + prop.explain_internal_inner(hints, indent_depth, depth, unknown_depth) + ) + } + JsValue::Module(ModuleValue { + module: name, + annotations, + }) => { + format!("module<{}, {}>", name, annotations) + } + JsValue::Unknown { + original_value: inner, + reason: explainer, + has_side_effects, + } => { + let has_side_effects = *has_side_effects; + if unknown_depth == 0 || explainer.is_empty() { + "???".to_string() + } else if let Some(inner) = inner { + let i = hints.len(); + hints.push(String::new()); + hints[i] = format!( + "- *{}* {}\n ⚠️ {}{}", + i, + inner.explain_internal(hints, 1, depth, unknown_depth - 1), + explainer, + if has_side_effects { + "\n ⚠️ This value might have side effects" + } else { + "" + } + ); + format!("???*{}*", i) + } else { + let i = hints.len(); + hints.push(String::new()); + hints[i] = format!( + "- *{}* {}{}", + i, + explainer, + if has_side_effects { + "\n ⚠️ This value might have side effects" + } else { + "" + } + ); + format!("???*{}*", i) + } + } + JsValue::WellKnownObject(obj) => { + let (name, explainer) = match obj { + WellKnownObjectKind::GlobalObject => ( + "Object", + "The global Object variable", + ), + WellKnownObjectKind::PathModule | WellKnownObjectKind::PathModuleDefault => ( + "path", + "The Node.js path module: https://nodejs.org/api/path.html", + ), + WellKnownObjectKind::FsModule | WellKnownObjectKind::FsModuleDefault => ( + "fs", + "The Node.js fs module: https://nodejs.org/api/fs.html", + ), + WellKnownObjectKind::FsModulePromises => ( + "fs/promises", + "The Node.js fs module: https://nodejs.org/api/fs.html#promises-api", + ), + WellKnownObjectKind::UrlModule | WellKnownObjectKind::UrlModuleDefault => ( + "url", + "The Node.js url module: https://nodejs.org/api/url.html", + ), + WellKnownObjectKind::ChildProcess | WellKnownObjectKind::ChildProcessDefault => ( + "child_process", + "The Node.js child_process module: https://nodejs.org/api/child_process.html", + ), + WellKnownObjectKind::OsModule | WellKnownObjectKind::OsModuleDefault => ( + "os", + "The Node.js os module: https://nodejs.org/api/os.html", + ), + WellKnownObjectKind::NodeProcess => ( + "process", + "The Node.js process module: https://nodejs.org/api/process.html", + ), + WellKnownObjectKind::NodeProcessArgv => ( + "process.argv", + "The Node.js process.argv property: https://nodejs.org/api/process.html#processargv", + ), + WellKnownObjectKind::NodeProcessEnv => ( + "process.env", + "The Node.js process.env property: https://nodejs.org/api/process.html#processenv", + ), + WellKnownObjectKind::NodePreGyp => ( + "@mapbox/node-pre-gyp", + "The Node.js @mapbox/node-pre-gyp module: https://github.com/mapbox/node-pre-gyp", + ), + WellKnownObjectKind::NodeExpressApp => ( + "express", + "The Node.js express package: https://github.com/expressjs/express" + ), + WellKnownObjectKind::NodeProtobufLoader => ( + "@grpc/proto-loader", + "The Node.js @grpc/proto-loader package: https://github.com/grpc/grpc-node" + ), + WellKnownObjectKind::NodeBuffer => ( + "Buffer", + "The Node.js Buffer object: https://nodejs.org/api/buffer.html#class-buffer" + ), + WellKnownObjectKind::RequireCache => ( + "require.cache", + "The CommonJS require.cache object: https://nodejs.org/api/modules.html#requirecache" + ), + }; + if depth > 0 { + let i = hints.len(); + hints.push(format!("- *{i}* {name}: {explainer}")); + format!("{name}*{i}*") + } else { + name.to_string() + } + } + JsValue::WellKnownFunction(func) => { + let (name, explainer) = match func { + WellKnownFunctionKind::ObjectAssign => ( + "Object.assign".to_string(), + "Object.assign method: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign", + ), + WellKnownFunctionKind::PathJoin => ( + "path.join".to_string(), + "The Node.js path.join method: https://nodejs.org/api/path.html#pathjoinpaths", + ), + WellKnownFunctionKind::PathDirname => ( + "path.dirname".to_string(), + "The Node.js path.dirname method: https://nodejs.org/api/path.html#pathdirnamepath", + ), + WellKnownFunctionKind::PathResolve(cwd) => ( + format!("path.resolve({cwd})"), + "The Node.js path.resolve method: https://nodejs.org/api/path.html#pathresolvepaths", + ), + WellKnownFunctionKind::Import => ( + "import".to_string(), + "The dynamic import() method from the ESM specification: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports" + ), + WellKnownFunctionKind::Require => ("require".to_string(), "The require method from CommonJS"), + WellKnownFunctionKind::RequireResolve => ("require.resolve".to_string(), "The require.resolve method from CommonJS"), + WellKnownFunctionKind::RequireContext => ("require.context".to_string(), "The require.context method from webpack"), + WellKnownFunctionKind::RequireContextRequire(..) => ("require.context(...)".to_string(), "The require.context(...) method from webpack: https://webpack.js.org/api/module-methods/#requirecontext"), + WellKnownFunctionKind::RequireContextRequireKeys(..) => ("require.context(...).keys".to_string(), "The require.context(...).keys method from webpack: https://webpack.js.org/guides/dependency-management/#requirecontext"), + WellKnownFunctionKind::RequireContextRequireResolve(..) => ("require.context(...).resolve".to_string(), "The require.context(...).resolve method from webpack: https://webpack.js.org/guides/dependency-management/#requirecontext"), + WellKnownFunctionKind::Define => ("define".to_string(), "The define method from AMD"), + WellKnownFunctionKind::FsReadMethod(name) => ( + format!("fs.{name}"), + "A file reading method from the Node.js fs module: https://nodejs.org/api/fs.html", + ), + WellKnownFunctionKind::PathToFileUrl => ( + "url.pathToFileURL".to_string(), + "The Node.js url.pathToFileURL method: https://nodejs.org/api/url.html#urlpathtofileurlpath", + ), + WellKnownFunctionKind::ChildProcessSpawnMethod(name) => ( + format!("child_process.{name}"), + "A process spawning method from the Node.js child_process module: https://nodejs.org/api/child_process.html", + ), + WellKnownFunctionKind::ChildProcessFork => ( + "child_process.fork".to_string(), + "The Node.js child_process.fork method: https://nodejs.org/api/child_process.html#child_processforkmodulepath-args-options", + ), + WellKnownFunctionKind::OsArch => ( + "os.arch".to_string(), + "The Node.js os.arch method: https://nodejs.org/api/os.html#os_os_arch", + ), + WellKnownFunctionKind::OsPlatform => ( + "os.process".to_string(), + "The Node.js os.process method: https://nodejs.org/api/os.html#os_os_process", + ), + WellKnownFunctionKind::OsEndianness => ( + "os.endianness".to_string(), + "The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness", + ), + WellKnownFunctionKind::ProcessCwd => ( + "process.cwd".to_string(), + "The Node.js process.cwd method: https://nodejs.org/api/process.html#processcwd", + ), + WellKnownFunctionKind::NodePreGypFind => ( + "find".to_string(), + "The Node.js @mapbox/node-pre-gyp module: https://github.com/mapbox/node-pre-gyp", + ), + WellKnownFunctionKind::NodeGypBuild => ( + "node-gyp-build".to_string(), + "The Node.js node-gyp-build module: https://github.com/prebuild/node-gyp-build" + ), + WellKnownFunctionKind::NodeBindings => ( + "bindings".to_string(), + "The Node.js bindings module: https://github.com/TooTallNate/node-bindings" + ), + WellKnownFunctionKind::NodeExpress => ( + "express".to_string(), + "require('express')() : https://github.com/expressjs/express" + ), + WellKnownFunctionKind::NodeExpressSet => ( + "set".to_string(), + "require('express')().set('view engine', 'jade') https://github.com/expressjs/express" + ), + WellKnownFunctionKind::NodeStrongGlobalize => ( + "SetRootDir".to_string(), + "require('strong-globalize')() https://github.com/strongloop/strong-globalize" + ), + WellKnownFunctionKind::NodeStrongGlobalizeSetRootDir => ( + "SetRootDir".to_string(), + "require('strong-globalize').SetRootDir(__dirname) https://github.com/strongloop/strong-globalize" + ), + WellKnownFunctionKind::NodeResolveFrom => ( + "resolveFrom".to_string(), + "require('resolve-from')(__dirname, 'node-gyp/bin/node-gyp') https://github.com/sindresorhus/resolve-from" + ), + WellKnownFunctionKind::NodeProtobufLoad => ( + "load/loadSync".to_string(), + "require('@grpc/proto-loader').load(filepath, { includeDirs: [root] }) https://github.com/grpc/grpc-node" + ), + }; + if depth > 0 { + let i = hints.len(); + hints.push(format!("- *{i}* {name}: {explainer}")); + format!("{name}*{i}*") + } else { + name + } + } + JsValue::Function(_, _, return_value) => { + if depth > 0 { + format!( + "(...) => {}", + return_value.explain_internal( + hints, + indent_depth, + depth - 1, + unknown_depth + ) + ) + } else { + "(...) => ...".to_string() + } + } + } + } +} + +// Unknown management +impl JsValue { + /// Convert the value into unknown with a specific reason. + pub fn make_unknown(&mut self, side_effects: bool, reason: impl Into>) { + *self = JsValue::unknown(take(self), side_effects || self.has_side_effects(), reason); + } + + /// Convert the owned value into unknown with a specific reason. + pub fn into_unknown( + mut self, + side_effects: bool, + reason: impl Into>, + ) -> Self { + self.make_unknown(side_effects, reason); + self + } + + /// Convert the value into unknown with a specific reason, but don't retain + /// the original value. + pub fn make_unknown_without_content( + &mut self, + side_effects: bool, + reason: impl Into>, + ) { + *self = JsValue::unknown_empty(side_effects || self.has_side_effects(), reason); + } + + /// Make all nested operations unknown when the value is an operation. + pub fn make_nested_operations_unknown(&mut self) -> bool { + fn inner(this: &mut JsValue) -> bool { + if matches!(this.meta_type(), JsValueMetaKind::Operation) { + this.make_unknown(false, "nested operation"); + true + } else { + this.for_each_children_mut(&mut inner) + } + } + if matches!(self.meta_type(), JsValueMetaKind::Operation) { + self.for_each_children_mut(&mut inner) + } else { + false + } + } + + pub fn add_unknown_mutations(&mut self, side_effects: bool) { + self.add_alt(JsValue::unknown_empty(side_effects, "unknown mutation")); + } +} + +// Defineable name management +impl JsValue { + /// When the value has a user-defineable name, return the length of it (in + /// segments). Otherwise returns None. + /// - any free var has itself as user-defineable name. + /// - any member access adds the identifier as segement to the name of the + /// object. + /// - some well-known objects/functions have a user-defineable names. + /// - member calls without arguments also have a user-defineable name which + /// is the property with `()` appended. + pub fn get_defineable_name_len(&self) -> Option { + match self { + JsValue::FreeVar(_) => Some(1), + JsValue::Member(_, obj, prop) if prop.as_str().is_some() => { + Some(obj.get_defineable_name_len()? + 1) + } + JsValue::WellKnownObject(obj) => obj.as_define_name().map(|d| d.len()), + JsValue::WellKnownFunction(func) => func.as_define_name().map(|d| d.len()), + JsValue::MemberCall(_, callee, prop, args) + if args.is_empty() && prop.as_str().is_some() => + { + Some(callee.get_defineable_name_len()? + 1) + } + + _ => None, + } + } + + /// Returns a reverse iterator over the segments of the user-defineable + /// name. e. g. `foo.bar().baz` would yield `baz`, `bar()`, `foo`. + /// `(1+2).foo.baz` would also yield `baz`, `foo` even while the value is + /// not a complete user-defineable name. Before calling this method you must + /// use [JsValue::get_defineable_name_len] to determine if the value has a + /// user-defineable name at all. + pub fn iter_defineable_name_rev(&self) -> DefineableNameIter<'_> { + DefineableNameIter { + next: Some(self), + index: 0, + } + } +} + +pub struct DefineableNameIter<'a> { + next: Option<&'a JsValue>, + index: usize, +} + +impl<'a> Iterator for DefineableNameIter<'a> { + type Item = Cow<'a, str>; + + fn next(&mut self) -> Option { + let value = self.next.take()?; + Some(match value { + JsValue::FreeVar(kind) => (&**kind).into(), + JsValue::Member(_, obj, prop) => { + self.next = Some(obj); + prop.as_str()?.into() + } + JsValue::WellKnownObject(obj) => { + let name = obj.as_define_name()?; + let i = self.index; + self.index += 1; + if self.index < name.len() { + self.next = Some(value); + } + name[name.len() - i - 1].into() + } + JsValue::WellKnownFunction(func) => { + let name = func.as_define_name()?; + let i = self.index; + self.index += 1; + if self.index < name.len() { + self.next = Some(value); + } + name[name.len() - i - 1].into() + } + JsValue::MemberCall(_, callee, prop, args) if args.is_empty() => { + self.next = Some(callee); + format!("{}()", prop.as_str()?).into() + } + _ => return None, + }) + } +} + +// Compile-time information gathering +impl JsValue { + /// Returns the constant string if the value represents a constant string. + pub fn as_str(&self) -> Option<&str> { + match self { + JsValue::Constant(c) => c.as_str(), + _ => None, + } + } + + /// Returns the constant bool if the value represents a constant boolean. + pub fn as_bool(&self) -> Option { + match self { + JsValue::Constant(c) => c.as_bool(), + _ => None, + } + } + + pub fn has_side_effects(&self) -> bool { + match self { + JsValue::Constant(_) => false, + JsValue::Concat(_, list) + | JsValue::Add(_, list) + | JsValue::Logical(_, _, list) + | JsValue::Alternatives(_, list) => list.iter().any(JsValue::has_side_effects), + JsValue::Binary(_, a, _, b) => a.has_side_effects() || b.has_side_effects(), + JsValue::Tenary(_, test, cons, alt) => { + test.has_side_effects() || cons.has_side_effects() || alt.has_side_effects() + } + JsValue::Not(_, value) => value.has_side_effects(), + JsValue::Array { items, .. } => items.iter().any(JsValue::has_side_effects), + JsValue::Object { parts, .. } => parts.iter().any(|v| match v { + ObjectPart::KeyValue(k, v) => k.has_side_effects() || v.has_side_effects(), + ObjectPart::Spread(v) => v.has_side_effects(), + }), + JsValue::Call(_, callee, args) => { + callee.has_side_effects() || args.iter().any(JsValue::has_side_effects) + } + JsValue::SuperCall(_, args) => args.iter().any(JsValue::has_side_effects), + JsValue::MemberCall(_, obj, prop, args) => { + obj.has_side_effects() + || prop.has_side_effects() + || args.iter().any(JsValue::has_side_effects) + } + JsValue::Member(_, obj, prop) => obj.has_side_effects() || prop.has_side_effects(), + JsValue::Function(_, _, _) => false, + JsValue::Url(_) => false, + JsValue::Variable(_) => false, + JsValue::Module(_) => false, + JsValue::WellKnownObject(_) => false, + JsValue::WellKnownFunction(_) => false, + JsValue::FreeVar(_) => false, + JsValue::Unknown { + has_side_effects, .. + } => *has_side_effects, + JsValue::Argument(_, _) => false, + JsValue::Iterated(_, iterable) => iterable.has_side_effects(), + JsValue::TypeOf(_, operand) => operand.has_side_effects(), + } + } + + /// Checks if the value is truthy. Returns None if we don't know. Returns + /// Some if we know if or if not the value is truthy. + pub fn is_truthy(&self) -> Option { + match self { + JsValue::Constant(c) => Some(c.is_truthy()), + JsValue::Concat(..) => self.is_empty_string().map(|x| !x), + JsValue::Url(..) + | JsValue::Array { .. } + | JsValue::Object { .. } + | JsValue::WellKnownObject(..) + | JsValue::WellKnownFunction(..) + | JsValue::Function(..) => Some(true), + JsValue::Alternatives(_, list) => merge_if_known(list, JsValue::is_truthy), + JsValue::Not(_, value) => value.is_truthy().map(|x| !x), + JsValue::Logical(_, op, list) => match op { + LogicalOperator::And => all_if_known(list, JsValue::is_truthy), + LogicalOperator::Or => any_if_known(list, JsValue::is_truthy), + LogicalOperator::NullishCoalescing => { + shortcircuit_if_known(list, JsValue::is_not_nullish, JsValue::is_truthy) + } + }, + JsValue::Binary(_, box a, op, box b) => { + let (positive_op, negate) = op.positive_op(); + match (positive_op, a, b) { + ( + PositiveBinaryOperator::StrictEqual, + JsValue::Constant(a), + JsValue::Constant(b), + ) if a.is_value_type() => Some(a == b), + ( + PositiveBinaryOperator::StrictEqual, + JsValue::Constant(a), + JsValue::Constant(b), + ) if a.is_value_type() => { + let same_type = { + use ConstantValue::*; + matches!( + (a, b), + (Num(_), Num(_)) + | (Str(_), Str(_)) + | (BigInt(_), BigInt(_)) + | (True | False, True | False) + | (Undefined, Undefined) + | (Null, Null) + ) + }; + if same_type { + Some(a == b) + } else { + None + } + } + ( + PositiveBinaryOperator::Equal, + JsValue::Constant(ConstantValue::Str(a)), + JsValue::Constant(ConstantValue::Str(b)), + ) => Some(a == b), + ( + PositiveBinaryOperator::Equal, + JsValue::Constant(ConstantValue::Num(a)), + JsValue::Constant(ConstantValue::Num(b)), + ) => Some(a == b), + _ => None, + } + .map(|x| x ^ negate) + } + _ => None, + } + } + + /// Checks if the value is falsy. Returns None if we don't know. Returns + /// Some if we know if or if not the value is falsy. + pub fn is_falsy(&self) -> Option { + self.is_truthy().map(|x| !x) + } + + /// Checks if the value is nullish (null or undefined). Returns None if we + /// don't know. Returns Some if we know if or if not the value is nullish. + pub fn is_nullish(&self) -> Option { + match self { + JsValue::Constant(c) => Some(c.is_nullish()), + JsValue::Concat(..) + | JsValue::Url(..) + | JsValue::Array { .. } + | JsValue::Object { .. } + | JsValue::WellKnownObject(..) + | JsValue::WellKnownFunction(..) + | JsValue::Not(..) + | JsValue::Binary(..) + | JsValue::Function(..) => Some(false), + JsValue::Alternatives(_, list) => merge_if_known(list, JsValue::is_nullish), + JsValue::Logical(_, op, list) => match op { + LogicalOperator::And => { + shortcircuit_if_known(list, JsValue::is_truthy, JsValue::is_nullish) + } + LogicalOperator::Or => { + shortcircuit_if_known(list, JsValue::is_falsy, JsValue::is_nullish) + } + LogicalOperator::NullishCoalescing => all_if_known(list, JsValue::is_nullish), + }, + _ => None, + } + } + + /// Checks if we know that the value is not nullish. Returns None if we + /// don't know. Returns Some if we know if or if not the value is not + /// nullish. + pub fn is_not_nullish(&self) -> Option { + self.is_nullish().map(|x| !x) + } + + /// Checks if we know that the value is an empty string. Returns None if we + /// don't know. Returns Some if we know if or if not the value is an empty + /// string. + pub fn is_empty_string(&self) -> Option { + match self { + JsValue::Constant(c) => Some(c.is_empty_string()), + JsValue::Concat(_, list) => all_if_known(list, JsValue::is_empty_string), + JsValue::Alternatives(_, list) => merge_if_known(list, JsValue::is_empty_string), + JsValue::Logical(_, op, list) => match op { + LogicalOperator::And => { + shortcircuit_if_known(list, JsValue::is_truthy, JsValue::is_empty_string) + } + LogicalOperator::Or => { + shortcircuit_if_known(list, JsValue::is_falsy, JsValue::is_empty_string) + } + LogicalOperator::NullishCoalescing => { + shortcircuit_if_known(list, JsValue::is_not_nullish, JsValue::is_empty_string) + } + }, + // Booleans are not empty strings + JsValue::Not(..) | JsValue::Binary(..) => Some(false), + // Objects are not empty strings + JsValue::Url(..) + | JsValue::Array { .. } + | JsValue::Object { .. } + | JsValue::WellKnownObject(..) + | JsValue::WellKnownFunction(..) + | JsValue::Function(..) => Some(false), + _ => None, + } + } + + /// Returns true, if the value is unknown and storing it as condition + /// doesn't make sense. This is for optimization purposes. + pub fn is_unknown(&self) -> bool { + match self { + JsValue::Unknown { .. } => true, + JsValue::Alternatives(_, list) => list.iter().any(|x| x.is_unknown()), + _ => false, + } + } + + /// Checks if we know that the value is a string. Returns None if we + /// don't know. Returns Some if we know if or if not the value is a string. + pub fn is_string(&self) -> Option { + match self { + JsValue::Constant(ConstantValue::Str(..)) + | JsValue::Concat(..) + | JsValue::TypeOf(..) => Some(true), + + // Objects are not strings + JsValue::Constant(..) + | JsValue::Array { .. } + | JsValue::Object { .. } + | JsValue::Url(..) + | JsValue::Module(..) + | JsValue::Function(..) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) => Some(false), + + // Booleans are not strings + JsValue::Not(..) | JsValue::Binary(..) => Some(false), + + JsValue::Add(_, list) => any_if_known(list, JsValue::is_string), + JsValue::Logical(_, op, list) => match op { + LogicalOperator::And => { + shortcircuit_if_known(list, JsValue::is_truthy, JsValue::is_string) + } + LogicalOperator::Or => { + shortcircuit_if_known(list, JsValue::is_falsy, JsValue::is_string) + } + LogicalOperator::NullishCoalescing => { + shortcircuit_if_known(list, JsValue::is_not_nullish, JsValue::is_string) + } + }, + + JsValue::Alternatives(_, v) => merge_if_known(v, JsValue::is_string), + + JsValue::Call( + _, + box JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireResolve + | WellKnownFunctionKind::PathJoin + | WellKnownFunctionKind::PathResolve(..) + | WellKnownFunctionKind::OsArch + | WellKnownFunctionKind::OsPlatform + | WellKnownFunctionKind::PathDirname + | WellKnownFunctionKind::PathToFileUrl + | WellKnownFunctionKind::ProcessCwd, + ), + _, + ) => Some(true), + + JsValue::FreeVar(..) + | JsValue::Variable(_) + | JsValue::Unknown { .. } + | JsValue::Argument(..) + | JsValue::Call(..) + | JsValue::MemberCall(..) + | JsValue::Member(..) + | JsValue::Tenary(..) + | JsValue::SuperCall(..) + | JsValue::Iterated(..) => None, + } + } + + /// Checks if we know that the value starts with a given string. Returns + /// None if we don't know. Returns Some if we know if or if not the + /// value starts with the given string. + pub fn starts_with(&self, str: &str) -> Option { + if let Some(s) = self.as_str() { + return Some(s.starts_with(str)); + } + match self { + JsValue::Alternatives(_, alts) => merge_if_known(alts, |a| a.starts_with(str)), + JsValue::Concat(_, list) => { + if let Some(item) = list.iter().next() { + if item.starts_with(str) == Some(true) { + Some(true) + } else if let Some(s) = item.as_str() { + if str.starts_with(s) { + None + } else { + Some(false) + } + } else { + None + } + } else { + Some(false) + } + } + + _ => None, + } + } + + /// Checks if we know that the value ends with a given string. Returns + /// None if we don't know. Returns Some if we know if or if not the + /// value ends with the given string. + pub fn ends_with(&self, str: &str) -> Option { + if let Some(s) = self.as_str() { + return Some(s.ends_with(str)); + } + match self { + JsValue::Alternatives(_, alts) => merge_if_known(alts, |alt| alt.ends_with(str)), + JsValue::Concat(_, list) => { + if let Some(item) = list.last() { + if item.ends_with(str) == Some(true) { + Some(true) + } else if let Some(s) = item.as_str() { + if str.ends_with(s) { + None + } else { + Some(false) + } + } else { + None + } + } else { + Some(false) + } + } + + _ => None, + } + } +} + +/// Compute the compile-time value of all elements of the list. If all evaluate +/// to the same value return that. Otherwise return None. +fn merge_if_known( + list: impl IntoIterator, + func: impl Fn(T) -> Option, +) -> Option { + let mut current = None; + for item in list.into_iter().map(func) { + if item.is_some() { + if current.is_none() { + current = item; + } else if current != item { + return None; + } + } else { + return None; + } + } + current +} + +/// Evaluates all elements of the list and returns Some(true) if all elements +/// are compile-time true. If any element is compile-time false, return +/// Some(false). Otherwise return None. +fn all_if_known( + list: impl IntoIterator, + func: impl Fn(T) -> Option, +) -> Option { + let mut unknown = false; + for item in list.into_iter().map(func) { + match item { + Some(false) => return Some(false), + None => unknown = true, + _ => {} + } + } + if unknown { + None + } else { + Some(true) + } +} + +/// Evaluates all elements of the list and returns Some(true) if any element is +/// compile-time true. If all elements are compile-time false, return +/// Some(false). Otherwise return None. +fn any_if_known( + list: impl IntoIterator, + func: impl Fn(T) -> Option, +) -> Option { + all_if_known(list, |x| func(x).map(|x| !x)).map(|x| !x) +} + +/// Selects the first element of the list where `use_item` is compile-time true. +/// For this element returns the result of `item_value`. Otherwise returns None. +fn shortcircuit_if_known( + list: impl IntoIterator, + use_item: impl Fn(T) -> Option, + item_value: impl FnOnce(T) -> Option, +) -> Option { + let mut it = list.into_iter().peekable(); + while let Some(item) = it.next() { + if it.peek().is_none() { + return item_value(item); + } else { + match use_item(item) { + Some(true) => return item_value(item), + None => return None, + _ => {} + } + } + } + None +} + +/// Macro to visit all children of a node with an async function +macro_rules! for_each_children_async { + ($value:expr, $visit_fn:expr, $($args:expr),+) => { + Ok(match &mut $value { + JsValue::Alternatives(_, list) + | JsValue::Concat(_, list) + | JsValue::Add(_, list) + | JsValue::Logical(_, _, list) + | JsValue::Array{ items: list, ..} => { + let mut modified = false; + for item in list.iter_mut() { + let (v, m) = $visit_fn(take(item), $($args),+).await?; + *item = v; + if m { + modified = true + } + } + $value.update_total_nodes(); + ($value, modified) + } + JsValue::Object{ parts, ..} => { + let mut modified = false; + for item in parts.iter_mut() { + match item { + ObjectPart::KeyValue(key, value) => { + let (v, m) = $visit_fn(take(key), $($args),+).await?; + *key = v; + if m { + modified = true + } + let (v, m) = $visit_fn(take(value), $($args),+).await?; + *value = v; + if m { + modified = true + } + } + ObjectPart::Spread(value) => { + let (v, m) = $visit_fn(take(value), $($args),+).await?; + *value = v; + if m { + modified = true + } + } + } + + } + $value.update_total_nodes(); + ($value, modified) + } + JsValue::Call(_, box callee, list) => { + let (new_callee, mut modified) = $visit_fn(take(callee), $($args),+).await?; + *callee = new_callee; + for item in list.iter_mut() { + let (v, m) = $visit_fn(take(item), $($args),+).await?; + *item = v; + if m { + modified = true + } + } + $value.update_total_nodes(); + ($value, modified) + } + JsValue::SuperCall(_, list) => { + let mut modified = false; + for item in list.iter_mut() { + let (v, m) = $visit_fn(take(item), $($args),+).await?; + *item = v; + if m { + modified = true + } + } + $value.update_total_nodes(); + ($value, modified) + } + JsValue::MemberCall(_, box obj, box prop, list) => { + let (new_callee, m1) = $visit_fn(take(obj), $($args),+).await?; + *obj = new_callee; + let (new_member, m2) = $visit_fn(take(prop), $($args),+).await?; + *prop = new_member; + let mut modified = m1 || m2; + for item in list.iter_mut() { + let (v, m) = $visit_fn(take(item), $($args),+).await?; + *item = v; + if m { + modified = true + } + } + $value.update_total_nodes(); + ($value, modified) + } + + JsValue::Function(_, _, box return_value) => { + let (new_return_value, modified) = $visit_fn(take(return_value), $($args),+).await?; + *return_value = new_return_value; + + $value.update_total_nodes(); + ($value, modified) + } + JsValue::Not(_, box value) => { + let (new_value, modified) = $visit_fn(take(value), $($args),+).await?; + *value = new_value; + + $value.update_total_nodes(); + ($value, modified) + } + JsValue::Binary(_, box a, _, box b) => { + let (v, m1) = $visit_fn(take(a), $($args),+).await?; + *a = v; + let (v, m2) = $visit_fn(take(b), $($args),+).await?; + *b = v; + $value.update_total_nodes(); + ($value, m1 || m2) + } + JsValue::Tenary(_, box test, box cons, box alt) => { + let (v, m1) = $visit_fn(take(test), $($args),+).await?; + *test = v; + let (v, m2) = $visit_fn(take(cons), $($args),+).await?; + *cons = v; + let (v, m3) = $visit_fn(take(alt), $($args),+).await?; + *alt = v; + $value.update_total_nodes(); + ($value, m1 || m2 || m3) + } + JsValue::Member(_, box obj, box prop) => { + let (v, m1) = $visit_fn(take(obj), $($args),+).await?; + *obj = v; + let (v, m2) = $visit_fn(take(prop), $($args),+).await?; + *prop = v; + $value.update_total_nodes(); + ($value, m1 || m2) + } + JsValue::Iterated(_, box iterable) => { + let (new_iterable, modified) = $visit_fn(take(iterable), $($args),+).await?; + *iterable = new_iterable; + + $value.update_total_nodes(); + ($value, modified) + } + JsValue::TypeOf(_, box operand) => { + let (new_operand, modified) = $visit_fn(take(operand), $($args),+).await?; + *operand = new_operand; + + $value.update_total_nodes(); + ($value, modified) + } + JsValue::Constant(_) + | JsValue::FreeVar(_) + | JsValue::Variable(_) + | JsValue::Module(..) + | JsValue::Url(_) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) + | JsValue::Unknown { .. } + | JsValue::Argument(..) => ($value, false), + }) + } +} + +// Visiting +impl JsValue { + /// Visit the node and all its children with a function in a loop until the + /// visitor returns false for the node and all children + pub async fn visit_async_until_settled<'a, F, R, E>( + self, + visitor: &mut F, + ) -> Result<(Self, bool), E> + where + R: 'a + Future> + Send, + F: 'a + FnMut(JsValue) -> R + Send, + { + let mut modified = false; + let mut v = self; + loop { + let m; + (v, m) = visitor(take(&mut v)).await?; + if !m { + break; + } + modified = true; + v = take(&mut v) + .visit_each_children_async_until_settled(visitor) + .await?; + } + Ok((v, modified)) + } + + /// Visit all children of the node with an async function in a loop until + /// the visitor returns false + pub async fn visit_each_children_async_until_settled<'a, F, R, E>( + mut self, + visitor: &mut F, + ) -> Result + where + R: 'a + Future> + Send, + F: 'a + FnMut(JsValue) -> R + Send, + { + fn visit_async_until_settled_box<'a, F, R, E>( + value: JsValue, + visitor: &'a mut F, + ) -> PinnedAsyncUntilSettledBox + where + R: 'a + Future> + Send, + F: 'a + FnMut(JsValue) -> R + Send, + E: 'a, + { + Box::pin(value.visit_async_until_settled(visitor)) + } + let (v, _) = for_each_children_async!(self, visit_async_until_settled_box, visitor)?; + Ok(v) + } + + /// Visit the node and all its children with an async function. + pub async fn visit_async<'a, F, R, E>(self, visitor: &mut F) -> Result<(Self, bool), E> + where + R: 'a + Future>, + F: 'a + FnMut(JsValue) -> R, + { + let (v, modified) = self.visit_each_children_async(visitor).await?; + let (v, m) = visitor(v).await?; + if m { + Ok((v, true)) + } else { + Ok((v, modified)) + } + } + + /// Visit all children of the node with an async function. + pub async fn visit_each_children_async<'a, F, R, E>( + mut self, + visitor: &mut F, + ) -> Result<(Self, bool), E> + where + R: 'a + Future>, + F: 'a + FnMut(JsValue) -> R, + { + fn visit_async_box<'a, F, R, E>(value: JsValue, visitor: &'a mut F) -> PinnedAsyncBox + where + R: 'a + Future>, + F: 'a + FnMut(JsValue) -> R, + E: 'a, + { + Box::pin(value.visit_async(visitor)) + } + for_each_children_async!(self, visit_async_box, visitor) + } + + /// Call an async function for each child of the node. + pub async fn for_each_children_async<'a, F, R, E>( + mut self, + visitor: &mut F, + ) -> Result<(Self, bool), E> + where + R: 'a + Future>, + F: 'a + FnMut(JsValue) -> R, + { + for_each_children_async!(self, |v, ()| visitor(v), ()) + } + + /// Visit the node and all its children with a function in a loop until the + /// visitor returns false + pub fn visit_mut_until_settled(&mut self, visitor: &mut impl FnMut(&mut JsValue) -> bool) { + while visitor(self) { + self.for_each_children_mut(&mut |value| { + value.visit_mut_until_settled(visitor); + false + }); + } + } + + /// Visit the node and all its children with a function. + pub fn visit_mut(&mut self, visitor: &mut impl FnMut(&mut JsValue) -> bool) -> bool { + let modified = self.for_each_children_mut(&mut |value| value.visit_mut(visitor)); + if visitor(self) { + true + } else { + modified + } + } + + /// Visit all children of the node with a function. Only visits nodes where + /// the condition is true. + pub fn visit_mut_conditional( + &mut self, + condition: impl Fn(&JsValue) -> bool, + visitor: &mut impl FnMut(&mut JsValue) -> bool, + ) -> bool { + if condition(self) { + let modified = self.for_each_children_mut(&mut |value| value.visit_mut(visitor)); + if visitor(self) { + true + } else { + modified + } + } else { + false + } + } + + /// Calls a function for each child of the node. Allows mutating the node. + /// Updates the total nodes count after mutation. + pub fn for_each_children_mut( + &mut self, + visitor: &mut impl FnMut(&mut JsValue) -> bool, + ) -> bool { + match self { + JsValue::Alternatives(_, list) + | JsValue::Concat(_, list) + | JsValue::Add(_, list) + | JsValue::Logical(_, _, list) + | JsValue::Array { items: list, .. } => { + let mut modified = false; + for item in list.iter_mut() { + if visitor(item) { + modified = true + } + } + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Not(_, value) => { + let modified = visitor(value); + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Object { parts, .. } => { + let mut modified = false; + for item in parts.iter_mut() { + match item { + ObjectPart::KeyValue(key, value) => { + if visitor(key) { + modified = true + } + if visitor(value) { + modified = true + } + } + ObjectPart::Spread(value) => { + if visitor(value) { + modified = true + } + } + } + } + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Call(_, callee, list) => { + let mut modified = visitor(callee); + for item in list.iter_mut() { + if visitor(item) { + modified = true + } + } + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::SuperCall(_, list) => { + let mut modified = false; + for item in list.iter_mut() { + if visitor(item) { + modified = true + } + } + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::MemberCall(_, obj, prop, list) => { + let m1 = visitor(obj); + let m2 = visitor(prop); + let mut modified = m1 || m2; + for item in list.iter_mut() { + if visitor(item) { + modified = true + } + } + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Function(_, _, return_value) => { + let modified = visitor(return_value); + + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Binary(_, a, _, b) => { + let m1 = visitor(a); + let m2 = visitor(b); + let modified = m1 || m2; + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Tenary(_, test, cons, alt) => { + let m1 = visitor(test); + let m2 = visitor(cons); + let m3 = visitor(alt); + let modified = m1 || m2 || m3; + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Member(_, obj, prop) => { + let m1 = visitor(obj); + let m2 = visitor(prop); + let modified = m1 || m2; + if modified { + self.update_total_nodes(); + } + modified + } + + JsValue::Iterated(_, iterable) => { + let modified = visitor(iterable); + if modified { + self.update_total_nodes(); + } + modified + } + + JsValue::TypeOf(_, operand) => { + let modified = visitor(operand); + if modified { + self.update_total_nodes(); + } + modified + } + + JsValue::Constant(_) + | JsValue::FreeVar(_) + | JsValue::Variable(_) + | JsValue::Module(..) + | JsValue::Url(_) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) + | JsValue::Unknown { .. } + | JsValue::Argument(..) => false, + } + } + + /// Calls a function for only early children. Allows mutating the + /// node. Updates the total nodes count after mutation. + pub fn for_each_early_children_mut( + &mut self, + visitor: &mut impl FnMut(&mut JsValue) -> bool, + ) -> bool { + match self { + JsValue::Call(_, callee, list) if !list.is_empty() => { + let m = visitor(callee); + if m { + self.update_total_nodes(); + } + m + } + JsValue::MemberCall(_, obj, prop, list) if !list.is_empty() => { + let m1 = visitor(obj); + let m2 = visitor(prop); + let modified = m1 || m2; + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Member(_, obj, _) => { + let m = visitor(obj); + if m { + self.update_total_nodes(); + } + m + } + _ => false, + } + } + + /// Calls a function for only late children. Allows mutating the + /// node. Updates the total nodes count after mutation. + pub fn for_each_late_children_mut( + &mut self, + visitor: &mut impl FnMut(&mut JsValue) -> bool, + ) -> bool { + match self { + JsValue::Call(_, _, list) if !list.is_empty() => { + let mut modified = false; + for item in list.iter_mut() { + if visitor(item) { + modified = true + } + } + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::MemberCall(_, _, _, list) if !list.is_empty() => { + let mut modified = false; + for item in list.iter_mut() { + if visitor(item) { + modified = true + } + } + if modified { + self.update_total_nodes(); + } + modified + } + JsValue::Member(_, _, prop) => { + let m = visitor(prop); + if m { + self.update_total_nodes(); + } + m + } + _ => self.for_each_children_mut(visitor), + } + } + + /// Visit the node and all its children with a function. + pub fn visit(&self, visitor: &mut impl FnMut(&JsValue)) { + self.for_each_children(&mut |value| value.visit(visitor)); + visitor(self); + } + + /// Calls a function for all children of the node. + pub fn for_each_children(&self, visitor: &mut impl FnMut(&JsValue)) { + match self { + JsValue::Alternatives(_, list) + | JsValue::Concat(_, list) + | JsValue::Add(_, list) + | JsValue::Logical(_, _, list) + | JsValue::Array { items: list, .. } => { + for item in list.iter() { + visitor(item); + } + } + JsValue::Not(_, value) => { + visitor(value); + } + JsValue::Object { parts, .. } => { + for item in parts.iter() { + match item { + ObjectPart::KeyValue(key, value) => { + visitor(key); + visitor(value); + } + ObjectPart::Spread(value) => { + visitor(value); + } + } + } + } + JsValue::Call(_, callee, list) => { + visitor(callee); + for item in list.iter() { + visitor(item); + } + } + JsValue::SuperCall(_, list) => { + for item in list.iter() { + visitor(item); + } + } + JsValue::MemberCall(_, obj, prop, list) => { + visitor(obj); + visitor(prop); + for item in list.iter() { + visitor(item); + } + } + JsValue::Function(_, _, return_value) => { + visitor(return_value); + } + JsValue::Member(_, obj, prop) => { + visitor(obj); + visitor(prop); + } + JsValue::Binary(_, a, _, b) => { + visitor(a); + visitor(b); + } + JsValue::Tenary(_, test, cons, alt) => { + visitor(test); + visitor(cons); + visitor(alt); + } + + JsValue::Iterated(_, iterable) => { + visitor(iterable); + } + + JsValue::TypeOf(_, operand) => { + visitor(operand); + } + + JsValue::Constant(_) + | JsValue::FreeVar(_) + | JsValue::Variable(_) + | JsValue::Module(..) + | JsValue::Url(_) + | JsValue::WellKnownObject(_) + | JsValue::WellKnownFunction(_) + | JsValue::Unknown { .. } + | JsValue::Argument(..) => {} + } + } +} + +// Alternatives management +impl JsValue { + /// Add an alternative to the current value. Might be a no-op if the value + /// already contains this alternative. Potentially expensive operation + /// as it has to compare the value with all existing alternatives. + fn add_alt(&mut self, v: Self) { + if self == &v { + return; + } + + if let JsValue::Alternatives(c, list) = self { + if !list.contains(&v) { + *c += v.total_nodes(); + list.push(v); + } + } else { + let l = take(self); + *self = JsValue::Alternatives(1 + l.total_nodes() + v.total_nodes(), vec![l, v]); + } + } +} + +// Normalization +impl JsValue { + /// Normalizes only the current node. Nested alternatives, concatenations, + /// or operations are collapsed. + pub fn normalize_shallow(&mut self) { + match self { + JsValue::Alternatives(_, v) => { + if v.len() == 1 { + *self = take(&mut v[0]); + } else { + let mut set = IndexSet::with_capacity(v.len()); + for v in take(v) { + match v { + JsValue::Alternatives(_, v) => { + for v in v { + set.insert(SimilarJsValue(v)); + } + } + v => { + set.insert(SimilarJsValue(v)); + } + } + } + if set.len() == 1 { + *self = set.into_iter().next().unwrap().0; + } else { + *v = set.into_iter().map(|v| v.0).collect(); + self.update_total_nodes(); + } + } + } + JsValue::Concat(_, v) => { + // Remove empty strings + v.retain(|v| v.as_str() != Some("")); + + // TODO(kdy1): Remove duplicate + let mut new: Vec = vec![]; + for v in take(v) { + if let Some(str) = v.as_str() { + if let Some(last) = new.last_mut() { + if let Some(last_str) = last.as_str() { + *last = [last_str, str].concat().into(); + } else { + new.push(v); + } + } else { + new.push(v); + } + } else if let JsValue::Concat(_, v) = v { + new.extend(v); + } else { + new.push(v); + } + } + if new.len() == 1 { + *self = new.into_iter().next().unwrap(); + } else { + *v = new; + self.update_total_nodes(); + } + } + JsValue::Add(_, v) => { + let mut added: Vec = Vec::new(); + let mut iter = take(v).into_iter(); + while let Some(item) = iter.next() { + if item.is_string() == Some(true) { + let mut concat = match added.len() { + 0 => Vec::new(), + 1 => vec![added.into_iter().next().unwrap()], + _ => vec![JsValue::Add( + 1 + added.iter().map(|v| v.total_nodes()).sum::(), + added, + )], + }; + concat.push(item); + for item in iter.by_ref() { + concat.push(item); + } + *self = JsValue::Concat( + 1 + concat.iter().map(|v| v.total_nodes()).sum::(), + concat, + ); + return; + } else { + added.push(item); + } + } + if added.len() == 1 { + *self = added.into_iter().next().unwrap(); + } else { + *v = added; + self.update_total_nodes(); + } + } + JsValue::Logical(_, op, list) => { + // Nested logical expressions can be normalized: e. g. `a && (b && c)` => `a && + // b && c` + if list.iter().any(|v| { + if let JsValue::Logical(_, inner_op, _) = v { + inner_op == op + } else { + false + } + }) { + // Taking the old list and constructing a new merged list + for mut v in take(list).into_iter() { + if let JsValue::Logical(_, inner_op, inner_list) = &mut v { + if inner_op == op { + list.append(inner_list); + } else { + list.push(v); + } + } else { + list.push(v); + } + } + self.update_total_nodes(); + } + } + _ => {} + } + } + + /// Normalizes the current node and all nested nodes. + pub fn normalize(&mut self) { + self.for_each_children_mut(&mut |child| { + child.normalize(); + true + }); + self.normalize_shallow(); + } +} + +// Similarity +// Like equality, but with depth limit +impl JsValue { + /// Check if the values are equal up to the given depth. Might return false + /// even if the values are equal when hitting the depth limit. + fn similar(&self, other: &JsValue, depth: usize) -> bool { + if depth == 0 { + return false; + } + fn all_similar(a: &[JsValue], b: &[JsValue], depth: usize) -> bool { + if a.len() != b.len() { + return false; + } + a.iter().zip(b.iter()).all(|(a, b)| a.similar(b, depth)) + } + fn all_parts_similar(a: &[ObjectPart], b: &[ObjectPart], depth: usize) -> bool { + if a.len() != b.len() { + return false; + } + a.iter().zip(b.iter()).all(|(a, b)| match (a, b) { + (ObjectPart::KeyValue(lk, lv), ObjectPart::KeyValue(rk, rv)) => { + lk.similar(rk, depth) && lv.similar(rv, depth) + } + (ObjectPart::Spread(l), ObjectPart::Spread(r)) => l.similar(r, depth), + _ => false, + }) + } + match (self, other) { + (JsValue::Constant(l), JsValue::Constant(r)) => l == r, + ( + JsValue::Array { + total_nodes: lc, + items: li, + mutable: lm, + }, + JsValue::Array { + total_nodes: rc, + items: ri, + mutable: rm, + }, + ) => lc == rc && lm == rm && all_similar(li, ri, depth - 1), + ( + JsValue::Object { + total_nodes: lc, + parts: lp, + mutable: lm, + }, + JsValue::Object { + total_nodes: rc, + parts: rp, + mutable: rm, + }, + ) => lc == rc && lm == rm && all_parts_similar(lp, rp, depth - 1), + (JsValue::Url(l), JsValue::Url(r)) => l == r, + (JsValue::Alternatives(lc, l), JsValue::Alternatives(rc, r)) => { + lc == rc && all_similar(l, r, depth - 1) + } + (JsValue::FreeVar(l), JsValue::FreeVar(r)) => l == r, + (JsValue::Variable(l), JsValue::Variable(r)) => l == r, + (JsValue::Concat(lc, l), JsValue::Concat(rc, r)) => { + lc == rc && all_similar(l, r, depth - 1) + } + (JsValue::Add(lc, l), JsValue::Add(rc, r)) => lc == rc && all_similar(l, r, depth - 1), + (JsValue::Logical(lc, lo, l), JsValue::Logical(rc, ro, r)) => { + lc == rc && lo == ro && all_similar(l, r, depth - 1) + } + (JsValue::Not(lc, l), JsValue::Not(rc, r)) => lc == rc && l.similar(r, depth - 1), + (JsValue::Call(lc, lf, la), JsValue::Call(rc, rf, ra)) => { + lc == rc && lf.similar(rf, depth - 1) && all_similar(la, ra, depth - 1) + } + (JsValue::MemberCall(lc, lo, lp, la), JsValue::MemberCall(rc, ro, rp, ra)) => { + lc == rc + && lo.similar(ro, depth - 1) + && lp.similar(rp, depth - 1) + && all_similar(la, ra, depth - 1) + } + (JsValue::Member(lc, lo, lp), JsValue::Member(rc, ro, rp)) => { + lc == rc && lo.similar(ro, depth - 1) && lp.similar(rp, depth - 1) + } + (JsValue::Binary(lc, la, lo, lb), JsValue::Binary(rc, ra, ro, rb)) => { + lc == rc && lo == ro && la.similar(ra, depth - 1) && lb.similar(rb, depth - 1) + } + ( + JsValue::Module(ModuleValue { + module: l, + annotations: la, + }), + JsValue::Module(ModuleValue { + module: r, + annotations: ra, + }), + ) => l == r && la == ra, + (JsValue::WellKnownObject(l), JsValue::WellKnownObject(r)) => l == r, + (JsValue::WellKnownFunction(l), JsValue::WellKnownFunction(r)) => l == r, + ( + JsValue::Unknown { + original_value: _, + reason: l, + has_side_effects: ls, + }, + JsValue::Unknown { + original_value: _, + reason: r, + has_side_effects: rs, + }, + ) => l == r && ls == rs, + (JsValue::Function(lc, _, l), JsValue::Function(rc, _, r)) => { + lc == rc && l.similar(r, depth - 1) + } + (JsValue::Argument(li, l), JsValue::Argument(ri, r)) => li == ri && l == r, + _ => false, + } + } + + /// Hashes the value up to the given depth. + fn similar_hash(&self, state: &mut H, depth: usize) { + if depth == 0 { + self.total_nodes().hash(state); + return; + } + + fn all_similar_hash(slice: &[JsValue], state: &mut H, depth: usize) { + for item in slice { + item.similar_hash(state, depth); + } + } + + fn all_parts_similar_hash( + slice: &[ObjectPart], + state: &mut H, + depth: usize, + ) { + for item in slice { + match item { + ObjectPart::KeyValue(key, value) => { + key.similar_hash(state, depth); + value.similar_hash(state, depth); + } + ObjectPart::Spread(value) => { + value.similar_hash(state, depth); + } + } + } + } + + match self { + JsValue::Constant(v) => Hash::hash(v, state), + JsValue::Object { parts, .. } => all_parts_similar_hash(parts, state, depth - 1), + JsValue::Url(v) => Hash::hash(v, state), + JsValue::FreeVar(v) => Hash::hash(v, state), + JsValue::Variable(v) => Hash::hash(v, state), + JsValue::Array { items: v, .. } + | JsValue::Alternatives(_, v) + | JsValue::Concat(_, v) + | JsValue::Add(_, v) + | JsValue::Logical(_, _, v) => all_similar_hash(v, state, depth - 1), + JsValue::Not(_, v) => v.similar_hash(state, depth - 1), + JsValue::Call(_, a, b) => { + a.similar_hash(state, depth - 1); + all_similar_hash(b, state, depth - 1); + } + JsValue::SuperCall(_, a) => { + all_similar_hash(a, state, depth - 1); + } + JsValue::MemberCall(_, a, b, c) => { + a.similar_hash(state, depth - 1); + b.similar_hash(state, depth - 1); + all_similar_hash(c, state, depth - 1); + } + JsValue::Member(_, o, p) => { + o.similar_hash(state, depth - 1); + p.similar_hash(state, depth - 1); + } + JsValue::Binary(_, a, o, b) => { + a.similar_hash(state, depth - 1); + o.hash(state); + b.similar_hash(state, depth - 1); + } + JsValue::Tenary(_, test, cons, alt) => { + test.similar_hash(state, depth - 1); + cons.similar_hash(state, depth - 1); + alt.similar_hash(state, depth - 1); + } + JsValue::Iterated(_, iterable) => { + iterable.similar_hash(state, depth - 1); + } + JsValue::TypeOf(_, operand) => { + operand.similar_hash(state, depth - 1); + } + JsValue::Module(ModuleValue { + module: v, + annotations: a, + }) => { + Hash::hash(v, state); + Hash::hash(a, state); + } + JsValue::WellKnownObject(v) => Hash::hash(v, state), + JsValue::WellKnownFunction(v) => Hash::hash(v, state), + JsValue::Unknown { + original_value: _, + reason: v, + has_side_effects, + } => { + Hash::hash(v, state); + Hash::hash(has_side_effects, state); + } + JsValue::Function(_, _, v) => v.similar_hash(state, depth - 1), + JsValue::Argument(i, v) => { + Hash::hash(i, state); + Hash::hash(v, state); + } + } + } +} + +/// The depth to use when comparing values for similarity. +const SIMILAR_EQ_DEPTH: usize = 3; +/// The depth to use when hashing values for similarity. +const SIMILAR_HASH_DEPTH: usize = 2; + +/// A wrapper around `JsValue` that implements `PartialEq` and `Hash` by +/// comparing the values with a depth of [SIMILAR_EQ_DEPTH] and hashing values +/// with a depth of [SIMILAR_HASH_DEPTH]. +struct SimilarJsValue(JsValue); + +impl PartialEq for SimilarJsValue { + fn eq(&self, other: &Self) -> bool { + self.0.similar(&other.0, SIMILAR_EQ_DEPTH) + } +} + +impl Eq for SimilarJsValue {} + +impl Hash for SimilarJsValue { + fn hash(&self, state: &mut H) { + self.0.similar_hash(state, SIMILAR_HASH_DEPTH) + } +} + +/// A list of well-known objects that have special meaning in the analysis. +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum WellKnownObjectKind { + GlobalObject, + PathModule, + PathModuleDefault, + FsModule, + FsModuleDefault, + FsModulePromises, + UrlModule, + UrlModuleDefault, + ChildProcess, + ChildProcessDefault, + OsModule, + OsModuleDefault, + NodeProcess, + NodeProcessArgv, + NodeProcessEnv, + NodePreGyp, + NodeExpressApp, + NodeProtobufLoader, + NodeBuffer, + RequireCache, +} + +impl WellKnownObjectKind { + pub fn as_define_name(&self) -> Option<&[&str]> { + match self { + Self::GlobalObject => Some(&["global"]), + Self::PathModule => Some(&["path"]), + Self::FsModule => Some(&["fs"]), + Self::UrlModule => Some(&["url"]), + Self::ChildProcess => Some(&["child_process"]), + Self::OsModule => Some(&["os"]), + Self::NodeProcess => Some(&["process"]), + Self::NodeProcessArgv => Some(&["process", "argv"]), + Self::NodeProcessEnv => Some(&["process", "env"]), + Self::NodeBuffer => Some(&["Buffer"]), + Self::RequireCache => Some(&["require", "cache"]), + _ => None, + } + } +} + +#[derive(Debug, Clone)] +pub struct RequireContextOptions { + pub dir: RcStr, + pub include_subdirs: bool, + /// this is a regex (pattern, flags) + pub filter: Regex, +} + +/// Convert an ECMAScript regex to a Rust regex. +fn regex_from_js(pattern: &str, flags: &str) -> Result { + // rust regex doesn't allow escaped slashes, but they are necessary in js + let pattern = pattern.replace("\\/", "/"); + + let mut applied_flags = String::new(); + for flag in flags.chars() { + match flag { + // indices for substring matches: not relevant for the regex itself + 'd' => {} + // global: default in rust, ignore + 'g' => {} + // case-insensitive: letters match both upper and lower case + 'i' => applied_flags.push('i'), + // multi-line mode: ^ and $ match begin/end of line + 'm' => applied_flags.push('m'), + // allow . to match \n + 's' => applied_flags.push('s'), + // Unicode support (enabled by default) + 'u' => applied_flags.push('u'), + // sticky search: not relevant for the regex itself + 'y' => {} + _ => bail!("unsupported flag `{}` in regex", flag), + } + } + + let regex = if !applied_flags.is_empty() { + format!("(?{}){}", applied_flags, pattern) + } else { + pattern + }; + + Regex::new(®ex).context("could not convert ECMAScript regex to Rust regex") +} + +/// Parse the arguments passed to a require.context invocation, validate them +/// and convert them to the appropriate rust values. +pub fn parse_require_context(args: &[JsValue]) -> Result { + if !(1..=3).contains(&args.len()) { + // https://linear.app/vercel/issue/WEB-910/add-support-for-requirecontexts-mode-argument + bail!("require.context() only supports 1-3 arguments (mode is not supported)"); + } + + let Some(dir) = args[0].as_str().map(|s| s.into()) else { + bail!("require.context(dir, ...) requires dir to be a constant string"); + }; + + let include_subdirs = if let Some(include_subdirs) = args.get(1) { + if let Some(include_subdirs) = include_subdirs.as_bool() { + include_subdirs + } else { + bail!( + "require.context(..., includeSubdirs, ...) requires includeSubdirs to be a \ + constant boolean", + ); + } + } else { + true + }; + + let filter = if let Some(filter) = args.get(2) { + if let JsValue::Constant(ConstantValue::Regex(pattern, flags)) = filter { + regex_from_js(pattern, flags)? + } else { + bail!("require.context(..., ..., filter) requires filter to be a regex"); + } + } else { + // https://webpack.js.org/api/module-methods/#requirecontext + // > optional, default /^\.\/.*$/, any file + static DEFAULT_REGEX: Lazy = Lazy::new(|| Regex::new(r"^\\./.*$").unwrap()); + + DEFAULT_REGEX.clone() + }; + + Ok(RequireContextOptions { + dir, + include_subdirs, + filter, + }) +} + +#[turbo_tasks::value(transparent)] +#[derive(Debug, Clone)] +pub struct RequireContextValue(IndexMap); + +#[turbo_tasks::value_impl] +impl RequireContextValue { + #[turbo_tasks::function] + pub async fn from_context_map(map: Vc) -> Result> { + let mut context_map = IndexMap::new(); + + for (key, entry) in map.await?.iter() { + context_map.insert(key.clone(), entry.origin_relative.clone()); + } + + Ok(Vc::cell(context_map)) + } +} + +impl Hash for RequireContextValue { + fn hash(&self, state: &mut H) { + self.0.len().hash(state); + for (i, (k, v)) in self.0.iter().enumerate() { + i.hash(state); + k.hash(state); + v.hash(state); + } + } +} + +/// A list of well-known functions that have special meaning in the analysis. +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +pub enum WellKnownFunctionKind { + ObjectAssign, + PathJoin, + PathDirname, + /// `0` is the current working directory. + PathResolve(Box), + Import, + Require, + RequireResolve, + RequireContext, + RequireContextRequire(Vc), + RequireContextRequireKeys(Vc), + RequireContextRequireResolve(Vc), + Define, + FsReadMethod(JsWord), + PathToFileUrl, + ChildProcessSpawnMethod(JsWord), + ChildProcessFork, + OsArch, + OsPlatform, + OsEndianness, + ProcessCwd, + NodePreGypFind, + NodeGypBuild, + NodeBindings, + NodeExpress, + NodeExpressSet, + NodeStrongGlobalize, + NodeStrongGlobalizeSetRootDir, + NodeResolveFrom, + NodeProtobufLoad, +} + +impl WellKnownFunctionKind { + pub fn as_define_name(&self) -> Option<&[&str]> { + match self { + Self::Import => Some(&["import"]), + Self::Require => Some(&["require"]), + Self::RequireResolve => Some(&["require", "resolve"]), + Self::RequireContext => Some(&["require", "context"]), + Self::Define => Some(&["define"]), + _ => None, + } + } +} + +fn is_unresolved(i: &Ident, unresolved_mark: Mark) -> bool { + i.span.ctxt.outer() == unresolved_mark +} + +#[doc(hidden)] +pub mod test_utils { + use anyhow::Result; + use indexmap::IndexMap; + use turbo_tasks::Vc; + use turbopack_core::{compile_time_info::CompileTimeInfo, error::PrettyPrintError}; + + use super::{ + builtin::early_replace_builtin, well_known::replace_well_known, JsValue, ModuleValue, + WellKnownFunctionKind, WellKnownObjectKind, + }; + use crate::analyzer::{ + builtin::replace_builtin, imports::ImportAnnotations, parse_require_context, + }; + + pub async fn early_visitor(mut v: JsValue) -> Result<(JsValue, bool)> { + let m = early_replace_builtin(&mut v); + Ok((v, m)) + } + + pub async fn visitor( + v: JsValue, + compile_time_info: Vc, + ) -> Result<(JsValue, bool)> { + let mut new_value = match v { + JsValue::Call( + _, + box JsValue::WellKnownFunction(WellKnownFunctionKind::Import), + ref args, + ) => match &args[0] { + JsValue::Constant(v) => JsValue::Module(ModuleValue { + module: v.to_string().into(), + annotations: ImportAnnotations::default(), + }), + _ => v.into_unknown(true, "import() non constant"), + }, + JsValue::Call( + _, + box JsValue::WellKnownFunction(WellKnownFunctionKind::RequireResolve), + ref args, + ) => match &args[0] { + JsValue::Constant(v) => (v.to_string() + "/resolved/lib/index.js").into(), + _ => v.into_unknown(true, "require.resolve non constant"), + }, + JsValue::Call( + _, + box JsValue::WellKnownFunction(WellKnownFunctionKind::RequireContext), + ref args, + ) => match parse_require_context(args) { + Ok(options) => { + let mut map = IndexMap::new(); + + map.insert("./a".into(), format!("[context: {}]/a", options.dir).into()); + map.insert("./b".into(), format!("[context: {}]/b", options.dir).into()); + map.insert("./c".into(), format!("[context: {}]/c", options.dir).into()); + + JsValue::WellKnownFunction(WellKnownFunctionKind::RequireContextRequire( + Vc::cell(map), + )) + } + Err(err) => v.into_unknown(true, PrettyPrintError(&err).to_string()), + }, + JsValue::FreeVar(ref var) => match &**var { + "import" => JsValue::WellKnownFunction(WellKnownFunctionKind::Import), + "require" => JsValue::WellKnownFunction(WellKnownFunctionKind::Require), + "define" => JsValue::WellKnownFunction(WellKnownFunctionKind::Define), + "__dirname" => "__dirname".into(), + "__filename" => "__filename".into(), + "process" => JsValue::WellKnownObject(WellKnownObjectKind::NodeProcess), + _ => v.into_unknown(true, "unknown global"), + }, + JsValue::Module(ModuleValue { + module: ref name, .. + }) => match name.as_ref() { + "path" => JsValue::WellKnownObject(WellKnownObjectKind::PathModule), + "os" => JsValue::WellKnownObject(WellKnownObjectKind::OsModule), + "process" => JsValue::WellKnownObject(WellKnownObjectKind::NodeProcess), + "@mapbox/node-pre-gyp" => JsValue::WellKnownObject(WellKnownObjectKind::NodePreGyp), + "node-pre-gyp" => JsValue::WellKnownFunction(WellKnownFunctionKind::NodeGypBuild), + _ => return Ok((v, false)), + }, + _ => { + let (mut v, m1) = replace_well_known(v, compile_time_info).await?; + let m2 = replace_builtin(&mut v); + let m = m1 || m2 || v.make_nested_operations_unknown(); + return Ok((v, m)); + } + }; + new_value.normalize_shallow(); + Ok((new_value, true)) + } +} + +#[cfg(test)] +mod tests { + use std::{mem::take, path::PathBuf, time::Instant}; + + use swc_core::{ + common::Mark, + ecma::{ + ast::EsVersion, parser::parse_file_as_program, transforms::base::resolver, + visit::VisitMutWith, + }, + testing::{fixture, run_test, NormalizedOutput}, + }; + use turbo_tasks::{util::FormatDuration, Value}; + use turbopack_core::{ + compile_time_info::CompileTimeInfo, + environment::{Environment, ExecutionEnvironment, NodeJsEnvironment}, + target::{Arch, CompileTarget, Endianness, Libc, Platform}, + }; + + use super::{ + graph::{create_graph, ConditionalKind, Effect, EffectArg, EvalContext, VarGraph}, + linker::link, + JsValue, + }; + + #[fixture("tests/analyzer/graph/**/input.js")] + fn fixture(input: PathBuf) { + crate::register(); + let graph_snapshot_path = input.with_file_name("graph.snapshot"); + let graph_explained_snapshot_path = input.with_file_name("graph-explained.snapshot"); + let graph_effects_snapshot_path = input.with_file_name("graph-effects.snapshot"); + let resolved_explained_snapshot_path = input.with_file_name("resolved-explained.snapshot"); + let resolved_effects_snapshot_path = input.with_file_name("resolved-effects.snapshot"); + let large_marker = input.with_file_name("large"); + + run_test(false, |cm, handler| { + let r = tokio::runtime::Builder::new_current_thread() + .build() + .unwrap(); + r.block_on(async move { + let fm = cm.load_file(&input).unwrap(); + + let mut m = parse_file_as_program( + &fm, + Default::default(), + EsVersion::latest(), + None, + &mut vec![], + ) + .map_err(|err| err.into_diagnostic(handler).emit())?; + + let unresolved_mark = Mark::new(); + let top_level_mark = Mark::new(); + m.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false)); + + let eval_context = EvalContext::new(&m, unresolved_mark, top_level_mark, None); + + let mut var_graph = create_graph(&m, &eval_context); + + let mut named_values = var_graph + .values + .clone() + .into_iter() + .map(|((id, ctx), value)| { + let unique = var_graph.values.keys().filter(|(i, _)| &id == i).count() == 1; + if unique { + (id.to_string(), value) + } else { + (format!("{id}{ctx:?}"), value) + } + }) + .collect::>(); + named_values.sort_by(|a, b| a.0.cmp(&b.0)); + + fn explain_all(values: &[(String, JsValue)]) -> String { + values + .iter() + .map(|(id, value)| { + let (explainer, hints) = value.explain(10, 5); + format!("{id} = {explainer}{hints}") + }) + .collect::>() + .join("\n\n") + } + + { + // Dump snapshot of graph + + let large = large_marker.exists(); + + if !large { + NormalizedOutput::from(format!("{:#?}", named_values)) + .compare_to_file(&graph_snapshot_path) + .unwrap(); + } + NormalizedOutput::from(explain_all(&named_values)) + .compare_to_file(&graph_explained_snapshot_path) + .unwrap(); + if !large { + NormalizedOutput::from(format!("{:#?}", var_graph.effects)) + .compare_to_file(&graph_effects_snapshot_path) + .unwrap(); + } + } + + { + // Dump snapshot of resolved + + let start = Instant::now(); + let mut resolved = Vec::new(); + for (id, val) in named_values.iter() { + let val = val.clone(); + let start = Instant::now(); + let res = resolve(&var_graph, val).await; + let time = start.elapsed(); + if time.as_millis() > 1 { + println!( + "linking {} {id} took {}", + input.display(), + FormatDuration(time) + ); + } + + resolved.push((id.clone(), res)); + } + let time = start.elapsed(); + if time.as_millis() > 1 { + println!("linking {} took {}", input.display(), FormatDuration(time)); + } + + let start = Instant::now(); + let explainer = explain_all(&resolved); + let time = start.elapsed(); + if time.as_millis() > 1 { + println!( + "explaining {} took {}", + input.display(), + FormatDuration(time) + ); + } + + NormalizedOutput::from(explainer) + .compare_to_file(&resolved_explained_snapshot_path) + .unwrap(); + } + + { + // Dump snapshot of resolved effects + + let start = Instant::now(); + let mut resolved = Vec::new(); + let mut queue = take(&mut var_graph.effects) + .into_iter() + .map(|effect| (0, effect)) + .rev() + .collect::>(); + let mut i = 0; + while let Some((parent, effect)) = queue.pop() { + i += 1; + let start = Instant::now(); + async fn handle_args( + args: Vec, + queue: &mut Vec<(usize, Effect)>, + var_graph: &VarGraph, + i: usize, + ) -> Vec { + let mut new_args = Vec::new(); + for arg in args { + match arg { + EffectArg::Value(v) => { + new_args.push(resolve(var_graph, v).await); + } + EffectArg::Closure(v, effects) => { + new_args.push(resolve(var_graph, v).await); + queue.extend( + effects.effects.into_iter().rev().map(|e| (i, e)), + ); + } + EffectArg::Spread => { + new_args.push(JsValue::unknown_empty(true, "spread")); + } + } + } + new_args + } + match effect { + Effect::Conditional { + condition, kind, .. + } => { + let condition = resolve(&var_graph, condition).await; + resolved.push((format!("{parent} -> {i} conditional"), condition)); + match *kind { + ConditionalKind::If { then } => { + queue + .extend(then.effects.into_iter().rev().map(|e| (i, e))); + } + ConditionalKind::IfElse { then, r#else } + | ConditionalKind::Ternary { then, r#else } => { + queue.extend( + r#else.effects.into_iter().rev().map(|e| (i, e)), + ); + queue + .extend(then.effects.into_iter().rev().map(|e| (i, e))); + } + ConditionalKind::And { expr } + | ConditionalKind::Or { expr } + | ConditionalKind::NullishCoalescing { expr } => { + queue + .extend(expr.effects.into_iter().rev().map(|e| (i, e))); + } + }; + } + Effect::Call { func, args, .. } => { + let func = resolve(&var_graph, func).await; + let new_args = handle_args(args, &mut queue, &var_graph, i).await; + resolved.push(( + format!("{parent} -> {i} call"), + JsValue::call(Box::new(func), new_args), + )); + } + Effect::FreeVar { var, .. } => { + resolved.push((format!("{parent} -> {i} free var"), var)); + } + Effect::MemberCall { + obj, prop, args, .. + } => { + let obj = resolve(&var_graph, obj).await; + let prop = resolve(&var_graph, prop).await; + let new_args = handle_args(args, &mut queue, &var_graph, i).await; + resolved.push(( + format!("{parent} -> {i} member call"), + JsValue::member_call(Box::new(obj), Box::new(prop), new_args), + )); + } + _ => {} + } + let time = start.elapsed(); + if time.as_millis() > 1 { + println!( + "linking effect {} took {}", + input.display(), + FormatDuration(time) + ); + } + } + let time = start.elapsed(); + if time.as_millis() > 1 { + println!( + "linking effects {} took {}", + input.display(), + FormatDuration(time) + ); + } + + let start = Instant::now(); + let explainer = explain_all(&resolved); + let time = start.elapsed(); + if time.as_millis() > 1 { + println!( + "explaining effects {} took {}", + input.display(), + FormatDuration(time) + ); + } + + NormalizedOutput::from(explainer) + .compare_to_file(&resolved_effects_snapshot_path) + .unwrap(); + } + + Ok(()) + }) + }) + .unwrap(); + } + + async fn resolve(var_graph: &VarGraph, val: JsValue) -> JsValue { + turbo_tasks_testing::VcStorage::with(async { + let compile_time_info = CompileTimeInfo::builder(Environment::new(Value::new( + ExecutionEnvironment::NodeJsLambda( + NodeJsEnvironment { + compile_target: CompileTarget { + arch: Arch::X64, + platform: Platform::Linux, + endianness: Endianness::Little, + libc: Libc::Glibc, + } + .into(), + ..Default::default() + } + .into(), + ), + ))) + .cell(); + link( + var_graph, + val, + &super::test_utils::early_visitor, + &(|val| Box::pin(super::test_utils::visitor(val, compile_time_info))), + Default::default(), + ) + .await + }) + .await + .unwrap() + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/top_level_await.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/top_level_await.rs new file mode 100644 index 0000000000000..61d44e29c0473 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/top_level_await.rs @@ -0,0 +1,73 @@ +use swc_core::{ + common::Span, + ecma::{ + ast::*, + visit::{noop_visit_type, Visit, VisitWith}, + }, +}; + +/// Checks if the program contains a top level await, if it does it will returns +/// the span of the first await. +pub(crate) fn has_top_level_await(m: &Program) -> Option { + let mut visitor = TopLevelAwaitVisitor::default(); + + m.visit_with(&mut visitor); + + visitor.top_level_await_span +} + +#[derive(Default)] +struct TopLevelAwaitVisitor { + top_level_await_span: Option, +} + +macro_rules! noop { + ($name:ident, $T:path) => { + fn $name(&mut self, _: &$T) {} + }; +} + +impl Visit for TopLevelAwaitVisitor { + fn visit_await_expr(&mut self, n: &AwaitExpr) { + if self.top_level_await_span.is_none() { + self.top_level_await_span = Some(n.span); + } + } + + // prevent non top level items from visiting their children + noop_visit_type!(); + noop!(visit_arrow_expr, ArrowExpr); + noop!(visit_constructor, Constructor); + noop!(visit_function, Function); + + fn visit_getter_prop(&mut self, n: &GetterProp) { + n.key.visit_children_with(self); + } + + fn visit_setter_prop(&mut self, n: &SetterProp) { + n.key.visit_children_with(self); + } + + fn visit_class_prop(&mut self, n: &ClassProp) { + n.key.visit_children_with(self); + n.decorators.visit_children_with(self); + if n.is_static { + n.value.visit_children_with(self); + } + } + + fn visit_private_prop(&mut self, n: &PrivateProp) { + n.decorators.visit_children_with(self); + if n.is_static { + n.value.visit_children_with(self); + } + } + + fn visit_auto_accessor(&mut self, n: &AutoAccessor) { + n.key.visit_children_with(self); + n.decorators.visit_children_with(self); + if n.is_static { + n.value.visit_children_with(self); + } + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/well_known.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/well_known.rs new file mode 100644 index 0000000000000..04bd40eb43563 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/well_known.rs @@ -0,0 +1,802 @@ +use std::mem::take; + +use anyhow::Result; +use turbo_tasks::Vc; +use turbopack_core::compile_time_info::CompileTimeInfo; +use url::Url; + +use super::{ + imports::ImportAnnotations, ConstantValue, JsValue, ModuleValue, WellKnownFunctionKind, + WellKnownObjectKind, +}; +use crate::analyzer::RequireContextValue; + +pub async fn replace_well_known( + value: JsValue, + compile_time_info: Vc, +) -> Result<(JsValue, bool)> { + Ok(match value { + JsValue::Call(_, box JsValue::WellKnownFunction(kind), args) => ( + well_known_function_call( + kind, + JsValue::unknown_empty(false, "this is not analyzed yet"), + args, + compile_time_info, + ) + .await?, + true, + ), + JsValue::Call(usize, callee, args) => { + // var fs = require('fs'), fs = __importStar(fs); + // TODO(WEB-552) this is not correct and has many false positives! + if args.len() == 1 { + if let JsValue::WellKnownObject(_) = &args[0] { + return Ok((args[0].clone(), true)); + } + } + (JsValue::Call(usize, callee, args), false) + } + JsValue::Member(_, box JsValue::WellKnownObject(kind), box prop) => { + well_known_object_member(kind, prop, compile_time_info).await? + } + JsValue::Member(_, box JsValue::WellKnownFunction(kind), box prop) => { + well_known_function_member(kind, prop) + } + _ => (value, false), + }) +} + +pub async fn well_known_function_call( + kind: WellKnownFunctionKind, + _this: JsValue, + args: Vec, + compile_time_info: Vc, +) -> Result { + Ok(match kind { + WellKnownFunctionKind::ObjectAssign => object_assign(args), + WellKnownFunctionKind::PathJoin => path_join(args), + WellKnownFunctionKind::PathDirname => path_dirname(args), + WellKnownFunctionKind::PathResolve(cwd) => path_resolve(*cwd, args), + WellKnownFunctionKind::Import => JsValue::unknown( + JsValue::call(Box::new(JsValue::WellKnownFunction(kind)), args), + true, + "import() is not supported", + ), + WellKnownFunctionKind::Require => require(args), + WellKnownFunctionKind::RequireContextRequire(value) => { + require_context_require(value, args).await? + } + WellKnownFunctionKind::RequireContextRequireKeys(value) => { + require_context_require_keys(value, args).await? + } + WellKnownFunctionKind::RequireContextRequireResolve(value) => { + require_context_require_resolve(value, args).await? + } + WellKnownFunctionKind::PathToFileUrl => path_to_file_url(args), + WellKnownFunctionKind::OsArch => compile_time_info + .environment() + .compile_target() + .await? + .arch + .as_str() + .into(), + WellKnownFunctionKind::OsPlatform => compile_time_info + .environment() + .compile_target() + .await? + .platform + .as_str() + .into(), + WellKnownFunctionKind::ProcessCwd => { + if let Some(cwd) = &*compile_time_info.environment().cwd().await? { + cwd.clone().into() + } else { + JsValue::unknown( + JsValue::call(Box::new(JsValue::WellKnownFunction(kind)), args), + true, + "process.cwd is not specified in the environment", + ) + } + } + WellKnownFunctionKind::OsEndianness => compile_time_info + .environment() + .compile_target() + .await? + .endianness + .as_str() + .into(), + WellKnownFunctionKind::NodeExpress => { + JsValue::WellKnownObject(WellKnownObjectKind::NodeExpressApp) + } + // bypass + WellKnownFunctionKind::NodeResolveFrom => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeResolveFrom) + } + + _ => JsValue::unknown( + JsValue::call(Box::new(JsValue::WellKnownFunction(kind)), args), + true, + "unsupported function", + ), + }) +} + +pub fn object_assign(args: Vec) -> JsValue { + if args.iter().all(|arg| matches!(arg, JsValue::Object { .. })) { + if let Some(mut merged_object) = args.into_iter().reduce(|mut acc, cur| { + if let JsValue::Object { parts, mutable, .. } = &mut acc { + if let JsValue::Object { + parts: next_parts, + mutable: next_mutable, + .. + } = &cur + { + parts.extend_from_slice(next_parts); + *mutable |= *next_mutable; + } + } + acc + }) { + merged_object.update_total_nodes(); + merged_object + } else { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::ObjectAssign, + )), + vec![], + ), + true, + "empty arguments for Object.assign", + ) + } + } else { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::ObjectAssign, + )), + args, + ), + true, + "only const object assign is supported", + ) + } +} + +pub fn path_join(args: Vec) -> JsValue { + if args.is_empty() { + return ".".into(); + } + let mut parts = Vec::new(); + for item in args { + if let Some(str) = item.as_str() { + let splitted = str.split('/'); + parts.extend(splitted.map(|s| s.into())); + } else { + parts.push(item); + } + } + let mut results_final = Vec::new(); + let mut results: Vec = Vec::new(); + for item in parts { + if let Some(str) = item.as_str() { + match str { + "" | "." => { + if results_final.is_empty() && results.is_empty() { + results_final.push(item); + } + } + ".." => { + if results.pop().is_none() { + results_final.push(item); + } + } + _ => results.push(item), + } + } else { + results_final.append(&mut results); + results_final.push(item); + } + } + results_final.append(&mut results); + let mut iter = results_final.into_iter(); + let first = iter.next().unwrap(); + let mut last_is_str = first.as_str().is_some(); + results.push(first); + for part in iter { + let is_str = part.as_str().is_some(); + if last_is_str && is_str { + results.push("/".into()); + } else { + results.push(JsValue::alternatives(vec!["/".into(), "".into()])); + } + results.push(part); + last_is_str = is_str; + } + JsValue::concat(results) +} + +pub fn path_resolve(cwd: JsValue, mut args: Vec) -> JsValue { + // If no path segments are passed, `path.resolve()` will return the absolute + // path of the current working directory. + if args.is_empty() { + return JsValue::unknown_empty(false, "cwd is not static analyzable"); + } + if args.len() == 1 { + return args.into_iter().next().unwrap(); + } + + // path.resolve stops at the string starting with `/` + for (idx, arg) in args.iter().enumerate().rev() { + if idx != 0 { + if let Some(str) = arg.as_str() { + if str.starts_with('/') { + return path_resolve(cwd, args.drain(idx..).collect()); + } + } + } + } + + let mut results_final = Vec::new(); + let mut results: Vec = Vec::new(); + for item in args { + if let Some(str) = item.as_str() { + for str in str.split('/') { + match str { + "" | "." => { + if results_final.is_empty() && results.is_empty() { + results_final.push(str.into()); + } + } + ".." => { + if results.pop().is_none() { + results_final.push("..".into()); + } + } + _ => results.push(str.into()), + } + } + } else { + results_final.append(&mut results); + results_final.push(item); + } + } + results_final.append(&mut results); + let mut iter = results_final.into_iter(); + let first = iter.next().unwrap(); + + let is_already_absolute = + first.is_empty_string() == Some(true) || first.starts_with("/") == Some(true); + + let mut last_was_str = first.as_str().is_some(); + + if !is_already_absolute { + results.push(cwd); + } + + results.push(first); + for part in iter { + let is_str = part.as_str().is_some(); + if last_was_str && is_str { + results.push("/".into()); + } else { + results.push(JsValue::alternatives(vec!["/".into(), "".into()])); + } + results.push(part); + last_was_str = is_str; + } + + JsValue::concat(results) +} + +pub fn path_dirname(mut args: Vec) -> JsValue { + if let Some(arg) = args.iter_mut().next() { + if let Some(str) = arg.as_str() { + if let Some(i) = str.rfind('/') { + return JsValue::Constant(ConstantValue::Str(str[..i].to_string().into())); + } else { + return JsValue::Constant(ConstantValue::Str("".into())); + } + } else if let JsValue::Concat(_, items) = arg { + if let Some(last) = items.last_mut() { + if let Some(str) = last.as_str() { + if let Some(i) = str.rfind('/') { + *last = JsValue::Constant(ConstantValue::Str(str[..i].to_string().into())); + return take(arg); + } + } + } + } + } + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::PathDirname, + )), + args, + ), + true, + "path.dirname with unsupported arguments", + ) +} + +pub fn require(args: Vec) -> JsValue { + if args.len() == 1 { + if let Some(s) = args[0].as_str() { + JsValue::Module(ModuleValue { + module: s.into(), + annotations: ImportAnnotations::default(), + }) + } else { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction(WellKnownFunctionKind::Require)), + args, + ), + true, + "only constant argument is supported", + ) + } + } else { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction(WellKnownFunctionKind::Require)), + args, + ), + true, + "only a single argument is supported", + ) + } +} + +/// (try to) statically evaluate `require.context(...)()` +pub async fn require_context_require( + val: Vc, + args: Vec, +) -> Result { + if args.is_empty() { + return Ok(JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequire(val), + )), + args, + ), + true, + "require.context(...).require() requires an argument specifying the module path", + )); + } + + let Some(s) = args[0].as_str() else { + return Ok(JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequire(val), + )), + args, + ), + true, + "require.context(...).require() only accepts a single, constant string argument", + )); + }; + + let map = val.await?; + let Some(m) = map.get(s) else { + return Ok(JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequire(val), + )), + args, + ), + true, + "require.context(...).require() can only be called with an argument that's in the \ + context", + )); + }; + + Ok(JsValue::Module(ModuleValue { + module: m.to_string().into(), + annotations: ImportAnnotations::default(), + })) +} + +/// (try to) statically evaluate `require.context(...).keys()` +pub async fn require_context_require_keys( + val: Vc, + args: Vec, +) -> Result { + Ok(if args.is_empty() { + let map = val.await?; + JsValue::array(map.keys().cloned().map(|k| k.into()).collect()) + } else { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequireKeys(val), + )), + args, + ), + true, + "require.context(...).keys() does not accept arguments", + ) + }) +} + +/// (try to) statically evaluate `require.context(...).resolve()` +pub async fn require_context_require_resolve( + val: Vc, + args: Vec, +) -> Result { + if args.len() != 1 { + return Ok(JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequireResolve(val), + )), + args, + ), + true, + "require.context(...).resolve() only accepts a single, constant string argument", + )); + } + + let Some(s) = args[0].as_str() else { + return Ok(JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequireResolve(val), + )), + args, + ), + true, + "require.context(...).resolve() only accepts a single, constant string argument", + )); + }; + + let map = val.await?; + let Some(m) = map.get(s) else { + return Ok(JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequireResolve(val), + )), + args, + ), + true, + "require.context(...).resolve() can only be called with an argument that's in the \ + context", + )); + }; + + Ok(m.as_str().into()) +} + +pub fn path_to_file_url(args: Vec) -> JsValue { + if args.len() == 1 { + if let Some(path) = args[0].as_str() { + Url::from_file_path(path) + .map(Box::new) + .map(JsValue::Url) + .unwrap_or_else(|_| { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::PathToFileUrl, + )), + args, + ), + true, + "url not parseable: path is relative or has an invalid prefix", + ) + }) + } else { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::PathToFileUrl, + )), + args, + ), + true, + "only constant argument is supported", + ) + } + } else { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::PathToFileUrl, + )), + args, + ), + true, + "only a single argument is supported", + ) + } +} + +pub fn well_known_function_member(kind: WellKnownFunctionKind, prop: JsValue) -> (JsValue, bool) { + let new_value = match (kind, prop.as_str()) { + (WellKnownFunctionKind::Require, Some("resolve")) => { + JsValue::WellKnownFunction(WellKnownFunctionKind::RequireResolve) + } + (WellKnownFunctionKind::Require, Some("cache")) => { + JsValue::WellKnownObject(WellKnownObjectKind::RequireCache) + } + (WellKnownFunctionKind::Require, Some("context")) => { + JsValue::WellKnownFunction(WellKnownFunctionKind::RequireContext) + } + (WellKnownFunctionKind::RequireContextRequire(val), Some("resolve")) => { + JsValue::WellKnownFunction(WellKnownFunctionKind::RequireContextRequireResolve(val)) + } + (WellKnownFunctionKind::RequireContextRequire(val), Some("keys")) => { + JsValue::WellKnownFunction(WellKnownFunctionKind::RequireContextRequireKeys(val)) + } + (WellKnownFunctionKind::NodeStrongGlobalize, Some("SetRootDir")) => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeStrongGlobalizeSetRootDir) + } + (WellKnownFunctionKind::NodeResolveFrom, Some("silent")) => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeResolveFrom) + } + #[allow(unreachable_patterns)] + (kind, _) => { + return ( + JsValue::member(Box::new(JsValue::WellKnownFunction(kind)), Box::new(prop)), + false, + ) + } + }; + (new_value, true) +} + +pub async fn well_known_object_member( + kind: WellKnownObjectKind, + prop: JsValue, + compile_time_info: Vc, +) -> Result<(JsValue, bool)> { + let new_value = match kind { + WellKnownObjectKind::GlobalObject => global_object(prop), + WellKnownObjectKind::PathModule | WellKnownObjectKind::PathModuleDefault => { + path_module_member(kind, prop) + } + WellKnownObjectKind::FsModule + | WellKnownObjectKind::FsModuleDefault + | WellKnownObjectKind::FsModulePromises => fs_module_member(kind, prop), + WellKnownObjectKind::UrlModule | WellKnownObjectKind::UrlModuleDefault => { + url_module_member(kind, prop) + } + WellKnownObjectKind::ChildProcess | WellKnownObjectKind::ChildProcessDefault => { + child_process_module_member(kind, prop) + } + WellKnownObjectKind::OsModule | WellKnownObjectKind::OsModuleDefault => { + os_module_member(kind, prop) + } + WellKnownObjectKind::NodeProcess => node_process_member(prop, compile_time_info).await?, + WellKnownObjectKind::NodePreGyp => node_pre_gyp(prop), + WellKnownObjectKind::NodeExpressApp => express(prop), + WellKnownObjectKind::NodeProtobufLoader => protobuf_loader(prop), + #[allow(unreachable_patterns)] + _ => { + return Ok(( + JsValue::member(Box::new(JsValue::WellKnownObject(kind)), Box::new(prop)), + false, + )) + } + }; + Ok((new_value, true)) +} + +fn global_object(prop: JsValue) -> JsValue { + match prop.as_str() { + Some("assign") => JsValue::WellKnownFunction(WellKnownFunctionKind::ObjectAssign), + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject(WellKnownObjectKind::GlobalObject)), + Box::new(prop), + ), + true, + "unsupported property on global Object", + ), + } +} + +pub fn path_module_member(kind: WellKnownObjectKind, prop: JsValue) -> JsValue { + match (kind, prop.as_str()) { + (.., Some("join")) => JsValue::WellKnownFunction(WellKnownFunctionKind::PathJoin), + (.., Some("dirname")) => JsValue::WellKnownFunction(WellKnownFunctionKind::PathDirname), + (.., Some("resolve")) => { + // cwd is added while resolving in refernces.rs + JsValue::WellKnownFunction(WellKnownFunctionKind::PathResolve(Box::new(JsValue::from( + "", + )))) + } + (WellKnownObjectKind::PathModule, Some("default")) => { + JsValue::WellKnownObject(WellKnownObjectKind::PathModuleDefault) + } + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject(WellKnownObjectKind::PathModule)), + Box::new(prop), + ), + true, + "unsupported property on Node.js path module", + ), + } +} + +pub fn fs_module_member(kind: WellKnownObjectKind, prop: JsValue) -> JsValue { + if let Some(word) = prop.as_str() { + match (kind, word) { + ( + .., + "realpath" | "realpathSync" | "stat" | "statSync" | "existsSync" + | "createReadStream" | "exists" | "open" | "openSync" | "readFile" | "readFileSync", + ) => { + return JsValue::WellKnownFunction(WellKnownFunctionKind::FsReadMethod( + word.into(), + )); + } + (WellKnownObjectKind::FsModule | WellKnownObjectKind::FsModuleDefault, "promises") => { + return JsValue::WellKnownObject(WellKnownObjectKind::FsModulePromises) + } + (WellKnownObjectKind::FsModule, "default") => { + return JsValue::WellKnownObject(WellKnownObjectKind::FsModuleDefault) + } + _ => {} + } + } + JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject(WellKnownObjectKind::FsModule)), + Box::new(prop), + ), + true, + "unsupported property on Node.js fs module", + ) +} + +pub fn url_module_member(kind: WellKnownObjectKind, prop: JsValue) -> JsValue { + match (kind, prop.as_str()) { + (.., Some("pathToFileURL")) => { + JsValue::WellKnownFunction(WellKnownFunctionKind::PathToFileUrl) + } + (WellKnownObjectKind::UrlModuleDefault, Some("default")) => { + JsValue::WellKnownObject(WellKnownObjectKind::UrlModuleDefault) + } + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject(WellKnownObjectKind::UrlModule)), + Box::new(prop), + ), + true, + "unsupported property on Node.js url module", + ), + } +} + +pub fn child_process_module_member(kind: WellKnownObjectKind, prop: JsValue) -> JsValue { + let prop_str = prop.as_str(); + match (kind, prop_str) { + (.., Some("spawn" | "spawnSync" | "execFile" | "execFileSync")) => { + JsValue::WellKnownFunction(WellKnownFunctionKind::ChildProcessSpawnMethod( + prop_str.unwrap().into(), + )) + } + (.., Some("fork")) => JsValue::WellKnownFunction(WellKnownFunctionKind::ChildProcessFork), + (WellKnownObjectKind::ChildProcess, Some("default")) => { + JsValue::WellKnownObject(WellKnownObjectKind::ChildProcessDefault) + } + + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject(WellKnownObjectKind::ChildProcess)), + Box::new(prop), + ), + true, + "unsupported property on Node.js child_process module", + ), + } +} + +fn os_module_member(kind: WellKnownObjectKind, prop: JsValue) -> JsValue { + match (kind, prop.as_str()) { + (.., Some("platform")) => JsValue::WellKnownFunction(WellKnownFunctionKind::OsPlatform), + (.., Some("arch")) => JsValue::WellKnownFunction(WellKnownFunctionKind::OsArch), + (.., Some("endianness")) => JsValue::WellKnownFunction(WellKnownFunctionKind::OsEndianness), + (WellKnownObjectKind::OsModule, Some("default")) => { + JsValue::WellKnownObject(WellKnownObjectKind::OsModuleDefault) + } + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject(WellKnownObjectKind::OsModule)), + Box::new(prop), + ), + true, + "unsupported property on Node.js os module", + ), + } +} + +async fn node_process_member( + prop: JsValue, + compile_time_info: Vc, +) -> Result { + Ok(match prop.as_str() { + Some("arch") => compile_time_info + .environment() + .compile_target() + .await? + .arch + .as_str() + .into(), + Some("platform") => compile_time_info + .environment() + .compile_target() + .await? + .platform + .as_str() + .into(), + Some("cwd") => JsValue::WellKnownFunction(WellKnownFunctionKind::ProcessCwd), + Some("argv") => JsValue::WellKnownObject(WellKnownObjectKind::NodeProcessArgv), + Some("env") => JsValue::WellKnownObject(WellKnownObjectKind::NodeProcessEnv), + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject(WellKnownObjectKind::NodeProcess)), + Box::new(prop), + ), + true, + "unsupported property on Node.js process object", + ), + }) +} + +fn node_pre_gyp(prop: JsValue) -> JsValue { + match prop.as_str() { + Some("find") => JsValue::WellKnownFunction(WellKnownFunctionKind::NodePreGypFind), + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject(WellKnownObjectKind::NodePreGyp)), + Box::new(prop), + ), + true, + "unsupported property on @mapbox/node-pre-gyp module", + ), + } +} + +fn express(prop: JsValue) -> JsValue { + match prop.as_str() { + Some("set") => JsValue::WellKnownFunction(WellKnownFunctionKind::NodeExpressSet), + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject( + WellKnownObjectKind::NodeExpressApp, + )), + Box::new(prop), + ), + true, + "unsupported property on require('express')() object", + ), + } +} + +fn protobuf_loader(prop: JsValue) -> JsValue { + match prop.as_str() { + Some("load") | Some("loadSync") => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeProtobufLoad) + } + _ => JsValue::unknown( + JsValue::member( + Box::new(JsValue::WellKnownObject( + WellKnownObjectKind::NodeProtobufLoader, + )), + Box::new(prop), + ), + true, + "unsupported property on require('@grpc/proto-loader') object", + ), + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/annotations.rs b/turbopack/crates/turbopack-ecmascript/src/annotations.rs new file mode 100644 index 0000000000000..d6c2ba6847ea5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/annotations.rs @@ -0,0 +1,34 @@ +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{Expr, KeyValueProp, ObjectLit, Prop, PropName, PropOrSpread}, +}; + +/// Changes the chunking type for the annotated import +pub const ANNOTATION_CHUNKING_TYPE: &str = "turbopack-chunking-type"; + +/// Enables a specified transition for the annotated import +pub const ANNOTATION_TRANSITION: &str = "turbopack-transition"; + +pub fn with_chunking_type(chunking_type: &str) -> Box { + with_clause(&[(ANNOTATION_CHUNKING_TYPE, chunking_type)]) +} + +pub fn with_transition(transition_name: &str) -> Box { + with_clause(&[(ANNOTATION_TRANSITION, transition_name)]) +} + +pub fn with_clause<'a>( + entries: impl IntoIterator, +) -> Box { + Box::new(ObjectLit { + span: DUMMY_SP, + props: entries.into_iter().map(|(k, v)| with_prop(k, v)).collect(), + }) +} + +fn with_prop(key: &str, value: &str) -> PropOrSpread { + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Str(key.into()), + value: Box::new(Expr::Lit(value.into())), + }))) +} diff --git a/turbopack/crates/turbopack-ecmascript/src/async_chunk/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/async_chunk/chunk_item.rs new file mode 100644 index 0000000000000..6fd76155f6e6b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/async_chunk/chunk_item.rs @@ -0,0 +1,215 @@ +use anyhow::Result; +use indoc::formatdoc; +use turbo_tasks::{RcStr, TryJoinIterExt, Value, Vc}; +use turbopack_core::{ + chunk::{ + ChunkData, ChunkItem, ChunkItemExt, ChunkType, ChunkableModule, ChunkingContext, + ChunkingContextExt, ChunksData, + }, + ident::AssetIdent, + module::Module, + output::OutputAssets, + reference::{ModuleReferences, SingleOutputAssetReference}, +}; + +use crate::{ + async_chunk::module::AsyncLoaderModule, + chunk::{ + data::EcmascriptChunkData, EcmascriptChunkItem, EcmascriptChunkItemContent, + EcmascriptChunkPlaceable, EcmascriptChunkType, + }, + utils::StringifyJs, +}; + +#[turbo_tasks::value(shared)] +pub struct AsyncLoaderChunkItem { + pub module: Vc, + pub chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl AsyncLoaderChunkItem { + #[turbo_tasks::function] + pub(super) async fn chunks(self: Vc) -> Result> { + let this = self.await?; + let module = this.module.await?; + if let Some(chunk_items) = module.availability_info.available_chunk_items() { + if chunk_items + .get( + module + .inner + .as_chunk_item(Vc::upcast(this.chunking_context)) + .resolve() + .await?, + ) + .await? + .is_some() + { + return Ok(Vc::cell(vec![])); + } + } + Ok(this.chunking_context.chunk_group_assets( + Vc::upcast(module.inner), + Value::new(module.availability_info), + )) + } + + #[turbo_tasks::function] + async fn chunks_data(self: Vc) -> Result> { + let this = self.await?; + Ok(ChunkData::from_assets( + this.chunking_context.output_root(), + self.chunks(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for AsyncLoaderChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let this = self.await?; + let module = this.module.await?; + + let id = if let Some(placeable) = + Vc::try_resolve_downcast::>(module.inner).await? + { + Some( + placeable + .as_chunk_item(Vc::upcast(this.chunking_context)) + .id() + .await?, + ) + } else { + None + }; + let id = id.as_deref(); + + let chunks_data = self.chunks_data().await?; + let chunks_data = chunks_data.iter().try_join().await?; + let chunks_data: Vec<_> = chunks_data + .iter() + .map(|chunk_data| EcmascriptChunkData::new(chunk_data)) + .collect(); + + let code = match (id, chunks_data.is_empty()) { + (Some(id), true) => { + formatdoc! { + r#" + __turbopack_export_value__((__turbopack_import__) => {{ + return Promise.resolve().then(() => {{ + return __turbopack_import__({id}); + }}); + }}); + "#, + id = StringifyJs(id), + } + } + (Some(id), false) => { + formatdoc! { + r#" + __turbopack_export_value__((__turbopack_import__) => {{ + return Promise.all({chunks:#}.map((chunk) => __turbopack_load__(chunk))).then(() => {{ + return __turbopack_import__({id}); + }}); + }}); + "#, + chunks = StringifyJs(&chunks_data), + id = StringifyJs(id), + } + } + (None, true) => { + formatdoc! { + r#" + __turbopack_export_value__((__turbopack_import__) => {{ + return Promise.resolve(); + }}); + "#, + } + } + (None, false) => { + formatdoc! { + r#" + __turbopack_export_value__((__turbopack_import__) => {{ + return Promise.all({chunks:#}.map((chunk) => __turbopack_load__(chunk))).then(() => {{}}); + }}); + "#, + chunks = StringifyJs(&chunks_data), + } + } + }; + + Ok(EcmascriptChunkItemContent { + inner_code: code.into(), + ..Default::default() + } + .into()) + } +} + +#[turbo_tasks::function] +fn chunk_reference_description() -> Vc { + Vc::cell("chunk".into()) +} + +#[turbo_tasks::value_impl] +impl ChunkItem for AsyncLoaderChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + async fn content_ident(&self) -> Result> { + let mut ident = self.module.ident(); + if let Some(available_chunk_items) = + self.module.await?.availability_info.available_chunk_items() + { + ident = ident.with_modifier(Vc::cell( + available_chunk_items.hash().await?.to_string().into(), + )); + } + Ok(ident) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let chunks = self.chunks(); + + Ok(Vc::cell( + chunks + .await? + .iter() + .copied() + .map(|chunk| { + Vc::upcast(SingleOutputAssetReference::new( + chunk, + chunk_reference_description(), + )) + }) + .collect(), + )) + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/async_chunk/mod.rs b/turbopack/crates/turbopack-ecmascript/src/async_chunk/mod.rs new file mode 100644 index 0000000000000..dd8dfeedf3096 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/async_chunk/mod.rs @@ -0,0 +1,2 @@ +pub mod chunk_item; +pub mod module; diff --git a/turbopack/crates/turbopack-ecmascript/src/async_chunk/module.rs b/turbopack/crates/turbopack-ecmascript/src/async_chunk/module.rs new file mode 100644 index 0000000000000..460067b09c86a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/async_chunk/module.rs @@ -0,0 +1,92 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{availability_info::AvailabilityInfo, ChunkableModule, ChunkingContext}, + ident::AssetIdent, + module::Module, + reference::{ModuleReferences, SingleModuleReference}, +}; + +use crate::async_chunk::chunk_item::AsyncLoaderChunkItem; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("async loader".into()) +} + +/// The AsyncLoaderModule is a module that loads another module async, by +/// putting it into a separate chunk group. +#[turbo_tasks::value] +pub struct AsyncLoaderModule { + pub inner: Vc>, + pub chunking_context: Vc>, + pub availability_info: AvailabilityInfo, +} + +#[turbo_tasks::value_impl] +impl AsyncLoaderModule { + #[turbo_tasks::function] + pub fn new( + module: Vc>, + chunking_context: Vc>, + availability_info: Value, + ) -> Vc { + Self::cell(AsyncLoaderModule { + inner: module, + chunking_context, + availability_info: availability_info.into_value(), + }) + } + + #[turbo_tasks::function] + pub fn asset_ident_for(module: Vc>) -> Vc { + module.ident().with_modifier(modifier()) + } +} + +#[turbo_tasks::function] +fn inner_module_reference_description() -> Vc { + Vc::cell("async module".into()) +} + +#[turbo_tasks::value_impl] +impl Module for AsyncLoaderModule { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + Self::asset_ident_for(self.inner) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + Ok(Vc::cell(vec![Vc::upcast(SingleModuleReference::new( + Vc::upcast(self.await?.inner), + inner_module_reference_description(), + ))])) + } +} + +#[turbo_tasks::value_impl] +impl Asset for AsyncLoaderModule { + #[turbo_tasks::function] + fn content(&self) -> Vc { + todo!() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for AsyncLoaderModule { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + AsyncLoaderChunkItem { + chunking_context, + module: self, + } + .cell(), + )) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/chunk_type.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/chunk_type.rs new file mode 100644 index 0000000000000..ba01ceadc3902 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/chunk_type.rs @@ -0,0 +1,88 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{RcStr, TryJoinIterExt, ValueDefault, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ + AsyncModuleInfo, Chunk, ChunkItem, ChunkItemWithAsyncModuleInfo, ChunkType, ChunkingContext, + }, + output::OutputAssets, +}; + +use super::{EcmascriptChunk, EcmascriptChunkContent, EcmascriptChunkItem}; + +#[turbo_tasks::value] +#[derive(Default)] +pub struct EcmascriptChunkType {} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptChunkType { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell("ecmascript".into()) + } +} + +#[turbo_tasks::value_impl] +impl ChunkType for EcmascriptChunkType { + #[turbo_tasks::function] + async fn chunk( + &self, + chunking_context: Vc>, + chunk_items: Vec, + referenced_output_assets: Vc, + ) -> Result>> { + let Some(chunking_context) = + Vc::try_resolve_downcast::>(chunking_context).await? + else { + bail!("Ecmascript chunking context not found"); + }; + let content = EcmascriptChunkContent { + chunk_items: chunk_items + .iter() + .map(|(chunk_item, async_info)| async move { + let Some(chunk_item) = + Vc::try_resolve_downcast::>(*chunk_item) + .await? + else { + bail!( + "Chunk item is not an ecmascript chunk item but reporting chunk type \ + ecmascript" + ); + }; + Ok((chunk_item, *async_info)) + }) + .try_join() + .await?, + referenced_output_assets: referenced_output_assets.await?.clone_value(), + } + .cell(); + Ok(Vc::upcast(EcmascriptChunk::new(chunking_context, content))) + } + + #[turbo_tasks::function] + async fn chunk_item_size( + &self, + _chunking_context: Vc>, + chunk_item: Vc>, + async_module_info: Option>, + ) -> Result> { + let Some(chunk_item) = + Vc::try_resolve_downcast::>(chunk_item).await? + else { + bail!("Chunk item is not an ecmascript chunk item but reporting chunk type ecmascript"); + }; + Ok(Vc::cell( + chunk_item + .content_with_async_module_info(async_module_info) + .await + .map_or(0, |content| content.inner_code.len()), + )) + } +} + +#[turbo_tasks::value_impl] +impl ValueDefault for EcmascriptChunkType { + #[turbo_tasks::function] + fn value_default() -> Vc { + Self::default().cell() + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/content.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/content.rs new file mode 100644 index 0000000000000..6c159d507a02e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/content.rs @@ -0,0 +1,15 @@ +use turbo_tasks::Vc; +use turbopack_core::{chunk::AsyncModuleInfo, output::OutputAsset}; + +use super::item::EcmascriptChunkItem; + +type EcmascriptChunkItemWithAsyncInfo = ( + Vc>, + Option>, +); + +#[turbo_tasks::value(shared)] +pub struct EcmascriptChunkContent { + pub chunk_items: Vec, + pub referenced_output_assets: Vec>>, +} diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/data.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/data.rs new file mode 100644 index 0000000000000..cdb0c862bc207 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/data.rs @@ -0,0 +1,40 @@ +use serde::Serialize; +use turbo_tasks::ReadRef; +use turbopack_core::chunk::{ChunkData, ModuleId}; + +#[derive(Serialize, Hash, PartialEq, Eq)] +#[serde(untagged)] +pub enum EcmascriptChunkData<'a> { + Simple(&'a str), + #[serde(rename_all = "camelCase")] + WithRuntimeInfo { + path: &'a str, + #[serde(skip_serializing_if = "<[_]>::is_empty", default)] + included: &'a [ReadRef], + #[serde(skip_serializing_if = "<[_]>::is_empty", default)] + excluded: &'a [ReadRef], + #[serde(skip_serializing_if = "<[_]>::is_empty", default)] + module_chunks: &'a [String], + }, +} + +impl<'a> EcmascriptChunkData<'a> { + pub fn new(chunk_data: &ChunkData) -> EcmascriptChunkData { + let ChunkData { + path, + included, + excluded, + module_chunks, + references: _, + } = chunk_data; + if included.is_empty() && excluded.is_empty() && module_chunks.is_empty() { + return EcmascriptChunkData::Simple(path); + } + EcmascriptChunkData::WithRuntimeInfo { + path, + included, + excluded, + module_chunks, + } + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs new file mode 100644 index 0000000000000..4b5c654454493 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/item.rs @@ -0,0 +1,269 @@ +use std::io::Write; + +use anyhow::{bail, Result}; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, Upcast, ValueToString, Vc}; +use turbo_tasks_fs::rope::Rope; +use turbopack_core::{ + chunk::{AsyncModuleInfo, ChunkItem, ChunkItemExt, ChunkingContext}, + code_builder::{Code, CodeBuilder}, + error::PrettyPrintError, + issue::{code_gen::CodeGenerationIssue, IssueExt, IssueSeverity, StyledString}, + source_map::GenerateSourceMap, +}; + +use crate::{ + references::async_module::{AsyncModuleOptions, OptionAsyncModuleOptions}, + utils::FormatIter, + EcmascriptModuleContent, EcmascriptOptions, +}; + +#[turbo_tasks::value(shared)] +#[derive(Default, Clone)] +pub struct EcmascriptChunkItemContent { + pub inner_code: Rope, + pub source_map: Option>>, + pub options: EcmascriptChunkItemOptions, + pub placeholder_for_future_extensions: (), +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItemContent { + #[turbo_tasks::function] + pub async fn new( + content: Vc, + chunking_context: Vc>, + options: Vc, + async_module_options: Vc, + ) -> Result> { + let refresh = options.await?.refresh; + let externals = *chunking_context + .environment() + .supports_commonjs_externals() + .await?; + + let content = content.await?; + let async_module = async_module_options.await?.clone_value(); + + Ok(EcmascriptChunkItemContent { + inner_code: content.inner_code.clone(), + source_map: content.source_map, + options: if content.is_esm { + EcmascriptChunkItemOptions { + strict: true, + refresh, + externals, + async_module, + ..Default::default() + } + } else { + if async_module.is_some() { + bail!("CJS module can't be async."); + } + + EcmascriptChunkItemOptions { + refresh, + externals, + // These things are not available in ESM + module: true, + exports: true, + require: true, + this: true, + ..Default::default() + } + }, + ..Default::default() + } + .cell()) + } + + #[turbo_tasks::function] + pub async fn module_factory(self: Vc) -> Result> { + let this = self.await?; + let mut args = vec![ + "r: __turbopack_require__", + "f: __turbopack_module_context__", + "i: __turbopack_import__", + "s: __turbopack_esm__", + "v: __turbopack_export_value__", + "n: __turbopack_export_namespace__", + "c: __turbopack_cache__", + "M: __turbopack_modules__", + "l: __turbopack_load__", + "j: __turbopack_dynamic__", + "P: __turbopack_resolve_absolute_path__", + "U: __turbopack_relative_url__", + "R: __turbopack_resolve_module_id_path__", + "g: global", + // HACK + "__dirname", + ]; + if this.options.async_module.is_some() { + args.push("a: __turbopack_async_module__"); + } + if this.options.externals { + args.push("x: __turbopack_external_require__"); + args.push("y: __turbopack_external_import__"); + } + if this.options.refresh { + args.push("k: __turbopack_refresh__"); + } + if this.options.module || this.options.refresh { + args.push("m: module"); + } + if this.options.exports { + args.push("e: exports"); + } + if this.options.require { + args.push("t: require"); + } + if this.options.wasm { + args.push("w: __turbopack_wasm__"); + args.push("u: __turbopack_wasm_module__"); + } + let mut code = CodeBuilder::default(); + let args = FormatIter(|| args.iter().copied().intersperse(", ")); + if this.options.this { + writeln!(code, "(function({{ {} }}) {{ !function() {{", args,)?; + } else { + writeln!(code, "(({{ {} }}) => (() => {{", args,)?; + } + if this.options.strict { + code += "\"use strict\";\n\n"; + } else { + code += "\n"; + } + + if this.options.async_module.is_some() { + code += "__turbopack_async_module__(async (__turbopack_handle_async_dependencies__, \ + __turbopack_async_result__) => { try {\n"; + } + + code.push_source(&this.inner_code, this.source_map); + + if let Some(opts) = &this.options.async_module { + write!( + code, + "__turbopack_async_result__();\n}} catch(e) {{ __turbopack_async_result__(e); }} \ + }}, {});", + opts.has_top_level_await + )?; + } + + if this.options.this { + code += "\n}.call(this) })"; + } else { + code += "\n})())"; + } + Ok(code.build().cell()) + } +} + +#[derive(PartialEq, Eq, Default, Debug, Clone, Serialize, Deserialize, TraceRawVcs)] +pub struct EcmascriptChunkItemOptions { + /// Whether this chunk item should be in "use strict" mode. + pub strict: bool, + /// Whether this chunk item's module factory should include a + /// `__turbopack_refresh__` argument. + pub refresh: bool, + /// Whether this chunk item's module factory should include a `module` + /// argument. + pub module: bool, + /// Whether this chunk item's module factory should include an `exports` + /// argument. + pub exports: bool, + /// Whether this chunk item's module factory should include a `require` + /// argument. + pub require: bool, + /// Whether this chunk item's module factory should include a + /// `__turbopack_external_require__` argument. + pub externals: bool, + /// Whether this chunk item's module is async (either has a top level await + /// or is importing async modules). + pub async_module: Option, + pub this: bool, + /// Whether this chunk item's module factory should include + /// `__turbopack_wasm__` to load WebAssembly. + pub wasm: bool, + pub placeholder_for_future_extensions: (), +} + +#[turbo_tasks::value_trait] +pub trait EcmascriptChunkItem: ChunkItem { + fn content(self: Vc) -> Vc; + fn content_with_async_module_info( + self: Vc, + _async_module_info: Option>, + ) -> Vc { + self.content() + } + fn chunking_context(self: Vc) -> Vc>; + + /// Specifies which availablility information the chunk item needs for code + /// generation + fn need_async_module_info(self: Vc) -> Vc { + Vc::cell(false) + } +} + +pub trait EcmascriptChunkItemExt: Send { + /// Generates the module factory for this chunk item. + fn code(self: Vc, async_module_info: Option>) -> Vc; +} + +impl EcmascriptChunkItemExt for T +where + T: Upcast>, +{ + /// Generates the module factory for this chunk item. + fn code(self: Vc, async_module_info: Option>) -> Vc { + module_factory_with_code_generation_issue(Vc::upcast(self), async_module_info) + } +} + +#[turbo_tasks::function] +async fn module_factory_with_code_generation_issue( + chunk_item: Vc>, + async_module_info: Option>, +) -> Result> { + Ok( + match chunk_item + .content_with_async_module_info(async_module_info) + .module_factory() + .resolve() + .await + { + Ok(factory) => factory, + Err(error) => { + let id = chunk_item.id().to_string().await; + let id = id.as_ref().map_or_else(|_| "unknown", |id| &**id); + let error = error.context(format!( + "An error occurred while generating the chunk item {}", + id + )); + let error_message = format!("{}", PrettyPrintError(&error)).into(); + let js_error_message = serde_json::to_string(&error_message)?; + CodeGenerationIssue { + severity: IssueSeverity::Error.cell(), + path: chunk_item.asset_ident().path(), + title: StyledString::Text("Code generation for chunk item errored".into()) + .cell(), + message: StyledString::Text(error_message).cell(), + } + .cell() + .emit(); + let mut code = CodeBuilder::default(); + code += "(() => {{\n\n"; + writeln!(code, "throw new Error({error});", error = &js_error_message)?; + code += "\n}})"; + code.build().cell() + } + }, + ) +} + +#[turbo_tasks::value(transparent)] +pub struct EcmascriptChunkItemsChunk(Vec>>); + +#[turbo_tasks::value(transparent)] +pub struct EcmascriptChunkItems(pub(super) Vec>>); diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/mod.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/mod.rs new file mode 100644 index 0000000000000..a45ad1374fe72 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/mod.rs @@ -0,0 +1,227 @@ +pub(crate) mod chunk_type; +pub(crate) mod content; +pub(crate) mod data; +pub(crate) mod item; +pub(crate) mod placeable; + +use std::fmt::Write; + +use anyhow::{bail, Result}; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::FileSystem; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{Chunk, ChunkItem, ChunkingContext, ModuleIds}, + ident::AssetIdent, + introspect::{ + module::IntrospectableModule, + utils::{children_from_output_assets, content_to_details}, + Introspectable, IntrospectableChildren, + }, + output::OutputAssets, + server_fs::ServerFileSystem, +}; + +pub use self::{ + chunk_type::EcmascriptChunkType, + content::EcmascriptChunkContent, + data::EcmascriptChunkData, + item::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemExt, + EcmascriptChunkItemOptions, + }, + placeable::{EcmascriptChunkPlaceable, EcmascriptChunkPlaceables, EcmascriptExports}, +}; + +#[turbo_tasks::value] +pub struct EcmascriptChunk { + pub chunking_context: Vc>, + pub content: Vc, +} + +#[turbo_tasks::value(transparent)] +pub struct EcmascriptChunks(Vec>); + +#[turbo_tasks::value_impl] +impl EcmascriptChunk { + #[turbo_tasks::function] + pub async fn new( + chunking_context: Vc>, + content: Vc, + ) -> Result> { + Ok(EcmascriptChunk { + chunking_context, + content, + } + .cell()) + } + + #[turbo_tasks::function] + pub async fn entry_ids(self: Vc) -> Result> { + // TODO return something usefull + Ok(Vc::cell(Default::default())) + } +} + +#[turbo_tasks::function] +fn chunk_item_key() -> Vc { + Vc::cell("chunk item".into()) +} + +#[turbo_tasks::function] +fn availability_root_key() -> Vc { + Vc::cell("current_availability_root".into()) +} + +#[turbo_tasks::value_impl] +impl Chunk for EcmascriptChunk { + #[turbo_tasks::function] + async fn ident(self: Vc) -> Result> { + let this = self.await?; + + let mut assets = Vec::new(); + + let EcmascriptChunkContent { chunk_items, .. } = &*this.content.await?; + let mut common_path = if let Some((chunk_item, _)) = chunk_items.first() { + let path = chunk_item.asset_ident().path().resolve().await?; + Some((path, path.await?)) + } else { + None + }; + + // The included chunk items describe the chunk uniquely + let chunk_item_key = chunk_item_key(); + for &(chunk_item, _) in chunk_items.iter() { + if let Some((common_path_vc, common_path_ref)) = common_path.as_mut() { + let path = chunk_item.asset_ident().path().await?; + while !path.is_inside_or_equal_ref(common_path_ref) { + let parent = common_path_vc.parent().resolve().await?; + if parent == *common_path_vc { + common_path = None; + break; + } + *common_path_vc = parent; + *common_path_ref = (*common_path_vc).await?; + } + } + assets.push((chunk_item_key, chunk_item.content_ident())); + } + + // Make sure the idents are resolved + for (_, ident) in assets.iter_mut() { + *ident = ident.resolve().await?; + } + + let ident = AssetIdent { + path: if let Some((common_path, _)) = common_path { + common_path + } else { + ServerFileSystem::new().root() + }, + query: Vc::::default(), + fragment: None, + assets, + modifiers: Vec::new(), + part: None, + layer: None, + }; + + Ok(AssetIdent::new(Value::new(ident))) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let content = this.content.await?; + Ok(Vc::cell(content.referenced_output_assets.clone())) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptChunk { + #[turbo_tasks::function] + async fn to_string(self: Vc) -> Result> { + Ok(Vc::cell( + format!("chunk {}", self.ident().to_string().await?).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunk { + #[turbo_tasks::function] + pub fn chunk_content(&self) -> Vc { + self.content + } + + #[turbo_tasks::function] + pub async fn chunk_items_count(&self) -> Result> { + Ok(Vc::cell(self.content.await?.chunk_items.len())) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptChunk { + #[turbo_tasks::function] + fn content(self: Vc) -> Result> { + bail!("EcmascriptChunk::content() is not implemented") + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("ecmascript chunk".into()) +} + +#[turbo_tasks::function] +fn chunk_item_module_key() -> Vc { + Vc::cell("module".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for EcmascriptChunk { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + fn title(self: Vc) -> Vc { + self.path().to_string() + } + + #[turbo_tasks::function] + async fn details(self: Vc) -> Result> { + let content = content_to_details(self.content()); + let mut details = String::new(); + let this = self.await?; + let chunk_content = this.content.await?; + details += "Chunk items:\n\n"; + for (chunk_item, _) in chunk_content.chunk_items.iter() { + writeln!(details, "- {}", chunk_item.asset_ident().to_string().await?)?; + } + details += "\nContent:\n\n"; + write!(details, "{}", content.await?)?; + Ok(Vc::cell(details.into())) + } + + #[turbo_tasks::function] + async fn children(self: Vc) -> Result> { + let mut children = children_from_output_assets(self.references()) + .await? + .clone_value(); + let chunk_item_module_key = chunk_item_module_key(); + for &(chunk_item, _) in self.await?.content.await?.chunk_items.iter() { + children.insert(( + chunk_item_module_key, + IntrospectableModule::new(chunk_item.module()), + )); + } + Ok(Vc::cell(children)) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk/placeable.rs b/turbopack/crates/turbopack-ecmascript/src/chunk/placeable.rs new file mode 100644 index 0000000000000..b4c13b0d3ea36 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/chunk/placeable.rs @@ -0,0 +1,230 @@ +use anyhow::Result; +use turbo_tasks::{TryFlatJoinIterExt, Vc}; +use turbo_tasks_fs::{glob::Glob, FileJsonContent, FileSystemPath}; +use turbopack_core::{ + asset::Asset, + chunk::ChunkableModule, + error::PrettyPrintError, + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, + module::Module, + resolve::{find_context_file, package_json, FindContextFileResult}, +}; + +use crate::references::{ + async_module::OptionAsyncModule, + esm::{EsmExport, EsmExports}, +}; + +#[turbo_tasks::value_trait] +pub trait EcmascriptChunkPlaceable: ChunkableModule + Module + Asset { + fn get_exports(self: Vc) -> Vc; + fn get_async_module(self: Vc) -> Vc { + Vc::cell(None) + } + fn is_marked_as_side_effect_free( + self: Vc, + side_effect_free_packages: Vc, + ) -> Vc { + is_marked_as_side_effect_free(self.ident().path(), side_effect_free_packages) + } +} + +#[turbo_tasks::value] +enum SideEffectsValue { + None, + Constant(bool), + Glob(Vc), +} + +#[turbo_tasks::function] +async fn side_effects_from_package_json( + package_json: Vc, +) -> Result> { + if let FileJsonContent::Content(content) = &*package_json.read_json().await? { + if let Some(side_effects) = content.get("sideEffects") { + if let Some(side_effects) = side_effects.as_bool() { + return Ok(SideEffectsValue::Constant(side_effects).cell()); + } else if let Some(side_effects) = side_effects.as_array() { + let globs = side_effects + .iter() + .filter_map(|side_effect| { + if let Some(side_effect) = side_effect.as_str() { + if side_effect.contains('/') { + Some(Glob::new(side_effect.into())) + } else { + Some(Glob::new(format!("**/{side_effect}").into())) + } + } else { + SideEffectsInPackageJsonIssue { + path: package_json, + description: Some( + StyledString::Text( + format!( + "Each element in sideEffects must be a string, but \ + found {:?}", + side_effect + ) + .into(), + ) + .cell(), + ), + } + .cell() + .emit(); + None + } + }) + .map(|glob| async move { + match glob.resolve().await { + Ok(glob) => Ok(Some(glob)), + Err(err) => { + SideEffectsInPackageJsonIssue { + path: package_json, + description: Some( + StyledString::Text( + format!( + "Invalid glob in sideEffects: {}", + PrettyPrintError(&err) + ) + .into(), + ) + .cell(), + ), + } + .cell() + .emit(); + Ok(None) + } + } + }) + .try_flat_join() + .await?; + return Ok( + SideEffectsValue::Glob(Glob::alternatives(globs).resolve().await?).cell(), + ); + } else { + SideEffectsInPackageJsonIssue { + path: package_json, + description: Some( + StyledString::Text( + format!( + "sideEffects must be a boolean or an array, but found {:?}", + side_effects + ) + .into(), + ) + .cell(), + ), + } + .cell() + .emit(); + } + } + } + Ok(SideEffectsValue::None.cell()) +} + +#[turbo_tasks::value] +struct SideEffectsInPackageJsonIssue { + path: Vc, + description: Option>, +} + +#[turbo_tasks::value_impl] +impl Issue for SideEffectsInPackageJsonIssue { + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Parse.into() + } + + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Warning.cell() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.path + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Invalid value for sideEffects in package.json".into()).cell() + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(self.description) + } +} + +#[turbo_tasks::function] +pub async fn is_marked_as_side_effect_free( + path: Vc, + side_effect_free_packages: Vc, +) -> Result> { + if side_effect_free_packages.await?.execute(&path.await?.path) { + return Ok(Vc::cell(true)); + } + + let find_package_json = find_context_file(path.parent(), package_json()).await?; + + if let FindContextFileResult::Found(package_json, _) = *find_package_json { + match *side_effects_from_package_json(package_json).await? { + SideEffectsValue::None => {} + SideEffectsValue::Constant(side_effects) => return Ok(Vc::cell(!side_effects)), + SideEffectsValue::Glob(glob) => { + if let Some(rel_path) = package_json + .parent() + .await? + .get_relative_path_to(&*path.await?) + { + return Ok(Vc::cell(!glob.await?.execute(&rel_path))); + } + } + } + } + + Ok(Vc::cell(false)) +} + +#[turbo_tasks::value(transparent)] +pub struct EcmascriptChunkPlaceables(Vec>>); + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceables { + #[turbo_tasks::function] + pub fn empty() -> Vc { + Vc::cell(Vec::new()) + } +} + +#[turbo_tasks::value(shared)] +pub enum EcmascriptExports { + EsmExports(Vc), + DynamicNamespace, + CommonJs, + Value, + None, +} + +#[turbo_tasks::value_impl] +impl EcmascriptExports { + #[turbo_tasks::function] + pub async fn needs_facade(&self) -> Result> { + Ok(match self { + EcmascriptExports::EsmExports(exports) => { + let exports = exports.await?; + let has_reexports = !exports.star_exports.is_empty() + || exports.exports.iter().any(|(_, export)| { + matches!( + export, + EsmExport::ImportedBinding(..) | EsmExport::ImportedNamespace(_) + ) + }); + Vc::cell(has_reexports) + } + _ => Vc::cell(false), + }) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs b/turbopack/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs new file mode 100644 index 0000000000000..0c81b36c2d946 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/chunk_group_files_asset.rs @@ -0,0 +1,262 @@ +use anyhow::Result; +use indexmap::IndexSet; +use turbo_tasks::{RcStr, TryJoinIterExt, Value, ValueToString, Vc}; +use turbo_tasks_fs::{File, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ + availability_info::AvailabilityInfo, ChunkItem, ChunkType, ChunkableModule, + ChunkingContext, ChunkingContextExt, EvaluatableAssets, + }, + ident::AssetIdent, + introspect::{ + module::IntrospectableModule, utils::content_to_details, Introspectable, + IntrospectableChildren, + }, + module::Module, + output::{OutputAsset, OutputAssets}, + reference::{ + ModuleReference, ModuleReferences, SingleModuleReference, SingleOutputAssetReference, + }, +}; + +use crate::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkType, EcmascriptExports, + }, + utils::StringifyJs, + EcmascriptModuleAsset, +}; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("chunk group files".into()) +} + +/// An asset that exports a list of chunk URLs by putting the [asset] into a +/// ChunkGroup with the provided ChunkingContext. +#[turbo_tasks::value(shared)] +pub struct ChunkGroupFilesAsset { + pub module: Vc>, + pub client_root: Vc, + pub chunking_context: Vc>, + pub runtime_entries: Option>, +} + +#[turbo_tasks::function] +fn module_description() -> Vc { + Vc::cell("module".into()) +} + +#[turbo_tasks::function] +fn runtime_entry_description() -> Vc { + Vc::cell("runtime entry".into()) +} + +#[turbo_tasks::value_impl] +impl Module for ChunkGroupFilesAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.module.ident().with_modifier(modifier()) + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let mut references: Vec>> = vec![Vc::upcast( + SingleModuleReference::new(Vc::upcast(self.module), module_description()), + )]; + + if let Some(runtime_entries) = self.runtime_entries { + references.extend(runtime_entries.await?.iter().map(|&entry| { + Vc::upcast(SingleModuleReference::new( + Vc::upcast(entry), + runtime_entry_description(), + )) + })); + } + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for ChunkGroupFilesAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + AssetContent::file(File::from(RcStr::from("// Chunking only content")).into()) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for ChunkGroupFilesAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + let this = self.await?; + Ok(Vc::upcast( + ChunkGroupFilesChunkItem { + chunking_context, + client_root: this.client_root, + inner: self, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for ChunkGroupFilesAsset { + #[turbo_tasks::function] + fn get_exports(&self) -> Vc { + EcmascriptExports::Value.cell() + } +} + +#[turbo_tasks::value] +struct ChunkGroupFilesChunkItem { + chunking_context: Vc>, + client_root: Vc, + inner: Vc, +} + +#[turbo_tasks::value_impl] +impl ChunkGroupFilesChunkItem { + #[turbo_tasks::function] + async fn chunks(self: Vc) -> Result> { + let this = self.await?; + let inner = this.inner.await?; + let chunks = if let Some(ecma) = + Vc::try_resolve_downcast_type::(inner.module).await? + { + inner.chunking_context.evaluated_chunk_group_assets( + inner.module.ident(), + inner + .runtime_entries + .unwrap_or_else(EvaluatableAssets::empty) + .with_entry(Vc::upcast(ecma)), + Value::new(AvailabilityInfo::Root), + ) + } else { + inner + .chunking_context + .root_chunk_group_assets(Vc::upcast(inner.module)) + }; + Ok(chunks) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for ChunkGroupFilesChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let chunks = self.chunks(); + let this = self.await?; + let module = this.inner.await?; + let client_root = module.client_root.await?; + let chunks_paths = chunks + .await? + .iter() + .map(|chunk| chunk.ident().path()) + .try_join() + .await?; + let chunks_paths: Vec<_> = chunks_paths + .iter() + .filter_map(|path| client_root.get_path_to(path)) + .collect(); + Ok(EcmascriptChunkItemContent { + inner_code: format!( + "__turbopack_export_value__({:#});\n", + StringifyJs(&chunks_paths) + ) + .into(), + ..Default::default() + } + .cell()) + } +} + +#[turbo_tasks::function] +fn chunk_group_chunk_reference_description() -> Vc { + Vc::cell("chunk group chunk".into()) +} + +#[turbo_tasks::value_impl] +impl ChunkItem for ChunkGroupFilesChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.inner.ident() + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let chunks = self.chunks(); + + Ok(Vc::cell( + chunks + .await? + .iter() + .copied() + .map(|chunk| { + SingleOutputAssetReference::new( + chunk, + chunk_group_chunk_reference_description(), + ) + }) + .map(Vc::upcast) + .collect(), + )) + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.inner) + } +} + +#[turbo_tasks::value_impl] +impl Introspectable for ChunkGroupFilesAsset { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + Vc::cell("chunk group files asset".into()) + } + + #[turbo_tasks::function] + fn details(self: Vc) -> Vc { + content_to_details(self.content()) + } + + #[turbo_tasks::function] + fn title(self: Vc) -> Vc { + self.ident().to_string() + } + + #[turbo_tasks::function] + async fn children(self: Vc) -> Result> { + let mut children = IndexSet::new(); + children.insert(( + Vc::cell("inner asset".into()), + IntrospectableModule::new(Vc::upcast(self.await?.module)), + )); + Ok(Vc::cell(children)) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/code_gen.rs b/turbopack/crates/turbopack-ecmascript/src/code_gen.rs new file mode 100644 index 0000000000000..f6fbac3fd42b3 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/code_gen.rs @@ -0,0 +1,141 @@ +use serde::{Deserialize, Serialize}; +use swc_core::ecma::visit::{AstParentKind, VisitMut}; +use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, Vc}; +use turbopack_core::chunk::{AsyncModuleInfo, ChunkingContext}; + +/// impl of code generation inferred from a ModuleReference. +/// This is rust only and can't be implemented by non-rust plugins. +#[turbo_tasks::value( + shared, + serialization = "none", + eq = "manual", + into = "new", + cell = "new" +)] +pub struct CodeGeneration { + /// ast nodes matching the span will be visitor by the visitor + #[turbo_tasks(debug_ignore, trace_ignore)] + pub visitors: Vec<(Vec, Box)>, +} + +pub trait VisitorFactory: Send + Sync { + fn create<'a>(&'a self) -> Box; +} + +#[turbo_tasks::value_trait] +pub trait CodeGenerateable { + fn code_generation( + self: Vc, + chunking_context: Vc>, + ) -> Vc; +} + +#[turbo_tasks::value_trait] +pub trait CodeGenerateableWithAsyncModuleInfo { + fn code_generation( + self: Vc, + chunking_context: Vc>, + async_module_info: Option>, + ) -> Vc; +} + +#[derive(Clone, Copy, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, ValueDebugFormat)] +pub enum CodeGen { + CodeGenerateable(Vc>), + CodeGenerateableWithAsyncModuleInfo(Vc>), +} + +#[turbo_tasks::value(transparent)] +pub struct CodeGenerateables(Vec); + +pub fn path_to( + path: &[AstParentKind], + f: impl FnMut(&AstParentKind) -> bool, +) -> Vec { + if let Some(pos) = path.iter().rev().position(f) { + let index = path.len() - pos - 1; + path[..index].to_vec() + } else { + path.to_vec() + } +} + +/// Creates a single-method visitor that will visit the AST nodes matching the +/// provided path. +/// +/// If you pass in `exact`, the visitor will only visit the nodes that match the +/// path exactly. Otherwise, the visitor will visit the closest matching parent +/// node in the path. +/// +/// Refer to the [swc_core::ecma::visit::VisitMut] trait for a list of all +/// possible visit methods. +#[macro_export] +macro_rules! create_visitor { + // This rule needs to be first, otherwise we run into the following error: + // expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `:` + // This is a regression on nightly. + (visit_mut_program($arg:ident: &mut Program) $b:block) => {{ + struct Visitor { + visit_mut_program: T, + } + + impl $crate::code_gen::VisitorFactory + for Box> + { + fn create<'a>(&'a self) -> Box { + Box::new(&**self) + } + } + + impl<'a, T: Fn(&mut swc_core::ecma::ast::Program) + Send + Sync> swc_core::ecma::visit::VisitMut + for &'a Visitor + { + fn visit_mut_program(&mut self, $arg: &mut swc_core::ecma::ast::Program) { + (self.visit_mut_program)($arg); + } + } + + ( + Vec::new(), + Box::new(Box::new(Visitor { + visit_mut_program: move |$arg: &mut swc_core::ecma::ast::Program| $b, + })) as Box, + ) + }}; + (exact $ast_path:expr, $name:ident($arg:ident: &mut $ty:ident) $b:block) => { + $crate::create_visitor!(__ $ast_path.to_vec(), $name($arg: &mut $ty) $b) + }; + ($ast_path:expr, $name:ident($arg:ident: &mut $ty:ident) $b:block) => { + $crate::create_visitor!(__ $crate::code_gen::path_to(&$ast_path, |n| { + matches!(n, swc_core::ecma::visit::AstParentKind::$ty(_)) + }), $name($arg: &mut $ty) $b) + }; + (__ $ast_path:expr, $name:ident($arg:ident: &mut $ty:ident) $b:block) => {{ + struct Visitor { + $name: T, + } + + impl $crate::code_gen::VisitorFactory + for Box> + { + fn create<'a>(&'a self) -> Box { + Box::new(&**self) + } + } + + impl<'a, T: Fn(&mut swc_core::ecma::ast::$ty) + Send + Sync> swc_core::ecma::visit::VisitMut + for &'a Visitor + { + fn $name(&mut self, $arg: &mut swc_core::ecma::ast::$ty) { + (self.$name)($arg); + } + } + + ( + $ast_path, + Box::new(Box::new(Visitor { + $name: move |$arg: &mut swc_core::ecma::ast::$ty| $b, + })) as Box, + ) + }}; +} diff --git a/turbopack/crates/turbopack-ecmascript/src/errors.rs b/turbopack/crates/turbopack-ecmascript/src/errors.rs new file mode 100644 index 0000000000000..f344245bf7025 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/errors.rs @@ -0,0 +1,20 @@ +pub mod failed_to_analyse { + pub mod ecmascript { + pub const DYNAMIC_IMPORT: &str = "TP1001"; + pub const REQUIRE: &str = "TP1002"; + pub const REQUIRE_RESOLVE: &str = "TP1003"; + pub const FS_METHOD: &str = "TP1004"; + pub const CHILD_PROCESS_SPAWN: &str = "TP1005"; + pub const PATH_METHOD: &str = "TP1006"; + pub const REQUIRE_CONTEXT: &str = "TP1007"; + pub const NODE_PRE_GYP_FIND: &str = "TP1100"; + pub const NODE_GYP_BUILD: &str = "TP1101"; + pub const NODE_BINDINGS: &str = "TP1102"; + pub const NODE_EXPRESS: &str = "TP1103"; + pub const NODE_RESOLVE_FROM: &str = "TP1104"; + pub const NODE_PROTOBUF_LOADER: &str = "TP1105"; + pub const AMD_DEFINE: &str = "TP1200"; + pub const NEW_URL_IMPORT_META: &str = "TP1201"; + pub const FREE_VAR_REFERENCE: &str = "TP1202"; + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/lib.rs b/turbopack/crates/turbopack-ecmascript/src/lib.rs new file mode 100644 index 0000000000000..ea2d6e7ed3536 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/lib.rs @@ -0,0 +1,876 @@ +// Needed for swc visit_ macros +#![allow(non_local_definitions)] +#![feature(box_patterns)] +#![feature(min_specialization)] +#![feature(iter_intersperse)] +#![feature(int_roundings)] +#![feature(arbitrary_self_types)] +#![recursion_limit = "256"] + +pub mod analyzer; +pub mod annotations; +pub mod async_chunk; +pub mod chunk; +pub mod chunk_group_files_asset; +pub mod code_gen; +mod errors; +pub mod magic_identifier; +pub mod manifest; +pub mod minify; +pub mod parse; +mod path_visitor; +pub mod references; +pub mod side_effect_optimization; +pub(crate) mod special_cases; +pub(crate) mod static_code; +mod swc_comments; +pub mod text; +pub(crate) mod transform; +pub mod tree_shake; +pub mod typescript; +pub mod utils; +pub mod webpack; + +use std::fmt::{Display, Formatter}; + +use anyhow::Result; +use chunk::EcmascriptChunkItem; +use code_gen::CodeGenerateable; +pub use parse::ParseResultSourceMap; +use parse::{parse, ParseResult}; +use path_visitor::ApplyVisitors; +use references::esm::UrlRewriteBehavior; +pub use references::{AnalyzeEcmascriptModuleResult, TURBOPACK_HELPER}; +use serde::{Deserialize, Serialize}; +pub use static_code::StaticEcmascriptCode; +use swc_core::{ + common::GLOBALS, + ecma::{ + codegen::{text_writer::JsWriter, Emitter}, + visit::{VisitMutWith, VisitMutWithPath}, + }, +}; +pub use transform::{ + CustomTransformer, EcmascriptInputTransform, EcmascriptInputTransforms, OptionTransformPlugin, + TransformContext, TransformPlugin, UnsupportedServerActionIssue, +}; +use turbo_tasks::{ + trace::TraceRawVcs, RcStr, ReadRef, TaskInput, TryJoinIterExt, Value, ValueToString, Vc, +}; +use turbo_tasks_fs::{rope::Rope, FileJsonContent, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ + AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext, EvaluatableAsset, + }, + compile_time_info::CompileTimeInfo, + context::AssetContext, + ident::AssetIdent, + module::{Module, OptionModule}, + reference::ModuleReferences, + reference_type::InnerAssets, + resolve::{ + find_context_file, origin::ResolveOrigin, package_json, parse::Request, + FindContextFileResult, ModulePart, + }, + source::Source, + source_map::{GenerateSourceMap, OptionSourceMap}, +}; +// TODO remove this +pub use turbopack_resolve::ecmascript as resolve; + +use self::{ + chunk::{EcmascriptChunkItemContent, EcmascriptChunkType, EcmascriptExports}, + code_gen::{CodeGen, CodeGenerateableWithAsyncModuleInfo, CodeGenerateables, VisitorFactory}, + tree_shake::asset::EcmascriptModulePartAsset, +}; +use crate::{ + chunk::EcmascriptChunkPlaceable, + references::{analyse_ecmascript_module, async_module::OptionAsyncModule}, + transform::remove_shebang, +}; + +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Hash, Debug, Clone, Copy, Default, TaskInput)] +pub enum SpecifiedModuleType { + #[default] + Automatic, + CommonJs, + EcmaScript, +} + +#[derive( + PartialOrd, + Ord, + PartialEq, + Eq, + Hash, + Debug, + Clone, + Copy, + Default, + Serialize, + Deserialize, + TraceRawVcs, +)] +#[serde(rename_all = "kebab-case")] +pub enum TreeShakingMode { + #[default] + ModuleFragments, + ReexportsOnly, +} + +#[turbo_tasks::value(transparent)] +pub struct OptionTreeShaking(pub Option); + +#[turbo_tasks::value(shared, serialization = "auto_for_input")] +#[derive(Hash, Debug, Default, Copy, Clone)] +pub struct EcmascriptOptions { + pub refresh: bool, + /// variant of tree shaking to use + pub tree_shaking_mode: Option, + /// module is forced to a specific type (happens e. g. for .cjs and .mjs) + pub specified_module_type: SpecifiedModuleType, + /// Determines how to treat `new URL(...)` rewrites. + /// This allows to construct url depends on the different building context, + /// e.g. SSR, CSR, or Node.js. + pub url_rewrite_behavior: Option, + /// External imports should used `__turbopack_import__` instead of + /// `__turbopack_require__` and become async module references. + pub import_externals: bool, + /// Ignore very dynamic requests which doesn't have any static known part. + /// If false, they will reference the whole directory. If true, they won't + /// reference anything and lead to an runtime error instead. + pub ignore_dynamic_requests: bool, + + /// The list of export names that should make tree shaking bail off. This is + /// required because tree shaking can split imports like `export const + /// runtime = 'edge'` as a separate module. + pub special_exports: Vc>, +} + +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Hash, Debug, Copy, Clone)] +pub enum EcmascriptModuleAssetType { + /// Module with EcmaScript code + Ecmascript, + /// Module with TypeScript code without types + Typescript { + // parse JSX syntax. + tsx: bool, + // follow references to imported types. + analyze_types: bool, + }, + /// Module with TypeScript declaration code + TypescriptDeclaration, +} + +impl Display for EcmascriptModuleAssetType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + EcmascriptModuleAssetType::Ecmascript => write!(f, "ecmascript"), + EcmascriptModuleAssetType::Typescript { tsx, analyze_types } => { + write!(f, "typescript")?; + if *tsx { + write!(f, "with JSX")?; + } + if *analyze_types { + write!(f, "with types")?; + } + Ok(()) + } + EcmascriptModuleAssetType::TypescriptDeclaration => write!(f, "typescript declaration"), + } + } +} + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("ecmascript".into()) +} + +#[derive(Clone)] +pub struct EcmascriptModuleAssetBuilder { + source: Vc>, + asset_context: Vc>, + ty: EcmascriptModuleAssetType, + transforms: Vc, + options: Vc, + compile_time_info: Vc, + inner_assets: Option>, +} + +impl EcmascriptModuleAssetBuilder { + pub fn with_inner_assets(mut self, inner_assets: Vc) -> Self { + self.inner_assets = Some(inner_assets); + self + } + + pub fn with_type(mut self, ty: EcmascriptModuleAssetType) -> Self { + self.ty = ty; + self + } + + pub fn build(self) -> Vc { + if let Some(inner_assets) = self.inner_assets { + EcmascriptModuleAsset::new_with_inner_assets( + self.source, + self.asset_context, + Value::new(self.ty), + self.transforms, + self.options, + self.compile_time_info, + inner_assets, + ) + } else { + EcmascriptModuleAsset::new( + self.source, + self.asset_context, + Value::new(self.ty), + self.transforms, + self.options, + self.compile_time_info, + ) + } + } + + pub async fn build_part(self, part: Vc) -> Result> { + let import_externals = self.options.await?.import_externals; + let base = self.build(); + Ok(EcmascriptModulePartAsset::new(base, part, import_externals)) + } +} + +#[turbo_tasks::value] +pub struct EcmascriptModuleAsset { + pub source: Vc>, + pub asset_context: Vc>, + pub ty: EcmascriptModuleAssetType, + pub transforms: Vc, + pub options: Vc, + pub compile_time_info: Vc, + pub inner_assets: Option>, + #[turbo_tasks(debug_ignore)] + #[serde(skip)] + last_successful_parse: turbo_tasks::State>>, +} + +/// An optional [EcmascriptModuleAsset] +#[turbo_tasks::value(transparent)] +pub struct OptionEcmascriptModuleAsset(Option>); + +/// A list of [EcmascriptModuleAsset]s +#[turbo_tasks::value(transparent)] +pub struct EcmascriptModuleAssets(Vec>); + +impl EcmascriptModuleAsset { + pub fn builder( + source: Vc>, + asset_context: Vc>, + transforms: Vc, + options: Vc, + compile_time_info: Vc, + ) -> EcmascriptModuleAssetBuilder { + EcmascriptModuleAssetBuilder { + source, + asset_context, + ty: EcmascriptModuleAssetType::Ecmascript, + transforms, + options, + compile_time_info, + inner_assets: None, + } + } +} + +#[turbo_tasks::value] +#[derive(Copy, Clone)] +pub(crate) struct ModuleTypeResult { + pub module_type: SpecifiedModuleType, + pub referenced_package_json: Option>, +} + +#[turbo_tasks::value_impl] +impl ModuleTypeResult { + #[turbo_tasks::function] + fn new(module_type: SpecifiedModuleType) -> Vc { + Self::cell(ModuleTypeResult { + module_type, + referenced_package_json: None, + }) + } + + #[turbo_tasks::function] + fn new_with_package_json( + module_type: SpecifiedModuleType, + package_json: Vc, + ) -> Vc { + Self::cell(ModuleTypeResult { + module_type, + referenced_package_json: Some(package_json), + }) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptModuleAsset { + #[turbo_tasks::function] + pub fn new( + source: Vc>, + asset_context: Vc>, + ty: Value, + transforms: Vc, + options: Vc, + compile_time_info: Vc, + ) -> Vc { + Self::cell(EcmascriptModuleAsset { + source, + asset_context, + ty: ty.into_value(), + transforms, + options, + compile_time_info, + inner_assets: None, + last_successful_parse: Default::default(), + }) + } + + #[turbo_tasks::function] + pub fn new_with_inner_assets( + source: Vc>, + asset_context: Vc>, + ty: Value, + transforms: Vc, + options: Vc, + compile_time_info: Vc, + inner_assets: Vc, + ) -> Vc { + Self::cell(EcmascriptModuleAsset { + source, + asset_context, + ty: ty.into_value(), + transforms, + options, + compile_time_info, + inner_assets: Some(inner_assets), + last_successful_parse: Default::default(), + }) + } + + #[turbo_tasks::function] + pub async fn source(self: Vc) -> Result>> { + Ok(self.await?.source) + } + + #[turbo_tasks::function] + pub fn analyze(self: Vc) -> Vc { + analyse_ecmascript_module(self, None) + } + + #[turbo_tasks::function] + pub async fn options(self: Vc) -> Result> { + Ok(self.await?.options) + } + + #[turbo_tasks::function] + pub fn parse(&self) -> Vc { + parse(self.source, Value::new(self.ty), self.transforms) + } + + #[turbo_tasks::function] + pub async fn failsafe_parse(self: Vc) -> Result> { + let real_result = self.parse(); + let real_result_value = real_result.await?; + let this = self.await?; + let result_value = if matches!(*real_result_value, ParseResult::Ok { .. }) { + this.last_successful_parse + .set(Some(real_result_value.clone())); + real_result_value + } else { + let state_ref = this.last_successful_parse.get(); + state_ref.as_ref().unwrap_or(&real_result_value).clone() + }; + Ok(ReadRef::cell(result_value)) + } + + #[turbo_tasks::function] + pub(crate) async fn determine_module_type(self: Vc) -> Result> { + let this = self.await?; + + match this.options.await?.specified_module_type { + SpecifiedModuleType::EcmaScript => { + return Ok(ModuleTypeResult::new(SpecifiedModuleType::EcmaScript)) + } + SpecifiedModuleType::CommonJs => { + return Ok(ModuleTypeResult::new(SpecifiedModuleType::CommonJs)) + } + SpecifiedModuleType::Automatic => {} + } + + let find_package_json = find_context_file( + self.origin_path() + .resolve() + .await? + .parent() + .resolve() + .await?, + package_json().resolve().await?, + ) + .await?; + let FindContextFileResult::Found(package_json, _) = *find_package_json else { + return Ok(ModuleTypeResult::new(SpecifiedModuleType::Automatic)); + }; + + // analysis.add_reference(PackageJsonReference::new(package_json)); + if let FileJsonContent::Content(content) = &*package_json.read_json().await? { + if let Some(r#type) = content.get("type") { + return Ok(ModuleTypeResult::new_with_package_json( + match r#type.as_str() { + Some("module") => SpecifiedModuleType::EcmaScript, + Some("commonjs") => SpecifiedModuleType::CommonJs, + _ => SpecifiedModuleType::Automatic, + }, + package_json, + )); + } + } + + Ok(ModuleTypeResult::new_with_package_json( + SpecifiedModuleType::Automatic, + package_json, + )) + } + + /// Generates module contents without an analysis pass. This is useful for + /// transforming code that is not a module, e.g. runtime code. + #[turbo_tasks::function] + pub async fn module_content_without_analysis( + self: Vc, + ) -> Result> { + let this = self.await?; + + let parsed = self.parse(); + + Ok(EcmascriptModuleContent::new_without_analysis( + parsed, + self.ident(), + this.options.await?.specified_module_type, + )) + } + + #[turbo_tasks::function] + pub async fn module_content( + self: Vc, + chunking_context: Vc>, + async_module_info: Option>, + ) -> Result> { + let parsed = self.parse().resolve().await?; + + let analyze = self.analyze().await?; + + let module_type_result = *self.determine_module_type().await?; + + Ok(EcmascriptModuleContent::new( + parsed, + self.ident(), + module_type_result.module_type, + chunking_context, + analyze.references, + analyze.code_generation, + analyze.async_module, + analyze.source_map, + analyze.exports, + async_module_info, + )) + } +} + +#[turbo_tasks::value_impl] +impl Module for EcmascriptModuleAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + if let Some(inner_assets) = self.inner_assets { + let mut ident = self.source.ident().await?.clone_value(); + for (name, asset) in inner_assets.await?.iter() { + ident.add_asset(Vc::cell(name.to_string().into()), asset.ident()); + } + ident.add_modifier(modifier()); + ident.layer = Some(self.asset_context.layer()); + Ok(AssetIdent::new(Value::new(ident))) + } else { + Ok(self + .source + .ident() + .with_modifier(modifier()) + .with_layer(self.asset_context.layer())) + } + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let analyze = self.analyze().await?; + let references = analyze.references.await?.iter().copied().collect(); + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for EcmascriptModuleAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast(ModuleChunkItem::cell(ModuleChunkItem { + module: self, + chunking_context, + }))) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for EcmascriptModuleAsset { + #[turbo_tasks::function] + async fn get_exports(self: Vc) -> Result> { + Ok(self.analyze().await?.exports) + } + + #[turbo_tasks::function] + async fn get_async_module(self: Vc) -> Result> { + Ok(self.analyze().await?.async_module) + } +} + +#[turbo_tasks::value_impl] +impl EvaluatableAsset for EcmascriptModuleAsset {} + +#[turbo_tasks::value_impl] +impl ResolveOrigin for EcmascriptModuleAsset { + #[turbo_tasks::function] + fn origin_path(&self) -> Vc { + self.source.ident().path() + } + + #[turbo_tasks::function] + fn asset_context(&self) -> Vc> { + self.asset_context + } + + #[turbo_tasks::function] + async fn get_inner_asset(&self, request: Vc) -> Result> { + Ok(Vc::cell(if let Some(inner_assets) = &self.inner_assets { + if let Some(request) = request.await?.request() { + inner_assets.await?.get(&request).copied() + } else { + None + } + } else { + None + })) + } +} + +#[turbo_tasks::value] +struct ModuleChunkItem { + module: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for ModuleChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } + + #[turbo_tasks::function] + async fn is_self_async(&self) -> Result> { + if let Some(async_module) = *self.module.get_async_module().await? { + Ok(async_module.is_self_async(self.module.analyze().await?.references)) + } else { + Ok(Vc::cell(false)) + } + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for ModuleChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("content() should not be called"); + } + + #[turbo_tasks::function] + async fn content_with_async_module_info( + self: Vc, + async_module_info: Option>, + ) -> Result> { + let this = self.await?; + let _span = tracing::info_span!( + "code generation", + module = self.asset_ident().to_string().await?.to_string() + ) + .entered(); + let async_module_options = this + .module + .get_async_module() + .module_options(async_module_info); + + // TODO check if we need to pass async_module_info at all + let content = this + .module + .module_content(this.chunking_context, async_module_info); + + Ok(EcmascriptChunkItemContent::new( + content, + this.chunking_context, + this.module.options(), + async_module_options, + )) + } +} + +/// The transformed contents of an Ecmascript module. +#[turbo_tasks::value] +pub struct EcmascriptModuleContent { + pub inner_code: Rope, + pub source_map: Option>>, + pub is_esm: bool, + // pub refresh: bool, +} + +#[turbo_tasks::value_impl] +impl EcmascriptModuleContent { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub async fn new( + parsed: Vc, + ident: Vc, + specified_module_type: SpecifiedModuleType, + chunking_context: Vc>, + references: Vc, + code_generation: Vc, + async_module: Vc, + source_map: Vc, + exports: Vc, + async_module_info: Option>, + ) -> Result> { + let mut code_gens = Vec::new(); + for r in references.await?.iter() { + let r = r.resolve().await?; + if let Some(code_gen) = + Vc::try_resolve_sidecast::>(r).await? + { + code_gens.push(code_gen.code_generation(chunking_context, async_module_info)); + } else if let Some(code_gen) = + Vc::try_resolve_sidecast::>(r).await? + { + code_gens.push(code_gen.code_generation(chunking_context)); + } + } + if let Some(async_module) = *async_module.await? { + code_gens.push(async_module.code_generation( + chunking_context, + async_module_info, + references, + )); + } + for c in code_generation.await?.iter() { + match c { + CodeGen::CodeGenerateable(c) => { + code_gens.push(c.code_generation(chunking_context)); + } + CodeGen::CodeGenerateableWithAsyncModuleInfo(c) => { + code_gens.push(c.code_generation(chunking_context, async_module_info)); + } + } + } + if let EcmascriptExports::EsmExports(exports) = *exports.await? { + code_gens.push(exports.code_generation(chunking_context)); + } + + // need to keep that around to allow references into that + let code_gens = code_gens.into_iter().try_join().await?; + let code_gens = code_gens.iter().map(|cg| &**cg).collect::>(); + let mut visitors = Vec::new(); + let mut root_visitors = Vec::new(); + for code_gen in code_gens { + for (path, visitor) in code_gen.visitors.iter() { + if path.is_empty() { + root_visitors.push(&**visitor); + } else { + visitors.push((path, &**visitor)); + } + } + } + + gen_content_with_visitors( + parsed, + ident, + specified_module_type, + visitors, + root_visitors, + source_map, + ) + .await + } + + /// Creates a new [`Vc`] without an analysis pass. + #[turbo_tasks::function] + pub async fn new_without_analysis( + parsed: Vc, + ident: Vc, + specified_module_type: SpecifiedModuleType, + ) -> Result> { + gen_content_with_visitors( + parsed, + ident, + specified_module_type, + Vec::new(), + Vec::new(), + OptionSourceMap::none(), + ) + .await + } +} + +async fn gen_content_with_visitors( + parsed: Vc, + ident: Vc, + specified_module_type: SpecifiedModuleType, + visitors: Vec<( + &Vec, + &dyn VisitorFactory, + )>, + root_visitors: Vec<&dyn VisitorFactory>, + original_src_map: Vc, +) -> Result> { + let parsed = parsed.await?; + + match &*parsed { + ParseResult::Ok { + program, + source_map, + globals, + eval_context, + comments, + .. + } => { + let mut program = program.clone(); + + GLOBALS.set(globals, || { + if !visitors.is_empty() { + program.visit_mut_with_path( + &mut ApplyVisitors::new(visitors), + &mut Default::default(), + ); + } + for visitor in root_visitors { + program.visit_mut_with(&mut visitor.create()); + } + program.visit_mut_with(&mut swc_core::ecma::transforms::base::hygiene::hygiene()); + program.visit_mut_with(&mut swc_core::ecma::transforms::base::fixer::fixer(None)); + + // we need to remove any shebang before bundling as it's only valid as the first + // line in a js file (not in a chunk item wrapped in the runtime) + remove_shebang(&mut program); + }); + + let mut bytes: Vec = vec![]; + // TODO: Insert this as a sourceless segment so that sourcemaps aren't affected. + // = format!("/* {} */\n", self.module.path().to_string().await?).into_bytes(); + + let mut mappings = vec![]; + + let comments = comments.consumable(); + + let mut emitter = Emitter { + cfg: swc_core::ecma::codegen::Config::default(), + cm: source_map.clone(), + comments: Some(&comments), + wr: JsWriter::new(source_map.clone(), "\n", &mut bytes, Some(&mut mappings)), + }; + + emitter.emit_program(&program)?; + + let srcmap = + ParseResultSourceMap::new(source_map.clone(), mappings, original_src_map).cell(); + + Ok(EcmascriptModuleContent { + inner_code: bytes.into(), + source_map: Some(Vc::upcast(srcmap)), + is_esm: eval_context.is_esm() + || specified_module_type == SpecifiedModuleType::EcmaScript, + } + .cell()) + } + ParseResult::Unparseable { messages } => Ok(EcmascriptModuleContent { + inner_code: format!( + "const e = new Error(`Could not parse module \ + '{path}'\n{error_messages}`);\ne.code = 'MODULE_UNPARSEABLE';\nthrow e;", + path = ident.path().to_string().await?, + error_messages = messages + .as_ref() + .and_then(|m| { m.first().map(|f| format!("\n{}", f)) }) + .unwrap_or("".into()) + ) + .into(), + source_map: None, + is_esm: false, + } + .cell()), + _ => Ok(EcmascriptModuleContent { + inner_code: format!( + "const e = new Error(\"Could not parse module '{path}'\");\ne.code = \ + 'MODULE_UNPARSEABLE';\nthrow e;", + path = ident.path().to_string().await? + ) + .into(), + source_map: None, + is_esm: false, + } + .cell()), + } +} + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-ecmascript/src/magic_identifier.rs b/turbopack/crates/turbopack-ecmascript/src/magic_identifier.rs new file mode 100644 index 0000000000000..d92bfdbda5199 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/magic_identifier.rs @@ -0,0 +1,214 @@ +use std::{ + borrow::Cow, + fmt::{Display, Write}, +}; + +use once_cell::sync::Lazy; +use regex::{Captures, Regex, Replacer}; + +pub fn mangle(content: &str) -> String { + let mut r = "__TURBOPACK__".to_string(); + let mut hex_mode = false; + for c in content.chars() { + if matches!(c, '0'..='9' | 'A'..='Z' | 'a'..='z' | ' ') { + if hex_mode { + r.push('$'); + hex_mode = false; + } + if c == ' ' { + r += "__"; + } else { + r.push(c); + } + } else if c == '_' && (!r.ends_with('_') || hex_mode) { + if hex_mode { + r.push('$'); + hex_mode = false; + } + r += "_"; + } else if c == '$' && !hex_mode { + r += "$$"; + } else if matches!(c, '\0'..='\u{ff}') { + if !hex_mode { + r.push('$'); + hex_mode = true; + } + write!(r, "{0:2x}", c as u8).unwrap(); + } else { + if !hex_mode { + r.push('$'); + } + write!(r, "_{:x}$", c as u32).unwrap(); + hex_mode = false; + } + } + if hex_mode { + r.push('$'); + } + r += "__"; + r +} + +/// Decodes a magic identifier into a string. +pub fn unmangle(identifier: &str) -> String { + static DECODE_REGEX: Lazy = + Lazy::new(|| Regex::new(r"^__TURBOPACK__([a-zA-Z0-9_$]+)__$").unwrap()); + + let Some(captures) = DECODE_REGEX.captures(identifier) else { + return identifier.to_string(); + }; + + let content = captures.get(1).unwrap().as_str(); + + enum Mode { + Text, + Underscore, + Hex, + LongHex, + } + let mut mode = Mode::Text; + let mut output = String::new(); + let mut buffer = String::with_capacity(2); + for char in content.chars() { + match mode { + Mode::Text => match char { + '_' => mode = Mode::Underscore, + '$' => mode = Mode::Hex, + c => output.push(c), + }, + Mode::Underscore => match char { + '_' => { + output.push(' '); + mode = Mode::Text; + } + '$' => { + output.push('_'); + mode = Mode::Hex; + } + c => { + output.push('_'); + output.push(c); + mode = Mode::Text; + } + }, + Mode::Hex => { + if buffer.len() == 2 { + if let Ok(byte) = u8::from_str_radix(&buffer, 16) { + output.push(byte as char); + } + buffer.clear(); + } + match char { + '_' => { + debug_assert!(buffer.is_empty()); + mode = Mode::LongHex; + } + '$' => { + debug_assert!(buffer.is_empty()); + mode = Mode::Text; + } + c => { + buffer.push(c); + } + } + } + Mode::LongHex => { + debug_assert!(char != '_'); + match char { + '$' => { + if let Ok(code) = u32::from_str_radix(&buffer, 16) { + output.push(std::char::from_u32(code).unwrap()); + } + buffer.clear(); + mode = Mode::Text; + } + c => { + buffer.push(c); + } + } + } + } + } + debug_assert!(matches!(mode, Mode::Text)); + output +} + +/// Decode all magic identifiers in a string. +pub fn unmangle_identifiers(text: &str, magic: impl Fn(String) -> T) -> Cow<'_, str> { + static IDENTIFIER_REGEX: Lazy = + Lazy::new(|| Regex::new(r"__TURBOPACK__[a-zA-Z0-9_$]+__").unwrap()); + + struct Rep O, O: Display>(T); + + impl O, O: Display> Replacer for Rep { + fn replace_append(&mut self, caps: &Captures<'_>, dst: &mut String) { + write!(dst, "{}", self.0(unmangle(caps.get(0).unwrap().as_str()))).unwrap(); + } + } + + IDENTIFIER_REGEX.replace_all(text, Rep(magic)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_encode() { + assert_eq!(mangle("Hello World"), "__TURBOPACK__Hello__World__"); + assert_eq!(mangle("Hello_World"), "__TURBOPACK__Hello_World__"); + assert_eq!(mangle("Hello__World"), "__TURBOPACK__Hello_$5f$World__"); + assert_eq!(mangle("Hello___World"), "__TURBOPACK__Hello_$5f$_World__"); + assert_eq!(mangle("Hello/World"), "__TURBOPACK__Hello$2f$World__"); + assert_eq!(mangle("Hello///World"), "__TURBOPACK__Hello$2f2f2f$World__"); + assert_eq!(mangle("Hello/_World"), "__TURBOPACK__Hello$2f$_World__"); + assert_eq!(mangle("Hello_/_World"), "__TURBOPACK__Hello_$2f$_World__"); + assert_eq!(mangle("Hello😀World"), "__TURBOPACK__Hello$_1f600$World__"); + assert_eq!( + mangle("Hello/😀/World"), + "__TURBOPACK__Hello$2f_1f600$$2f$World__" + ); + assert_eq!( + mangle("Hello😀😀World"), + "__TURBOPACK__Hello$_1f600$$_1f600$World__" + ); + } + + #[test] + fn test_decode() { + assert_eq!(unmangle("__TURBOPACK__Hello__World__"), "Hello World"); + assert_eq!(unmangle("__TURBOPACK__Hello_World__"), "Hello_World"); + assert_eq!(unmangle("__TURBOPACK__Hello_$5f$World__"), "Hello__World"); + assert_eq!(unmangle("__TURBOPACK__Hello_$5f$_World__"), "Hello___World"); + assert_eq!(unmangle("__TURBOPACK__Hello$2f$World__"), "Hello/World"); + assert_eq!( + unmangle("__TURBOPACK__Hello$2f2f2f$World__"), + "Hello///World" + ); + assert_eq!(unmangle("__TURBOPACK__Hello$2f$_World__"), "Hello/_World"); + assert_eq!(unmangle("__TURBOPACK__Hello_$2f$_World__"), "Hello_/_World"); + assert_eq!( + unmangle("__TURBOPACK__Hello$_1f600$World__"), + "Hello😀World" + ); + assert_eq!( + unmangle("__TURBOPACK__Hello$2f_1f600$$2f$World__"), + "Hello/😀/World" + ); + assert_eq!( + unmangle("__TURBOPACK__Hello$_1f600$$_1f600$World__"), + "Hello😀😀World" + ); + } + + #[test] + fn test_unmangle_identifiers() { + assert_eq!( + unmangle_identifiers( + "Hello __TURBOPACK__Hello__World__ __TURBOPACK__Hello_World__", + |s| format!("{{{s}}}") + ), + "Hello {Hello World} {Hello_World}" + ); + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs b/turbopack/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs new file mode 100644 index 0000000000000..deacb22cfa791 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/manifest/chunk_asset.rs @@ -0,0 +1,163 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ + availability_info::AvailabilityInfo, ChunkableModule, ChunkingContext, ChunkingContextExt, + }, + ident::AssetIdent, + module::Module, + output::OutputAssets, + reference::{ModuleReferences, SingleOutputAssetReference}, +}; + +use super::chunk_item::ManifestChunkItem; +use crate::chunk::{EcmascriptChunkPlaceable, EcmascriptExports}; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("manifest chunk".into()) +} + +/// The manifest module is deferred until requested by the manifest loader +/// item when the dynamic `import()` expression is reached. Its responsibility +/// is to generate a Promise that will resolve only after all the necessary +/// chunks needed by the dynamic import are loaded by the client. +/// +/// Splitting the dynamic import into a quickly generate-able manifest loader +/// item and a slow-to-generate manifest chunk allows for faster incremental +/// compilation. The traversal won't be performed until the dynamic import is +/// actually reached, instead of eagerly as part of the chunk that the dynamic +/// import appears in. +#[turbo_tasks::value(shared)] +pub struct ManifestAsyncModule { + pub inner: Vc>, + pub chunking_context: Vc>, + pub availability_info: AvailabilityInfo, +} + +#[turbo_tasks::value_impl] +impl ManifestAsyncModule { + #[turbo_tasks::function] + pub fn new( + module: Vc>, + chunking_context: Vc>, + availability_info: Value, + ) -> Vc { + Self::cell(ManifestAsyncModule { + inner: module, + chunking_context, + availability_info: availability_info.into_value(), + }) + } + + #[turbo_tasks::function] + pub(super) async fn chunks(self: Vc) -> Result> { + let this = self.await?; + Ok(this + .chunking_context + .chunk_group_assets(Vc::upcast(this.inner), Value::new(this.availability_info))) + } + + #[turbo_tasks::function] + pub async fn manifest_chunks(self: Vc) -> Result> { + let this = self.await?; + if let Some(chunk_items) = this.availability_info.available_chunk_items() { + if chunk_items + .get( + this.inner + .as_chunk_item(Vc::upcast(this.chunking_context)) + .resolve() + .await?, + ) + .await? + .is_some() + { + return Ok(Vc::cell(vec![])); + } + } + Ok(this + .chunking_context + .chunk_group_assets(Vc::upcast(self), Value::new(this.availability_info))) + } + + #[turbo_tasks::function] + pub fn module_ident(&self) -> Vc { + self.inner.ident() + } + + #[turbo_tasks::function] + pub async fn content_ident(&self) -> Result> { + let mut ident = self.inner.ident(); + if let Some(available_modules) = self.availability_info.available_chunk_items() { + ident = + ident.with_modifier(Vc::cell(available_modules.hash().await?.to_string().into())); + } + Ok(ident) + } +} + +#[turbo_tasks::function] +fn manifest_chunk_reference_description() -> Vc { + Vc::cell("manifest chunk".into()) +} + +#[turbo_tasks::value_impl] +impl Module for ManifestAsyncModule { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.inner.ident().with_modifier(modifier()) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let chunks = self.chunks(); + + Ok(Vc::cell( + chunks + .await? + .iter() + .copied() + .map(|chunk| { + Vc::upcast(SingleOutputAssetReference::new( + chunk, + manifest_chunk_reference_description(), + )) + }) + .collect(), + )) + } +} + +#[turbo_tasks::value_impl] +impl Asset for ManifestAsyncModule { + #[turbo_tasks::function] + fn content(&self) -> Vc { + todo!() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for ManifestAsyncModule { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + ManifestChunkItem { + chunking_context, + manifest: self, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for ManifestAsyncModule { + #[turbo_tasks::function] + fn get_exports(&self) -> Vc { + EcmascriptExports::Value.cell() + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/manifest/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/manifest/chunk_item.rs new file mode 100644 index 0000000000000..9080b7558857c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/manifest/chunk_item.rs @@ -0,0 +1,116 @@ +use anyhow::Result; +use indoc::formatdoc; +use turbo_tasks::{TryJoinIterExt, Vc}; +use turbopack_core::{ + chunk::{ChunkData, ChunkItem, ChunkType, ChunkingContext, ChunksData}, + ident::AssetIdent, + module::Module, + reference::{ModuleReferences, SingleOutputAssetReference}, +}; + +use super::chunk_asset::ManifestAsyncModule; +use crate::{ + chunk::{ + data::EcmascriptChunkData, EcmascriptChunkItem, EcmascriptChunkItemContent, + EcmascriptChunkType, + }, + utils::StringifyJs, +}; + +/// The ManifestChunkItem generates a __turbopack_load__ call for every chunk +/// necessary to load the real asset. Once all the loads resolve, it is safe to +/// __turbopack_import__ the actual module that was dynamically imported. +#[turbo_tasks::value(shared)] +pub(super) struct ManifestChunkItem { + pub chunking_context: Vc>, + pub manifest: Vc, +} + +#[turbo_tasks::value_impl] +impl ManifestChunkItem { + #[turbo_tasks::function] + async fn chunks_data(self: Vc) -> Result> { + let this = self.await?; + Ok(ChunkData::from_assets( + this.chunking_context.output_root(), + this.manifest.chunks(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for ManifestChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let chunks_data = self.chunks_data().await?; + let chunks_data = chunks_data.iter().try_join().await?; + let chunks_data: Vec<_> = chunks_data + .iter() + .map(|chunk_data| EcmascriptChunkData::new(chunk_data)) + .collect(); + + let code = formatdoc! { + r#" + __turbopack_export_value__({:#}); + "#, + StringifyJs(&chunks_data) + }; + + Ok(EcmascriptChunkItemContent { + inner_code: code.into(), + ..Default::default() + } + .into()) + } +} + +#[turbo_tasks::value_impl] +impl ChunkItem for ManifestChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.manifest.ident() + } + + #[turbo_tasks::function] + fn content_ident(&self) -> Vc { + self.manifest.content_ident() + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let mut references = this.manifest.references().await?.clone_value(); + + let key = Vc::cell("chunk data reference".into()); + + for chunk_data in &*self.chunks_data().await? { + references.extend(chunk_data.references().await?.iter().map(|&output_asset| { + Vc::upcast(SingleOutputAssetReference::new(output_asset, key)) + })); + } + + Ok(Vc::cell(references)) + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.manifest) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/manifest/loader_item.rs b/turbopack/crates/turbopack-ecmascript/src/manifest/loader_item.rs new file mode 100644 index 0000000000000..5c9fc07495288 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/manifest/loader_item.rs @@ -0,0 +1,219 @@ +use std::io::Write as _; + +use anyhow::{anyhow, Result}; +use indoc::writedoc; +use turbo_tasks::{RcStr, TryJoinIterExt, Vc}; +use turbopack_core::{ + chunk::{ + ChunkData, ChunkItem, ChunkItemExt, ChunkType, ChunkableModule, ChunkingContext, ChunksData, + }, + ident::AssetIdent, + module::Module, + reference::{ModuleReference, ModuleReferences, SingleOutputAssetReference}, +}; + +use super::chunk_asset::ManifestAsyncModule; +use crate::{ + chunk::{ + data::EcmascriptChunkData, EcmascriptChunkItem, EcmascriptChunkItemContent, + EcmascriptChunkPlaceable, EcmascriptChunkType, + }, + utils::StringifyJs, +}; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("loader".into()) +} + +/// The manifest loader item is shipped in the same chunk that uses the dynamic +/// `import()` expression. Its responsibility is to load the manifest chunk from +/// the server. The dynamic import has been rewritten to import this manifest +/// loader item, which will load the manifest chunk from the server, which +/// will load all the chunks needed by the dynamic import. Finally, we'll be +/// able to import the module we're trying to dynamically import. +/// +/// Splitting the dynamic import into a quickly generate-able manifest loader +/// item and a slow-to-generate manifest chunk allows for faster incremental +/// compilation. The traversal won't be performed until the dynamic import is +/// actually reached, instead of eagerly as part of the chunk that the dynamic +/// import appears in. +#[turbo_tasks::value] +pub struct ManifestLoaderChunkItem { + manifest: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ManifestLoaderChunkItem { + #[turbo_tasks::function] + pub fn new( + manifest: Vc, + chunking_context: Vc>, + ) -> Vc { + Self::cell(ManifestLoaderChunkItem { + manifest, + chunking_context, + }) + } + + #[turbo_tasks::function] + pub async fn chunks_data(self: Vc) -> Result> { + let this = self.await?; + let chunks = this.manifest.manifest_chunks(); + Ok(ChunkData::from_assets( + this.chunking_context.output_root(), + chunks, + )) + } + + #[turbo_tasks::function] + pub fn asset_ident_for(module: Vc>) -> Vc { + module.ident().with_modifier(modifier()) + } +} + +#[turbo_tasks::function] +fn manifest_loader_chunk_reference_description() -> Vc { + Vc::cell("manifest loader chunk".into()) +} + +#[turbo_tasks::function] +fn chunk_data_reference_description() -> Vc { + Vc::cell("chunk data reference".into()) +} + +#[turbo_tasks::value_impl] +impl ChunkItem for ManifestLoaderChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.manifest.module_ident().with_modifier(modifier()) + } + + #[turbo_tasks::function] + fn content_ident(&self) -> Vc { + self.manifest.content_ident().with_modifier(modifier()) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + + let chunks = this.manifest.manifest_chunks(); + + let mut references: Vec>> = chunks + .await? + .iter() + .map(|&chunk| { + Vc::upcast(SingleOutputAssetReference::new( + chunk, + manifest_loader_chunk_reference_description(), + )) + }) + .collect(); + + for chunk_data in &*self.chunks_data().await? { + references.extend(chunk_data.references().await?.iter().map(|&output_asset| { + Vc::upcast(SingleOutputAssetReference::new( + output_asset, + chunk_data_reference_description(), + )) + })); + } + + Ok(Vc::cell(references)) + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Result>> { + Ok(Vc::upcast(self.chunking_context)) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.manifest) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for ManifestLoaderChunkItem { + #[turbo_tasks::function] + async fn chunking_context(&self) -> Result>> { + Ok(self.manifest.await?.chunking_context) + } + + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let this = &*self.await?; + let mut code = Vec::new(); + + let manifest = this.manifest.await?; + + // We need several items in order for a dynamic import to fully load. First, we + // need the chunk path of the manifest chunk, relative from the output root. The + // chunk is a servable file, which will contain the manifest chunk item, which + // will perform the actual chunk traversal and generate load statements. + let chunks_server_data = &*self.chunks_data().await?.iter().try_join().await?; + + // We also need the manifest chunk item's id, which points to a CJS module that + // exports a promise for all of the necessary chunk loads. + let item_id = &*this + .manifest + .as_chunk_item(Vc::upcast(manifest.chunking_context)) + .id() + .await?; + + // Finally, we need the id of the module that we're actually trying to + // dynamically import. + let placeable = + Vc::try_resolve_downcast::>(manifest.inner) + .await? + .ok_or_else(|| anyhow!("asset is not placeable in ecmascript chunk"))?; + let dynamic_id = &*placeable + .as_chunk_item(Vc::upcast(manifest.chunking_context)) + .id() + .await?; + + // This is the code that will be executed when the dynamic import is reached. + // It will load the manifest chunk, which will load all the chunks needed by + // the dynamic import, and finally we'll be able to import the module we're + // trying to dynamically import. + // This is similar to what happens when the first evaluated chunk is executed + // on first page load, but it's happening on-demand instead of eagerly. + writedoc!( + code, + r#" + __turbopack_export_value__((__turbopack_import__) => {{ + return Promise.all({chunks_server_data}.map((chunk) => __turbopack_load__(chunk))).then(() => {{ + return __turbopack_require__({item_id}); + }}).then((chunks) => {{ + return Promise.all(chunks.map((chunk) => __turbopack_load__(chunk))); + }}).then(() => {{ + return __turbopack_import__({dynamic_id}); + }}); + }}); + "#, + chunks_server_data = StringifyJs( + &chunks_server_data + .iter() + .map(|chunk_data| EcmascriptChunkData::new(chunk_data)) + .collect::>() + ), + item_id = StringifyJs(item_id), + dynamic_id = StringifyJs(dynamic_id), + )?; + + Ok(EcmascriptChunkItemContent { + inner_code: code.into(), + ..Default::default() + } + .into()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/manifest/mod.rs b/turbopack/crates/turbopack-ecmascript/src/manifest/mod.rs new file mode 100644 index 0000000000000..d327d4dbd8309 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/manifest/mod.rs @@ -0,0 +1,3 @@ +pub mod chunk_asset; +pub mod chunk_item; +pub mod loader_item; diff --git a/turbopack/crates/turbopack-ecmascript/src/minify.rs b/turbopack/crates/turbopack-ecmascript/src/minify.rs new file mode 100644 index 0000000000000..f94859d23d8c3 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/minify.rs @@ -0,0 +1,153 @@ +use std::{io::Write, sync::Arc}; + +use anyhow::{bail, Context, Result}; +use swc_core::{ + base::{try_with_handler, Compiler}, + common::{ + comments::{Comments, SingleThreadedComments}, + BytePos, FileName, FilePathMapping, LineCol, Mark, SourceMap as SwcSourceMap, GLOBALS, + }, + ecma::{ + self, + ast::{EsVersion, Program}, + codegen::{ + text_writer::{self, JsWriter, WriteJs}, + Emitter, Node, + }, + minifier::option::{ExtraOptions, MinifyOptions}, + parser::{lexer::Lexer, Parser, StringInput, Syntax}, + transforms::base::fixer::paren_remover, + visit::FoldWith, + }, +}; +use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + code_builder::{Code, CodeBuilder}, + source_map::GenerateSourceMap, +}; + +use crate::ParseResultSourceMap; + +#[turbo_tasks::function] +pub async fn minify(path: Vc, code: Vc) -> Result> { + let path = path.await?; + let original_map = code.generate_source_map(); + let code = code.await?; + + let cm = Arc::new(SwcSourceMap::new(FilePathMapping::empty())); + let compiler = Arc::new(Compiler::new(cm.clone())); + let fm = compiler.cm.new_source_file( + FileName::Custom(path.path.to_string()), + code.source_code().to_str()?.to_string(), + ); + + let lexer = Lexer::new( + Syntax::default(), + EsVersion::latest(), + StringInput::from(&*fm), + None, + ); + let mut parser = Parser::new_from(lexer); + // TODO should use our own handler that emits issues instead. + let program = try_with_handler(cm.clone(), Default::default(), |handler| { + GLOBALS.set(&Default::default(), || { + let program = match parser.parse_program() { + Ok(program) => program, + Err(err) => { + // TODO should emit an issue + bail!( + "failed to parse source code\n{err:?}\n{}", + code.source_code().to_str()? + ) + } + }; + let comments = SingleThreadedComments::default(); + let unresolved_mark = Mark::new(); + let top_level_mark = Mark::new(); + + Ok(compiler.run_transform(handler, false, || { + let program = program.fold_with(&mut paren_remover(Some(&comments))); + + let mut program = + program.fold_with(&mut swc_core::ecma::transforms::base::resolver( + unresolved_mark, + top_level_mark, + false, + )); + + program = swc_core::ecma::minifier::optimize( + program, + cm.clone(), + Some(&comments), + None, + &MinifyOptions { + compress: Some(Default::default()), + mangle: Some(Default::default()), + ..Default::default() + }, + &ExtraOptions { + top_level_mark, + unresolved_mark, + }, + ); + + program.fold_with(&mut ecma::transforms::base::fixer::fixer(Some( + &comments as &dyn Comments, + ))) + })) + }) + })?; + + let (src, src_map_buf) = print_program(cm.clone(), program)?; + + let mut builder = CodeBuilder::default(); + builder.push_source( + &src.into(), + Some(Vc::upcast( + ParseResultSourceMap::new(cm, src_map_buf, original_map).cell(), + )), + ); + + write!( + builder, + "\n\n//# sourceMappingURL={}.map", + urlencoding::encode(path.file_name()) + )?; + Ok(builder.build().cell()) +} + +// From https://github.com/swc-project/swc/blob/11efd4e7c5e8081f8af141099d3459c3534c1e1d/crates/swc/src/lib.rs#L523-L560 +fn print_program( + cm: Arc, + program: Program, +) -> Result<(String, Vec<(BytePos, LineCol)>)> { + let mut src_map_buf = vec![]; + + let src = { + let mut buf = vec![]; + { + let wr = Box::new(text_writer::omit_trailing_semi(Box::new(JsWriter::new( + cm.clone(), + "\n", + &mut buf, + Some(&mut src_map_buf), + )))) as Box; + + let mut emitter = Emitter { + cfg: swc_core::ecma::codegen::Config::default().with_minify(true), + comments: None, + cm: cm.clone(), + wr, + }; + + program + .emit_with(&mut emitter) + .context("failed to emit module")?; + } + // Invalid utf8 is valid in javascript world. + String::from_utf8(buf).expect("invalid utf8 character detected") + }; + + Ok((src, src_map_buf)) +} diff --git a/turbopack/crates/turbopack-ecmascript/src/parse.rs b/turbopack/crates/turbopack-ecmascript/src/parse.rs new file mode 100644 index 0000000000000..0f2b065c00962 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/parse.rs @@ -0,0 +1,508 @@ +use std::{borrow::Cow, future::Future, sync::Arc}; + +use anyhow::{anyhow, Context, Result}; +use swc_core::{ + base::SwcComments, + common::{ + errors::{Handler, HANDLER}, + input::StringInput, + source_map::SourceMapGenConfig, + BytePos, FileName, Globals, LineCol, Mark, SyntaxContext, GLOBALS, + }, + ecma::{ + ast::{EsVersion, Program}, + lints::{config::LintConfig, rules::LintParams}, + parser::{lexer::Lexer, EsSyntax, Parser, Syntax, TsSyntax}, + transforms::base::{ + helpers::{Helpers, HELPERS}, + resolver, + }, + visit::{FoldWith, VisitMutWith}, + }, +}; +use tracing::Instrument; +use turbo_tasks::{util::WrapFuture, RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::{FileContent, FileSystemPath}; +use turbo_tasks_hash::hash_xxh3_hash64; +use turbopack_core::{ + asset::{Asset, AssetContent}, + error::PrettyPrintError, + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, + source::Source, + source_map::{GenerateSourceMap, OptionSourceMap, SourceMap}, + SOURCE_MAP_PREFIX, +}; +use turbopack_swc_utils::emitter::IssueEmitter; + +use super::EcmascriptModuleAssetType; +use crate::{ + analyzer::graph::EvalContext, + swc_comments::ImmutableComments, + transform::{EcmascriptInputTransforms, TransformContext}, + EcmascriptInputTransform, +}; + +#[turbo_tasks::value(shared, serialization = "none", eq = "manual")] +#[allow(clippy::large_enum_variant)] +pub enum ParseResult { + // Note: Ok must not contain any Vc as it's snapshot by failsafe_parse + Ok { + #[turbo_tasks(debug_ignore, trace_ignore)] + program: Program, + #[turbo_tasks(debug_ignore, trace_ignore)] + comments: Arc, + #[turbo_tasks(debug_ignore, trace_ignore)] + eval_context: EvalContext, + #[turbo_tasks(debug_ignore, trace_ignore)] + globals: Arc, + #[turbo_tasks(debug_ignore, trace_ignore)] + source_map: Arc, + }, + Unparseable { + messages: Option>, + }, + NotFound, +} + +impl PartialEq for ParseResult { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Ok { .. }, Self::Ok { .. }) => false, + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[turbo_tasks::value(shared, serialization = "none", eq = "manual")] +pub struct ParseResultSourceMap { + /// Confusingly, SWC's SourceMap is not a mapping of transformed locations + /// to source locations. It's a map of filesnames to file contents. + #[turbo_tasks(debug_ignore, trace_ignore)] + files_map: Arc, + + /// The position mappings that can generate a real source map. + #[turbo_tasks(debug_ignore, trace_ignore)] + mappings: Vec<(BytePos, LineCol)>, + + /// An input's original source map, if one exists. This will be used to + /// trace locations back to the input's pre-transformed sources. + original_source_map: Vc, +} + +impl PartialEq for ParseResultSourceMap { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.files_map, &other.files_map) && self.mappings == other.mappings + } +} + +impl ParseResultSourceMap { + pub fn new( + files_map: Arc, + mappings: Vec<(BytePos, LineCol)>, + original_source_map: Vc, + ) -> Self { + ParseResultSourceMap { + files_map, + mappings, + original_source_map, + } + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for ParseResultSourceMap { + #[turbo_tasks::function] + async fn generate_source_map(&self) -> Result> { + let original_src_map = if let Some(input) = *self.original_source_map.await? { + Some(input.await?.to_source_map().await?) + } else { + None + }; + let input_map = if let Some(map) = original_src_map.as_ref() { + map.as_regular_source_map().map(Cow::into_owned) + } else { + None + }; + let map = self.files_map.build_source_map_with_config( + &self.mappings, + input_map, + InlineSourcesContentConfig {}, + ); + Ok(Vc::cell(Some(SourceMap::new_regular(map).cell()))) + } +} + +/// A config to generate a source map which includes the source content of every +/// source file. SWC doesn't inline sources content by default when generating a +/// sourcemap, so we need to provide a custom config to do it. +struct InlineSourcesContentConfig {} + +impl SourceMapGenConfig for InlineSourcesContentConfig { + fn file_name_to_source(&self, f: &FileName) -> String { + match f { + FileName::Custom(s) => { + format!("{SOURCE_MAP_PREFIX}{s}") + } + _ => f.to_string(), + } + } + + fn inline_sources_content(&self, _f: &FileName) -> bool { + true + } +} + +#[turbo_tasks::function] +pub async fn parse( + source: Vc>, + ty: Value, + transforms: Vc, +) -> Result> { + let name = source.ident().to_string().await?.to_string(); + let span = tracing::info_span!("parse ecmascript", name = name, ty = display(&*ty)); + match parse_internal(source, ty, transforms) + .instrument(span) + .await + { + Ok(result) => Ok(result), + Err(error) => Err(error.context(format!( + "failed to parse {}", + source.ident().to_string().await? + ))), + } +} + +async fn parse_internal( + source: Vc>, + ty: Value, + transforms: Vc, +) -> Result> { + let content = source.content(); + let fs_path_vc = source.ident().path(); + let fs_path = &*fs_path_vc.await?; + let ident = &*source.ident().to_string().await?; + let file_path_hash = hash_xxh3_hash64(&*source.ident().to_string().await?) as u128; + let ty = ty.into_value(); + let content = match content.await { + Ok(content) => content, + Err(error) => { + let error: RcStr = PrettyPrintError(&error).to_string().into(); + ReadSourceIssue { + source, + error: error.clone(), + } + .cell() + .emit(); + + return Ok(ParseResult::Unparseable { + messages: Some(vec![error]), + } + .cell()); + } + }; + Ok(match &*content { + AssetContent::File(file) => match &*file.await? { + FileContent::NotFound => ParseResult::NotFound.cell(), + FileContent::Content(file) => match file.content().to_str() { + Ok(string) => { + let transforms = &*transforms.await?; + match parse_content( + string.into_owned(), + fs_path_vc, + fs_path, + ident, + file_path_hash, + source, + ty, + transforms, + ) + .await + { + Ok(result) => result, + Err(e) => { + return Err(e).context(anyhow!( + "Transforming and/or parsing of {} failed", + source.ident().to_string().await? + )); + } + } + } + Err(error) => { + let error: RcStr = PrettyPrintError(&error).to_string().into(); + ReadSourceIssue { + source, + error: error.clone(), + } + .cell() + .emit(); + ParseResult::Unparseable { + messages: Some(vec![error]), + } + .cell() + } + }, + }, + AssetContent::Redirect { .. } => ParseResult::Unparseable { messages: None }.cell(), + }) +} + +async fn parse_content( + string: String, + fs_path_vc: Vc, + fs_path: &FileSystemPath, + ident: &str, + file_path_hash: u128, + source: Vc>, + ty: EcmascriptModuleAssetType, + transforms: &[EcmascriptInputTransform], +) -> Result> { + let source_map: Arc = Default::default(); + let handler = Handler::with_emitter( + true, + false, + Box::new(IssueEmitter::new( + source, + source_map.clone(), + Some("Ecmascript file had an error".into()), + )), + ); + + let emitter = Box::new(IssueEmitter::new( + source, + source_map.clone(), + Some("Parsing ecmascript source code failed".into()), + )); + let parser_handler = Handler::with_emitter(true, false, emitter.clone()); + let globals = Arc::new(Globals::new()); + let globals_ref = &globals; + let helpers = GLOBALS.set(globals_ref, || Helpers::new(true)); + let mut result = WrapFuture::new( + async { + let file_name = FileName::Custom(ident.to_string()); + let fm = source_map.new_source_file(file_name.clone(), string); + + let comments = SwcComments::default(); + + let mut parsed_program = { + let lexer = Lexer::new( + match ty { + EcmascriptModuleAssetType::Ecmascript => Syntax::Es(EsSyntax { + jsx: true, + fn_bind: true, + decorators: true, + decorators_before_export: true, + export_default_from: true, + import_attributes: true, + allow_super_outside_method: true, + allow_return_outside_function: true, + auto_accessors: true, + explicit_resource_management: true, + }), + EcmascriptModuleAssetType::Typescript { tsx, .. } => { + Syntax::Typescript(TsSyntax { + decorators: true, + dts: false, + no_early_errors: true, + tsx, + disallow_ambiguous_jsx_like: false, + }) + } + EcmascriptModuleAssetType::TypescriptDeclaration => { + Syntax::Typescript(TsSyntax { + decorators: true, + dts: true, + no_early_errors: true, + tsx: false, + disallow_ambiguous_jsx_like: false, + }) + } + }, + EsVersion::latest(), + StringInput::from(&*fm), + Some(&comments), + ); + + let mut parser = Parser::new_from(lexer); + let span = tracing::trace_span!("swc_parse").entered(); + let program_result = parser.parse_program(); + drop(span); + + let mut has_errors = vec![]; + for e in parser.take_errors() { + let mut e = e.into_diagnostic(&parser_handler); + has_errors.extend(e.message.iter().map(|m| m.0.as_str().into())); + e.emit(); + } + + if !has_errors.is_empty() { + return Ok(ParseResult::Unparseable { + messages: Some(has_errors), + }); + } + + match program_result { + Ok(parsed_program) => parsed_program, + Err(e) => { + let mut e = e.into_diagnostic(&parser_handler); + let messages = e.message.iter().map(|m| m.0.as_str().into()).collect(); + + e.emit(); + + return Ok(ParseResult::Unparseable { + messages: Some(messages), + }); + } + } + }; + + let unresolved_mark = Mark::new(); + let top_level_mark = Mark::new(); + + let is_typescript = matches!( + ty, + EcmascriptModuleAssetType::Typescript { .. } + | EcmascriptModuleAssetType::TypescriptDeclaration + ); + let span = tracing::trace_span!("swc_resolver").entered(); + + parsed_program.visit_mut_with(&mut resolver( + unresolved_mark, + top_level_mark, + is_typescript, + )); + drop(span); + + let span = tracing::trace_span!("swc_lint").entered(); + + let lint_config = LintConfig::default(); + let rules = swc_core::ecma::lints::rules::all(LintParams { + program: &parsed_program, + lint_config: &lint_config, + unresolved_ctxt: SyntaxContext::empty().apply_mark(unresolved_mark), + top_level_ctxt: SyntaxContext::empty().apply_mark(top_level_mark), + es_version: EsVersion::latest(), + source_map: source_map.clone(), + }); + parsed_program = + parsed_program.fold_with(&mut swc_core::ecma::lints::rules::lint_to_fold(rules)); + drop(span); + + let transform_context = TransformContext { + comments: &comments, + source_map: &source_map, + top_level_mark, + unresolved_mark, + file_path_str: &fs_path.path, + file_name_str: fs_path.file_name(), + file_name_hash: file_path_hash, + file_path: fs_path_vc, + }; + let span = tracing::trace_span!("transforms"); + async { + for transform in transforms.iter() { + transform + .apply(&mut parsed_program, &transform_context) + .await?; + } + anyhow::Ok(()) + } + .instrument(span) + .await?; + + if parser_handler.has_errors() { + let messages = if let Some(error) = emitter.emitted_issues.last() { + // The emitter created in here only uses StyledString::Text + if let StyledString::Text(xx) = &*error.await?.message.await? { + Some(vec![xx.clone()]) + } else { + None + } + } else { + None + }; + let messages = + Some(messages.unwrap_or_else(|| vec![String::clone(&fm.src).into()])); + return Ok(ParseResult::Unparseable { messages }); + } + + parsed_program.visit_mut_with( + &mut swc_core::ecma::transforms::base::helpers::inject_helpers(unresolved_mark), + ); + + let eval_context = EvalContext::new( + &parsed_program, + unresolved_mark, + top_level_mark, + Some(source), + ); + + Ok::(ParseResult::Ok { + program: parsed_program, + comments: Arc::new(ImmutableComments::new(comments)), + eval_context, + // Temporary globals as the current one can't be moved yet, since they are + // borrowed + globals: Arc::new(Globals::new()), + source_map, + }) + }, + |f, cx| { + GLOBALS.set(globals_ref, || { + HANDLER.set(&handler, || HELPERS.set(&helpers, || f.poll(cx))) + }) + }, + ) + .await?; + if let ParseResult::Ok { + globals: ref mut g, .. + } = result + { + // Assign the correct globals + *g = globals; + } + Ok(result.cell()) +} + +#[turbo_tasks::value] +struct ReadSourceIssue { + source: Vc>, + error: RcStr, +} + +#[turbo_tasks::value_impl] +impl Issue for ReadSourceIssue { + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.source.ident().path() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Reading source code for parsing failed".into()).cell() + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some( + StyledString::Text( + format!( + "An unexpected error happened while trying to read the source code to parse: \ + {}", + self.error + ) + .into(), + ) + .cell(), + )) + } + + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Error.cell() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Load.cell() + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/path_visitor.rs b/turbopack/crates/turbopack-ecmascript/src/path_visitor.rs new file mode 100644 index 0000000000000..5c83fbc9036cd --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/path_visitor.rs @@ -0,0 +1,304 @@ +use std::borrow::Cow; + +use swc_core::{ + common::pass::AstKindPath, + ecma::{ + ast::*, + visit::{AstParentKind, VisitMut, VisitMutAstPath, VisitMutWith, VisitMutWithPath}, + }, +}; + +use crate::code_gen::VisitorFactory; + +pub type AstPath = Vec; + +// Invariant: Each [AstPath] in `visitors` contains a value at position `index`. +pub struct ApplyVisitors<'a, 'b> { + /// `VisitMut` should be shallow. In other words, it should not visit + /// children of the node. + visitors: Cow<'b, [(&'a AstPath, &'a dyn VisitorFactory)]>, + + index: usize, +} + +/// Do two binary searches to find the sub-slice that has `path[index] == kind`. +/// Returns None if no item matches that. `visitors` need to be sorted by path. +fn find_range<'a, 'b>( + visitors: &'b [(&'a AstPath, &'a dyn VisitorFactory)], + kind: &AstParentKind, + index: usize, +) -> Option<&'b [(&'a AstPath, &'a dyn VisitorFactory)]> { + // Precondition: visitors is never empty + if visitors.first().unwrap().0[index] > *kind || visitors.last().unwrap().0[index] < *kind { + // Fast path: If ast path of the first visitor is already out of range, then we + // can skip the whole visit. + return None; + } + + let start = if visitors.first().unwrap().0[index] == *kind { + // Fast path: It looks like the whole range is selected + 0 + } else { + visitors.partition_point(|(path, _)| path[index] < *kind) + }; + + if start >= visitors.len() { + return None; + } + + if visitors[start].0[index] > *kind { + // Fast path: If the starting point is greater than the given kind, it's + // meaningless to visit later. + return None; + } + + let end = if visitors.last().unwrap().0[index] == *kind { + // Fast path: It's likely that the whole range is selected + visitors.len() + } else { + visitors[start..].partition_point(|(path, _)| path[index] == *kind) + start + }; + if end == start { + return None; + } + // Postcondition: return value is never empty + Some(&visitors[start..end]) +} + +impl<'a, 'b> ApplyVisitors<'a, 'b> { + /// `visitors` must have an non-empty [AstPath]. + pub fn new(mut visitors: Vec<(&'a AstPath, &'a dyn VisitorFactory)>) -> Self { + assert!(!visitors.is_empty()); + visitors.sort_by_key(|(path, _)| *path); + Self { + visitors: Cow::Owned(visitors), + index: 0, + } + } + + #[inline(never)] + fn visit_if_required(&mut self, n: &mut N, ast_path: &mut AstKindPath) + where + N: for<'aa> VisitMutWith + + for<'aa, 'bb> VisitMutWithPath>, + { + let mut index = self.index; + let mut current_visitors = self.visitors.as_ref(); + while index < ast_path.len() { + let current = index == ast_path.len() - 1; + let kind = ast_path[index]; + if let Some(visitors) = find_range(current_visitors, &kind, index) { + // visitors contains all items that match kind at index. Some of them terminate + // here, some need furth visiting. The terminating items are at the start due to + // sorting of the list. + index += 1; + + // skip items that terminate here + let nested_visitors_start = + visitors.partition_point(|(path, _)| path.len() == index); + if current { + // Potentially skip visiting this sub tree + if nested_visitors_start < visitors.len() { + n.visit_mut_children_with_path( + &mut ApplyVisitors { + // We only select visitors starting from `nested_visitors_start` + // which maintains the invariant. + visitors: Cow::Borrowed(&visitors[nested_visitors_start..]), + index, + }, + ast_path, + ); + } + for (_, visitor) in visitors[..nested_visitors_start].iter() { + n.visit_mut_with(&mut visitor.create()); + } + return; + } else { + // `current_visitors` has the invariant that is must not be empty. + // When it becomes empty, we must early exit + current_visitors = &visitors[nested_visitors_start..]; + if current_visitors.is_empty() { + // Nothing to do in this subtree, skip it + return; + } + } + } else { + // Skip visiting this sub tree + return; + } + } + // Ast path is unchanged, just keep visiting + n.visit_mut_children_with_path(self, ast_path); + } +} + +macro_rules! method { + ($name:ident, $T:ty) => { + fn $name(&mut self, n: &mut $T, ast_path: &mut AstKindPath) { + self.visit_if_required(n, ast_path); + } + }; +} + +impl VisitMutAstPath for ApplyVisitors<'_, '_> { + // TODO: we need a macro to apply that for all methods + method!(visit_mut_prop, Prop); + method!(visit_mut_simple_assign_target, SimpleAssignTarget); + method!(visit_mut_expr, Expr); + method!(visit_mut_member_expr, MemberExpr); + method!(visit_mut_pat, Pat); + method!(visit_mut_stmt, Stmt); + method!(visit_mut_module_decl, ModuleDecl); + method!(visit_mut_module_item, ModuleItem); + method!(visit_mut_call_expr, CallExpr); + method!(visit_mut_lit, Lit); + method!(visit_mut_str, Str); +} + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use swc_core::{ + common::{errors::HANDLER, FileName, Mark, SourceFile, SourceMap}, + ecma::{ + ast::*, + codegen::{text_writer::JsWriter, Emitter}, + parser::parse_file_as_module, + transforms::base::resolver, + visit::{fields::*, AstParentKind, VisitMut, VisitMutWith, VisitMutWithPath}, + }, + testing::run_test, + }; + + use super::{ApplyVisitors, VisitorFactory}; + + fn parse(fm: &SourceFile) -> Module { + let mut m = parse_file_as_module( + fm, + Default::default(), + EsVersion::latest(), + None, + &mut vec![], + ) + .map_err(|err| HANDLER.with(|handler| err.into_diagnostic(handler).emit())) + .unwrap(); + + let unresolved_mark = Mark::new(); + let top_level_mark = Mark::new(); + m.visit_mut_with(&mut resolver(unresolved_mark, top_level_mark, false)); + + m + } + + struct StrReplacer<'a> { + from: &'a str, + to: &'a str, + } + + impl VisitorFactory for Box> { + fn create<'a>(&'a self) -> Box { + Box::new(&**self) + } + } + + impl VisitMut for &'_ StrReplacer<'_> { + fn visit_mut_str(&mut self, s: &mut Str) { + s.value = s.value.replace(self.from, self.to).into(); + s.raw = None; + } + } + + fn replacer(from: &'static str, to: &'static str) -> impl VisitorFactory { + Box::new(StrReplacer { from, to }) + } + + fn to_js(m: &Module, cm: &Arc) -> String { + let mut bytes = Vec::new(); + let mut emitter = Emitter { + cfg: swc_core::ecma::codegen::Config::default().with_minify(true), + cm: cm.clone(), + comments: None, + wr: JsWriter::new(cm.clone(), "\n", &mut bytes, None), + }; + + emitter.emit_module(m).unwrap(); + + String::from_utf8(bytes).unwrap() + } + + #[test] + fn path_visitor() { + run_test(false, |cm, _handler| { + let fm = cm.new_source_file(FileName::Anon, "('foo', 'bar', ['baz']);".into()); + + let m = parse(&fm); + + let module_kind = AstParentKind::Module(ModuleField::Body(0)); + let module_item_kind = AstParentKind::ModuleItem(ModuleItemField::Stmt); + let stmt_kind = AstParentKind::Stmt(StmtField::Expr); + let expr_stmt_kind = AstParentKind::ExprStmt(ExprStmtField::Expr); + let expr_kind = AstParentKind::Expr(ExprField::Paren); + let paren_kind = AstParentKind::ParenExpr(ParenExprField::Expr); + let expr2_kind = AstParentKind::Expr(ExprField::Seq); + let seq_kind = AstParentKind::SeqExpr(SeqExprField::Exprs(1)); + let expr3_kind = AstParentKind::Expr(ExprField::Lit); + let lit_kind = AstParentKind::Lit(LitField::Str); + + { + let path = vec![ + module_kind, + module_item_kind, + stmt_kind, + expr_stmt_kind, + expr_kind, + paren_kind, + expr2_kind, + seq_kind, + expr3_kind, + lit_kind, + ]; + let bar_replacer = replacer("bar", "bar-success"); + + let mut m = m.clone(); + m.visit_mut_with_path( + &mut ApplyVisitors::new(vec![(&path, &bar_replacer)]), + &mut Default::default(), + ); + + let s = to_js(&m, &cm); + assert_eq!(s, r#"("foo","bar-success",["baz"]);"#); + } + + { + let wrong_path = vec![ + module_kind, + module_item_kind, + stmt_kind, + expr_stmt_kind, + // expr_kind, + paren_kind, + expr2_kind, + seq_kind, + expr3_kind, + lit_kind, + ]; + let bar_replacer = replacer("bar", "bar-success"); + + let mut m = m.clone(); + m.visit_mut_with_path( + &mut ApplyVisitors::new(vec![(&wrong_path, &bar_replacer)]), + &mut Default::default(), + ); + + let s = to_js(&m, &cm); + assert!(!s.contains("bar-success")); + } + + drop(m); + + Ok(()) + }) + .unwrap(); + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/amd.rs b/turbopack/crates/turbopack-ecmascript/src/references/amd.rs new file mode 100644 index 0000000000000..7e0e9b8ffee67 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/amd.rs @@ -0,0 +1,286 @@ +use std::mem::take; + +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::DUMMY_SP, + ecma::{ + ast::{CallExpr, Callee, Expr, ExprOrSpread, Lit}, + utils::private_ident, + }, + quote, quote_expr, +}; +use turbo_tasks::{ + debug::ValueDebugFormat, trace::TraceRawVcs, RcStr, ReadRef, TryJoinIterExt, Value, + ValueToString, Vc, +}; +use turbopack_core::{ + chunk::{ChunkableModuleReference, ChunkingContext}, + issue::IssueSource, + reference::ModuleReference, + resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, +}; +use turbopack_resolve::ecmascript::{cjs_resolve, try_to_severity}; + +use super::pattern_mapping::{PatternMapping, ResolveType::ChunkItem}; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, + references::AstPath, +}; + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct AmdDefineAssetReference { + origin: Vc>, + request: Vc, + issue_source: Vc, + in_try: bool, +} + +#[turbo_tasks::value_impl] +impl AmdDefineAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + issue_source: Vc, + in_try: bool, + ) -> Vc { + Self::cell(AmdDefineAssetReference { + origin, + request, + issue_source, + in_try, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for AmdDefineAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + cjs_resolve( + self.origin, + self.request, + Some(self.issue_source), + try_to_severity(self.in_try), + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for AmdDefineAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("AMD define dependency {}", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for AmdDefineAssetReference {} + +#[derive(ValueDebugFormat, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, Clone)] +pub enum AmdDefineDependencyElement { + Request { + request: Vc, + request_str: String, + }, + Exports, + Module, + Require, +} + +#[derive( + ValueDebugFormat, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, Copy, Clone, +)] +pub enum AmdDefineFactoryType { + Unknown, + Function, + Value, +} + +#[turbo_tasks::value(shared)] +#[derive(Debug)] +pub struct AmdDefineWithDependenciesCodeGen { + dependencies_requests: Vec, + origin: Vc>, + path: Vc, + factory_type: AmdDefineFactoryType, + issue_source: Vc, + in_try: bool, +} + +impl AmdDefineWithDependenciesCodeGen { + pub fn new( + dependencies_requests: Vec, + origin: Vc>, + path: Vc, + factory_type: AmdDefineFactoryType, + issue_source: Vc, + in_try: bool, + ) -> Vc { + Self::cell(AmdDefineWithDependenciesCodeGen { + dependencies_requests, + origin, + path, + factory_type, + issue_source, + in_try, + }) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for AmdDefineWithDependenciesCodeGen { + #[turbo_tasks::function] + async fn code_generation( + &self, + chunking_context: Vc>, + ) -> Result> { + let mut visitors = Vec::new(); + + let resolved_elements = self + .dependencies_requests + .iter() + .map(|element| async move { + Ok(match element { + AmdDefineDependencyElement::Request { + request, + request_str, + } => ResolvedElement::PatternMapping { + pattern_mapping: PatternMapping::resolve_request( + *request, + self.origin, + Vc::upcast(chunking_context), + cjs_resolve( + self.origin, + *request, + Some(self.issue_source), + try_to_severity(self.in_try), + ), + Value::new(ChunkItem), + ) + .await?, + request_str: request_str.to_string(), + }, + AmdDefineDependencyElement::Exports => { + ResolvedElement::Expr(quote!("exports" as Expr)) + } + AmdDefineDependencyElement::Module => { + ResolvedElement::Expr(quote!("module" as Expr)) + } + AmdDefineDependencyElement::Require => { + ResolvedElement::Expr(quote!("__turbopack_require__" as Expr)) + } + }) + }) + .try_join() + .await?; + + let factory_type = self.factory_type; + + let path = self.path.await?; + visitors.push( + create_visitor!(exact path, visit_mut_call_expr(call_expr: &mut CallExpr) { + transform_amd_factory(call_expr, &resolved_elements, factory_type) + }), + ); + + Ok(CodeGeneration { visitors }.into()) + } +} + +enum ResolvedElement { + PatternMapping { + pattern_mapping: ReadRef, + request_str: String, + }, + Expr(Expr), +} + +/// Transforms `define([dep1, dep2], factory)` into: +/// ```js +/// __turbopack_export_value__( +/// factory( +/// __turbopack_require__(dep1), +/// __turbopack_require__(dep2), +/// ), +/// ); +/// ``` +fn transform_amd_factory( + call_expr: &mut CallExpr, + resolved_elements: &[ResolvedElement], + factory_type: AmdDefineFactoryType, +) { + let CallExpr { args, callee, .. } = call_expr; + let Some(factory) = take(args).pop().map(|e| e.expr) else { + return; + }; + + let deps = resolved_elements + .iter() + .map(|element| match element { + ResolvedElement::PatternMapping { + pattern_mapping: pm, + request_str: request, + } => { + let key_expr = Expr::Lit(Lit::Str(request.as_str().into())); + pm.create_require(key_expr) + } + ResolvedElement::Expr(expr) => expr.clone(), + }) + .map(ExprOrSpread::from) + .collect(); + + match factory_type { + AmdDefineFactoryType::Unknown => { + // ((f, r = typeof f !== "function" ? f : f([...])) => r !== undefined && + // __turbopack_export_value__(r))(...) + let f = private_ident!("f"); + let call_f = Expr::Call(CallExpr { + args: deps, + callee: Callee::Expr(Box::new(Expr::Ident(f.clone()))), + span: DUMMY_SP, + type_args: None, + }); + *callee = Callee::Expr(quote_expr!( + "($f1, r = typeof $f2 !== \"function\" ? $f3 : $call_f) => r !== undefined && \ + __turbopack_export_value(r)", + f1 = f.clone(), + f2 = f.clone(), + f3 = f, + call_f: Expr = call_f + )); + args.push(ExprOrSpread { + expr: factory, + spread: None, + }); + } + AmdDefineFactoryType::Function => { + // (r => r !== undefined && __turbopack_export_value__(r))(...([...])) + *callee = Callee::Expr(quote_expr!( + "r => r !== undefined && __turbopack_export_value__(r)" + )); + args.push(ExprOrSpread { + expr: Box::new(Expr::Call(CallExpr { + args: deps, + callee: Callee::Expr(factory), + span: DUMMY_SP, + type_args: None, + })), + spread: None, + }); + } + AmdDefineFactoryType::Value => { + // __turbopack_export_value__(...) + *callee = Callee::Expr(quote_expr!("__turbopack_export_value__")); + args.push(ExprOrSpread { + expr: factory, + spread: None, + }); + } + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs new file mode 100644 index 0000000000000..e2e2e8f5367f9 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/async_module.rs @@ -0,0 +1,249 @@ +use anyhow::Result; +use indexmap::IndexSet; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{ArrayLit, ArrayPat, Expr, Ident, Program}, + quote, +}; +use turbo_tasks::{trace::TraceRawVcs, ReadRef, TryFlatJoinIterExt, TryJoinIterExt, Vc}; +use turbopack_core::{ + chunk::{ + AsyncModuleInfo, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + }, + reference::{ModuleReference, ModuleReferences}, + resolve::ExternalType, +}; + +use super::esm::base::ReferencedAsset; +use crate::{code_gen::CodeGeneration, create_visitor, references::esm::base::insert_hoisted_stmt}; + +/// Information needed for generating the async module wrapper for +/// [EcmascriptChunkItem](crate::chunk::EcmascriptChunkItem)s. +#[derive(PartialEq, Eq, Default, Debug, Clone, Serialize, Deserialize, TraceRawVcs)] +pub struct AsyncModuleOptions { + pub has_top_level_await: bool, +} + +/// Option<[AsyncModuleOptions]>. +#[turbo_tasks::value(transparent)] +pub struct OptionAsyncModuleOptions(Option); + +#[turbo_tasks::value_impl] +impl OptionAsyncModuleOptions { + #[turbo_tasks::function] + pub(crate) fn none() -> Vc { + Vc::cell(None) + } +} + +/// Contains the information necessary to decide if an ecmascript module is +/// async. +/// +/// It will check if the current module or any of it's children contain a top +/// level await statement or is referencing an external ESM module. +#[turbo_tasks::value(shared)] +pub struct AsyncModule { + pub has_top_level_await: bool, + pub import_externals: bool, +} + +/// Option<[AsyncModule]>. +#[turbo_tasks::value(transparent)] +pub struct OptionAsyncModule(Option>); + +#[turbo_tasks::value_impl] +impl OptionAsyncModule { + /// Create an empty [OptionAsyncModule]. + #[turbo_tasks::function] + pub fn none() -> Vc { + Vc::cell(None) + } + + #[turbo_tasks::function] + pub async fn module_options( + self: Vc, + async_module_info: Option>, + ) -> Result> { + if let Some(async_module) = &*self.await? { + return Ok(async_module.module_options(async_module_info)); + } + + Ok(OptionAsyncModuleOptions::none()) + } +} + +#[turbo_tasks::value(transparent)] +struct AsyncModuleIdents(IndexSet); + +async fn get_inherit_async_referenced_asset( + r: Vc>, +) -> Result>> { + let Some(r) = Vc::try_resolve_downcast::>(r).await? else { + return Ok(None); + }; + let Some(ty) = *r.chunking_type().await? else { + return Ok(None); + }; + if !matches!(ty, ChunkingType::ParallelInheritAsync) { + return Ok(None); + }; + let referenced_asset: turbo_tasks::ReadRef = + ReferencedAsset::from_resolve_result(r.resolve_reference()).await?; + Ok(Some(referenced_asset)) +} + +#[turbo_tasks::value_impl] +impl AsyncModule { + #[turbo_tasks::function] + async fn get_async_idents( + &self, + chunking_context: Vc>, + async_module_info: Vc, + references: Vc, + ) -> Result> { + let async_module_info = async_module_info.await?; + + let reference_idents = references + .await? + .iter() + .map(|r| async { + let Some(referenced_asset) = get_inherit_async_referenced_asset(*r).await? else { + return Ok(None); + }; + Ok(match &*referenced_asset { + ReferencedAsset::External(_, ExternalType::EcmaScriptModule) => { + if self.import_externals { + referenced_asset.get_ident().await? + } else { + None + } + } + ReferencedAsset::Some(placeable) => { + let chunk_item = placeable + .as_chunk_item(Vc::upcast(chunking_context)) + .resolve() + .await?; + if async_module_info + .referenced_async_modules + .contains(&chunk_item) + { + referenced_asset.get_ident().await? + } else { + None + } + } + ReferencedAsset::External(..) => None, + ReferencedAsset::None => None, + }) + }) + .try_flat_join() + .await?; + + Ok(Vc::cell(IndexSet::from_iter(reference_idents))) + } + + #[turbo_tasks::function] + pub(crate) async fn is_self_async(&self, references: Vc) -> Result> { + if self.has_top_level_await { + return Ok(Vc::cell(true)); + } + + Ok(Vc::cell( + self.import_externals + && references + .await? + .iter() + .map(|r| async { + let Some(referenced_asset) = get_inherit_async_referenced_asset(*r).await? + else { + return Ok(false); + }; + Ok(matches!( + &*referenced_asset, + ReferencedAsset::External(_, ExternalType::EcmaScriptModule) + )) + }) + .try_join() + .await? + .iter() + .any(|&b| b), + )) + } + + /// Returns + #[turbo_tasks::function] + pub async fn module_options( + self: Vc, + async_module_info: Option>, + ) -> Result> { + if async_module_info.is_none() { + return Ok(Vc::cell(None)); + } + + Ok(Vc::cell(Some(AsyncModuleOptions { + has_top_level_await: self.await?.has_top_level_await, + }))) + } + + #[turbo_tasks::function] + pub async fn code_generation( + self: Vc, + chunking_context: Vc>, + async_module_info: Option>, + references: Vc, + ) -> Result> { + let mut visitors = Vec::new(); + + if let Some(async_module_info) = async_module_info { + let async_idents = self + .get_async_idents(chunking_context, async_module_info, references) + .await?; + + if !async_idents.is_empty() { + visitors.push(create_visitor!(visit_mut_program(program: &mut Program) { + add_async_dependency_handler(program, &async_idents); + })); + } + } + + Ok(CodeGeneration { visitors }.into()) + } +} + +fn add_async_dependency_handler(program: &mut Program, idents: &IndexSet) { + let idents = idents + .iter() + .map(|ident| Ident::new(ident.clone().into(), DUMMY_SP)) + .collect::>(); + + let stmt = quote!( + "var __turbopack_async_dependencies__ = __turbopack_handle_async_dependencies__($deps);" + as Stmt, + deps: Expr = Expr::Array(ArrayLit { + span: DUMMY_SP, + elems: idents + .iter() + .map(|ident| { Some(Expr::Ident(ident.clone()).into()) }) + .collect(), + }), + ); + + insert_hoisted_stmt(program, stmt); + + let stmt = quote!( + "($deps = __turbopack_async_dependencies__.then ? (await \ + __turbopack_async_dependencies__)() : __turbopack_async_dependencies__);" as Stmt, + deps: AssignTarget = ArrayPat { + span: DUMMY_SP, + elems: idents + .into_iter() + .map(|ident| { Some(ident.into()) }) + .collect(), + optional: false, + type_ann: None, + }.into(), + ); + + insert_hoisted_stmt(program, stmt); +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/cjs.rs b/turbopack/crates/turbopack-ecmascript/src/references/cjs.rs new file mode 100644 index 0000000000000..fe6ba26dbfbf1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/cjs.rs @@ -0,0 +1,320 @@ +use anyhow::Result; +use swc_core::{ + common::{util::take::Take, DUMMY_SP}, + ecma::ast::{CallExpr, Expr, ExprOrSpread, Ident, Lit}, + quote, +}; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ChunkableModuleReference, ChunkingContext}, + issue::IssueSource, + reference::ModuleReference, + resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, +}; +use turbopack_resolve::ecmascript::{cjs_resolve, try_to_severity}; + +use super::pattern_mapping::{PatternMapping, ResolveType::ChunkItem}; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, + references::AstPath, +}; + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct CjsAssetReference { + pub origin: Vc>, + pub request: Vc, + pub issue_source: Vc, + pub in_try: bool, +} + +#[turbo_tasks::value_impl] +impl CjsAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + issue_source: Vc, + in_try: bool, + ) -> Vc { + Self::cell(CjsAssetReference { + origin, + request, + issue_source, + in_try, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for CjsAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + cjs_resolve( + self.origin, + self.request, + Some(self.issue_source), + try_to_severity(self.in_try), + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for CjsAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("generic commonjs {}", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for CjsAssetReference {} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct CjsRequireAssetReference { + pub origin: Vc>, + pub request: Vc, + pub path: Vc, + pub issue_source: Vc, + pub in_try: bool, +} + +#[turbo_tasks::value_impl] +impl CjsRequireAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + path: Vc, + issue_source: Vc, + in_try: bool, + ) -> Vc { + Self::cell(CjsRequireAssetReference { + origin, + request, + path, + issue_source, + in_try, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for CjsRequireAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + cjs_resolve( + self.origin, + self.request, + Some(self.issue_source), + try_to_severity(self.in_try), + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for CjsRequireAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("require {}", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for CjsRequireAssetReference {} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for CjsRequireAssetReference { + #[turbo_tasks::function] + async fn code_generation( + &self, + chunking_context: Vc>, + ) -> Result> { + let pm = PatternMapping::resolve_request( + self.request, + self.origin, + Vc::upcast(chunking_context), + cjs_resolve( + self.origin, + self.request, + Some(self.issue_source), + try_to_severity(self.in_try), + ), + Value::new(ChunkItem), + ) + .await?; + let mut visitors = Vec::new(); + + let path = &self.path.await?; + visitors.push(create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + let old_expr = expr.take(); + let message = if let Expr::Call(CallExpr { args, ..}) = old_expr { + match args.into_iter().next() { + Some(ExprOrSpread { spread: None, expr: key_expr }) => { + *expr = pm.create_require(*key_expr); + return; + } + Some(ExprOrSpread { spread: Some(_), expr: _ }) => { + "spread operator is not analyse-able in require() expressions." + } + _ => { + "require() expressions require at least 1 argument" + } + } + } else { + "visitor must be executed on a CallExpr" + }; + *expr = quote!( + "(() => { throw new Error($message); })()" as Expr, + message: Expr = Expr::Lit(Lit::Str(message.into())) + ); + })); + + Ok(CodeGeneration { visitors }.into()) + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct CjsRequireResolveAssetReference { + pub origin: Vc>, + pub request: Vc, + pub path: Vc, + pub issue_source: Vc, + pub in_try: bool, +} + +#[turbo_tasks::value_impl] +impl CjsRequireResolveAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + path: Vc, + issue_source: Vc, + in_try: bool, + ) -> Vc { + Self::cell(CjsRequireResolveAssetReference { + origin, + request, + path, + issue_source, + in_try, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for CjsRequireResolveAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + cjs_resolve( + self.origin, + self.request, + Some(self.issue_source), + try_to_severity(self.in_try), + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for CjsRequireResolveAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("require.resolve {}", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for CjsRequireResolveAssetReference {} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for CjsRequireResolveAssetReference { + #[turbo_tasks::function] + async fn code_generation( + &self, + chunking_context: Vc>, + ) -> Result> { + let pm = PatternMapping::resolve_request( + self.request, + self.origin, + Vc::upcast(chunking_context), + cjs_resolve( + self.origin, + self.request, + Some(self.issue_source), + try_to_severity(self.in_try), + ), + Value::new(ChunkItem), + ) + .await?; + let mut visitors = Vec::new(); + + let path = &self.path.await?; + // Inline the result of the `require.resolve` call as a literal. + visitors.push(create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + if let Expr::Call(call_expr) = expr { + let args = std::mem::take(&mut call_expr.args); + *expr = match args.into_iter().next() { + Some(ExprOrSpread { expr, spread: None }) => pm.create_id(*expr), + other => { + let message = match other { + // These are SWC bugs: https://github.com/swc-project/swc/issues/5394 + Some(ExprOrSpread { spread: Some(_), expr: _ }) => { + "spread operator is not analyse-able in require() expressions." + } + _ => { + "require() expressions require at least 1 argument" + } + }; + quote!( + "(() => { throw new Error($message); })()" as Expr, + message: Expr = Expr::Lit(Lit::Str(message.into())) + ) + }, + }; + } + // CjsRequireResolveAssetReference will only be used for Expr::Call. + // Due to eventual consistency the path might match something else, + // but we can ignore that as it will be recomputed anyway. + })); + + Ok(CodeGeneration { visitors }.into()) + } +} + +#[turbo_tasks::value(shared)] +#[derive(Hash, Debug)] +pub struct CjsRequireCacheAccess { + pub path: Vc, +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for CjsRequireCacheAccess { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let mut visitors = Vec::new(); + + let path = &self.path.await?; + visitors.push(create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + if let Expr::Member(_) = expr { + *expr = Expr::Ident(Ident::new("__turbopack_cache__".into(), DUMMY_SP)); + } else { + unreachable!("`CjsRequireCacheAccess` is only created from `MemberExpr`"); + } + })); + + Ok(CodeGeneration { visitors }.into()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/constant_condition.rs b/turbopack/crates/turbopack-ecmascript/src/references/constant_condition.rs new file mode 100644 index 0000000000000..8f5f64e5b204d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/constant_condition.rs @@ -0,0 +1,58 @@ +use anyhow::Result; +use swc_core::quote; +use turbo_tasks::{Value, Vc}; +use turbopack_core::chunk::ChunkingContext; + +use super::AstPath; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, +}; + +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Debug, Clone, Copy, Hash)] +pub enum ConstantConditionValue { + Truthy, + Falsy, + Nullish, +} + +#[turbo_tasks::value] +pub struct ConstantCondition { + value: ConstantConditionValue, + path: Vc, +} + +#[turbo_tasks::value_impl] +impl ConstantCondition { + #[turbo_tasks::function] + pub fn new(value: Value, path: Vc) -> Vc { + Self::cell(ConstantCondition { + value: value.into_value(), + path, + }) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for ConstantCondition { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let value = self.value; + let visitors = [ + create_visitor!(exact &self.path.await?, visit_mut_expr(expr: &mut Expr) { + *expr = match value { + ConstantConditionValue::Truthy => quote!("(\"TURBOPACK compile-time truthy\", 1)" as Expr), + ConstantConditionValue::Falsy => quote!("(\"TURBOPACK compile-time falsy\", 0)" as Expr), + ConstantConditionValue::Nullish => quote!("(\"TURBOPACK compile-time nullish\", null)" as Expr), + }; + }), + ] + .into(); + + Ok(CodeGeneration { visitors }.cell()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/constant_value.rs b/turbopack/crates/turbopack-ecmascript/src/references/constant_value.rs new file mode 100644 index 0000000000000..c2f94aeed1b62 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/constant_value.rs @@ -0,0 +1,53 @@ +use anyhow::Result; +use swc_core::quote; +use turbo_tasks::{Value, Vc}; +use turbopack_core::{chunk::ChunkingContext, compile_time_info::CompileTimeDefineValue}; + +use super::AstPath; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, +}; + +#[turbo_tasks::value] +pub struct ConstantValue { + value: CompileTimeDefineValue, + path: Vc, +} + +#[turbo_tasks::value_impl] +impl ConstantValue { + #[turbo_tasks::function] + pub fn new(value: Value, path: Vc) -> Vc { + Self::cell(ConstantValue { + value: value.into_value(), + path, + }) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for ConstantValue { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let value = self.value.clone(); + let path = &self.path.await?; + + let visitor = create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + *expr = match value { + CompileTimeDefineValue::Bool(true) => quote!("(\"TURBOPACK compile-time value\", true)" as Expr), + CompileTimeDefineValue::Bool(false) => quote!("(\"TURBOPACK compile-time value\", false)" as Expr), + CompileTimeDefineValue::String(ref s) => quote!("(\"TURBOPACK compile-time value\", $e)" as Expr, e: Expr = s.to_string().into()), + CompileTimeDefineValue::JSON(ref s) => quote!("(\"TURBOPACK compile-time value\", JSON.parse($e))" as Expr, e: Expr = s.to_string().into()), + }; + }); + + Ok(CodeGeneration { + visitors: vec![visitor], + } + .cell()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/dynamic_expression.rs b/turbopack/crates/turbopack-ecmascript/src/references/dynamic_expression.rs new file mode 100644 index 0000000000000..6aee2d0e6e387 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/dynamic_expression.rs @@ -0,0 +1,71 @@ +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use swc_core::quote; +use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, Vc}; +use turbopack_core::chunk::ChunkingContext; + +use super::AstPath; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, +}; + +#[derive(PartialEq, Eq, TraceRawVcs, Serialize, Deserialize, ValueDebugFormat)] +enum DynamicExpressionType { + Promise, + Normal, +} + +#[turbo_tasks::value] +pub struct DynamicExpression { + path: Vc, + ty: DynamicExpressionType, +} + +#[turbo_tasks::value_impl] +impl DynamicExpression { + #[turbo_tasks::function] + pub fn new(path: Vc) -> Vc { + Self::cell(DynamicExpression { + path, + ty: DynamicExpressionType::Normal, + }) + } + + #[turbo_tasks::function] + pub fn new_promise(path: Vc) -> Vc { + Self::cell(DynamicExpression { + path, + ty: DynamicExpressionType::Promise, + }) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for DynamicExpression { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let path = &self.path.await?; + + let visitor = match self.ty { + DynamicExpressionType::Normal => { + create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + *expr = quote!("(() => { const e = new Error(\"Cannot find module as expression is too dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })()" as Expr); + }) + } + DynamicExpressionType::Promise => { + create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + *expr = quote!("Promise.resolve().then(() => { const e = new Error(\"Cannot find module as expression is too dynamic\"); e.code = 'MODULE_NOT_FOUND'; throw e; })" as Expr); + }) + } + }; + + Ok(CodeGeneration { + visitors: vec![visitor], + } + .cell()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs new file mode 100644 index 0000000000000..8852d61a52442 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/base.rs @@ -0,0 +1,414 @@ +use anyhow::{anyhow, bail, Result}; +use lazy_static::lazy_static; +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{self, Expr, ExprStmt, Ident, Lit, ModuleItem, Program, Script, Stmt}, + quote, +}; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + ChunkingTypeOption, ModuleId, + }, + issue::{IssueSeverity, IssueSource}, + module::Module, + reference::ModuleReference, + reference_type::{EcmaScriptModulesReferenceSubType, ImportWithType}, + resolve::{ + origin::{ResolveOrigin, ResolveOriginExt}, + parse::Request, + ExternalType, ModulePart, ModuleResolveResult, ModuleResolveResultItem, + }, +}; +use turbopack_resolve::ecmascript::esm_resolve; + +use crate::{ + analyzer::imports::ImportAnnotations, + chunk::EcmascriptChunkPlaceable, + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, magic_identifier, + references::util::{request_to_string, throw_module_not_found_expr}, + tree_shake::{asset::EcmascriptModulePartAsset, TURBOPACK_PART_IMPORT_SOURCE}, +}; + +#[turbo_tasks::value] +pub enum ReferencedAsset { + Some(Vc>), + External(RcStr, ExternalType), + None, +} + +impl ReferencedAsset { + pub async fn get_ident(&self) -> Result> { + Ok(match self { + ReferencedAsset::Some(asset) => Some(Self::get_ident_from_placeable(asset).await?), + ReferencedAsset::External(request, ty) => Some(magic_identifier::mangle(&format!( + "{ty} external {request}" + ))), + ReferencedAsset::None => None, + }) + } + + pub(crate) async fn get_ident_from_placeable( + asset: &Vc>, + ) -> Result { + let path = asset.ident().to_string().await?; + Ok(magic_identifier::mangle(&format!( + "imported module {}", + path + ))) + } +} + +#[turbo_tasks::value_impl] +impl ReferencedAsset { + #[turbo_tasks::function] + pub async fn from_resolve_result(resolve_result: Vc) -> Result> { + // TODO handle multiple keyed results + for (_key, result) in resolve_result.await?.primary.iter() { + match result { + ModuleResolveResultItem::External(request, ty) => { + return Ok(ReferencedAsset::External(request.clone(), *ty).cell()); + } + &ModuleResolveResultItem::Module(module) => { + if let Some(placeable) = + Vc::try_resolve_downcast::>(module) + .await? + { + return Ok(ReferencedAsset::cell(ReferencedAsset::Some(placeable))); + } + } + // TODO ignore should probably be handled differently + _ => {} + } + } + Ok(ReferencedAsset::cell(ReferencedAsset::None)) + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct EsmAssetReference { + pub origin: Vc>, + pub request: Vc, + pub annotations: ImportAnnotations, + pub issue_source: Option>, + pub export_name: Option>, + pub import_externals: bool, + pub special_exports: Vc>, +} + +/// A list of [EsmAssetReference]s +#[turbo_tasks::value(transparent)] +pub struct EsmAssetReferences(Vec>); + +impl EsmAssetReference { + fn get_origin(&self) -> Vc> { + let mut origin = self.origin; + if let Some(transition) = self.annotations.transition() { + origin = origin.with_transition(transition.into()); + } + origin + } +} + +#[turbo_tasks::value_impl] +impl EsmAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + issue_source: Option>, + annotations: Value, + export_name: Option>, + special_exports: Vc>, + import_externals: bool, + ) -> Vc { + Self::cell(EsmAssetReference { + origin, + request, + issue_source, + annotations: annotations.into_value(), + export_name, + import_externals, + special_exports, + }) + } + + #[turbo_tasks::function] + pub(crate) fn get_referenced_asset(self: Vc) -> Vc { + ReferencedAsset::from_resolve_result(self.resolve_reference()) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for EsmAssetReference { + #[turbo_tasks::function] + async fn resolve_reference(&self) -> Result> { + let ty = if matches!(self.annotations.module_type(), Some("json")) { + EcmaScriptModulesReferenceSubType::ImportWithType(ImportWithType::Json) + } else if let Some(part) = &self.export_name { + EcmaScriptModulesReferenceSubType::ImportPart(*part) + } else { + EcmaScriptModulesReferenceSubType::Import + }; + + if let Request::Module { module, .. } = &*self.request.await? { + if module == TURBOPACK_PART_IMPORT_SOURCE { + if let Some(part) = self.export_name { + let full_module: Vc = + Vc::try_resolve_downcast_type(self.origin) + .await? + .expect("EsmAssetReference origin should be a EcmascriptModuleAsset"); + + let module = + EcmascriptModulePartAsset::new(full_module, part, self.import_externals); + + return Ok(ModuleResolveResult::module(Vc::upcast(module)).cell()); + } + + bail!("export_name is required for part import") + } + } + + Ok(esm_resolve( + self.get_origin().resolve().await?, + self.request, + Value::new(ty), + IssueSeverity::Error.cell(), + self.issue_source, + )) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EsmAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!( + "import {} with {}", + self.request.to_string().await?, + self.annotations + ) + .into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for EsmAssetReference { + #[turbo_tasks::function] + fn chunking_type(&self) -> Result> { + Ok(Vc::cell( + if let Some(chunking_type) = self.annotations.chunking_type() { + match chunking_type { + "parallel" => Some(ChunkingType::ParallelInheritAsync), + "none" => None, + _ => return Err(anyhow!("unknown chunking_type: {}", chunking_type)), + } + } else { + Some(ChunkingType::ParallelInheritAsync) + }, + )) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for EsmAssetReference { + #[turbo_tasks::function] + async fn code_generation( + self: Vc, + chunking_context: Vc>, + ) -> Result> { + let mut visitors = Vec::new(); + + let this = &*self.await?; + let chunking_type = self.chunking_type().await?; + let resolved = self.resolve_reference().await?; + + // Insert code that throws immediately at time of import if a request is + // unresolvable + if resolved.is_unresolveable_ref() { + let request = request_to_string(this.request).await?.to_string(); + visitors.push(create_visitor!(visit_mut_program(program: &mut Program) { + insert_hoisted_stmt(program, Stmt::Expr(ExprStmt { + expr: Box::new(throw_module_not_found_expr( + &request + )), + span: DUMMY_SP, + })); + })); + + return Ok(CodeGeneration { visitors }.into()); + } + + // only chunked references can be imported + if chunking_type.is_some() { + let referenced_asset = self.get_referenced_asset().await?; + let import_externals = this.import_externals; + if let Some(ident) = referenced_asset.get_ident().await? { + match &*referenced_asset { + ReferencedAsset::Some(asset) => { + let id = asset + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?; + visitors.push(create_visitor!(visit_mut_program(program: &mut Program) { + let stmt = quote!( + "var $name = __turbopack_import__($id);" as Stmt, + name = Ident::new(ident.clone().into(), DUMMY_SP), + id: Expr = Expr::Lit(match &*id { + ModuleId::String(s) => s.clone().as_str().into(), + ModuleId::Number(n) => (*n as f64).into(), + }) + ); + insert_hoisted_stmt(program, stmt); + })); + } + ReferencedAsset::External(request, ExternalType::EcmaScriptModule) => { + if !*chunking_context + .environment() + .supports_esm_externals() + .await? + { + bail!( + "the chunking context ({}) does not support external modules (esm \ + request: {})", + chunking_context.name().await?, + request + ); + } + let request = request.clone(); + visitors.push(create_visitor!(visit_mut_program(program: &mut Program) { + let stmt = if import_externals { + quote!( + "var $name = __turbopack_external_import__($id);" as Stmt, + name = Ident::new(ident.clone().into(), DUMMY_SP), + id: Expr = Expr::Lit(request.to_string().into()) + ) + } else { + quote!( + "var $name = __turbopack_external_require__($id, true);" as Stmt, + name = Ident::new(ident.clone().into(), DUMMY_SP), + id: Expr = Expr::Lit(request.to_string().into()) + ) + }; + insert_hoisted_stmt(program, stmt); + })); + } + ReferencedAsset::External( + request, + ExternalType::CommonJs | ExternalType::Url, + ) => { + if !*chunking_context + .environment() + .supports_commonjs_externals() + .await? + { + bail!( + "the chunking context ({}) does not support external modules \ + (request: {})", + chunking_context.name().await?, + request + ); + } + let request = request.clone(); + visitors.push(create_visitor!(visit_mut_program(program: &mut Program) { + let stmt = quote!( + "var $name = __turbopack_external_require__($id, true);" as Stmt, + name = Ident::new(ident.clone().into(), DUMMY_SP), + id: Expr = Expr::Lit(request.to_string().into()) + ); + insert_hoisted_stmt(program, stmt); + })); + } + #[allow(unreachable_patterns)] + ReferencedAsset::External(request, ty) => { + bail!( + "Unsupported external type {:?} for ESM reference with request: {:?}", + ty, + request + ) + } + ReferencedAsset::None => {} + } + } + } + + Ok(CodeGeneration { visitors }.into()) + } +} + +lazy_static! { + static ref ESM_HOISTING_LOCATION: &'static str = Box::leak(Box::new(magic_identifier::mangle( + "ecmascript hoisting location" + ))); +} + +pub(crate) fn insert_hoisted_stmt(program: &mut Program, stmt: Stmt) { + match program { + Program::Module(ast::Module { body, .. }) => { + let pos = body.iter().position(|item| { + if let ModuleItem::Stmt(Stmt::Expr(ExprStmt { + expr: box Expr::Lit(Lit::Str(s)), + .. + })) = item + { + &*s.value == *ESM_HOISTING_LOCATION + } else { + false + } + }); + if let Some(pos) = pos { + let has_stmt = body[0..pos].iter().any(|item| { + if let ModuleItem::Stmt(item_stmt) = item { + stmt == *item_stmt + } else { + false + } + }); + if !has_stmt { + body.insert(pos, ModuleItem::Stmt(stmt)); + } + } else { + body.splice( + 0..0, + [ + ModuleItem::Stmt(stmt), + ModuleItem::Stmt(Stmt::Expr(ExprStmt { + expr: Box::new(Expr::Lit(Lit::Str((*ESM_HOISTING_LOCATION).into()))), + span: DUMMY_SP, + })), + ], + ); + } + } + Program::Script(Script { body, .. }) => { + let pos = body.iter().position(|item| { + if let Stmt::Expr(ExprStmt { + expr: box Expr::Lit(Lit::Str(s)), + .. + }) = item + { + &*s.value == *ESM_HOISTING_LOCATION + } else { + false + } + }); + if let Some(pos) = pos { + body.insert(pos, stmt); + } else { + body.insert( + 0, + Stmt::Expr(ExprStmt { + expr: Box::new(Expr::Lit(Lit::Str((*ESM_HOISTING_LOCATION).into()))), + span: DUMMY_SP, + }), + ); + body.insert(0, stmt); + } + } + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs new file mode 100644 index 0000000000000..c817b5dcfe512 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/binding.rs @@ -0,0 +1,201 @@ +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::{Span, SyntaxContext}, + ecma::{ + ast::{ + ComputedPropName, Expr, Ident, KeyValueProp, Lit, MemberExpr, MemberProp, Number, Prop, + PropName, SeqExpr, SimpleAssignTarget, Str, + }, + visit::{ + fields::{CalleeField, PropField}, + AstParentKind, + }, + }, +}; +use turbo_tasks::{trace::TraceRawVcs, RcStr, TaskInput, Vc}; +use turbopack_core::chunk::ChunkingContext; + +use super::EsmAssetReference; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration, VisitorFactory}, + create_visitor, + references::AstPath, +}; + +#[turbo_tasks::value(shared)] +#[derive(Hash, Debug)] +pub struct EsmBindings { + pub bindings: Vec, +} + +#[turbo_tasks::value_impl] +impl EsmBindings { + #[turbo_tasks::function] + pub fn new(bindings: Vec) -> Vc { + EsmBindings { bindings }.cell() + } +} + +#[derive(Hash, Clone, Debug, TaskInput, Serialize, Deserialize, PartialEq, Eq, TraceRawVcs)] +pub struct EsmBinding { + pub reference: Vc, + pub export: Option, + pub ast_path: Vc, +} + +impl EsmBinding { + pub fn new( + reference: Vc, + export: Option, + ast_path: Vc, + ) -> Self { + EsmBinding { + reference, + export, + ast_path, + } + } + + async fn to_visitors( + &self, + visitors: &mut Vec<(Vec, Box)>, + ) -> Result<()> { + let item = self.clone(); + let imported_module = self.reference.get_referenced_asset(); + + let mut ast_path = item.ast_path.await?.clone_value(); + let imported_module = imported_module.await?.get_ident().await?; + + loop { + match ast_path.last() { + // Shorthand properties get special treatment because we need to rewrite them to + // normal key-value pairs. + Some(swc_core::ecma::visit::AstParentKind::Prop(PropField::Shorthand)) => { + ast_path.pop(); + visitors.push( + create_visitor!(exact ast_path, visit_mut_prop(prop: &mut Prop) { + if let Prop::Shorthand(ident) = prop { + // TODO: Merge with the above condition when https://rust-lang.github.io/rfcs/2497-if-let-chains.html lands. + if let Some(imported_ident) = imported_module.as_deref() { + *prop = Prop::KeyValue(KeyValueProp { + key: PropName::Ident(ident.clone()), + value: Box::new(make_expr(imported_ident, item.export.as_deref(), ident.span, false)) + }); + } + } + })); + break; + } + // Any other expression can be replaced with the import accessor. + Some(swc_core::ecma::visit::AstParentKind::Expr(_)) => { + ast_path.pop(); + let in_call = matches!( + ast_path.last(), + Some(swc_core::ecma::visit::AstParentKind::Callee( + CalleeField::Expr + )) + ); + + visitors.push( + create_visitor!(exact ast_path, visit_mut_expr(expr: &mut Expr) { + if let Some(ident) = imported_module.as_deref() { + use swc_core::common::Spanned; + *expr = make_expr(ident, item.export.as_deref(), expr.span(), in_call); + } + // If there's no identifier for the imported module, + // resolution failed and will insert code that throws + // before this expression is reached. Leave behind the original identifier. + })); + break; + } + Some(swc_core::ecma::visit::AstParentKind::BindingIdent( + swc_core::ecma::visit::fields::BindingIdentField::Id, + )) => { + ast_path.pop(); + + // We need to handle LHS because of code like + // (function (RouteKind1){})(RouteKind || RouteKind = {}) + if let Some(swc_core::ecma::visit::AstParentKind::SimpleAssignTarget( + swc_core::ecma::visit::fields::SimpleAssignTargetField::Ident, + )) = ast_path.last() + { + ast_path.pop(); + + visitors.push( + create_visitor!(exact ast_path, visit_mut_simple_assign_target(l: &mut SimpleAssignTarget) { + if let Some(ident) = imported_module.as_deref() { + use swc_core::common::Spanned; + *l = match make_expr(ident, item.export.as_deref(), l.span(), false) { + Expr::Ident(ident) => SimpleAssignTarget::Ident(ident.into()), + Expr::Member(member) => SimpleAssignTarget::Member(member), + _ => unreachable!(), + }; + } + })); + break; + } + } + Some(_) => { + ast_path.pop(); + } + None => break, + } + } + + Ok(()) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for EsmBindings { + #[turbo_tasks::function] + async fn code_generation( + self: Vc, + _context: Vc>, + ) -> Result> { + let this = self.await?; + let mut visitors = Vec::new(); + let bindings = this.bindings.clone(); + + for item in bindings.into_iter() { + item.to_visitors(&mut visitors).await?; + } + + Ok(CodeGeneration { visitors }.into()) + } +} + +fn make_expr(imported_module: &str, export: Option<&str>, span: Span, in_call: bool) -> Expr { + let span = span.with_ctxt(SyntaxContext::empty()); + if let Some(export) = export { + let mut expr = Expr::Member(MemberExpr { + span, + obj: Box::new(Expr::Ident(Ident::new(imported_module.into(), span))), + prop: MemberProp::Computed(ComputedPropName { + span, + expr: Box::new(Expr::Lit(Lit::Str(Str { + span, + value: export.into(), + raw: None, + }))), + }), + }); + if in_call { + expr = Expr::Seq(SeqExpr { + exprs: vec![ + Box::new(Expr::Lit(Lit::Num(Number { + span, + value: 0.0, + raw: None, + }))), + Box::new(expr), + ], + span, + }); + } + expr + } else { + Expr::Ident(Ident::new(imported_module.into(), span)) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/dynamic.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/dynamic.rs new file mode 100644 index 0000000000000..39aace538688c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/dynamic.rs @@ -0,0 +1,161 @@ +use anyhow::Result; +use swc_core::{ + common::{util::take::Take, DUMMY_SP}, + ecma::ast::{CallExpr, Callee, Expr, ExprOrSpread, Lit}, + quote_expr, +}; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ChunkableModuleReference, ChunkingContext, ChunkingType, ChunkingTypeOption}, + environment::ChunkLoading, + issue::IssueSource, + reference::ModuleReference, + reference_type::EcmaScriptModulesReferenceSubType, + resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, +}; +use turbopack_resolve::ecmascript::{esm_resolve, try_to_severity}; + +use super::super::pattern_mapping::{PatternMapping, ResolveType}; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, + references::AstPath, +}; + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct EsmAsyncAssetReference { + pub origin: Vc>, + pub request: Vc, + pub path: Vc, + pub issue_source: Vc, + pub in_try: bool, + pub import_externals: bool, +} + +#[turbo_tasks::value_impl] +impl EsmAsyncAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + path: Vc, + issue_source: Vc, + in_try: bool, + import_externals: bool, + ) -> Vc { + Self::cell(EsmAsyncAssetReference { + origin, + request, + path, + issue_source, + in_try, + import_externals, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for EsmAsyncAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + esm_resolve( + self.origin, + self.request, + Value::new(EcmaScriptModulesReferenceSubType::DynamicImport), + try_to_severity(self.in_try), + Some(self.issue_source), + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EsmAsyncAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("dynamic import {}", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for EsmAsyncAssetReference { + #[turbo_tasks::function] + fn chunking_type(&self) -> Vc { + Vc::cell(Some(ChunkingType::Async)) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for EsmAsyncAssetReference { + #[turbo_tasks::function] + async fn code_generation( + &self, + chunking_context: Vc>, + ) -> Result> { + let pm = PatternMapping::resolve_request( + self.request, + self.origin, + Vc::upcast(chunking_context), + esm_resolve( + self.origin, + self.request, + Value::new(EcmaScriptModulesReferenceSubType::DynamicImport), + try_to_severity(self.in_try), + Some(self.issue_source), + ), + if matches!( + *chunking_context.environment().chunk_loading().await?, + ChunkLoading::Edge + ) { + Value::new(ResolveType::ChunkItem) + } else { + Value::new(ResolveType::AsyncChunkLoader) + }, + ) + .await?; + + let path = &self.path.await?; + let import_externals = self.import_externals; + + let visitor = create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + let old_expr = expr.take(); + let message = if let Expr::Call(CallExpr { args, ..}) = old_expr { + match args.into_iter().next() { + Some(ExprOrSpread { spread: None, expr: key_expr }) => { + *expr = pm.create_import(*key_expr, import_externals); + return; + } + // These are SWC bugs: https://github.com/swc-project/swc/issues/5394 + Some(ExprOrSpread { spread: Some(_), expr: _ }) => { + "spread operator is illegal in import() expressions." + } + _ => { + "import() expressions require at least 1 argument" + } + } + } else { + "visitor must be executed on a CallExpr" + }; + let error = quote_expr!( + "() => { throw new Error($message); }", + message: Expr = Expr::Lit(Lit::Str(message.into())) + ); + *expr = Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!("Promise.resolve().then")), + args: vec![ExprOrSpread { + spread: None, + expr: error, + }], + span: DUMMY_SP, + type_args: None, + }); + }); + + Ok(CodeGeneration { + visitors: vec![visitor], + } + .into()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs new file mode 100644 index 0000000000000..221e0de763c22 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/export.rs @@ -0,0 +1,538 @@ +use std::{ + collections::{BTreeMap, HashSet}, + ops::ControlFlow, +}; + +use anyhow::Result; +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{ + self, ComputedPropName, Expr, ExprStmt, Ident, KeyValueProp, Lit, MemberExpr, MemberProp, + ModuleItem, ObjectLit, Program, Prop, PropName, PropOrSpread, Script, Stmt, Str, + }, + quote, quote_expr, +}; +use turbo_tasks::{trace::TraceRawVcs, RcStr, TryFlatJoinIterExt, ValueToString, Vc}; +use turbo_tasks_fs::glob::Glob; +use turbopack_core::{ + chunk::ChunkingContext, + ident::AssetIdent, + issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, StyledString}, + module::Module, + reference::ModuleReference, +}; + +use super::base::ReferencedAsset; +use crate::{ + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, + references::esm::base::insert_hoisted_stmt, +}; + +#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)] +pub enum EsmExport { + /// A local binding that is exported (export { a } or export const a = 1) + /// + /// The last bool is true if the binding is a mutable binding + LocalBinding(RcStr, bool), + /// An imported binding that is exported (export { a as b } from "...") + /// + /// The last bool is true if the binding is a mutable binding + ImportedBinding(Vc>, RcStr, bool), + /// An imported namespace that is exported (export * from "...") + ImportedNamespace(Vc>), + /// An error occurred while resolving the export + Error, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)] +pub enum FoundExportType { + Found, + Dynamic, + NotFound, + SideEffects, + Unknown, +} + +#[turbo_tasks::value] +pub struct FollowExportsResult { + pub module: Vc>, + pub export_name: Option, + pub ty: FoundExportType, +} + +#[turbo_tasks::function] +pub async fn follow_reexports( + module: Vc>, + export_name: RcStr, + side_effect_free_packages: Vc, +) -> Result> { + if !*module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await? + { + return Ok(FollowExportsResult::cell(FollowExportsResult { + module, + export_name: Some(export_name), + ty: FoundExportType::SideEffects, + })); + } + let mut module = module; + let mut export_name = export_name; + loop { + let exports = module.get_exports().await?; + let EcmascriptExports::EsmExports(exports) = &*exports else { + return Ok(FollowExportsResult::cell(FollowExportsResult { + module, + export_name: Some(export_name), + ty: FoundExportType::Dynamic, + })); + }; + + // Try to find the export in the local exports + let exports_ref = exports.await?; + if let Some(export) = exports_ref.exports.get(&export_name) { + match handle_declared_export(module, export_name, export, side_effect_free_packages) + .await? + { + ControlFlow::Continue((m, n)) => { + module = m; + export_name = n; + continue; + } + ControlFlow::Break(result) => { + return Ok(result.cell()); + } + } + } + + // Try to find the export in the star exports + if !exports_ref.star_exports.is_empty() && &*export_name != "default" { + let result = get_all_export_names(module).await?; + if let Some(m) = result.esm_exports.get(&export_name) { + module = *m; + continue; + } + return match &result.dynamic_exporting_modules[..] { + [] => Ok(FollowExportsResult { + module, + export_name: Some(export_name), + ty: FoundExportType::NotFound, + } + .cell()), + [module] => Ok(FollowExportsResult { + module: *module, + export_name: Some(export_name), + ty: FoundExportType::Dynamic, + } + .cell()), + _ => Ok(FollowExportsResult { + module, + export_name: Some(export_name), + ty: FoundExportType::Dynamic, + } + .cell()), + }; + } + + return Ok(FollowExportsResult::cell(FollowExportsResult { + module, + export_name: Some(export_name), + ty: FoundExportType::NotFound, + })); + } +} + +async fn handle_declared_export( + module: Vc>, + export_name: RcStr, + export: &EsmExport, + side_effect_free_packages: Vc, +) -> Result>, RcStr)>> { + match export { + EsmExport::ImportedBinding(reference, name, _) => { + if let ReferencedAsset::Some(module) = + *ReferencedAsset::from_resolve_result(reference.resolve_reference()).await? + { + if !*module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await? + { + return Ok(ControlFlow::Break(FollowExportsResult { + module, + export_name: Some(name.clone()), + ty: FoundExportType::SideEffects, + })); + } + return Ok(ControlFlow::Continue((module, name.clone()))); + } + } + EsmExport::ImportedNamespace(reference) => { + if let ReferencedAsset::Some(m) = + *ReferencedAsset::from_resolve_result(reference.resolve_reference()).await? + { + return Ok(ControlFlow::Break(FollowExportsResult { + module: m, + export_name: None, + ty: FoundExportType::Found, + })); + } + } + EsmExport::LocalBinding(..) => { + return Ok(ControlFlow::Break(FollowExportsResult { + module, + export_name: Some(export_name), + ty: FoundExportType::Found, + })); + } + EsmExport::Error => { + return Ok(ControlFlow::Break(FollowExportsResult { + module, + export_name: Some(export_name), + ty: FoundExportType::Unknown, + })); + } + } + Ok(ControlFlow::Break(FollowExportsResult { + module, + export_name: Some(export_name), + ty: FoundExportType::Unknown, + })) +} + +#[turbo_tasks::value] +struct AllExportNamesResult { + esm_exports: IndexMap>>, + dynamic_exporting_modules: Vec>>, +} + +#[turbo_tasks::function] +async fn get_all_export_names( + module: Vc>, +) -> Result> { + let exports = module.get_exports().await?; + let EcmascriptExports::EsmExports(exports) = &*exports else { + return Ok(AllExportNamesResult { + esm_exports: IndexMap::new(), + dynamic_exporting_modules: vec![module], + } + .cell()); + }; + + let exports = exports.await?; + let mut esm_exports = IndexMap::new(); + let mut dynamic_exporting_modules = Vec::new(); + esm_exports.extend(exports.exports.keys().cloned().map(|n| (n, module))); + let star_export_names = exports + .star_exports + .iter() + .map(|esm_ref| async { + Ok( + if let ReferencedAsset::Some(m) = + *ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await? + { + Some(get_all_export_names(m)) + } else { + None + }, + ) + }) + .try_flat_join() + .await?; + for star_export_names in star_export_names { + let star_export_names = star_export_names.await?; + esm_exports.extend( + star_export_names + .esm_exports + .iter() + .map(|(k, &v)| (k.clone(), v)), + ); + dynamic_exporting_modules + .extend(star_export_names.dynamic_exporting_modules.iter().copied()); + } + + Ok(AllExportNamesResult { + esm_exports, + dynamic_exporting_modules, + } + .cell()) +} + +#[turbo_tasks::value] +pub struct ExpandStarResult { + pub star_exports: Vec, + pub has_dynamic_exports: bool, +} + +#[turbo_tasks::function] +pub async fn expand_star_exports( + root_module: Vc>, +) -> Result> { + let mut set = HashSet::new(); + let mut has_dynamic_exports = false; + let mut checked_modules = HashSet::new(); + checked_modules.insert(root_module); + let mut queue = vec![(root_module, root_module.get_exports())]; + while let Some((asset, exports)) = queue.pop() { + match &*exports.await? { + EcmascriptExports::EsmExports(exports) => { + let exports = exports.await?; + set.extend(exports.exports.keys().filter(|n| *n != "default").cloned()); + for esm_ref in exports.star_exports.iter() { + if let ReferencedAsset::Some(asset) = + &*ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await? + { + if checked_modules.insert(*asset) { + queue.push((*asset, asset.get_exports())); + } + } + } + } + EcmascriptExports::None => emit_star_exports_issue( + asset.ident(), + format!( + "export * used with module {} which has no exports\nTypescript only: Did you \ + want to export only types with `export type * from \"...\"`?\nNote: Using \ + `export type` is more efficient than `export *` as it won't emit any runtime \ + code.", + asset.ident().to_string().await? + ) + .into(), + ), + EcmascriptExports::Value => emit_star_exports_issue( + asset.ident(), + format!( + "export * used with module {} which only has a default export (default export \ + is not exported with export *)\nDid you want to use `export {{ default }} \ + from \"...\";` instead?", + asset.ident().to_string().await? + ) + .into(), + ), + EcmascriptExports::CommonJs => { + has_dynamic_exports = true; + emit_star_exports_issue( + asset.ident(), + format!( + "export * used with module {} which is a CommonJS module with exports \ + only available at runtime\nList all export names manually (`export {{ a, \ + b, c }} from \"...\") or rewrite the module to ESM, to avoid the \ + additional runtime code.`", + asset.ident().to_string().await? + ) + .into(), + ); + } + EcmascriptExports::DynamicNamespace => { + has_dynamic_exports = true; + } + } + } + + Ok(ExpandStarResult { + star_exports: set.into_iter().collect(), + has_dynamic_exports, + } + .cell()) +} + +fn emit_star_exports_issue(source_ident: Vc, message: RcStr) { + AnalyzeIssue { + code: None, + message: StyledString::Text(message).cell(), + source_ident, + severity: IssueSeverity::Warning.into(), + source: None, + title: Vc::cell("unexpected export *".into()), + } + .cell() + .emit(); +} + +#[turbo_tasks::value(shared)] +#[derive(Hash, Debug)] +pub struct EsmExports { + pub exports: BTreeMap, + pub star_exports: Vec>>, +} + +/// The expanded version of [EsmExports], the `exports` field here includes all +/// exports that could be expanded from `star_exports`. +/// +/// `star_exports` that could not be (fully) expanded end up in +/// `dynamic_exports`. +#[turbo_tasks::value(shared)] +#[derive(Hash, Debug)] +pub struct ExpandedExports { + pub exports: BTreeMap, + /// Modules we couldn't analyse all exports of. + pub dynamic_exports: Vec>>, +} + +#[turbo_tasks::value_impl] +impl EsmExports { + #[turbo_tasks::function] + pub async fn expand_exports(&self) -> Result> { + let mut exports: BTreeMap = self.exports.clone(); + let mut dynamic_exports = vec![]; + + for esm_ref in self.star_exports.iter() { + // TODO(PACK-2176): we probably need to handle re-exporting from external + // modules. + let ReferencedAsset::Some(asset) = + &*ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await? + else { + continue; + }; + + let export_info = expand_star_exports(*asset).await?; + + for export in &export_info.star_exports { + if !exports.contains_key(export) { + exports.insert( + export.clone(), + EsmExport::ImportedBinding(Vc::upcast(*esm_ref), export.clone(), false), + ); + } + } + + if export_info.has_dynamic_exports { + dynamic_exports.push(*asset); + } + } + + Ok(ExpandedExports { + exports, + dynamic_exports, + } + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for EsmExports { + #[turbo_tasks::function] + async fn code_generation( + self: Vc, + _context: Vc>, + ) -> Result> { + let mut visitors = Vec::new(); + + let expanded = self.expand_exports().await?; + + let mut dynamic_exports = Vec::>::new(); + for dynamic_export_asset in &expanded.dynamic_exports { + let ident = ReferencedAsset::get_ident_from_placeable(dynamic_export_asset).await?; + + dynamic_exports.push(quote_expr!( + "__turbopack_dynamic__($arg)", + arg: Expr = Ident::new(ident.into(), DUMMY_SP).into() + )); + } + + let mut props = Vec::new(); + for (exported, local) in &expanded.exports { + let expr = match local { + EsmExport::Error => Some(quote!( + "(() => { throw new Error(\"Failed binding. See build errors!\"); })" as Expr, + )), + EsmExport::LocalBinding(name, mutable) => { + if *mutable { + Some(quote!( + "([() => $local, (v) => $local = v])" as Expr, + local = Ident::new((name as &str).into(), DUMMY_SP) + )) + } else { + Some(quote!( + "(() => $local)" as Expr, + local = Ident::new((name as &str).into(), DUMMY_SP) + )) + } + } + EsmExport::ImportedBinding(esm_ref, name, mutable) => { + let referenced_asset = + ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await?; + referenced_asset.get_ident().await?.map(|ident| { + let expr = Expr::Member(MemberExpr { + span: DUMMY_SP, + obj: Box::new(Expr::Ident(Ident::new(ident.into(), DUMMY_SP))), + prop: MemberProp::Computed(ComputedPropName { + span: DUMMY_SP, + expr: Box::new(Expr::Lit(Lit::Str(Str { + span: DUMMY_SP, + value: (name as &str).into(), + raw: None, + }))), + }), + }); + if *mutable { + quote!( + "([() => $expr, (v) => $expr = v])" as Expr, + expr: Expr = expr, + ) + } else { + quote!( + "(() => $expr)" as Expr, + expr: Expr = expr, + ) + } + }) + } + EsmExport::ImportedNamespace(esm_ref) => { + let referenced_asset = + ReferencedAsset::from_resolve_result(esm_ref.resolve_reference()).await?; + referenced_asset.get_ident().await?.map(|ident| { + quote!( + "(() => $imported)" as Expr, + imported = Ident::new(ident.into(), DUMMY_SP) + ) + }) + } + }; + if let Some(expr) = expr { + props.push(PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Str(Str { + span: DUMMY_SP, + value: exported.as_str().into(), + raw: None, + }), + value: Box::new(expr), + })))); + } + } + let getters = Expr::Object(ObjectLit { + span: DUMMY_SP, + props, + }); + let dynamic_stmt = if !dynamic_exports.is_empty() { + Some(Stmt::Expr(ExprStmt { + span: DUMMY_SP, + expr: Expr::from_exprs(dynamic_exports), + })) + } else { + None + }; + + visitors.push(create_visitor!(visit_mut_program(program: &mut Program) { + let stmt = quote!("__turbopack_esm__($getters);" as Stmt, + getters: Expr = getters.clone() + ); + match program { + Program::Module(ast::Module { body, .. }) => { + body.insert(0, ModuleItem::Stmt(stmt)); + } + Program::Script(Script { body, .. }) => { + body.insert(0, stmt); + } + } + if let Some(dynamic_stmt) = dynamic_stmt.clone() { + insert_hoisted_stmt(program, dynamic_stmt); + } + })); + + Ok(CodeGeneration { visitors }.into()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/meta.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/meta.rs new file mode 100644 index 0000000000000..3ec0e1728d484 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/meta.rs @@ -0,0 +1,185 @@ +use std::borrow::Cow; + +use anyhow::Result; +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{Expr, Ident}, + quote, +}; +use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::chunk::ChunkingContext; + +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, magic_identifier, + references::{as_abs_path, esm::base::insert_hoisted_stmt, AstPath}, +}; + +/// Responsible for initializing the `import.meta` object binding, so that it +/// may be referenced in th the file. +/// +/// There can be many references to import.meta, and they appear at any nesting +/// in the file. But we must only initialize the binding a single time. +#[turbo_tasks::value(shared)] +#[derive(Hash, Debug)] +pub struct ImportMetaBinding { + path: Vc, +} + +#[turbo_tasks::value_impl] +impl ImportMetaBinding { + #[turbo_tasks::function] + pub fn new(path: Vc) -> Vc { + ImportMetaBinding { path }.cell() + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for ImportMetaBinding { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let path = as_abs_path(self.path).await?.as_str().map_or_else( + || { + quote!( + "(() => { throw new Error('could not convert import.meta.url to filepath') })()" + as Expr + ) + }, + |path| { + let formatted = encode_path(path).trim_start_matches("/ROOT/").to_string(); + quote!( + "`file://${__turbopack_resolve_absolute_path__($formatted)}`" as Expr, + formatted: Expr = formatted.into() + ) + }, + ); + + let visitor = create_visitor!(visit_mut_program(program: &mut Program) { + // [NOTE] url property is lazy-evaluated, as it should be computed once turbopack_runtime injects a function + // to calculate an absolute path. + let meta = quote!( + "const $name = { get url() { return $path } };" as Stmt, + name = meta_ident(), + path: Expr = path.clone(), + ); + insert_hoisted_stmt(program, meta); + }); + + Ok(CodeGeneration { + visitors: vec![visitor], + } + .into()) + } +} + +/// Handles rewriting `import.meta` references into the injected binding created +/// by ImportMetaBindi ImportMetaBinding. +/// +/// There can be many references to import.meta, and they appear at any nesting +/// in the file. But all references refer to the same mutable object. +#[turbo_tasks::value(shared)] +#[derive(Hash, Debug)] +pub struct ImportMetaRef { + ast_path: Vc, +} + +#[turbo_tasks::value_impl] +impl ImportMetaRef { + #[turbo_tasks::function] + pub fn new(ast_path: Vc) -> Vc { + ImportMetaRef { ast_path }.cell() + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for ImportMetaRef { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let ast_path = &self.ast_path.await?; + let visitor = create_visitor!(ast_path, visit_mut_expr(expr: &mut Expr) { + *expr = Expr::Ident(meta_ident()); + }); + + Ok(CodeGeneration { + visitors: vec![visitor], + } + .into()) + } +} + +/// URL encodes special chars that would appear in the "pathname" portion. +/// https://github.com/nodejs/node/blob/3bed5f11e039153eff5cbfd9513b8f55fd53fc43/lib/internal/url.js#L1513-L1526 +fn encode_path(path: &'_ str) -> Cow<'_, str> { + let mut encoded = String::new(); + let mut start = 0; + for (i, c) in path.chars().enumerate() { + let mapping = match c { + '%' => "%25", + '\\' => "%5C", + '\n' => "%0A", + '\r' => "%0D", + '\t' => "%09", + _ => continue, + }; + + if encoded.is_empty() { + encoded.reserve(path.len()); + } + + encoded += &path[start..i]; + encoded += mapping; + start = i + 1; + } + + if encoded.is_empty() { + return Cow::Borrowed(path); + } + encoded += &path[start..]; + Cow::Owned(encoded) +} + +fn meta_ident() -> Ident { + Ident::new(magic_identifier::mangle("import.meta").into(), DUMMY_SP) +} + +#[cfg(test)] +mod test { + use super::encode_path; + + #[test] + fn test_encode_path_regular() { + let input = "abc"; + assert_eq!(encode_path(input), "abc"); + } + + #[test] + fn test_encode_path_special_chars() { + let input = "abc%def\\ghi\njkl\rmno\tpqr"; + assert_eq!(encode_path(input), "abc%25def%5Cghi%0Ajkl%0Dmno%09pqr"); + } + + #[test] + fn test_encode_path_special_char_start() { + let input = "%abc"; + assert_eq!(encode_path(input), "%25abc"); + } + + #[test] + fn test_encode_path_special_char_end() { + let input = "abc%"; + assert_eq!(encode_path(input), "abc%25"); + } + + #[test] + fn test_encode_path_special_char_contiguous() { + let input = "%%%"; + assert_eq!(encode_path(input), "%25%25%25"); + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/mod.rs new file mode 100644 index 0000000000000..1e44b3656b61f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/mod.rs @@ -0,0 +1,18 @@ +pub(crate) mod base; +pub(crate) mod binding; +pub(crate) mod dynamic; +pub(crate) mod export; +pub(crate) mod meta; +pub(crate) mod module_id; +pub(crate) mod module_item; +pub(crate) mod url; + +pub use self::{ + base::EsmAssetReference, + binding::EsmBinding, + dynamic::EsmAsyncAssetReference, + export::{EsmExport, EsmExports}, + meta::{ImportMetaBinding, ImportMetaRef}, + module_item::EsmModuleItem, + url::{UrlAssetReference, UrlRewriteBehavior}, +}; diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/module_id.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/module_id.rs new file mode 100644 index 0000000000000..e92131afcf275 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/module_id.rs @@ -0,0 +1,97 @@ +use anyhow::Result; +use swc_core::{ecma::ast::Expr, quote}; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, + ChunkingTypeOption, ModuleId, + }, + reference::ModuleReference, + resolve::ModuleResolveResult, +}; + +use super::{base::ReferencedAsset, EsmAssetReference}; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, + references::AstPath, +}; + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct EsmModuleIdAssetReference { + inner: Vc, + ast_path: Vc, +} + +#[turbo_tasks::value_impl] +impl EsmModuleIdAssetReference { + #[turbo_tasks::function] + pub fn new(inner: Vc, ast_path: Vc) -> Vc { + Self::cell(EsmModuleIdAssetReference { inner, ast_path }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for EsmModuleIdAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + self.inner.resolve_reference() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EsmModuleIdAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("module id of {}", self.inner.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for EsmModuleIdAssetReference { + #[turbo_tasks::function] + fn chunking_type(&self) -> Vc { + self.inner.chunking_type() + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for EsmModuleIdAssetReference { + #[turbo_tasks::function] + async fn code_generation( + &self, + chunking_context: Vc>, + ) -> Result> { + let mut visitors = Vec::new(); + + if let ReferencedAsset::Some(asset) = &*self.inner.get_referenced_asset().await? { + let id = asset + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?; + let id = Expr::Lit(match &*id { + ModuleId::String(s) => s.as_str().into(), + ModuleId::Number(n) => (*n as f64).into(), + }); + visitors.push( + create_visitor!(self.ast_path.await?, visit_mut_expr(expr: &mut Expr) { + *expr = id.clone() + }), + ); + } else { + // If the referenced asset can't be found, replace the expression with null. + // This can happen if the referenced asset is an external, or doesn't resolve + // to anything. + visitors.push( + create_visitor!(self.ast_path.await?, visit_mut_expr(expr: &mut Expr) { + *expr = quote!("null" as Expr); + }), + ); + } + + Ok(CodeGeneration { visitors }.into()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/module_item.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/module_item.rs new file mode 100644 index 0000000000000..a41ba2b5d6b2a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/module_item.rs @@ -0,0 +1,108 @@ +use std::mem::replace; + +use anyhow::Result; +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{ + ClassDecl, Decl, DefaultDecl, ExportDecl, ExportDefaultDecl, ExportDefaultExpr, FnDecl, + Ident, ModuleDecl, ModuleItem, Stmt, + }, + quote, +}; +use turbo_tasks::Vc; +use turbopack_core::chunk::ChunkingContext; + +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, magic_identifier, + references::AstPath, +}; + +/// Makes code changes to remove export/import declarations and places the +/// expr/decl in a normal statement. Unnamed expr/decl will be named with the +/// magic identifier "export default" +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct EsmModuleItem { + pub path: Vc, +} + +#[turbo_tasks::value_impl] +impl EsmModuleItem { + #[turbo_tasks::function] + pub fn new(path: Vc) -> Vc { + Self::cell(EsmModuleItem { path }) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for EsmModuleItem { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let mut visitors = Vec::new(); + + let path = &self.path.await?; + visitors.push( + create_visitor!(path, visit_mut_module_item(module_item: &mut ModuleItem) { + let item = replace(module_item, ModuleItem::Stmt(quote!(";" as Stmt))); + if let ModuleItem::ModuleDecl(module_decl) = item { + match module_decl { + ModuleDecl::ExportDefaultExpr(ExportDefaultExpr { box expr, .. }) => { + let stmt = quote!("const $name = $expr;" as Stmt, + name = Ident::new(magic_identifier::mangle("default export").into(), DUMMY_SP), + expr: Expr = expr + ); + *module_item = ModuleItem::Stmt(stmt); + } + ModuleDecl::ExportDefaultDecl(ExportDefaultDecl { decl, span }) => { + match decl { + DefaultDecl::Class(class) => { + *module_item = ModuleItem::Stmt(Stmt::Decl(Decl::Class(ClassDecl { + ident: class.ident.unwrap_or_else(|| Ident::new(magic_identifier::mangle("default export").into(), DUMMY_SP)), + declare: false, + class: class.class + }))) + } + DefaultDecl::Fn(fn_expr) => { + *module_item = ModuleItem::Stmt(Stmt::Decl(Decl::Fn(FnDecl { + ident: fn_expr.ident.unwrap_or_else(|| Ident::new(magic_identifier::mangle("default export").into(), DUMMY_SP)), + declare: false, + function: fn_expr.function + }))) + } + DefaultDecl::TsInterfaceDecl(_) => { + // not matching, might happen due to eventual consistency + *module_item = ModuleItem::ModuleDecl(ModuleDecl::ExportDefaultDecl(ExportDefaultDecl { decl, span })); + } + } + } + ModuleDecl::ExportDecl(ExportDecl { decl, .. }) => { + *module_item = ModuleItem::Stmt(Stmt::Decl(decl)); + } + ModuleDecl::ExportNamed(_) => { + // already removed + } + ModuleDecl::ExportAll(_) => { + // already removed + } + ModuleDecl::Import(_) => { + // already removed + } + _ => { + // not matching, might happen due to eventual consistency + *module_item = ModuleItem::ModuleDecl(module_decl); + } + } + } else { + // not matching, might happen due to eventual consistency + *module_item = item; + } + }), + ); + + Ok(CodeGeneration { visitors }.into()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/esm/url.rs b/turbopack/crates/turbopack-ecmascript/src/references/esm/url.rs new file mode 100644 index 0000000000000..89bf7cf20dc74 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/esm/url.rs @@ -0,0 +1,307 @@ +use anyhow::{bail, Result}; +use swc_core::{ + ecma::ast::{Expr, ExprOrSpread, NewExpr}, + quote, +}; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + ChunkingTypeOption, + }, + environment::Rendering, + issue::IssueSource, + reference::ModuleReference, + reference_type::{ReferenceType, UrlReferenceSubType}, + resolve::{ + origin::ResolveOrigin, parse::Request, url_resolve, ExternalType, ModuleResolveResult, + }, +}; +use turbopack_resolve::ecmascript::try_to_severity; + +use super::base::ReferencedAsset; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, + references::AstPath, + utils::module_id_to_lit, +}; + +/// Determines how to treat `new URL(...)` rewrites. +/// This allows to construct url depends on the different building context, +/// e.g. SSR, CSR, or Node.js. +#[turbo_tasks::value(shared)] +#[derive(Debug, Copy, Clone, Hash)] +pub enum UrlRewriteBehavior { + /// Omits base, resulting in a relative URL. + Relative, + /// Uses the full URL, including the base. + Full, + /// Do not attempt to rewrite the URL. + None, +} + +/// URL Asset References are injected during code analysis when we find a +/// (staticly analyzable) `new URL("path", import.meta.url)`. +/// +/// It's responsible rewriting the `URL` constructor's arguments to allow the +/// referenced file to be imported/fetched/etc. +#[turbo_tasks::value] +pub struct UrlAssetReference { + origin: Vc>, + request: Vc, + rendering: Vc, + ast_path: Vc, + issue_source: Vc, + in_try: bool, + url_rewrite_behavior: Vc, +} + +#[turbo_tasks::value_impl] +impl UrlAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + rendering: Vc, + ast_path: Vc, + issue_source: Vc, + in_try: bool, + url_rewrite_behavior: Vc, + ) -> Vc { + UrlAssetReference { + origin, + request, + rendering, + ast_path, + issue_source, + in_try, + url_rewrite_behavior, + } + .cell() + } + + #[turbo_tasks::function] + pub(crate) fn get_referenced_asset(self: Vc) -> Vc { + ReferencedAsset::from_resolve_result(self.resolve_reference()) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for UrlAssetReference { + #[turbo_tasks::function] + async fn resolve_reference(&self) -> Vc { + url_resolve( + self.origin, + self.request, + Value::new(ReferenceType::Url(UrlReferenceSubType::EcmaScriptNewUrl)), + Some(self.issue_source), + try_to_severity(self.in_try), + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for UrlAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("new URL({})", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for UrlAssetReference { + #[turbo_tasks::function] + fn chunking_type(&self) -> Vc { + Vc::cell(Some(ChunkingType::Parallel)) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for UrlAssetReference { + /// Rewrites call to the `new URL()` ctor depends on the current + /// conditions. Generated code will point to the output path of the asset, + /// as similar to the webpack's behavior. This is based on the + /// configuration (UrlRewriteBehavior), and the current context + /// (rendering), lastly the asset's condition (if it's referenced / + /// external). The following table shows the behavior: + /* + * original call: `new URL(url, base);` + ┌───────────────────────────────┬─────────────────────────────────────────────────────────────────────────┬────────────────────────────────────────────────┬───────────────────────┐ + │ UrlRewriteBehavior\RefAsset │ ReferencedAsset::Some() │ ReferencedAsset::External │ ReferencedAsset::None │ + ├───────────────────────────────┼─────────────────────────────────────────────────────────────────────────┼────────────────────────────────────────────────┼───────────────────────┤ + │ Relative │ __turbopack_relative_url__(__turbopack_require__(urlId)) │ __turbopack_relative_url__(url) │ new URL(url, base) │ + │ Full(RenderingClient::Client) │ new URL(__turbopack_require__(urlId), location.origin) │ new URL(url, location.origin) │ new URL(url, base) │ + │ Full(RenderingClient::..) │ new URL(__turbopack_resolve_module_id_path__(urlId)) │ new URL(url, base) │ new URL(url, base) │ + │ None │ new URL(url, base) │ new URL(url, base) │ new URL(url, base) │ + └───────────────────────────────┴─────────────────────────────────────────────────────────────────────────┴────────────────────────────────────────────────┴───────────────────────┘ + */ + #[turbo_tasks::function] + async fn code_generation( + self: Vc, + chunking_context: Vc>, + ) -> Result> { + let this = self.await?; + let mut visitors = vec![]; + let rewrite_behavior = &*this.url_rewrite_behavior.await?; + + match rewrite_behavior { + UrlRewriteBehavior::Relative => { + let referenced_asset = self.get_referenced_asset().await?; + let ast_path = this.ast_path.await?; + + // if the referenced url is in the module graph of turbopack, replace it into + // the chunk item will be emitted into output path to point the + // static asset path. for the `new URL()` call, replace it into + // pseudo url object `__turbopack_relative_url__` + // which is injected by turbopack's runtime to resolve into the relative path + // omitting the base. + match &*referenced_asset { + ReferencedAsset::Some(asset) => { + // We rewrite the first `new URL()` arguments to be a require() of the chunk + // item, which exports the static asset path to the linked file. + let id = asset + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?; + + visitors.push(create_visitor!(ast_path, visit_mut_expr(new_expr: &mut Expr) { + let should_rewrite_to_relative = if let Expr::New(NewExpr { args: Some(args), .. }) = new_expr { + matches!(args.first(), Some(ExprOrSpread { .. })) + } else { + false + }; + + if should_rewrite_to_relative { + *new_expr = quote!( + "new __turbopack_relative_url__(__turbopack_require__($id))" as Expr, + id: Expr = module_id_to_lit(&id), + ); + } + })); + } + ReferencedAsset::External(request, ExternalType::Url) => { + let request = request.to_string(); + visitors.push(create_visitor!(ast_path, visit_mut_expr(new_expr: &mut Expr) { + let should_rewrite_to_relative = if let Expr::New(NewExpr { args: Some(args), .. }) = new_expr { + matches!(args.first(), Some(ExprOrSpread { .. })) + } else { + false + }; + + if should_rewrite_to_relative { + *new_expr = quote!( + "new __turbopack_relative_url__($id)" as Expr, + id: Expr = request.as_str().into(), + ); + } + })); + } + ReferencedAsset::External(request, ty) => { + bail!( + "Unsupported external type {:?} for URL reference with request: {:?}", + ty, + request + ) + } + ReferencedAsset::None => {} + } + } + UrlRewriteBehavior::Full => { + let referenced_asset = self.get_referenced_asset().await?; + let ast_path = this.ast_path.await?; + + // For rendering environments (CSR), we rewrite the `import.meta.url` to + // be a location.origin because it allows us to access files from the root of + // the dev server. + // + // By default for the remaining environments, turbopack's runtime have overriden + // `import.meta.url`. + let rewrite_url_base = match &*this.rendering.await? { + Rendering::Client => Some(quote!("location.origin" as Expr)), + Rendering::None | Rendering::Server => None, + }; + + match &*referenced_asset { + ReferencedAsset::Some(asset) => { + // We rewrite the first `new URL()` arguments to be a require() of the + // chunk item, which returns the asset path as its exports. + let id = asset + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?; + + // If there's a rewrite to the base url, then the current rendering + // environment should able to resolve the asset path + // (asset_url) from the base. Wrap the module id + // with __turbopack_require__ which returns the asset_url. + // + // Otherwise, the envioronment should provide an absolute path to the actual + // output asset; delegate those calculation to the + // runtime fn __turbopack_resolve_module_id_path__. + let url_segment_resolver = if rewrite_url_base.is_some() { + quote!( + "__turbopack_require__($id)" as Expr, + id: Expr = module_id_to_lit(&id), + ) + } else { + quote!( + "__turbopack_resolve_module_id_path__($id)" as Expr, + id: Expr = module_id_to_lit(&id), + ) + }; + + visitors.push(create_visitor!(ast_path, visit_mut_expr(new_expr: &mut Expr) { + if let Expr::New(NewExpr { args: Some(args), .. }) = new_expr { + if let Some(ExprOrSpread { box expr, spread: None }) = args.get_mut(0) { + *expr = url_segment_resolver.clone(); + } + + if let Some(ExprOrSpread { box expr, spread: None }) = args.get_mut(1) { + if let Some(rewrite) = &rewrite_url_base { + *expr = rewrite.clone(); + } else { + // If rewrite for the base doesn't exists, means __turbopack_resolve_module_id_path__ + // should resolve the full path correctly and there shouldn't be a base. + args.remove(1); + } + } + } + })); + } + ReferencedAsset::External(request, ExternalType::Url) => { + let request = request.to_string(); + visitors.push(create_visitor!(ast_path, visit_mut_expr(new_expr: &mut Expr) { + if let Expr::New(NewExpr { args: Some(args), .. }) = new_expr { + if let Some(ExprOrSpread { box expr, spread: None }) = args.get_mut(0) { + *expr = request.as_str().into() + } + + if let Some(rewrite) = &rewrite_url_base { + if let Some(ExprOrSpread { box expr, spread: None }) = args.get_mut(1) { + *expr = rewrite.clone(); + } + } + } + })); + } + ReferencedAsset::External(request, ty) => { + bail!( + "Unsupported external type {:?} for URL reference with request: {:?}", + ty, + request + ) + } + ReferencedAsset::None => {} + } + } + UrlRewriteBehavior::None => { + // Asked to not rewrite the URL, so we don't do anything. + } + }; + + Ok(CodeGeneration { visitors }.into()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/external_module.rs b/turbopack/crates/turbopack-ecmascript/src/references/external_module.rs new file mode 100644 index 0000000000000..5108f6b37bf27 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/external_module.rs @@ -0,0 +1,246 @@ +use std::{fmt::Display, io::Write}; + +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, RcStr, TaskInput, Vc}; +use turbo_tasks_fs::{glob::Glob, rope::RopeBuilder, FileContent, FileSystem, VirtualFileSystem}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext}, + ident::AssetIdent, + module::Module, + reference::ModuleReferences, +}; + +use crate::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkType, EcmascriptExports, + }, + references::async_module::{AsyncModule, OptionAsyncModule}, + utils::StringifyJs, + EcmascriptModuleContent, EcmascriptOptions, +}; + +#[turbo_tasks::function] +fn layer() -> Vc { + Vc::cell("external".into()) +} + +#[derive( + Copy, Clone, Debug, Eq, PartialEq, Serialize, Deserialize, TraceRawVcs, TaskInput, Hash, +)] +pub enum CachedExternalType { + CommonJs, + EcmaScriptViaRequire, + EcmaScriptViaImport, +} + +impl Display for CachedExternalType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + CachedExternalType::CommonJs => write!(f, "cjs"), + CachedExternalType::EcmaScriptViaRequire => write!(f, "esm_require"), + CachedExternalType::EcmaScriptViaImport => write!(f, "esm_import"), + } + } +} + +#[turbo_tasks::value] +pub struct CachedExternalModule { + pub request: RcStr, + pub external_type: CachedExternalType, +} + +#[turbo_tasks::value_impl] +impl CachedExternalModule { + #[turbo_tasks::function] + pub fn new(request: RcStr, external_type: CachedExternalType) -> Vc { + Self::cell(CachedExternalModule { + request, + external_type, + }) + } + + #[turbo_tasks::function] + pub fn content(&self) -> Result> { + let mut code = RopeBuilder::default(); + + if self.external_type == CachedExternalType::EcmaScriptViaImport { + writeln!( + code, + "const mod = await __turbopack_external_import__({});", + StringifyJs(&self.request) + )?; + } else { + writeln!( + code, + "const mod = __turbopack_external_require__({});", + StringifyJs(&self.request) + )?; + } + + writeln!(code)?; + + if self.external_type == CachedExternalType::CommonJs { + writeln!(code, "module.exports = mod;")?; + } else { + writeln!(code, "__turbopack_export_namespace__(mod);")?; + } + + Ok(EcmascriptModuleContent { + inner_code: code.build(), + source_map: None, + is_esm: self.external_type != CachedExternalType::CommonJs, + } + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl Module for CachedExternalModule { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + let fs = VirtualFileSystem::new_with_name("externals".into()); + + AssetIdent::from_path(fs.root()) + .with_layer(layer()) + .with_modifier(Vc::cell(self.request.clone())) + .with_modifier(Vc::cell(self.external_type.to_string().into())) + } +} + +#[turbo_tasks::value_impl] +impl Asset for CachedExternalModule { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + // should be `NotFound` as this function gets called to detect source changes + AssetContent::file(FileContent::NotFound.cell()) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for CachedExternalModule { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + CachedExternalModuleChunkItem { + module: self, + chunking_context, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for CachedExternalModule { + #[turbo_tasks::function] + fn get_exports(&self) -> Vc { + if self.external_type == CachedExternalType::CommonJs { + EcmascriptExports::CommonJs.cell() + } else { + EcmascriptExports::DynamicNamespace.cell() + } + } + + #[turbo_tasks::function] + fn get_async_module(&self) -> Vc { + Vc::cell( + if self.external_type == CachedExternalType::EcmaScriptViaImport { + Some( + AsyncModule { + has_top_level_await: true, + import_externals: true, + } + .cell(), + ) + } else { + None + }, + ) + } + + #[turbo_tasks::function] + fn is_marked_as_side_effect_free( + self: Vc, + _side_effect_free_packages: Vc, + ) -> Vc { + Vc::cell(false) + } +} + +#[turbo_tasks::value] +pub struct CachedExternalModuleChunkItem { + module: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for CachedExternalModuleChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + fn ty(self: Vc) -> Vc> { + Vc::upcast(Vc::::default()) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn is_self_async(&self) -> Result> { + Ok(Vc::cell( + self.module.await?.external_type == CachedExternalType::EcmaScriptViaImport, + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for CachedExternalModuleChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("content() should not be called"); + } + + #[turbo_tasks::function] + async fn content_with_async_module_info( + &self, + async_module_info: Option>, + ) -> Result> { + let async_module_options = self + .module + .get_async_module() + .module_options(async_module_info); + + Ok(EcmascriptChunkItemContent::new( + self.module.content(), + self.chunking_context, + EcmascriptOptions::default().cell(), + async_module_options, + )) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/mod.rs b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs new file mode 100644 index 0000000000000..3047f918ab90a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/mod.rs @@ -0,0 +1,2993 @@ +pub mod amd; +pub mod async_module; +pub mod cjs; +pub mod constant_condition; +pub mod constant_value; +pub mod dynamic_expression; +pub mod esm; +pub mod external_module; +pub mod node; +pub mod pattern_mapping; +pub mod raw; +pub mod require_context; +pub mod type_issue; +pub mod typescript; +pub mod unreachable; +pub mod util; + +use std::{ + borrow::Cow, + collections::{BTreeMap, HashMap}, + future::Future, + mem::take, + pin::Pin, + sync::Arc, +}; + +use anyhow::Result; +use constant_condition::{ConstantCondition, ConstantConditionValue}; +use constant_value::ConstantValue; +use indexmap::IndexSet; +use lazy_static::lazy_static; +use num_traits::Zero; +use once_cell::sync::Lazy; +use parking_lot::Mutex; +use regex::Regex; +use sourcemap::decode_data_url; +use swc_core::{ + atoms::JsWord, + common::{ + comments::{CommentKind, Comments}, + errors::{DiagnosticId, Handler, HANDLER}, + pass::AstNodePath, + source_map::Pos, + Globals, Span, Spanned, GLOBALS, + }, + ecma::{ + ast::*, + visit::{ + fields::{AssignExprField, AssignTargetField, SimpleAssignTargetField}, + AstParentKind, AstParentNodeRef, VisitAstPath, VisitWithPath, + }, + }, +}; +use tracing::Instrument; +use turbo_tasks::{RcStr, TryJoinIterExt, Upcast, Value, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + compile_time_info::{CompileTimeInfo, FreeVarReference}, + error::PrettyPrintError, + issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, IssueSource, StyledString}, + module::Module, + reference::{ModuleReference, ModuleReferences, SourceMapReference}, + reference_type::{CommonJsReferenceSubType, ReferenceType}, + resolve::{ + find_context_file, + origin::{PlainResolveOrigin, ResolveOrigin, ResolveOriginExt}, + parse::Request, + pattern::Pattern, + resolve, FindContextFileResult, ModulePart, + }, + source::Source, + source_map::{GenerateSourceMap, OptionSourceMap, SourceMap}, +}; +use turbopack_resolve::{ + ecmascript::{apply_cjs_specific_options, cjs_resolve, try_to_severity}, + typescript::tsconfig, +}; +use turbopack_swc_utils::emitter::IssueEmitter; +use unreachable::Unreachable; + +use self::{ + amd::{ + AmdDefineAssetReference, AmdDefineDependencyElement, AmdDefineFactoryType, + AmdDefineWithDependenciesCodeGen, + }, + cjs::CjsAssetReference, + esm::{ + binding::EsmBindings, export::EsmExport, EsmAssetReference, EsmAsyncAssetReference, + EsmExports, EsmModuleItem, ImportMetaBinding, ImportMetaRef, UrlAssetReference, + }, + node::DirAssetReference, + raw::FileSourceReference, + typescript::{TsConfigReference, TsReferencePathAssetReference, TsReferenceTypeAssetReference}, +}; +use super::{ + analyzer::{ + builtin::replace_builtin, + graph::{create_graph, Effect}, + linker::link, + well_known::replace_well_known, + ConstantValue as JsConstantValue, JsValue, ObjectPart, WellKnownFunctionKind, + WellKnownObjectKind, + }, + errors, + parse::ParseResult, + special_cases::special_cases, + utils::js_value_to_pattern, + webpack::{ + parse::{webpack_runtime, WebpackRuntime}, + WebpackChunkAssetReference, WebpackEntryAssetReference, WebpackRuntimeAssetReference, + }, + EcmascriptModuleAssetType, ModuleTypeResult, +}; +pub use crate::references::esm::export::{follow_reexports, FollowExportsResult}; +use crate::{ + analyzer::{ + builtin::early_replace_builtin, + graph::{ConditionalKind, EffectArg, EvalContext, VarGraph}, + imports::{ImportAnnotations, ImportedSymbol, Reexport}, + parse_require_context, + top_level_await::has_top_level_await, + ConstantNumber, ConstantString, ModuleValue, RequireContextValue, + }, + chunk::EcmascriptExports, + code_gen::{CodeGen, CodeGenerateable, CodeGenerateableWithAsyncModuleInfo, CodeGenerateables}, + magic_identifier, parse, + references::{ + async_module::{AsyncModule, OptionAsyncModule}, + cjs::{CjsRequireAssetReference, CjsRequireCacheAccess, CjsRequireResolveAssetReference}, + dynamic_expression::DynamicExpression, + esm::{module_id::EsmModuleIdAssetReference, EsmBinding, UrlRewriteBehavior}, + node::PackageJsonReference, + require_context::{RequireContextAssetReference, RequireContextMap}, + type_issue::SpecifiedModuleTypeIssue, + }, + tree_shake::{find_turbopack_part_id_in_asserts, part_of_module, split}, + EcmascriptInputTransforms, EcmascriptModuleAsset, SpecifiedModuleType, TreeShakingMode, +}; + +#[derive(Clone)] +#[turbo_tasks::value(shared)] +pub struct AnalyzeEcmascriptModuleResult { + pub references: Vc, + pub local_references: Vc, + pub reexport_references: Vc, + pub evaluation_references: Vc, + pub code_generation: Vc, + pub exports: Vc, + pub async_module: Vc, + /// `true` when the analysis was successful. + pub successful: bool, + pub source_map: Vc, +} + +/// A temporary analysis result builder to pass around, to be turned into an +/// `Vc` eventually. +pub struct AnalyzeEcmascriptModuleResultBuilder { + references: IndexSet>>, + local_references: IndexSet>>, + reexport_references: IndexSet>>, + evaluation_references: IndexSet>>, + code_gens: Vec, + exports: EcmascriptExports, + async_module: Vc, + successful: bool, + source_map: Option>, + bindings: Vec, +} + +impl AnalyzeEcmascriptModuleResultBuilder { + pub fn new() -> Self { + Self { + references: IndexSet::new(), + local_references: IndexSet::new(), + reexport_references: IndexSet::new(), + evaluation_references: IndexSet::new(), + code_gens: Vec::new(), + exports: EcmascriptExports::None, + async_module: Vc::cell(None), + successful: false, + source_map: None, + bindings: Vec::new(), + } + } + + /// Adds an asset reference to the analysis result. + pub fn add_reference(&mut self, reference: Vc) + where + R: Upcast>, + { + let r = Vc::upcast(reference); + self.references.insert(r); + self.local_references.insert(Vc::upcast(reference)); + } + + /// Adds an asset reference to the analysis result. + pub fn add_import_reference(&mut self, reference: Vc) { + self.references.insert(Vc::upcast(reference)); + } + + /// Adds an reexport reference to the analysis result. + pub fn add_local_reference(&mut self, reference: Vc) + where + R: Upcast>, + { + self.local_references.insert(Vc::upcast(reference)); + } + + /// Adds an reexport reference to the analysis result. + pub fn add_reexport_reference(&mut self, reference: Vc) + where + R: Upcast>, + { + self.reexport_references.insert(Vc::upcast(reference)); + } + + /// Adds an evaluation reference to the analysis result. + pub fn add_evaluation_reference(&mut self, reference: Vc) { + self.evaluation_references.insert(Vc::upcast(reference)); + } + + /// Adds a codegen to the analysis result. + pub fn add_code_gen(&mut self, code_gen: Vc) + where + C: Upcast>, + { + self.code_gens + .push(CodeGen::CodeGenerateable(Vc::upcast(code_gen))); + } + + /// Adds a codegen to the analysis result. + #[allow(dead_code)] + pub fn add_code_gen_with_availability_info(&mut self, code_gen: Vc) + where + C: Upcast>, + { + self.code_gens + .push(CodeGen::CodeGenerateableWithAsyncModuleInfo(Vc::upcast( + code_gen, + ))); + } + + pub fn add_binding(&mut self, binding: EsmBinding) { + self.bindings.push(binding); + } + + /// Sets the analysis result ES export. + pub fn set_source_map(&mut self, source_map: Vc) { + self.source_map = Some(source_map); + } + + /// Sets the analysis result ES export. + pub fn set_exports(&mut self, exports: EcmascriptExports) { + self.exports = exports; + } + + /// Sets the analysis result ES export. + pub fn set_async_module(&mut self, async_module: Vc) { + self.async_module = Vc::cell(Some(async_module)); + } + + /// Sets whether the analysis was successful. + pub fn set_successful(&mut self, successful: bool) { + self.successful = successful; + } + + /// Builds the final analysis result. Resolves internal Vcs for performance + /// in using them. + pub async fn build( + mut self, + track_reexport_references: bool, + ) -> Result> { + let bindings = EsmBindings::new(take(&mut self.bindings)); + if !bindings.await?.bindings.is_empty() { + self.add_code_gen(bindings); + } + + let mut references: Vec<_> = self.references.into_iter().collect(); + for r in references.iter_mut() { + *r = r.resolve().await?; + } + let mut local_references: Vec<_> = track_reexport_references + .then(|| self.local_references.into_iter()) + .into_iter() + .flatten() + .collect(); + for r in local_references.iter_mut() { + *r = r.resolve().await?; + } + let mut reexport_references: Vec<_> = track_reexport_references + .then(|| self.reexport_references.into_iter()) + .into_iter() + .flatten() + .collect(); + for r in reexport_references.iter_mut() { + *r = r.resolve().await?; + } + let mut evaluation_references: Vec<_> = track_reexport_references + .then(|| self.evaluation_references.into_iter()) + .into_iter() + .flatten() + .collect(); + for r in evaluation_references.iter_mut() { + *r = r.resolve().await?; + } + for c in self.code_gens.iter_mut() { + match c { + CodeGen::CodeGenerateable(c) => { + *c = c.resolve().await?; + } + CodeGen::CodeGenerateableWithAsyncModuleInfo(c) => { + *c = c.resolve().await?; + } + } + } + let source_map = if let Some(source_map) = self.source_map { + source_map + } else { + OptionSourceMap::none() + }; + Ok(AnalyzeEcmascriptModuleResult::cell( + AnalyzeEcmascriptModuleResult { + references: Vc::cell(references), + local_references: Vc::cell(local_references), + reexport_references: Vc::cell(reexport_references), + evaluation_references: Vc::cell(evaluation_references), + code_generation: Vc::cell(self.code_gens), + exports: self.exports.into(), + async_module: self.async_module, + successful: self.successful, + source_map, + }, + )) + } +} + +impl Default for AnalyzeEcmascriptModuleResultBuilder { + fn default() -> Self { + Self::new() + } +} + +struct AnalysisState<'a> { + handler: &'a Handler, + source: Vc>, + origin: Vc>, + compile_time_info: Vc, + var_graph: &'a VarGraph, + /// This is the current state of known values of function + /// arguments. + fun_args_values: Mutex>>, + // There can be many references to import.meta, but only the first should hoist + // the object allocation. + first_import_meta: bool, + tree_shaking_mode: Option, + special_exports: Vc>, + import_externals: bool, + ignore_dynamic_requests: bool, +} + +impl<'a> AnalysisState<'a> { + async fn link_value(&self, value: JsValue, in_try: bool) -> Result { + let fun_args_values = self.fun_args_values.lock().clone(); + link( + self.var_graph, + value, + &early_value_visitor, + &|value| value_visitor(self.origin, value, self.compile_time_info, in_try), + fun_args_values, + ) + .await + } +} + +fn set_handler_and_globals(handler: &Handler, globals: &Arc, f: F) -> R +where + F: FnOnce() -> R, +{ + HANDLER.set(handler, || GLOBALS.set(globals, f)) +} + +#[turbo_tasks::function] +pub(crate) async fn analyse_ecmascript_module( + module: Vc, + part: Option>, +) -> Result> { + let span = { + let module = module.ident().to_string().await?.to_string(); + tracing::info_span!("analyse ecmascript module", module = module) + }; + let result = analyse_ecmascript_module_internal(module, part) + .instrument(span) + .await; + + match result { + Ok(result) => Ok(result), + Err(err) => Err(err.context(format!( + "failed to analyse ecmascript module '{}'", + module.ident().to_string().await? + ))), + } +} + +pub(crate) async fn analyse_ecmascript_module_internal( + module: Vc, + part: Option>, +) -> Result> { + let raw_module = module.await?; + + let source = raw_module.source; + let ty = Value::new(raw_module.ty); + let transforms = raw_module.transforms; + let options = raw_module.options; + let compile_time_info = raw_module.compile_time_info; + let options = options.await?; + let special_exports = options.special_exports; + let import_externals = options.import_externals; + + let origin = Vc::upcast::>(module); + + let mut analysis = AnalyzeEcmascriptModuleResultBuilder::new(); + let path = origin.origin_path(); + + // Is this a typescript file that requires analzying type references? + let analyze_types = match &*ty { + EcmascriptModuleAssetType::Typescript { analyze_types, .. } => *analyze_types, + EcmascriptModuleAssetType::TypescriptDeclaration => true, + EcmascriptModuleAssetType::Ecmascript => false, + }; + + let parsed = if let Some(part) = part { + let parsed = parse(source, ty, transforms); + let split_data = split(source.ident(), source, parsed, special_exports); + part_of_module(split_data, part) + } else { + module.failsafe_parse() + }; + + let ModuleTypeResult { + module_type: specified_type, + referenced_package_json, + } = *module.determine_module_type().await?; + + if let Some(package_json) = referenced_package_json { + analysis.add_reference(PackageJsonReference::new(package_json)); + } + + if analyze_types { + match &*find_context_file(path.parent(), tsconfig()).await? { + FindContextFileResult::Found(tsconfig, _) => { + analysis.add_reference(TsConfigReference::new(origin, *tsconfig)); + } + FindContextFileResult::NotFound(_) => {} + }; + } + + special_cases(&path.await?.path, &mut analysis); + + let parsed = parsed.await?; + + let ParseResult::Ok { + program, + globals, + eval_context, + comments, + source_map, + .. + } = &*parsed + else { + return analysis.build(false).await; + }; + + let mut import_references = Vec::new(); + + let pos = program.span().lo; + if analyze_types { + if let Some(comments) = comments.get_leading(pos) { + for comment in comments.iter() { + if let CommentKind::Line = comment.kind { + lazy_static! { + static ref REFERENCE_PATH: Regex = + Regex::new(r#"^/\s*\s*$"#) + .unwrap(); + static ref REFERENCE_TYPES: Regex = + Regex::new(r#"^/\s*\s*$"#) + .unwrap(); + } + let text = &comment.text; + if let Some(m) = REFERENCE_PATH.captures(text) { + let path = &m[1]; + analysis + .add_reference(TsReferencePathAssetReference::new(origin, path.into())); + } else if let Some(m) = REFERENCE_TYPES.captures(text) { + let types = &m[1]; + analysis.add_reference(TsReferenceTypeAssetReference::new( + origin, + types.into(), + )); + } + } + } + } + } + + // Only use the last sourceMappingURL comment by spec + let mut paths_by_pos = Vec::new(); + for (pos, comments) in comments.trailing.iter() { + for comment in comments.iter().rev() { + lazy_static! { + static ref SOURCE_MAP_FILE_REFERENCE: Regex = + Regex::new(r"# sourceMappingURL=(.*)$").unwrap(); + } + if let Some(m) = SOURCE_MAP_FILE_REFERENCE.captures(&comment.text) { + let path = m.get(1).unwrap().as_str(); + paths_by_pos.push((pos, path)); + break; + } + } + } + let mut source_map_from_comment = false; + if let Some((_, path)) = paths_by_pos.into_iter().max_by_key(|&(pos, _)| pos) { + let origin_path = origin.origin_path(); + if path.ends_with(".map") { + let source_map_origin = origin_path.parent().join(path.into()); + let reference = SourceMapReference::new(origin_path, source_map_origin); + analysis.add_reference(reference); + let source_map = reference.generate_source_map(); + analysis.set_source_map(convert_to_turbopack_source_map( + source_map, + source_map_origin, + )); + source_map_from_comment = true; + } else if path.starts_with("data:application/json;base64,") { + let source_map_origin = origin_path; + let source_map = maybe_decode_data_url(path.into()); + analysis.set_source_map(convert_to_turbopack_source_map( + source_map, + source_map_origin, + )); + source_map_from_comment = true; + } + } + if !source_map_from_comment { + if let Some(generate_source_map) = + Vc::try_resolve_sidecast::>(source).await? + { + let source_map_origin = source.ident().path(); + analysis.set_source_map(convert_to_turbopack_source_map( + generate_source_map.generate_source_map(), + source_map_origin, + )); + } + } + + let handler = Handler::with_emitter( + true, + false, + Box::new(IssueEmitter::new(source, source_map.clone(), None)), + ); + + let mut var_graph = + set_handler_and_globals(&handler, globals, || create_graph(program, eval_context)); + + let mut evaluation_references = Vec::new(); + + for (i, r) in eval_context.imports.references().enumerate() { + let r = EsmAssetReference::new( + origin, + Request::parse(Value::new(RcStr::from(&*r.module_path).into())), + r.issue_source, + Value::new(r.annotations.clone()), + match options.tree_shaking_mode { + Some(TreeShakingMode::ModuleFragments) => match &r.imported_symbol { + ImportedSymbol::ModuleEvaluation => { + evaluation_references.push(i); + Some(ModulePart::evaluation()) + } + ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())), + ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), + ImportedSymbol::Exports => Some(ModulePart::exports()), + }, + Some(TreeShakingMode::ReexportsOnly) => match &r.imported_symbol { + ImportedSymbol::ModuleEvaluation => { + evaluation_references.push(i); + Some(ModulePart::evaluation()) + } + ImportedSymbol::Symbol(name) => Some(ModulePart::export((&**name).into())), + ImportedSymbol::Part(part_id) => Some(ModulePart::internal(*part_id)), + ImportedSymbol::Exports => None, + }, + None => None, + }, + special_exports, + import_externals, + ); + + import_references.push(r); + } + + for r in import_references.iter_mut() { + // Resolving these references here avoids many resolve wrapper tasks when + // passing that to other turbo tasks functions later. + *r = r.resolve().await?; + } + + for r in import_references.iter() { + // `add_import_reference` will avoid adding duplicate references + analysis.add_import_reference(*r); + } + for i in evaluation_references { + analysis.add_evaluation_reference(import_references[i]); + } + + let (webpack_runtime, webpack_entry, webpack_chunks, esm_exports, esm_star_exports) = + set_handler_and_globals(&handler, globals, || { + // TODO migrate to effects + let mut visitor = + ModuleReferencesVisitor::new(eval_context, &import_references, &mut analysis); + + for (i, reexport) in eval_context.imports.reexports() { + let import_ref = import_references[i]; + match reexport { + Reexport::Star => { + visitor.esm_star_exports.push(Vc::upcast(import_ref)); + } + Reexport::Namespace { exported: n } => { + visitor.esm_exports.insert( + n.as_str().into(), + EsmExport::ImportedNamespace(Vc::upcast(import_ref)), + ); + } + Reexport::Named { + imported: i, + exported: e, + } => { + visitor.esm_exports.insert( + e.as_str().into(), + EsmExport::ImportedBinding( + Vc::upcast(import_ref), + i.to_string().into(), + false, + ), + ); + } + } + } + + program.visit_with_path(&mut visitor, &mut Default::default()); + + ( + visitor.webpack_runtime, + visitor.webpack_entry, + visitor.webpack_chunks, + visitor.esm_exports, + visitor.esm_star_exports, + ) + }); + + for export in esm_exports.values() { + match *export { + EsmExport::LocalBinding(..) => {} + EsmExport::ImportedNamespace(reference) => { + analysis.add_reexport_reference(reference); + } + EsmExport::ImportedBinding(reference, ..) => { + analysis.add_reexport_reference(reference); + } + EsmExport::Error => {} + } + } + for &export in esm_star_exports.iter() { + analysis.add_reexport_reference(export); + } + + let mut ignore_effect_span = None; + // Check if it was a webpack entry + if let Some((request, span)) = webpack_runtime { + let request = Request::parse(Value::new(request.into())); + let runtime = resolve_as_webpack_runtime(origin, request, transforms); + + if let WebpackRuntime::Webpack5 { .. } = &*runtime.await? { + ignore_effect_span = Some(span); + analysis.add_reference( + WebpackRuntimeAssetReference { + origin, + request, + runtime, + transforms, + } + .cell(), + ); + + if webpack_entry { + analysis.add_reference( + WebpackEntryAssetReference { + source, + runtime, + transforms, + } + .cell(), + ); + } + + for chunk in webpack_chunks { + analysis.add_reference( + WebpackChunkAssetReference { + chunk_id: chunk, + runtime, + transforms, + } + .cell(), + ); + } + } + } + + let exports = if !esm_exports.is_empty() || !esm_star_exports.is_empty() { + if specified_type == SpecifiedModuleType::CommonJs { + SpecifiedModuleTypeIssue { + path: source.ident().path(), + specified_type, + } + .cell() + .emit(); + } + + let esm_exports = EsmExports { + exports: esm_exports, + star_exports: esm_star_exports, + } + .cell(); + + EcmascriptExports::EsmExports(esm_exports) + } else if specified_type == SpecifiedModuleType::EcmaScript { + match detect_dynamic_export(program) { + DetectedDynamicExportType::CommonJs => { + SpecifiedModuleTypeIssue { + path: source.ident().path(), + specified_type, + } + .cell() + .emit(); + + EcmascriptExports::EsmExports( + EsmExports { + exports: Default::default(), + star_exports: Default::default(), + } + .cell(), + ) + } + DetectedDynamicExportType::Namespace => EcmascriptExports::DynamicNamespace, + DetectedDynamicExportType::Value => EcmascriptExports::Value, + DetectedDynamicExportType::UsingModuleDeclarations + | DetectedDynamicExportType::None => EcmascriptExports::EsmExports( + EsmExports { + exports: Default::default(), + star_exports: Default::default(), + } + .cell(), + ), + } + } else { + match detect_dynamic_export(program) { + DetectedDynamicExportType::CommonJs => EcmascriptExports::CommonJs, + DetectedDynamicExportType::Namespace => EcmascriptExports::DynamicNamespace, + DetectedDynamicExportType::Value => EcmascriptExports::Value, + DetectedDynamicExportType::UsingModuleDeclarations => EcmascriptExports::EsmExports( + EsmExports { + exports: Default::default(), + star_exports: Default::default(), + } + .cell(), + ), + DetectedDynamicExportType::None => EcmascriptExports::None, + } + }; + + let top_level_await_span = + set_handler_and_globals(&handler, globals, || has_top_level_await(program)); + let has_top_level_await = top_level_await_span.is_some(); + + if eval_context.is_esm() || specified_type == SpecifiedModuleType::EcmaScript { + let async_module = AsyncModule { + has_top_level_await, + import_externals, + } + .cell(); + analysis.set_async_module(async_module); + } else if let Some(span) = top_level_await_span { + AnalyzeIssue { + code: None, + message: StyledString::Text("top level await is only supported in ESM modules.".into()) + .cell(), + source_ident: source.ident(), + severity: IssueSeverity::Error.into(), + source: Some(issue_source(source, span)), + title: Vc::cell("unexpected top level await".into()), + } + .cell() + .emit(); + } + + analysis.set_exports(exports); + + let effects = take(&mut var_graph.effects); + + let mut analysis_state = AnalysisState { + handler: &handler, + source, + origin, + compile_time_info, + var_graph: &var_graph, + fun_args_values: Mutex::new(HashMap::>::new()), + first_import_meta: true, + tree_shaking_mode: options.tree_shaking_mode, + import_externals: options.import_externals, + special_exports: options.special_exports, + ignore_dynamic_requests: options.ignore_dynamic_requests, + }; + + enum Action { + Effect(Effect), + LeaveScope(u32), + } + + // This is a stack of effects to process. We use a stack since during processing + // of an effect we might want to add more effects into the middle of the + // processing. Using a stack where effects are appended in reverse + // order allows us to do that. It's recursion implemented as Stack. + let mut queue_stack = Mutex::new(Vec::new()); + queue_stack + .get_mut() + .extend(effects.into_iter().map(Action::Effect).rev()); + + while let Some(action) = queue_stack.get_mut().pop() { + let effect = match action { + Action::LeaveScope(func_ident) => { + analysis_state.fun_args_values.get_mut().remove(&func_ident); + continue; + } + Action::Effect(effect) => effect, + }; + + let add_effects = |effects: Vec| { + queue_stack + .lock() + .extend(effects.into_iter().map(Action::Effect).rev()) + }; + + match effect { + Effect::Conditional { + condition, + kind, + ast_path: condition_ast_path, + span: _, + in_try, + } => { + let condition = analysis_state.link_value(condition, in_try).await?; + + macro_rules! inactive { + ($block:ident) => { + analysis.add_code_gen(Unreachable::new(Vc::cell($block.ast_path.to_vec()))); + }; + } + macro_rules! condition { + ($expr:expr) => { + analysis.add_code_gen(ConstantCondition::new( + Value::new($expr), + Vc::cell(condition_ast_path.to_vec()), + )); + }; + } + macro_rules! active { + ($block:ident) => { + queue_stack + .get_mut() + .extend($block.effects.into_iter().map(Action::Effect).rev()) + }; + } + match *kind { + ConditionalKind::If { then } => match condition.is_truthy() { + Some(true) => { + condition!(ConstantConditionValue::Truthy); + active!(then); + } + Some(false) => { + condition!(ConstantConditionValue::Falsy); + inactive!(then); + } + None => { + active!(then); + } + }, + ConditionalKind::IfElse { then, r#else } + | ConditionalKind::Ternary { then, r#else } => match condition.is_truthy() { + Some(true) => { + condition!(ConstantConditionValue::Truthy); + active!(then); + inactive!(r#else); + } + Some(false) => { + condition!(ConstantConditionValue::Falsy); + active!(r#else); + inactive!(then); + } + None => { + active!(then); + active!(r#else); + } + }, + ConditionalKind::And { expr } => match condition.is_truthy() { + Some(true) => { + condition!(ConstantConditionValue::Truthy); + active!(expr); + } + Some(false) => { + // The condition value needs to stay since it's used + inactive!(expr); + } + None => { + active!(expr); + } + }, + ConditionalKind::Or { expr } => match condition.is_truthy() { + Some(true) => { + // The condition value needs to stay since it's used + inactive!(expr); + } + Some(false) => { + condition!(ConstantConditionValue::Falsy); + active!(expr); + } + None => { + active!(expr); + } + }, + ConditionalKind::NullishCoalescing { expr } => match condition.is_nullish() { + Some(true) => { + condition!(ConstantConditionValue::Nullish); + active!(expr); + } + Some(false) => { + inactive!(expr); + } + None => { + active!(expr); + } + }, + } + } + Effect::Call { + func, + args, + ast_path, + span, + in_try, + } => { + if let Some(ignored) = &ignore_effect_span { + if *ignored == span { + continue; + } + } + let func = analysis_state.link_value(func, in_try).await?; + + handle_call( + &ast_path, + span, + func, + JsValue::unknown_empty(false, "no this provided"), + args, + &analysis_state, + &add_effects, + &mut analysis, + in_try, + ) + .await?; + } + Effect::MemberCall { + obj, + prop, + mut args, + ast_path, + span, + in_try, + } => { + if let Some(ignored) = &ignore_effect_span { + if *ignored == span { + continue; + } + } + let mut obj = analysis_state.link_value(obj, in_try).await?; + let prop = analysis_state.link_value(prop, in_try).await?; + + if let JsValue::Array { + items: ref mut values, + mutable, + .. + } = obj + { + if matches!(prop.as_str(), Some("map" | "forEach" | "filter")) { + if let [EffectArg::Closure(value, block)] = &mut args[..] { + *value = analysis_state.link_value(take(value), in_try).await?; + if let JsValue::Function(_, func_ident, _) = value { + let mut closure_arg = JsValue::alternatives(take(values)); + if mutable { + closure_arg.add_unknown_mutations(true); + } + analysis_state + .fun_args_values + .get_mut() + .insert(*func_ident, vec![closure_arg]); + queue_stack.get_mut().push(Action::LeaveScope(*func_ident)); + queue_stack.get_mut().extend( + take(&mut block.effects) + .into_iter() + .map(Action::Effect) + .rev(), + ); + continue; + } + } + } + } + + let func = analysis_state + .link_value( + JsValue::member(Box::new(obj.clone()), Box::new(prop)), + in_try, + ) + .await?; + + handle_call( + &ast_path, + span, + func, + obj, + args, + &analysis_state, + &add_effects, + &mut analysis, + in_try, + ) + .await?; + } + Effect::FreeVar { + var, + ast_path, + span, + in_try: _, + } => { + handle_free_var(&ast_path, var, span, &analysis_state, &mut analysis).await?; + } + Effect::Member { + obj, + prop, + ast_path, + span, + in_try, + } => { + let obj = analysis_state.link_value(obj, in_try).await?; + let prop = analysis_state.link_value(prop, in_try).await?; + + handle_member(&ast_path, obj, prop, span, &analysis_state, &mut analysis).await?; + } + Effect::ImportedBinding { + esm_reference_index, + export, + ast_path, + span: _, + in_try: _, + } => { + if let Some(r) = import_references.get(esm_reference_index) { + if let Some("__turbopack_module_id__") = export.as_deref() { + analysis + .add_reference(EsmModuleIdAssetReference::new(*r, Vc::cell(ast_path))) + } else { + analysis.add_local_reference(*r); + analysis.add_binding(EsmBinding::new(*r, export, Vc::cell(ast_path))); + } + } + } + Effect::ImportMeta { + ast_path, + span: _, + in_try: _, + } => { + if analysis_state.first_import_meta { + analysis_state.first_import_meta = false; + analysis.add_code_gen(ImportMetaBinding::new(source.ident().path())); + } + + analysis.add_code_gen(ImportMetaRef::new(Vc::cell(ast_path))); + } + Effect::Url { + input, + ast_path, + span, + in_try, + } => { + let pat = js_value_to_pattern(&input); + if !pat.has_constant_parts() { + handler.span_warn_with_code( + span, + &format!("new URL({input}, import.meta.url) is very dynamic"), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::NEW_URL_IMPORT_META.to_string(), + ), + ); + if options.ignore_dynamic_requests { + continue; + } + } + analysis.add_reference(UrlAssetReference::new( + origin, + Request::parse(Value::new(pat)), + compile_time_info.environment().rendering(), + Vc::cell(ast_path), + IssueSource::from_swc_offsets(source, span.lo.to_usize(), span.hi.to_usize()), + in_try, + options + .url_rewrite_behavior + .unwrap_or(UrlRewriteBehavior::Relative) + .cell(), + )); + } + } + } + + analysis.set_successful(true); + + analysis + .build(matches!( + options.tree_shaking_mode, + Some(TreeShakingMode::ReexportsOnly) + )) + .await +} + +fn handle_call_boxed<'a, G: Fn(Vec) + Send + Sync + 'a>( + ast_path: &'a [AstParentKind], + span: Span, + func: JsValue, + this: JsValue, + args: Vec, + state: &'a AnalysisState<'a>, + add_effects: &'a G, + analysis: &'a mut AnalyzeEcmascriptModuleResultBuilder, + in_try: bool, +) -> Pin> + Send + 'a>> { + Box::pin(handle_call( + ast_path, + span, + func, + this, + args, + state, + add_effects, + analysis, + in_try, + )) +} + +async fn handle_call) + Send + Sync>( + ast_path: &[AstParentKind], + span: Span, + func: JsValue, + this: JsValue, + args: Vec, + state: &AnalysisState<'_>, + add_effects: &G, + analysis: &mut AnalyzeEcmascriptModuleResultBuilder, + in_try: bool, +) -> Result<()> { + let &AnalysisState { + handler, + origin, + source, + compile_time_info, + ignore_dynamic_requests, + .. + } = state; + fn explain_args(args: &[JsValue]) -> (String, String) { + JsValue::explain_args(args, 10, 2) + } + let linked_args = |args: Vec| async move { + args.into_iter() + .map(|arg| { + let add_effects = &add_effects; + async move { + let value = match arg { + EffectArg::Value(value) => value, + EffectArg::Closure(value, block) => { + add_effects(block.effects); + value + } + EffectArg::Spread => { + JsValue::unknown_empty(true, "spread is not supported yet") + } + }; + state.link_value(value, in_try).await + } + }) + .try_join() + .await + }; + match func { + JsValue::Alternatives(_, alts) => { + for alt in alts { + handle_call_boxed( + ast_path, + span, + alt, + this.clone(), + args.clone(), + state, + add_effects, + analysis, + in_try, + ) + .await?; + } + } + JsValue::WellKnownFunction(WellKnownFunctionKind::Import) => { + let args = linked_args(args).await?; + if args.len() == 1 { + let pat = js_value_to_pattern(&args[0]); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("import({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::DYNAMIC_IMPORT.to_string(), + ), + ); + if ignore_dynamic_requests { + analysis.add_code_gen(DynamicExpression::new_promise(Vc::cell( + ast_path.to_vec(), + ))); + return Ok(()); + } + } + analysis.add_reference(EsmAsyncAssetReference::new( + origin, + Request::parse(Value::new(pat)), + Vc::cell(ast_path.to_vec()), + issue_source(source, span), + in_try, + state.import_externals, + )); + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("import({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::DYNAMIC_IMPORT.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::Require) => { + let args = linked_args(args).await?; + if args.len() == 1 { + let pat = js_value_to_pattern(&args[0]); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("require({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::REQUIRE.to_string(), + ), + ); + if ignore_dynamic_requests { + analysis.add_code_gen(DynamicExpression::new(Vc::cell(ast_path.to_vec()))); + return Ok(()); + } + } + analysis.add_reference(CjsRequireAssetReference::new( + origin, + Request::parse(Value::new(pat)), + Vc::cell(ast_path.to_vec()), + issue_source(source, span), + in_try, + )); + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("require({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error(errors::failed_to_analyse::ecmascript::REQUIRE.to_string()), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::Define) => { + analyze_amd_define( + source, + analysis, + origin, + handler, + span, + ast_path, + linked_args(args).await?, + in_try, + ); + } + + JsValue::WellKnownFunction(WellKnownFunctionKind::RequireResolve) => { + let args = linked_args(args).await?; + if args.len() == 1 { + let pat = js_value_to_pattern(&args[0]); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("require.resolve({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::REQUIRE_RESOLVE.to_string(), + ), + ); + if ignore_dynamic_requests { + analysis.add_code_gen(DynamicExpression::new(Vc::cell(ast_path.to_vec()))); + return Ok(()); + } + } + analysis.add_reference(CjsRequireResolveAssetReference::new( + origin, + Request::parse(Value::new(pat)), + Vc::cell(ast_path.to_vec()), + issue_source(source, span), + in_try, + )); + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("require.resolve({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::REQUIRE_RESOLVE.to_string(), + ), + ) + } + + JsValue::WellKnownFunction(WellKnownFunctionKind::RequireContext) => { + let args = linked_args(args).await?; + let options = match parse_require_context(&args) { + Ok(options) => options, + Err(err) => { + let (args, hints) = explain_args(&args); + handler.span_err_with_code( + span, + &format!( + "require.context({args}) is not statically analyze-able: {}{hints}", + PrettyPrintError(&err) + ), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::REQUIRE_CONTEXT.to_string(), + ), + ); + return Ok(()); + } + }; + + analysis.add_reference(RequireContextAssetReference::new( + source, + origin, + options.dir, + options.include_subdirs, + Vc::cell(options.filter), + Vc::cell(ast_path.to_vec()), + Some(issue_source(source, span)), + in_try, + )); + } + + JsValue::WellKnownFunction(WellKnownFunctionKind::FsReadMethod(name)) => { + let args = linked_args(args).await?; + if !args.is_empty() { + let pat = js_value_to_pattern(&args[0]); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("fs.{name}({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::FS_METHOD.to_string(), + ), + ); + if ignore_dynamic_requests { + return Ok(()); + } + } + analysis.add_reference(FileSourceReference::new(source, Pattern::new(pat))); + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("fs.{name}({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error(errors::failed_to_analyse::ecmascript::FS_METHOD.to_string()), + ) + } + + JsValue::WellKnownFunction(WellKnownFunctionKind::PathResolve(..)) => { + let parent_path = origin.origin_path().parent().await?; + let args = linked_args(args).await?; + + let linked_func_call = state + .link_value( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::PathResolve(Box::new( + parent_path.path.as_str().into(), + )), + )), + args.clone(), + ), + in_try, + ) + .await?; + + let pat = js_value_to_pattern(&linked_func_call); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("path.resolve({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::PATH_METHOD.to_string(), + ), + ); + if ignore_dynamic_requests { + return Ok(()); + } + } + analysis.add_reference(FileSourceReference::new(source, Pattern::new(pat))); + return Ok(()); + } + + JsValue::WellKnownFunction(WellKnownFunctionKind::PathJoin) => { + let context_path = source.ident().path().await?; + // ignore path.join in `node-gyp`, it will includes too many files + if context_path.path.contains("node_modules/node-gyp") { + return Ok(()); + } + let args = linked_args(args).await?; + let linked_func_call = state + .link_value( + JsValue::call( + Box::new(JsValue::WellKnownFunction(WellKnownFunctionKind::PathJoin)), + args.clone(), + ), + in_try, + ) + .await?; + let pat = js_value_to_pattern(&linked_func_call); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("path.join({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::PATH_METHOD.to_string(), + ), + ); + if ignore_dynamic_requests { + return Ok(()); + } + } + analysis.add_reference(DirAssetReference::new(source, Pattern::new(pat))); + return Ok(()); + } + JsValue::WellKnownFunction(WellKnownFunctionKind::ChildProcessSpawnMethod(name)) => { + let args = linked_args(args).await?; + + // Is this specifically `spawn(process.argv[0], ['-e', ...])`? + if is_invoking_node_process_eval(&args) { + return Ok(()); + } + + if !args.is_empty() { + let mut show_dynamic_warning = false; + let pat = js_value_to_pattern(&args[0]); + if pat.is_match_ignore_dynamic("node") && args.len() >= 2 { + let first_arg = + JsValue::member(Box::new(args[1].clone()), Box::new(0_f64.into())); + let first_arg = state.link_value(first_arg, in_try).await?; + let pat = js_value_to_pattern(&first_arg); + let dynamic = !pat.has_constant_parts(); + if dynamic { + show_dynamic_warning = true; + } + if !dynamic || !ignore_dynamic_requests { + analysis.add_reference(CjsAssetReference::new( + origin, + Request::parse(Value::new(pat)), + issue_source(source, span), + in_try, + )); + } + } + let dynamic = !pat.has_constant_parts(); + if dynamic { + show_dynamic_warning = true; + } + if !dynamic || !ignore_dynamic_requests { + analysis.add_reference(FileSourceReference::new(source, Pattern::new(pat))); + } + if show_dynamic_warning { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("child_process.{name}({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::CHILD_PROCESS_SPAWN.to_string(), + ), + ); + } + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("child_process.{name}({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::CHILD_PROCESS_SPAWN.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::ChildProcessFork) => { + let args = linked_args(args).await?; + if !args.is_empty() { + let first_arg = &args[0]; + let pat = js_value_to_pattern(first_arg); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("child_process.fork({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::CHILD_PROCESS_SPAWN.to_string(), + ), + ); + if ignore_dynamic_requests { + return Ok(()); + } + } + analysis.add_reference(CjsAssetReference::new( + origin, + Request::parse(Value::new(pat)), + issue_source(source, span), + in_try, + )); + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("child_process.fork({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::CHILD_PROCESS_SPAWN.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::NodePreGypFind) => { + use turbopack_resolve::node_native_binding::NodePreGypConfigReference; + + let args = linked_args(args).await?; + if args.len() == 1 { + let first_arg = &args[0]; + let pat = js_value_to_pattern(first_arg); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("node-pre-gyp.find({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::NODE_PRE_GYP_FIND.to_string(), + ), + ); + // Always ignore this dynamic request + return Ok(()); + } + analysis.add_reference(NodePreGypConfigReference::new( + origin.origin_path().parent(), + Pattern::new(pat), + compile_time_info.environment().compile_target(), + )); + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!( + "require('@mapbox/node-pre-gyp').find({args}) is not statically \ + analyse-able{hints}", + ), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::NODE_PRE_GYP_FIND.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeGypBuild) => { + use turbopack_resolve::node_native_binding::NodeGypBuildReference; + + let args = linked_args(args).await?; + if args.len() == 1 { + let first_arg = state.link_value(args[0].clone(), in_try).await?; + if let Some(s) = first_arg.as_str() { + // TODO this resolving should happen within Vc + let current_context = origin + .origin_path() + .root() + .join(s.trim_start_matches("/ROOT/").into()); + analysis.add_reference(NodeGypBuildReference::new( + current_context, + compile_time_info.environment().compile_target(), + )); + return Ok(()); + } + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!( + "require('node-gyp-build')({args}) is not statically analyse-able{hints}", + ), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::NODE_GYP_BUILD.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeBindings) => { + use turbopack_resolve::node_native_binding::NodeBindingsReference; + + let args = linked_args(args).await?; + if args.len() == 1 { + let first_arg = state.link_value(args[0].clone(), in_try).await?; + if let Some(s) = first_arg.as_str() { + analysis + .add_reference(NodeBindingsReference::new(origin.origin_path(), s.into())); + return Ok(()); + } + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("require('bindings')({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::NODE_BINDINGS.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeExpressSet) => { + let args = linked_args(args).await?; + if args.len() == 2 { + if let Some(s) = args.first().and_then(|arg| arg.as_str()) { + let pkg_or_dir = args.get(1).unwrap(); + let pat = js_value_to_pattern(pkg_or_dir); + if !pat.has_constant_parts() { + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("require('express')().set({args}) is very dynamic{hints}",), + DiagnosticId::Lint( + errors::failed_to_analyse::ecmascript::NODE_EXPRESS.to_string(), + ), + ); + // Always ignore this dynamic request + return Ok(()); + } + match s { + "views" => { + if let Pattern::Constant(p) = &pat { + let abs_pattern = if p.starts_with("/ROOT/") { + pat + } else { + let linked_func_call = state + .link_value( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::PathJoin, + )), + vec![ + JsValue::FreeVar("__dirname".into()), + pkg_or_dir.clone(), + ], + ), + in_try, + ) + .await?; + js_value_to_pattern(&linked_func_call) + }; + analysis.add_reference(DirAssetReference::new( + source, + Pattern::new(abs_pattern), + )); + return Ok(()); + } + } + "view engine" => { + if let Some(pkg) = pkg_or_dir.as_str() { + if pkg != "html" { + let pat = js_value_to_pattern(pkg_or_dir); + analysis.add_reference(CjsAssetReference::new( + origin, + Request::parse(Value::new(pat)), + issue_source(source, span), + in_try, + )); + } + return Ok(()); + } + } + _ => {} + } + } + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("require('express')().set({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::NODE_EXPRESS.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeStrongGlobalizeSetRootDir) => { + let args = linked_args(args).await?; + if let Some(p) = args.first().and_then(|arg| arg.as_str()) { + let abs_pattern = if p.starts_with("/ROOT/") { + Pattern::Constant(format!("{p}/intl").into()) + } else { + let linked_func_call = state + .link_value( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::PathJoin, + )), + vec![ + JsValue::FreeVar("__dirname".into()), + p.into(), + "intl".into(), + ], + ), + in_try, + ) + .await?; + js_value_to_pattern(&linked_func_call) + }; + analysis.add_reference(DirAssetReference::new(source, Pattern::new(abs_pattern))); + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!( + "require('strong-globalize').SetRootDir({args}) is not statically \ + analyse-able{hints}", + ), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::NODE_GYP_BUILD.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeResolveFrom) => { + let args = linked_args(args).await?; + if args.len() == 2 && args.get(1).and_then(|arg| arg.as_str()).is_some() { + analysis.add_reference(CjsAssetReference::new( + origin, + Request::parse(Value::new(js_value_to_pattern(&args[1]))), + issue_source(source, span), + in_try, + )); + return Ok(()); + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!("require('resolve-from')({args}) is not statically analyse-able{hints}",), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::NODE_RESOLVE_FROM.to_string(), + ), + ) + } + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeProtobufLoad) => { + let args = linked_args(args).await?; + if args.len() == 2 { + if let Some(JsValue::Object { parts, .. }) = args.get(1) { + for dir in + parts + .iter() + .filter_map(|object_part| { + if let ObjectPart::KeyValue( + JsValue::Constant(key), + JsValue::Array { items: dirs, .. }, + ) = object_part + { + if key.as_str() == Some("includeDirs") { + return Some(dirs.iter().filter_map(|dir| { + dir.as_str().map(ToString::to_string) + })); + } + } + None + }) + .flatten() + { + analysis.add_reference(DirAssetReference::new( + source, + Pattern::new(Pattern::Constant(dir.into())), + )); + } + return Ok(()); + } + } + let (args, hints) = explain_args(&args); + handler.span_warn_with_code( + span, + &format!( + "require('@grpc/proto-loader').load({args}) is not statically \ + analyse-able{hints}", + ), + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::NODE_PROTOBUF_LOADER.to_string(), + ), + ) + } + _ => { + for arg in args { + if let EffectArg::Closure(_, block) = arg { + add_effects(block.effects); + } + } + } + } + Ok(()) +} + +async fn handle_member( + ast_path: &[AstParentKind], + obj: JsValue, + prop: JsValue, + span: Span, + state: &AnalysisState<'_>, + analysis: &mut AnalyzeEcmascriptModuleResultBuilder, +) -> Result<()> { + if let Some(prop) = prop.as_str() { + if let Some(def_name_len) = obj.get_defineable_name_len() { + let compile_time_info = state.compile_time_info.await?; + let free_var_references = compile_time_info.free_var_references.await?; + for (name, value) in free_var_references.iter() { + if name.len() != def_name_len + 1 { + continue; + } + let mut it = name.iter().map(|v| Cow::Borrowed(&**v)).rev(); + if it.next().unwrap() != Cow::Borrowed(prop) { + continue; + } + if it.eq(obj.iter_defineable_name_rev()) + && handle_free_var_reference(ast_path, value, span, state, analysis).await? + { + return Ok(()); + } + } + } + } + match (obj, prop) { + (JsValue::WellKnownFunction(WellKnownFunctionKind::Require), JsValue::Constant(s)) + if s.as_str() == Some("cache") => + { + analysis.add_code_gen( + CjsRequireCacheAccess { + path: Vc::cell(ast_path.to_vec()), + } + .cell(), + ); + } + _ => {} + } + + Ok(()) +} + +async fn handle_free_var( + ast_path: &[AstParentKind], + var: JsValue, + span: Span, + state: &AnalysisState<'_>, + analysis: &mut AnalyzeEcmascriptModuleResultBuilder, +) -> Result<()> { + if let Some(def_name_len) = var.get_defineable_name_len() { + let compile_time_info = state.compile_time_info.await?; + let free_var_references = compile_time_info.free_var_references.await?; + for (name, value) in free_var_references.iter() { + if name.len() != def_name_len { + continue; + } + + if var + .iter_defineable_name_rev() + .eq(name.iter().map(|v| Cow::Borrowed(&**v)).rev()) + && handle_free_var_reference(ast_path, value, span, state, analysis).await? + { + return Ok(()); + } + } + } + + Ok(()) +} + +async fn handle_free_var_reference( + ast_path: &[AstParentKind], + value: &FreeVarReference, + span: Span, + state: &AnalysisState<'_>, + analysis: &mut AnalyzeEcmascriptModuleResultBuilder, +) -> Result { + // We don't want to replace assignments as this would lead to invalid code. + if matches!( + ast_path, + [ + .., + AstParentKind::AssignExpr(AssignExprField::Left), + AstParentKind::AssignTarget(AssignTargetField::Simple), + AstParentKind::SimpleAssignTarget(SimpleAssignTargetField::Member), + ] + ) { + return Ok(false); + } + + match value { + FreeVarReference::Error(error_message) => state.handler.span_err_with_code( + span, + error_message, + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::FREE_VAR_REFERENCE.to_string(), + ), + ), + + FreeVarReference::Value(value) => { + analysis.add_code_gen(ConstantValue::new( + Value::new(value.clone()), + Vc::cell(ast_path.to_vec()), + )); + } + FreeVarReference::EcmaScriptModule { + request, + lookup_path, + export, + } => { + let esm_reference = EsmAssetReference::new( + lookup_path.map_or(state.origin, |lookup_path| { + Vc::upcast(PlainResolveOrigin::new( + state.origin.asset_context(), + lookup_path, + )) + }), + Request::parse(Value::new(request.clone().into())), + Some(IssueSource::from_swc_offsets( + state.source, + span.lo.to_usize(), + span.hi.to_usize(), + )), + Default::default(), + match state.tree_shaking_mode { + Some(TreeShakingMode::ModuleFragments) + | Some(TreeShakingMode::ReexportsOnly) => export + .as_ref() + .map(|export| ModulePart::export(export.clone())), + None => None, + }, + state.special_exports, + state.import_externals, + ) + .resolve() + .await?; + analysis.add_reference(esm_reference); + analysis.add_binding(EsmBinding::new( + esm_reference, + export.clone(), + Vc::cell(ast_path.to_vec()), + )); + } + } + Ok(true) +} + +fn issue_source(source: Vc>, span: Span) -> Vc { + IssueSource::from_swc_offsets(source, span.lo.to_usize(), span.hi.to_usize()) +} + +fn analyze_amd_define( + source: Vc>, + analysis: &mut AnalyzeEcmascriptModuleResultBuilder, + origin: Vc>, + handler: &Handler, + span: Span, + ast_path: &[AstParentKind], + args: Vec, + in_try: bool, +) { + match &args[..] { + [JsValue::Constant(id), JsValue::Array { items: deps, .. }, _] if id.as_str().is_some() => { + analyze_amd_define_with_deps( + source, + analysis, + origin, + handler, + span, + ast_path, + id.as_str(), + deps, + in_try, + ); + } + [JsValue::Array { items: deps, .. }, _] => { + analyze_amd_define_with_deps( + source, analysis, origin, handler, span, ast_path, None, deps, in_try, + ); + } + [JsValue::Constant(id), JsValue::Function(..)] if id.as_str().is_some() => { + analysis.add_code_gen(AmdDefineWithDependenciesCodeGen::new( + vec![ + AmdDefineDependencyElement::Require, + AmdDefineDependencyElement::Exports, + AmdDefineDependencyElement::Module, + ], + origin, + Vc::cell(ast_path.to_vec()), + AmdDefineFactoryType::Function, + issue_source(source, span), + in_try, + )); + } + [JsValue::Constant(id), _] if id.as_str().is_some() => { + analysis.add_code_gen(AmdDefineWithDependenciesCodeGen::new( + vec![ + AmdDefineDependencyElement::Require, + AmdDefineDependencyElement::Exports, + AmdDefineDependencyElement::Module, + ], + origin, + Vc::cell(ast_path.to_vec()), + AmdDefineFactoryType::Unknown, + issue_source(source, span), + in_try, + )); + } + [JsValue::Function(..)] => { + analysis.add_code_gen(AmdDefineWithDependenciesCodeGen::new( + vec![ + AmdDefineDependencyElement::Require, + AmdDefineDependencyElement::Exports, + AmdDefineDependencyElement::Module, + ], + origin, + Vc::cell(ast_path.to_vec()), + AmdDefineFactoryType::Function, + issue_source(source, span), + in_try, + )); + } + [JsValue::Object { .. }] => { + analysis.add_code_gen(AmdDefineWithDependenciesCodeGen::new( + vec![], + origin, + Vc::cell(ast_path.to_vec()), + AmdDefineFactoryType::Value, + issue_source(source, span), + in_try, + )); + } + [_] => { + analysis.add_code_gen(AmdDefineWithDependenciesCodeGen::new( + vec![ + AmdDefineDependencyElement::Require, + AmdDefineDependencyElement::Exports, + AmdDefineDependencyElement::Module, + ], + origin, + Vc::cell(ast_path.to_vec()), + AmdDefineFactoryType::Unknown, + issue_source(source, span), + in_try, + )); + } + _ => { + handler.span_err_with_code( + span, + "unsupported AMD define() form", + DiagnosticId::Error(errors::failed_to_analyse::ecmascript::AMD_DEFINE.to_string()), + ); + } + } +} + +fn analyze_amd_define_with_deps( + source: Vc>, + analysis: &mut AnalyzeEcmascriptModuleResultBuilder, + origin: Vc>, + handler: &Handler, + span: Span, + ast_path: &[AstParentKind], + id: Option<&str>, + deps: &[JsValue], + in_try: bool, +) { + let mut requests = Vec::new(); + for dep in deps { + if let Some(dep) = dep.as_str() { + match dep { + "exports" => { + requests.push(AmdDefineDependencyElement::Exports); + } + "require" => { + handler.span_warn_with_code( + span, + "using \"require\" as dependency in an AMD define() is not yet supported", + DiagnosticId::Error( + errors::failed_to_analyse::ecmascript::AMD_DEFINE.to_string(), + ), + ); + requests.push(AmdDefineDependencyElement::Require); + } + "module" => { + requests.push(AmdDefineDependencyElement::Module); + } + _ => { + let request = Request::parse_string(dep.into()); + let reference = AmdDefineAssetReference::new( + origin, + request, + issue_source(source, span), + in_try, + ); + requests.push(AmdDefineDependencyElement::Request { + request, + request_str: dep.to_string(), + }); + analysis.add_reference(reference); + } + } + } else { + handler.span_err_with_code( + // TODO(alexkirsz) It'd be best to highlight the argument's span, but + // `JsValue`s do not keep a hold of their original span. + span, + "unsupported AMD define() dependency element form", + DiagnosticId::Error(errors::failed_to_analyse::ecmascript::AMD_DEFINE.to_string()), + ); + } + } + + if id.is_some() { + handler.span_warn_with_code( + span, + "passing an ID to AMD define() is not yet fully supported", + DiagnosticId::Lint(errors::failed_to_analyse::ecmascript::AMD_DEFINE.to_string()), + ); + } + + analysis.add_code_gen(AmdDefineWithDependenciesCodeGen::new( + requests, + origin, + Vc::cell(ast_path.to_vec()), + AmdDefineFactoryType::Function, + issue_source(source, span), + in_try, + )); +} + +/// Used to generate the "root" path to a __filename/__dirname/import.meta.url +/// reference. +pub async fn as_abs_path(path: Vc) -> Result { + // TODO: This should be updated to generate a real system path on the fly + // during runtime, so that the generated code is constant between systems + // but the runtime evaluation can take into account the project's + // actual root directory. + require_resolve(path).await +} + +/// Generates an absolute path usable for `require.resolve()` calls. +async fn require_resolve(path: Vc) -> Result { + Ok(format!("/ROOT/{}", path.await?.path.as_str()).into()) +} + +async fn early_value_visitor(mut v: JsValue) -> Result<(JsValue, bool)> { + let modified = early_replace_builtin(&mut v); + Ok((v, modified)) +} + +async fn value_visitor( + origin: Vc>, + v: JsValue, + compile_time_info: Vc, + in_try: bool, +) -> Result<(JsValue, bool)> { + let (mut v, modified) = value_visitor_inner(origin, v, compile_time_info, in_try).await?; + v.normalize_shallow(); + Ok((v, modified)) +} + +async fn value_visitor_inner( + origin: Vc>, + v: JsValue, + compile_time_info: Vc, + in_try: bool, +) -> Result<(JsValue, bool)> { + if let Some(def_name_len) = v.get_defineable_name_len() { + let compile_time_info = compile_time_info.await?; + let defines = compile_time_info.defines.await?; + for (name, value) in defines.iter() { + if name.len() != def_name_len { + continue; + } + if v.iter_defineable_name_rev() + .eq(name.iter().map(|v| Cow::Borrowed(&**v)).rev()) + { + return Ok((value.into(), true)); + } + } + } + let value = match v { + JsValue::Call( + _, + box JsValue::WellKnownFunction(WellKnownFunctionKind::RequireResolve), + args, + ) => require_resolve_visitor(origin, args, in_try).await?, + JsValue::Call( + _, + box JsValue::WellKnownFunction(WellKnownFunctionKind::RequireContext), + args, + ) => require_context_visitor(origin, args, in_try).await?, + JsValue::Call( + _, + box JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequire(..) + | WellKnownFunctionKind::RequireContextRequireKeys(..) + | WellKnownFunctionKind::RequireContextRequireResolve(..), + ), + _, + ) => { + // TODO: figure out how to do static analysis without invalidating the while + // analysis when a new file gets added + v.into_unknown( + true, + "require.context() static analysis is currently limited", + ) + } + JsValue::FreeVar(ref kind) => match &**kind { + "__dirname" => as_abs_path(origin.origin_path().parent()).await?, + "__filename" => as_abs_path(origin.origin_path()).await?, + + "require" => JsValue::WellKnownFunction(WellKnownFunctionKind::Require), + "define" => JsValue::WellKnownFunction(WellKnownFunctionKind::Define), + "import" => JsValue::WellKnownFunction(WellKnownFunctionKind::Import), + "process" => JsValue::WellKnownObject(WellKnownObjectKind::NodeProcess), + "Object" => JsValue::WellKnownObject(WellKnownObjectKind::GlobalObject), + "Buffer" => JsValue::WellKnownObject(WellKnownObjectKind::NodeBuffer), + _ => return Ok((v, false)), + }, + JsValue::Module(ModuleValue { + module: ref name, .. + }) => { + if *compile_time_info.environment().node_externals().await? { + // TODO check externals + match &**name { + "node:path" | "path" => { + JsValue::WellKnownObject(WellKnownObjectKind::PathModule) + } + "node:fs/promises" | "fs/promises" => { + JsValue::WellKnownObject(WellKnownObjectKind::FsModule) + } + "node:fs" | "fs" => JsValue::WellKnownObject(WellKnownObjectKind::FsModule), + "node:child_process" | "child_process" => { + JsValue::WellKnownObject(WellKnownObjectKind::ChildProcess) + } + "node:os" | "os" => JsValue::WellKnownObject(WellKnownObjectKind::OsModule), + "node:process" | "process" => { + JsValue::WellKnownObject(WellKnownObjectKind::NodeProcess) + } + "@mapbox/node-pre-gyp" => { + JsValue::WellKnownObject(WellKnownObjectKind::NodePreGyp) + } + "node-gyp-build" => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeGypBuild) + } + "node:bindings" | "bindings" => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeBindings) + } + "express" => JsValue::WellKnownFunction(WellKnownFunctionKind::NodeExpress), + "strong-globalize" => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeStrongGlobalize) + } + "resolve-from" => { + JsValue::WellKnownFunction(WellKnownFunctionKind::NodeResolveFrom) + } + "@grpc/proto-loader" => { + JsValue::WellKnownObject(WellKnownObjectKind::NodeProtobufLoader) + } + _ => v.into_unknown(true, "cross module analyzing is not yet supported"), + } + } else { + v.into_unknown(true, "cross module analyzing is not yet supported") + } + } + JsValue::Argument(..) => { + v.into_unknown(true, "cross function analyzing is not yet supported") + } + _ => { + let (mut v, mut modified) = replace_well_known(v, compile_time_info).await?; + modified = replace_builtin(&mut v) || modified; + modified = modified || v.make_nested_operations_unknown(); + return Ok((v, modified)); + } + }; + Ok((value, true)) +} + +async fn require_resolve_visitor( + origin: Vc>, + args: Vec, + in_try: bool, +) -> Result { + Ok(if args.len() == 1 { + let pat = js_value_to_pattern(&args[0]); + let request = Request::parse(Value::new(pat.clone())); + let resolved = cjs_resolve(origin, request, None, try_to_severity(in_try)) + .resolve() + .await?; + let mut values = resolved + .primary_modules() + .await? + .iter() + .map(|&module| async move { require_resolve(module.ident().path()).await }) + .try_join() + .await?; + + match values.len() { + 0 => JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireResolve, + )), + args, + ), + false, + "unresolveable request", + ), + 1 => values.pop().unwrap(), + _ => JsValue::alternatives(values), + } + } else { + JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireResolve, + )), + args, + ), + true, + "only a single argument is supported", + ) + }) +} + +async fn require_context_visitor( + origin: Vc>, + args: Vec, + in_try: bool, +) -> Result { + let options = match parse_require_context(&args) { + Ok(options) => options, + Err(err) => { + return Ok(JsValue::unknown( + JsValue::call( + Box::new(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContext, + )), + args, + ), + true, + PrettyPrintError(&err).to_string(), + )) + } + }; + + let dir = origin.origin_path().parent().join(options.dir.clone()); + + let map = RequireContextMap::generate( + origin, + dir, + options.include_subdirs, + Vc::cell(options.filter), + None, + try_to_severity(in_try), + ); + + Ok(JsValue::WellKnownFunction( + WellKnownFunctionKind::RequireContextRequire(RequireContextValue::from_context_map(map)), + )) +} + +#[derive(Debug)] +enum StaticExpr { + String(String), + FreeVar(Vec), + ImportedVar(String, Vec), + Unknown, +} + +// TODO get rid of that +#[derive(Default)] +struct StaticAnalyser { + imports: HashMap)>, +} + +impl StaticAnalyser { + fn prop_to_name(&self, prop: &MemberProp) -> Option { + match prop { + MemberProp::Ident(ident) => Some(ident.sym.to_string()), + MemberProp::PrivateName(_) => None, + MemberProp::Computed(ComputedPropName { expr, .. }) => match self.evaluate_expr(expr) { + StaticExpr::String(str) => Some(str), + _ => None, + }, + } + } + + fn evaluate_expr(&self, expr: &Expr) -> StaticExpr { + match expr { + Expr::Lit(Lit::Str(str)) => StaticExpr::String(str.value.to_string()), + Expr::Ident(ident) => { + let str = ident.sym.to_string(); + match self.imports.get(&str) { + Some((module, import)) => { + StaticExpr::ImportedVar(module.clone(), import.clone()) + } + None => StaticExpr::FreeVar(vec![str]), + } + } + Expr::Member(member) => match self.evaluate_expr(&member.obj) { + StaticExpr::FreeVar(mut vec) => match self.prop_to_name(&member.prop) { + Some(name) => { + vec.push(name); + StaticExpr::FreeVar(vec) + } + None => StaticExpr::Unknown, + }, + StaticExpr::ImportedVar(module, mut vec) => match self.prop_to_name(&member.prop) { + Some(name) => { + vec.push(name); + StaticExpr::ImportedVar(module, vec) + } + None => StaticExpr::Unknown, + }, + _ => StaticExpr::Unknown, + }, + _ => StaticExpr::Unknown, + } + } +} + +struct ModuleReferencesVisitor<'a> { + eval_context: &'a EvalContext, + old_analyser: StaticAnalyser, + import_references: &'a [Vc], + analysis: &'a mut AnalyzeEcmascriptModuleResultBuilder, + esm_exports: BTreeMap, + esm_star_exports: Vec>>, + webpack_runtime: Option<(RcStr, Span)>, + webpack_entry: bool, + webpack_chunks: Vec, +} + +impl<'a> ModuleReferencesVisitor<'a> { + fn new( + eval_context: &'a EvalContext, + import_references: &'a [Vc], + analysis: &'a mut AnalyzeEcmascriptModuleResultBuilder, + ) -> Self { + Self { + eval_context, + old_analyser: StaticAnalyser::default(), + import_references, + analysis, + esm_exports: BTreeMap::new(), + esm_star_exports: Vec::new(), + webpack_runtime: None, + webpack_entry: false, + webpack_chunks: Vec::new(), + } + } +} + +fn as_parent_path(ast_path: &AstNodePath>) -> Vec { + ast_path.iter().map(|n| n.kind()).collect() +} + +fn for_each_ident_in_decl(decl: &Decl, f: &mut impl FnMut(RcStr)) { + match decl { + Decl::Class(ClassDecl { ident, .. }) | Decl::Fn(FnDecl { ident, .. }) => { + f(ident.sym.as_str().into()); + } + Decl::Var(var_decl) => { + let decls = &*var_decl.decls; + decls + .iter() + .for_each(|VarDeclarator { name, .. }| for_each_ident_in_pat(name, f)); + } + Decl::Using(using_decl) => { + let decls = &*using_decl.decls; + decls + .iter() + .for_each(|VarDeclarator { name, .. }| for_each_ident_in_pat(name, f)); + } + Decl::TsInterface(_) | Decl::TsTypeAlias(_) | Decl::TsEnum(_) | Decl::TsModule(_) => { + // ignore typescript for code generation + } + } +} +fn for_each_ident_in_pat(pat: &Pat, f: &mut impl FnMut(RcStr)) { + match pat { + Pat::Ident(BindingIdent { id, .. }) => { + f(id.sym.as_str().into()); + } + Pat::Array(ArrayPat { elems, .. }) => elems.iter().for_each(|e| { + if let Some(e) = e { + for_each_ident_in_pat(e, f); + } + }), + Pat::Rest(RestPat { arg, .. }) => { + for_each_ident_in_pat(arg, f); + } + Pat::Object(ObjectPat { props, .. }) => { + props.iter().for_each(|p| match p { + ObjectPatProp::KeyValue(KeyValuePatProp { value, .. }) => { + for_each_ident_in_pat(value, f); + } + ObjectPatProp::Assign(AssignPatProp { key, .. }) => { + f(key.sym.as_str().into()); + } + ObjectPatProp::Rest(RestPat { arg, .. }) => { + for_each_ident_in_pat(arg, f); + } + }); + } + Pat::Assign(AssignPat { left, .. }) => { + for_each_ident_in_pat(left, f); + } + Pat::Invalid(_) | Pat::Expr(_) => { + panic!("Unexpected pattern while enumerating idents"); + } + } +} + +impl<'a> VisitAstPath for ModuleReferencesVisitor<'a> { + fn visit_export_all<'ast: 'r, 'r>( + &mut self, + export: &'ast ExportAll, + ast_path: &mut AstNodePath>, + ) { + let path = Vc::cell(as_parent_path(ast_path)); + self.analysis.add_code_gen(EsmModuleItem::new(path)); + export.visit_children_with_path(self, ast_path); + } + + fn visit_named_export<'ast: 'r, 'r>( + &mut self, + export: &'ast NamedExport, + ast_path: &mut AstNodePath>, + ) { + let path = Vc::cell(as_parent_path(ast_path)); + // We create mutable exports for fake ESMs generated by module splitting + let is_fake_esm = export + .with + .as_deref() + .map(find_turbopack_part_id_in_asserts) + .is_some(); + + if export.src.is_none() { + for spec in export.specifiers.iter() { + fn to_string(name: &ModuleExportName) -> &JsWord { + name.atom() + } + match spec { + ExportSpecifier::Namespace(_) => { + panic!( + "ExportNamespaceSpecifier will not happen in combination with src == \ + None" + ); + } + ExportSpecifier::Default(_) => { + panic!( + "ExportDefaultSpecifier will not happen in combination with src == \ + None" + ); + } + ExportSpecifier::Named(ExportNamedSpecifier { orig, exported, .. }) => { + let key = to_string(exported.as_ref().unwrap_or(orig)).as_str().into(); + let binding_name = to_string(orig).as_str().into(); + let export = { + let imported_binding = if let ModuleExportName::Ident(ident) = orig { + self.eval_context.imports.get_binding(&ident.to_id()) + } else { + None + }; + if let Some((index, export)) = imported_binding { + let esm_ref = self.import_references[index]; + if let Some(export) = export { + EsmExport::ImportedBinding( + Vc::upcast(esm_ref), + export, + is_fake_esm, + ) + } else { + EsmExport::ImportedNamespace(Vc::upcast(esm_ref)) + } + } else { + EsmExport::LocalBinding(binding_name, is_fake_esm) + } + }; + self.esm_exports.insert(key, export); + } + } + } + } + + self.analysis.add_code_gen(EsmModuleItem::new(path)); + export.visit_children_with_path(self, ast_path); + } + + fn visit_export_decl<'ast: 'r, 'r>( + &mut self, + export: &'ast ExportDecl, + ast_path: &mut AstNodePath>, + ) { + for_each_ident_in_decl(&export.decl, &mut |name| { + self.esm_exports + .insert(name.clone(), EsmExport::LocalBinding(name, false)); + }); + self.analysis + .add_code_gen(EsmModuleItem::new(Vc::cell(as_parent_path(ast_path)))); + export.visit_children_with_path(self, ast_path); + } + + fn visit_export_default_expr<'ast: 'r, 'r>( + &mut self, + export: &'ast ExportDefaultExpr, + ast_path: &mut AstNodePath>, + ) { + self.esm_exports.insert( + "default".into(), + EsmExport::LocalBinding(magic_identifier::mangle("default export").into(), false), + ); + self.analysis + .add_code_gen(EsmModuleItem::new(Vc::cell(as_parent_path(ast_path)))); + export.visit_children_with_path(self, ast_path); + } + + fn visit_export_default_decl<'ast: 'r, 'r>( + &mut self, + export: &'ast ExportDefaultDecl, + ast_path: &mut AstNodePath>, + ) { + match &export.decl { + DefaultDecl::Class(ClassExpr { ident, .. }) | DefaultDecl::Fn(FnExpr { ident, .. }) => { + self.esm_exports.insert( + "default".into(), + EsmExport::LocalBinding( + ident + .as_ref() + .map(|i| i.sym.as_str().into()) + .unwrap_or_else(|| magic_identifier::mangle("default export").into()), + false, + ), + ); + } + DefaultDecl::TsInterfaceDecl(..) => { + // ignore + } + } + self.analysis + .add_code_gen(EsmModuleItem::new(Vc::cell(as_parent_path(ast_path)))); + export.visit_children_with_path(self, ast_path); + } + + fn visit_import_decl<'ast: 'r, 'r>( + &mut self, + import: &'ast ImportDecl, + ast_path: &mut AstNodePath>, + ) { + let path = Vc::cell(as_parent_path(ast_path)); + let src = import.src.value.to_string(); + import.visit_children_with_path(self, ast_path); + if import.type_only { + return; + } + for specifier in &import.specifiers { + match specifier { + ImportSpecifier::Named(named) => { + if !named.is_type_only { + self.old_analyser.imports.insert( + named.local.sym.to_string(), + ( + src.clone(), + vec![match &named.imported { + Some(ModuleExportName::Ident(ident)) => ident.sym.to_string(), + Some(ModuleExportName::Str(str)) => str.value.to_string(), + None => named.local.sym.to_string(), + }], + ), + ); + } + } + ImportSpecifier::Default(default_import) => { + self.old_analyser.imports.insert( + default_import.local.sym.to_string(), + (src.clone(), vec!["default".to_string()]), + ); + } + ImportSpecifier::Namespace(namespace) => { + self.old_analyser + .imports + .insert(namespace.local.sym.to_string(), (src.clone(), Vec::new())); + } + } + } + self.analysis.add_code_gen(EsmModuleItem::new(path)); + } + + fn visit_var_declarator<'ast: 'r, 'r>( + &mut self, + decl: &'ast VarDeclarator, + ast_path: &mut AstNodePath>, + ) { + if let Some(ident) = decl.name.as_ident() { + if &*ident.id.sym == "__webpack_require__" { + if let Some(init) = &decl.init { + if let Some(call) = init.as_call() { + if let Some(expr) = call.callee.as_expr() { + if let Some(ident) = expr.as_ident() { + if &*ident.sym == "require" { + if let [ExprOrSpread { spread: None, expr }] = &call.args[..] { + if let Some(Lit::Str(str)) = expr.as_lit() { + self.webpack_runtime = + Some((str.value.as_str().into(), call.span)); + return; + } + } + } + } + } + } + } + } + } + decl.visit_children_with_path(self, ast_path); + } + + fn visit_call_expr<'ast: 'r, 'r>( + &mut self, + call: &'ast CallExpr, + ast_path: &mut AstNodePath>, + ) { + if let Callee::Expr(expr) = &call.callee { + if let StaticExpr::FreeVar(var) = self.old_analyser.evaluate_expr(expr) { + match &var[..] { + [webpack_require, property] + if webpack_require == "__webpack_require__" && property == "C" => + { + self.webpack_entry = true; + } + [webpack_require, property] + if webpack_require == "__webpack_require__" && property == "X" => + { + if let [_, ExprOrSpread { + spread: None, + expr: chunk_ids, + }, _] = &call.args[..] + { + if let Some(array) = chunk_ids.as_array() { + for elem in array.elems.iter().flatten() { + if let ExprOrSpread { spread: None, expr } = elem { + if let Some(lit) = expr.as_lit() { + self.webpack_chunks.push(lit.clone()); + } + } + } + } + } + } + _ => {} + } + } + } + call.visit_children_with_path(self, ast_path); + } +} + +#[turbo_tasks::function] +async fn resolve_as_webpack_runtime( + origin: Vc>, + request: Vc, + transforms: Vc, +) -> Result> { + let ty = Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)); + let options = origin.resolve_options(ty.clone()); + + let options = apply_cjs_specific_options(options); + + let resolved = resolve( + origin.origin_path().parent().resolve().await?, + Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), + request, + options, + ); + + if let Some(source) = *resolved.first_source().await? { + Ok(webpack_runtime(source, transforms)) + } else { + Ok(WebpackRuntime::None.into()) + } +} + +// TODO enable serialization +#[turbo_tasks::value(transparent, serialization = "none")] +pub struct AstPath(#[turbo_tasks(trace_ignore)] Vec); + +pub static TURBOPACK_HELPER: Lazy = Lazy::new(|| "__turbopack-helper__".into()); + +pub fn is_turbopack_helper_import(import: &ImportDecl) -> bool { + let annotations = ImportAnnotations::parse(import.with.as_deref()); + + annotations.get(&TURBOPACK_HELPER).is_some() +} + +#[derive(Debug)] +enum DetectedDynamicExportType { + CommonJs, + Namespace, + Value, + None, + UsingModuleDeclarations, +} + +fn detect_dynamic_export(p: &Program) -> DetectedDynamicExportType { + use swc_core::ecma::visit::{visit_obj_and_computed, Visit, VisitWith}; + + if let Program::Module(m) = p { + // Check for imports/exports + if m.body.iter().any(|item| { + item.as_module_decl().map_or(false, |module_decl| { + module_decl + .as_import() + .map_or(true, |import| !is_turbopack_helper_import(import)) + }) + }) { + return DetectedDynamicExportType::UsingModuleDeclarations; + } + } + + struct Visitor { + cjs: bool, + value: bool, + namespace: bool, + found: bool, + } + + impl Visit for Visitor { + visit_obj_and_computed!(); + + fn visit_ident(&mut self, i: &Ident) { + // The detection is not perfect, it might have some false positives, e. g. in + // cases where `module` is used in some other way. e. g. `const module = 42;`. + // But a false positive doesn't break anything, it only opts out of some + // optimizations, which is acceptable. + if &*i.sym == "module" || &*i.sym == "exports" { + self.cjs = true; + self.found = true; + } + if &*i.sym == "__turbopack_export_value__" { + self.value = true; + self.found = true; + } + if &*i.sym == "__turbopack_export_namespace__" { + self.namespace = true; + self.found = true; + } + } + fn visit_expr(&mut self, n: &Expr) { + if self.found { + return; + } + n.visit_children_with(self); + } + + fn visit_stmt(&mut self, n: &Stmt) { + if self.found { + return; + } + n.visit_children_with(self); + } + } + + let mut v = Visitor { + cjs: false, + value: false, + namespace: false, + found: false, + }; + p.visit_with(&mut v); + if v.cjs { + DetectedDynamicExportType::CommonJs + } else if v.value { + DetectedDynamicExportType::Value + } else if v.namespace { + DetectedDynamicExportType::Namespace + } else { + DetectedDynamicExportType::None + } +} + +/// Detects whether a list of arguments is specifically +/// `(process.argv[0], ['-e', ...])`. This is useful for detecting if a node +/// process is being spawned to interpret a string of JavaScript code, and does +/// not require static analysis. +fn is_invoking_node_process_eval(args: &[JsValue]) -> bool { + if args.len() < 2 { + return false; + } + + if let JsValue::Member(_, obj, constant) = &args[0] { + // Is the first argument to spawn `process.argv[]`? + if let ( + box JsValue::WellKnownObject(WellKnownObjectKind::NodeProcessArgv), + box JsValue::Constant(JsConstantValue::Num(ConstantNumber(num))), + ) = (obj, constant) + { + // Is it specifically `process.argv[0]`? + if num.is_zero() { + if let JsValue::Array { + total_nodes: _, + items, + mutable: _, + } = &args[1] + { + // Is `-e` one of the arguments passed to the program? + if items.iter().any(|e| { + if let JsValue::Constant(JsConstantValue::Str(ConstantString::Word(arg))) = + e + { + arg == "-e" + } else { + false + } + }) { + // If so, this is likely spawning node to evaluate a string, and + // does not need to be statically analyzed. + return true; + } + } + } + } + } + + false +} + +#[turbo_tasks::function] +fn maybe_decode_data_url(url: RcStr) -> Vc { + if let Ok(map) = decode_data_url(&url) { + Vc::cell(Some(SourceMap::new_decoded(map).cell())) + } else { + Vc::cell(None) + } +} + +#[turbo_tasks::function] +async fn convert_to_turbopack_source_map( + source_map: Vc, + origin: Vc, +) -> Result> { + let Some(source_map) = *source_map.await? else { + return Ok(Vc::cell(None)); + }; + Ok(Vc::cell(Some(source_map.with_resolved_sources(origin)))) +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/node.rs b/turbopack/crates/turbopack-ecmascript/src/references/node.rs new file mode 100644 index 0000000000000..49c78c2b28ef4 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/node.rs @@ -0,0 +1,158 @@ +use anyhow::Result; +use either::Either; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + file_source::FileSource, + raw_module::RawModule, + reference::ModuleReference, + resolve::{ + pattern::{read_matches, Pattern, PatternMatch}, + ModuleResolveResult, RequestKey, + }, + source::Source, +}; + +#[turbo_tasks::value] +#[derive(Hash, Clone, Debug)] +pub struct PackageJsonReference { + pub package_json: Vc, +} + +#[turbo_tasks::value_impl] +impl PackageJsonReference { + #[turbo_tasks::function] + pub fn new(package_json: Vc) -> Vc { + Self::cell(PackageJsonReference { package_json }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for PackageJsonReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + ModuleResolveResult::module(Vc::upcast(RawModule::new(Vc::upcast(FileSource::new( + self.package_json, + ))))) + .cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for PackageJsonReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("package.json {}", self.package_json.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct DirAssetReference { + pub source: Vc>, + pub path: Vc, +} + +#[turbo_tasks::value_impl] +impl DirAssetReference { + #[turbo_tasks::function] + pub fn new(source: Vc>, path: Vc) -> Vc { + Self::cell(DirAssetReference { source, path }) + } +} + +#[turbo_tasks::function] +async fn resolve_reference_from_dir( + parent_path: Vc, + path: Vc, +) -> Result> { + let path_ref = path.await?; + let (abs_path, rel_path) = path_ref.split_could_match("/ROOT/"); + let matches = match (abs_path, rel_path) { + (Some(abs_path), Some(rel_path)) => Either::Right( + read_matches( + parent_path.root().resolve().await?, + "/ROOT/".into(), + true, + Pattern::new(abs_path.or_any_nested_file()), + ) + .await? + .into_iter() + .chain( + read_matches( + parent_path, + "".into(), + true, + Pattern::new(rel_path.or_any_nested_file()), + ) + .await? + .into_iter(), + ), + ), + (Some(abs_path), None) => Either::Left( + // absolute path only + read_matches( + parent_path.root().resolve().await?, + "/ROOT/".into(), + true, + Pattern::new(abs_path.or_any_nested_file()), + ) + .await? + .into_iter(), + ), + (None, Some(rel_path)) => Either::Left( + // relative path only + read_matches( + parent_path, + "".into(), + true, + Pattern::new(rel_path.or_any_nested_file()), + ) + .await? + .into_iter(), + ), + (None, None) => return Ok(ModuleResolveResult::unresolveable().cell()), + }; + let mut affecting_sources = Vec::new(); + let mut results = Vec::new(); + for pat_match in matches { + match pat_match { + PatternMatch::File(matched_path, file) => { + let realpath = file.realpath_with_links().await?; + for &symlink in &realpath.symlinks { + affecting_sources.push(Vc::upcast(FileSource::new(symlink))); + } + results.push(( + RequestKey::new(matched_path.clone()), + Vc::upcast(RawModule::new(Vc::upcast(FileSource::new(realpath.path)))), + )); + } + PatternMatch::Directory(..) => {} + } + } + Ok(ModuleResolveResult::modules_with_affecting_sources(results, affecting_sources).cell()) +} + +#[turbo_tasks::value_impl] +impl ModuleReference for DirAssetReference { + #[turbo_tasks::function] + async fn resolve_reference(&self) -> Result> { + let parent_path = self.source.ident().path().parent(); + Ok(resolve_reference_from_dir( + parent_path.resolve().await?, + self.path, + )) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for DirAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("directory assets {}", self.path.to_string().await?,).into(), + )) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/pattern_mapping.rs b/turbopack/crates/turbopack-ecmascript/src/references/pattern_mapping.rs new file mode 100644 index 0000000000000..c0c87b707f51d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/pattern_mapping.rs @@ -0,0 +1,422 @@ +use std::{borrow::Cow, collections::HashSet}; + +use anyhow::Result; +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{ + CallExpr, Callee, Expr, ExprOrSpread, KeyValueProp, Lit, ObjectLit, Prop, PropName, + PropOrSpread, + }, + quote, quote_expr, +}; +use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, RcStr, TryJoinIterExt, Value, Vc}; +use turbopack_core::{ + chunk::{ChunkItemExt, ChunkableModule, ChunkingContext, ModuleId}, + issue::{code_gen::CodeGenerationIssue, IssueExt, IssueSeverity, StyledString}, + resolve::{ + origin::ResolveOrigin, parse::Request, ExternalType, ModuleResolveResult, + ModuleResolveResultItem, + }, +}; + +use super::util::{request_to_string, throw_module_not_found_expr}; +use crate::{references::util::throw_module_not_found_error_expr, utils::module_id_to_lit}; + +#[derive(PartialEq, Eq, ValueDebugFormat, TraceRawVcs, Serialize, Deserialize)] +pub(crate) enum SinglePatternMapping { + /// Invalid request. + Invalid, + /// Unresolveable request. + Unresolveable(String), + /// Ignored request. + Ignored, + /// Constant request that always maps to the same module. + /// + /// ### Example + /// ```js + /// require("./module") + /// ``` + Module(ModuleId), + /// Constant request that always maps to the same module. + /// This is used for dynamic imports. + /// Module id points to a loader module. + /// + /// ### Example + /// ```js + /// import("./module") + /// ``` + ModuleLoader(ModuleId), + /// External reference with request and type + External(RcStr, ExternalType), +} + +/// A mapping from a request pattern (e.g. "./module", `./images/${name}.png`) +/// to corresponding module ids. The same pattern can map to multiple module ids +/// at runtime when using variable interpolation. +#[turbo_tasks::value] +pub(crate) enum PatternMapping { + /// Constant request that always maps to the same module. + /// + /// ### Example + /// ```js + /// require("./module") + /// ``` + Single(SinglePatternMapping), + /// Variable request that can map to different modules at runtime. + /// + /// ### Example + /// ```js + /// require(`./images/${name}.png`) + /// ``` + Map(IndexMap), +} + +#[derive(Hash, Debug, Copy, Clone)] +#[turbo_tasks::value(serialization = "auto_for_input")] +pub(crate) enum ResolveType { + AsyncChunkLoader, + ChunkItem, +} + +impl SinglePatternMapping { + pub fn create_id(&self, key_expr: Cow<'_, Expr>) -> Expr { + match self { + Self::Invalid => { + quote!( + "(() => { throw new Error('could not resolve \"' + $arg + '\" into a module'); })()" as Expr, + arg: Expr = key_expr.into_owned() + ) + } + Self::Unresolveable(request) => throw_module_not_found_expr(request), + Self::Ignored => { + quote!("undefined" as Expr) + } + Self::Module(module_id) | Self::ModuleLoader(module_id) => module_id_to_lit(module_id), + Self::External(s, _) => Expr::Lit(Lit::Str(s.as_str().into())), + } + } + + pub fn create_require(&self, key_expr: Cow<'_, Expr>) -> Expr { + match self { + Self::Invalid => self.create_id(key_expr), + Self::Unresolveable(request) => throw_module_not_found_expr(request), + Self::Ignored => { + quote!("{}" as Expr) + } + Self::Module(_) | Self::ModuleLoader(_) => Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!("__turbopack_require__")), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(self.create_id(key_expr)), + }], + span: DUMMY_SP, + type_args: None, + }), + Self::External(request, ExternalType::CommonJs) => Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!("__turbopack_external_require__")), + args: vec![ExprOrSpread { + spread: None, + expr: request.as_str().into(), + }], + span: DUMMY_SP, + type_args: None, + }), + Self::External(request, ty) => throw_module_not_found_error_expr( + request, + &format!("Unsupported external type {:?} for commonjs reference", ty), + ), + } + } + + pub fn create_import(&self, key_expr: Cow<'_, Expr>, import_externals: bool) -> Expr { + match self { + Self::Invalid => { + let error = quote_expr!( + "() => { throw new Error('could not resolve \"' + $arg + '\" into a module'); }", + arg: Expr = key_expr.into_owned() + ); + Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!("Promise.resolve().then")), + args: vec![ExprOrSpread { + spread: None, + expr: error, + }], + span: DUMMY_SP, + type_args: None, + }) + } + Self::Unresolveable(_) => self.create_id(key_expr), + Self::External(_, ExternalType::EcmaScriptModule) => { + if import_externals { + Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!("__turbopack_external_import__")), + args: vec![ExprOrSpread { + spread: None, + expr: Box::new(key_expr.into_owned()), + }], + span: DUMMY_SP, + type_args: None, + }) + } else { + Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!("Promise.resolve().then")), + args: vec![ExprOrSpread { + spread: None, + expr: quote_expr!( + "() => __turbopack_external_require__($arg, true)", + arg: Expr = key_expr.into_owned() + ), + }], + span: DUMMY_SP, + type_args: None, + }) + } + } + Self::External(_, ExternalType::CommonJs | ExternalType::Url) => Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!("Promise.resolve().then")), + args: vec![ExprOrSpread { + spread: None, + expr: quote_expr!( + "() => __turbopack_external_require__($arg, true)", + arg: Expr = key_expr.into_owned() + ), + }], + span: DUMMY_SP, + type_args: None, + }), + #[allow(unreachable_patterns)] + Self::External(request, ty) => throw_module_not_found_error_expr( + request, + &format!( + "Unsupported external type {:?} for dynamic import reference", + ty + ), + ), + Self::ModuleLoader(module_id) => Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!( + "__turbopack_require__($arg)", + arg: Expr = module_id_to_lit(module_id) + )), + args: vec![ExprOrSpread { + spread: None, + expr: quote_expr!("__turbopack_import__"), + }], + span: DUMMY_SP, + type_args: None, + }), + Self::Ignored => { + quote!("Promise.resolve({})" as Expr) + } + Self::Module(_) => Expr::Call(CallExpr { + callee: Callee::Expr(quote_expr!("Promise.resolve().then")), + args: vec![ExprOrSpread { + spread: None, + expr: quote_expr!( + "() => __turbopack_import__($arg)", + arg: Expr = self.create_id(key_expr) + ), + }], + span: DUMMY_SP, + type_args: None, + }), + } + } +} + +enum ImportMode { + Require, + Import { import_externals: bool }, +} + +fn create_context_map( + map: &IndexMap, + key_expr: &Expr, + import_mode: ImportMode, +) -> Expr { + let props = map + .iter() + .map(|(k, v)| { + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Str(k.as_str().into()), + value: quote_expr!( + "{ id: () => $id, module: () => $module }", + id: Expr = v.create_id(Cow::Borrowed(key_expr)), + module: Expr = match import_mode { + ImportMode::Require => v.create_require(Cow::Borrowed(key_expr)), + ImportMode::Import { import_externals } => v.create_import(Cow::Borrowed(key_expr), import_externals), + }, + ), + }))) + }) + .collect(); + + Expr::Object(ObjectLit { + span: DUMMY_SP, + props, + }) +} + +impl PatternMapping { + pub fn create_id(&self, key_expr: Expr) -> Expr { + match self { + PatternMapping::Single(pm) => pm.create_id(Cow::Owned(key_expr)), + PatternMapping::Map(map) => { + let map = create_context_map(map, &key_expr, ImportMode::Require); + + quote!("__turbopack_module_context__($map).resolve($key)" as Expr, + map: Expr = map, + key: Expr = key_expr + ) + } + } + } + + pub fn create_require(&self, key_expr: Expr) -> Expr { + match self { + PatternMapping::Single(pm) => pm.create_require(Cow::Owned(key_expr)), + PatternMapping::Map(map) => { + let map = create_context_map(map, &key_expr, ImportMode::Require); + + quote!("__turbopack_module_context__($map)($key)" as Expr, + map: Expr = map, + key: Expr = key_expr + ) + } + } + } + + pub fn create_import(&self, key_expr: Expr, import_externals: bool) -> Expr { + match self { + PatternMapping::Single(pm) => pm.create_import(Cow::Owned(key_expr), import_externals), + PatternMapping::Map(map) => { + let map = + create_context_map(map, &key_expr, ImportMode::Import { import_externals }); + + quote!("__turbopack_module_context__($map).import($key)" as Expr, + map: Expr = map, + key: Expr = key_expr + ) + } + } + } +} + +async fn to_single_pattern_mapping( + origin: Vc>, + chunking_context: Vc>, + resolve_item: &ModuleResolveResultItem, + resolve_type: ResolveType, +) -> Result { + let module = match resolve_item { + ModuleResolveResultItem::Module(module) => *module, + ModuleResolveResultItem::External(s, ty) => { + return Ok(SinglePatternMapping::External(s.clone(), *ty)); + } + ModuleResolveResultItem::Ignore => return Ok(SinglePatternMapping::Ignored), + _ => { + // TODO implement mapping + CodeGenerationIssue { + severity: IssueSeverity::Bug.into(), + title: StyledString::Text( + "pattern mapping is not implemented for this result".into(), + ) + .cell(), + message: StyledString::Text( + format!( + "the reference resolves to a non-trivial result, which is not supported \ + yet: {:?}", + resolve_item + ) + .into(), + ) + .cell(), + path: origin.origin_path(), + } + .cell() + .emit(); + return Ok(SinglePatternMapping::Invalid); + } + }; + if let Some(chunkable) = Vc::try_resolve_downcast::>(module).await? { + match resolve_type { + ResolveType::AsyncChunkLoader => { + let loader_id = chunking_context.async_loader_chunk_item_id(chunkable); + return Ok(SinglePatternMapping::ModuleLoader( + loader_id.await?.clone_value(), + )); + } + ResolveType::ChunkItem => { + let chunk_item = chunkable.as_chunk_item(chunking_context); + return Ok(SinglePatternMapping::Module( + chunk_item.id().await?.clone_value(), + )); + } + } + } + CodeGenerationIssue { + severity: IssueSeverity::Bug.into(), + title: StyledString::Text("non-ecmascript placeable asset".into()).cell(), + message: StyledString::Text( + "asset is not placeable in ESM chunks, so it doesn't have a module id".into(), + ) + .cell(), + path: origin.origin_path(), + } + .cell() + .emit(); + Ok(SinglePatternMapping::Invalid) +} + +#[turbo_tasks::value_impl] +impl PatternMapping { + /// Resolves a request into a pattern mapping. + // NOTE(alexkirsz) I would rather have used `resolve` here but it's already reserved by the Vc + // impl. + #[turbo_tasks::function] + pub async fn resolve_request( + request: Vc, + origin: Vc>, + chunking_context: Vc>, + resolve_result: Vc, + resolve_type: Value, + ) -> Result> { + let resolve_type = resolve_type.into_value(); + let result = resolve_result.await?; + match result.primary.len() { + 0 => Ok(PatternMapping::Single(SinglePatternMapping::Unresolveable( + request_to_string(request).await?.to_string(), + )) + .cell()), + 1 => { + let resolve_item = result.primary.first().unwrap().1; + let single_pattern_mapping = + to_single_pattern_mapping(origin, chunking_context, resolve_item, resolve_type) + .await?; + Ok(PatternMapping::Single(single_pattern_mapping).cell()) + } + _ => { + let mut set = HashSet::new(); + let map = result + .primary + .iter() + .filter_map(|(k, v)| { + let request = k.request.as_ref()?; + set.insert(request).then(|| (request.to_string(), v)) + }) + .map(|(k, v)| async move { + let single_pattern_mapping = + to_single_pattern_mapping(origin, chunking_context, v, resolve_type) + .await?; + Ok((k, single_pattern_mapping)) + }) + .try_join() + .await? + .into_iter() + .collect(); + Ok(PatternMapping::Map(map).cell()) + } + } + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/raw.rs b/turbopack/crates/turbopack-ecmascript/src/references/raw.rs new file mode 100644 index 0000000000000..be2878a4830c1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/raw.rs @@ -0,0 +1,42 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ + reference::ModuleReference, + resolve::{pattern::Pattern, resolve_raw, ModuleResolveResult}, + source::Source, +}; + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct FileSourceReference { + pub source: Vc>, + pub path: Vc, +} + +#[turbo_tasks::value_impl] +impl FileSourceReference { + #[turbo_tasks::function] + pub fn new(source: Vc>, path: Vc) -> Vc { + Self::cell(FileSourceReference { source, path }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for FileSourceReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + let context_dir = self.source.ident().path().parent(); + + resolve_raw(context_dir, self.path, false).as_raw_module_result() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for FileSourceReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("raw asset {}", self.path.to_string().await?,).into(), + )) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/require_context.rs b/turbopack/crates/turbopack-ecmascript/src/references/require_context.rs new file mode 100644 index 0000000000000..6c1db7bd6412d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/require_context.rs @@ -0,0 +1,527 @@ +use std::{borrow::Cow, collections::VecDeque, sync::Arc}; + +use anyhow::{bail, Result}; +use indexmap::IndexMap; +use swc_core::{ + common::DUMMY_SP, + ecma::{ + ast::{ + Expr, ExprStmt, KeyValueProp, Lit, ModuleItem, ObjectLit, Prop, PropName, PropOrSpread, + Stmt, {self}, + }, + codegen::{text_writer::JsWriter, Emitter}, + }, + quote, quote_expr, +}; +use turbo_tasks::{primitives::Regex, RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::{DirectoryContent, DirectoryEntry, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ + ChunkItem, ChunkItemExt, ChunkType, ChunkableModule, ChunkableModuleReference, + ChunkingContext, + }, + ident::AssetIdent, + issue::{IssueSeverity, IssueSource}, + module::Module, + reference::{ModuleReference, ModuleReferences}, + resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, + source::Source, +}; +use turbopack_resolve::ecmascript::{cjs_resolve, try_to_severity}; + +use crate::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType, EcmascriptExports, + }, + code_gen::CodeGeneration, + create_visitor, + references::{ + pattern_mapping::{PatternMapping, ResolveType}, + AstPath, + }, + utils::module_id_to_lit, + CodeGenerateable, EcmascriptChunkPlaceable, +}; + +#[turbo_tasks::value] +#[derive(Debug)] +pub(crate) enum DirListEntry { + File(Vc), + Dir(Vc), +} + +#[turbo_tasks::value(transparent)] +pub(crate) struct DirList(IndexMap); + +#[turbo_tasks::value_impl] +impl DirList { + #[turbo_tasks::function] + pub(crate) fn read(dir: Vc, recursive: bool, filter: Vc) -> Vc { + Self::read_internal(dir, dir, recursive, filter) + } + + #[turbo_tasks::function] + pub(crate) async fn read_internal( + root: Vc, + dir: Vc, + recursive: bool, + filter: Vc, + ) -> Result> { + let root_val = &*dir.await?; + let regex = &*filter.await?; + + let mut list = IndexMap::new(); + + let dir_content = dir.read_dir().await?; + let entries = match &*dir_content { + DirectoryContent::Entries(entries) => Some(entries), + DirectoryContent::NotFound => None, + }; + + for (_, entry) in entries.iter().flat_map(|m| m.iter()) { + match entry { + DirectoryEntry::File(path) => { + if let Some(relative_path) = root_val.get_relative_path_to(&*path.await?) { + if regex.is_match(&relative_path) { + list.insert(relative_path, DirListEntry::File(*path)); + } + } + } + DirectoryEntry::Directory(path) if recursive => { + if let Some(relative_path) = root_val.get_relative_path_to(&*path.await?) { + list.insert( + relative_path, + DirListEntry::Dir(DirList::read_internal( + root, *path, recursive, filter, + )), + ); + } + } + // ignore everything else + _ => {} + } + } + + list.sort_keys(); + + Ok(Vc::cell(list)) + } + + #[turbo_tasks::function] + async fn flatten(self: Vc) -> Result> { + let this = self.await?; + + let mut queue = VecDeque::from([this]); + + let mut list = IndexMap::new(); + + while let Some(dir) = queue.pop_front() { + for (k, entry) in &*dir { + match entry { + DirListEntry::File(path) => { + list.insert(k.clone(), *path); + } + DirListEntry::Dir(d) => { + queue.push_back(d.await?); + } + } + } + } + + Ok(Vc::cell(list)) + } +} + +#[turbo_tasks::value(transparent)] +pub(crate) struct FlatDirList(IndexMap>); + +#[turbo_tasks::value_impl] +impl FlatDirList { + #[turbo_tasks::function] + pub(crate) fn read(dir: Vc, recursive: bool, filter: Vc) -> Vc { + DirList::read(dir, recursive, filter).flatten() + } +} + +#[turbo_tasks::value] +#[derive(Debug)] +pub struct RequireContextMapEntry { + pub origin_relative: RcStr, + pub request: Vc, + pub result: Vc, +} + +/// The resolved context map for a `require.context(..)` call. +#[turbo_tasks::value(transparent)] +pub struct RequireContextMap(IndexMap); + +#[turbo_tasks::value_impl] +impl RequireContextMap { + #[turbo_tasks::function] + pub(crate) async fn generate( + origin: Vc>, + dir: Vc, + recursive: bool, + filter: Vc, + issue_source: Option>, + issue_severity: Vc, + ) -> Result> { + let origin_path = &*origin.origin_path().parent().await?; + + let list = &*FlatDirList::read(dir, recursive, filter).await?; + + let mut map = IndexMap::new(); + + for (context_relative, path) in list { + if let Some(origin_relative) = origin_path.get_relative_path_to(&*path.await?) { + let request = Request::parse(Value::new(origin_relative.clone().into())); + let result = cjs_resolve(origin, request, issue_source, issue_severity); + + map.insert( + context_relative.clone(), + RequireContextMapEntry { + origin_relative, + request, + result, + }, + ); + } else { + bail!("invariant error: this was already checked in `list_dir`"); + } + } + + Ok(Vc::cell(map)) + } +} + +/// A reference for `require.context()`, will replace it with an inlined map +/// wrapped in `__turbopack_module_context__`; +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct RequireContextAssetReference { + pub inner: Vc, + pub dir: RcStr, + pub include_subdirs: bool, + + pub path: Vc, + pub issue_source: Option>, + pub in_try: bool, +} + +#[turbo_tasks::value_impl] +impl RequireContextAssetReference { + #[turbo_tasks::function] + pub fn new( + source: Vc>, + origin: Vc>, + dir: RcStr, + include_subdirs: bool, + filter: Vc, + path: Vc, + issue_source: Option>, + in_try: bool, + ) -> Vc { + let map = RequireContextMap::generate( + origin, + origin.origin_path().parent().join(dir.clone()), + include_subdirs, + filter, + issue_source, + try_to_severity(in_try), + ); + let inner = RequireContextAsset { + source, + origin, + map, + + dir: dir.clone(), + include_subdirs, + } + .cell(); + + Self::cell(RequireContextAssetReference { + inner, + dir, + include_subdirs, + path, + issue_source, + in_try, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for RequireContextAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + ModuleResolveResult::module(Vc::upcast(self.inner)).cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for RequireContextAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!( + "require.context {}/{}", + self.dir, + if self.include_subdirs { "**" } else { "*" }, + ) + .into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for RequireContextAssetReference {} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for RequireContextAssetReference { + #[turbo_tasks::function] + async fn code_generation( + &self, + chunking_context: Vc>, + ) -> Result> { + let chunk_item = self.inner.as_chunk_item(Vc::upcast(chunking_context)); + let module_id = chunk_item.id().await?.clone_value(); + + let mut visitors = Vec::new(); + + let path = &self.path.await?; + visitors.push(create_visitor!(path, visit_mut_expr(expr: &mut Expr) { + if let Expr::Call(_) = expr { + *expr = quote!( + "__turbopack_module_context__(__turbopack_require__($id))" as Expr, + id: Expr = module_id_to_lit(&module_id) + ); + } + })); + + Ok(CodeGeneration { visitors }.into()) + } +} + +#[turbo_tasks::value(transparent)] +pub struct ResolvedModuleReference(Vc); + +#[turbo_tasks::value_impl] +impl ModuleReference for ResolvedModuleReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + self.0 + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for ResolvedModuleReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("resolved reference".into())) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for ResolvedModuleReference {} + +#[turbo_tasks::value] +pub struct RequireContextAsset { + source: Vc>, + + origin: Vc>, + map: Vc, + + dir: RcStr, + include_subdirs: bool, +} + +#[turbo_tasks::function] +fn modifier(dir: RcStr, include_subdirs: bool) -> Vc { + Vc::cell( + format!( + "require.context {}/{}", + dir, + if include_subdirs { "**" } else { "*" }, + ) + .into(), + ) +} + +#[turbo_tasks::value_impl] +impl Module for RequireContextAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source + .ident() + .with_modifier(modifier(self.dir.clone(), self.include_subdirs)) + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let map = &*self.map.await?; + + Ok(Vc::cell( + map.iter() + .map(|(_, entry)| Vc::upcast(Vc::::cell(entry.result))) + .collect(), + )) + } +} + +#[turbo_tasks::value_impl] +impl Asset for RequireContextAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + unimplemented!() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for RequireContextAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + let this = self.await?; + Ok(Vc::upcast( + RequireContextChunkItem { + chunking_context, + inner: self, + + origin: this.origin, + map: this.map, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for RequireContextAsset { + #[turbo_tasks::function] + fn get_exports(&self) -> Vc { + EcmascriptExports::Value.cell() + } +} + +#[turbo_tasks::value] +pub struct RequireContextChunkItem { + chunking_context: Vc>, + inner: Vc, + + origin: Vc>, + map: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for RequireContextChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let map = &*self.map.await?; + + let mut context_map = ObjectLit { + span: DUMMY_SP, + props: vec![], + }; + + for (key, entry) in map { + let pm = PatternMapping::resolve_request( + entry.request, + self.origin, + Vc::upcast(self.chunking_context), + entry.result, + Value::new(ResolveType::ChunkItem), + ) + .await?; + + let PatternMapping::Single(pm) = &*pm else { + continue; + }; + + let key_expr = Expr::Lit(Lit::Str(entry.origin_relative.as_str().into())); + + let prop = KeyValueProp { + key: PropName::Str(key.as_str().into()), + value: quote_expr!( + "{ id: () => $id, module: () => $module }", + id: Expr = + pm.create_id(Cow::Borrowed(&key_expr)), + module: Expr = + pm.create_require(Cow::Borrowed(&key_expr)), + ), + }; + + context_map + .props + .push(PropOrSpread::Prop(Box::new(Prop::KeyValue(prop)))); + } + + let expr = quote_expr!( + "__turbopack_export_value__($obj);", + obj: Expr = Expr::Object(context_map), + ); + + let module = ast::Module { + span: DUMMY_SP, + body: vec![ModuleItem::Stmt(Stmt::Expr(ExprStmt { + span: DUMMY_SP, + expr, + }))], + shebang: None, + }; + + let source_map: Arc = Default::default(); + let mut bytes: Vec = vec![]; + let mut emitter = Emitter { + cfg: swc_core::ecma::codegen::Config::default(), + cm: source_map.clone(), + comments: None, + wr: JsWriter::new(source_map, "\n", &mut bytes, None), + }; + + emitter.emit_module(&module)?; + + Ok(EcmascriptChunkItemContent { + inner_code: bytes.into(), + ..Default::default() + } + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl ChunkItem for RequireContextChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.inner.ident() + } + + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.inner.references() + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.inner) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/type_issue.rs b/turbopack/crates/turbopack-ecmascript/src/references/type_issue.rs new file mode 100644 index 0000000000000..5e6d8a8da9900 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/type_issue.rs @@ -0,0 +1,86 @@ +use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::issue::{Issue, IssueSeverity, IssueStage, OptionStyledString, StyledString}; + +use crate::SpecifiedModuleType; + +#[turbo_tasks::value(shared)] +pub struct SpecifiedModuleTypeIssue { + pub path: Vc, + pub specified_type: SpecifiedModuleType, +} + +#[turbo_tasks::value_impl] +impl Issue for SpecifiedModuleTypeIssue { + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.path + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text(match self.specified_type { + SpecifiedModuleType::CommonJs => "Specified module format (CommonJs) is not matching \ + the module format of the source code (EcmaScript \ + Modules)" + .into(), + SpecifiedModuleType::EcmaScript => "Specified module format (EcmaScript Modules) is \ + not matching the module format of the source code \ + (CommonJs)" + .into(), + SpecifiedModuleType::Automatic => "Specified module format is not matching the module \ + format of the source code" + .into(), + }) + .cell() + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some( + StyledString::Text(match self.specified_type { + SpecifiedModuleType::CommonJs => { + "The CommonJs module format was specified in the package.json that is \ + affecting this source file or by using an special extension, but Ecmascript \ + import/export syntax is used in the source code.\nThe module was \ + automatically converted to an EcmaScript module, but that is in conflict with \ + the specified module format. Either change the \"type\" field in the \ + package.json or replace EcmaScript import/export syntax with CommonJs syntas \ + in the source file.\nIn some cases EcmaScript import/export syntax is added \ + by an transform and isn't actually part of the source code. In these cases \ + revisit transformation options to inject the correct syntax." + .into() + } + SpecifiedModuleType::EcmaScript => { + "The EcmaScript module format was specified in the package.json that is \ + affecting this source file or by using an special extension, but it looks \ + like that CommonJs syntax is used in the source code.\nExports made by \ + CommonJs syntax will lead to a runtime error, since the module is in \ + EcmaScript mode. Either change the \"type\" field in the package.json or \ + replace CommonJs syntax with EcmaScript import/export syntax in the source \ + file." + .into() + } + SpecifiedModuleType::Automatic => "The module format specified in the \ + package.json file is not matching the module \ + format of the source code." + .into(), + }) + .cell(), + )) + } + + #[turbo_tasks::function] + fn severity(&self) -> Vc { + match self.specified_type { + SpecifiedModuleType::CommonJs => IssueSeverity::Error.cell(), + SpecifiedModuleType::EcmaScript => IssueSeverity::Warning.cell(), + SpecifiedModuleType::Automatic => IssueSeverity::Hint.cell(), + } + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Analysis.into() + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/typescript.rs b/turbopack/crates/turbopack-ecmascript/src/references/typescript.rs new file mode 100644 index 0000000000000..c7e177b80e366 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/typescript.rs @@ -0,0 +1,146 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + context::AssetContext, + file_source::FileSource, + reference::ModuleReference, + reference_type::{ReferenceType, TypeScriptReferenceSubType}, + resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, +}; +use turbopack_resolve::typescript::type_resolve; + +use crate::typescript::TsConfigModuleAsset; + +#[turbo_tasks::value] +#[derive(Hash, Clone, Debug)] +pub struct TsConfigReference { + pub tsconfig: Vc, + pub origin: Vc>, +} + +#[turbo_tasks::value_impl] +impl TsConfigReference { + #[turbo_tasks::function] + pub fn new(origin: Vc>, tsconfig: Vc) -> Vc { + Self::cell(TsConfigReference { tsconfig, origin }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for TsConfigReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + ModuleResolveResult::module(Vc::upcast(TsConfigModuleAsset::new( + self.origin, + Vc::upcast(FileSource::new(self.tsconfig)), + ))) + .into() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for TsConfigReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("tsconfig {}", self.tsconfig.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct TsReferencePathAssetReference { + pub origin: Vc>, + pub path: RcStr, +} + +#[turbo_tasks::value_impl] +impl TsReferencePathAssetReference { + #[turbo_tasks::function] + pub fn new(origin: Vc>, path: RcStr) -> Vc { + Self::cell(TsReferencePathAssetReference { origin, path }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for TsReferencePathAssetReference { + #[turbo_tasks::function] + async fn resolve_reference(&self) -> Result> { + Ok( + if let Some(path) = &*self + .origin + .origin_path() + .parent() + .try_join(self.path.clone()) + .await? + { + let module = self + .origin + .asset_context() + .process( + Vc::upcast(FileSource::new(*path)), + Value::new(ReferenceType::TypeScript( + TypeScriptReferenceSubType::Undefined, + )), + ) + .module(); + ModuleResolveResult::module(module).cell() + } else { + ModuleResolveResult::unresolveable().cell() + }, + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for TsReferencePathAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("typescript reference path comment {}", self.path,).into(), + )) + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct TsReferenceTypeAssetReference { + pub origin: Vc>, + pub module: RcStr, +} + +#[turbo_tasks::value_impl] +impl TsReferenceTypeAssetReference { + #[turbo_tasks::function] + pub fn new(origin: Vc>, module: RcStr) -> Vc { + Self::cell(TsReferenceTypeAssetReference { origin, module }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for TsReferenceTypeAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + type_resolve( + self.origin, + Request::module( + self.module.clone(), + Value::new(RcStr::default().into()), + Vc::::default(), + Vc::::default(), + ), + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for TsReferenceTypeAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("typescript reference type comment {}", self.module,).into(), + )) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/unreachable.rs b/turbopack/crates/turbopack-ecmascript/src/references/unreachable.rs new file mode 100644 index 0000000000000..77365b0a3c527 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/unreachable.rs @@ -0,0 +1,48 @@ +use anyhow::Result; +use swc_core::quote; +use turbo_tasks::Vc; +use turbopack_core::chunk::ChunkingContext; + +use super::AstPath; +use crate::{ + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, +}; + +#[turbo_tasks::value] +pub struct Unreachable { + path: Vc, +} + +#[turbo_tasks::value_impl] +impl Unreachable { + #[turbo_tasks::function] + pub fn new(path: Vc) -> Vc { + Self::cell(Unreachable { path }) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for Unreachable { + #[turbo_tasks::function] + async fn code_generation( + &self, + _context: Vc>, + ) -> Result> { + let path = self.path.await?; + let visitors = [ + // Unreachable might be used on Stmt or Expr + create_visitor!(exact path, visit_mut_expr(expr: &mut Expr) { + *expr = quote!("(\"TURBOPACK unreachable\", undefined)" as Expr); + }), + create_visitor!(exact path, visit_mut_stmt(stmt: &mut Stmt) { + // TODO(WEB-553) walk ast to find all `var` declarations and keep them + // since they hoist out of the scope + *stmt = quote!("{\"TURBOPACK unreachable\";}" as Stmt); + }), + ] + .into(); + + Ok(CodeGeneration { visitors }.cell()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/references/util.rs b/turbopack/crates/turbopack-ecmascript/src/references/util.rs new file mode 100644 index 0000000000000..a464c8ff099a0 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/references/util.rs @@ -0,0 +1,37 @@ +use anyhow::Result; +use swc_core::{ecma::ast::Expr, quote}; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::resolve::parse::Request; + +/// Creates a IIFE expression that throws a "Cannot find module" error for the +/// given request string +pub fn throw_module_not_found_expr(request: &str) -> Expr { + let message = format!("Cannot find module '{request}'"); + quote!( + "(() => { const e = new Error($message); e.code = 'MODULE_NOT_FOUND'; throw e; })()" + as Expr, + message: Expr = message.into() + ) +} + +/// Creates a IIFE expression that throws a "Cannot find module" error for the +/// given request string +pub fn throw_module_not_found_error_expr(request: &str, message: &str) -> Expr { + let message = format!("Cannot find module '{request}': {message}"); + quote!( + "(() => { const e = new Error($message); e.code = 'MODULE_NOT_FOUND'; throw e; })()" + as Expr, + message: Expr = message.into() + ) +} + +#[turbo_tasks::function] +pub async fn request_to_string(request: Vc) -> Result> { + Ok(Vc::cell( + request + .await? + .request() + // TODO: Handle Request::Dynamic, Request::Alternatives + .unwrap_or_else(|| "unknown".into()), + )) +} diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/chunk_item.rs new file mode 100644 index 0000000000000..b6360a1b6b780 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/chunk_item.rs @@ -0,0 +1,199 @@ +use std::sync::Arc; + +use anyhow::{bail, Result}; +use swc_core::{ + common::{util::take::Take, Globals, GLOBALS}, + ecma::{ + ast::Program, + codegen::{text_writer::JsWriter, Emitter}, + visit::{VisitMutWith, VisitMutWithPath}, + }, +}; +use turbo_tasks::{TryJoinIterExt, Vc}; +use turbo_tasks_fs::rope::RopeBuilder; +use turbopack_core::{ + chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkingContext}, + ident::AssetIdent, + module::Module, + reference::ModuleReferences, +}; + +use super::module::EcmascriptModuleFacadeModule; +use crate::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemOptions, + EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptExports, + }, + code_gen::{CodeGenerateable, CodeGenerateableWithAsyncModuleInfo}, + path_visitor::ApplyVisitors, +}; + +/// The chunk item for [EcmascriptModuleFacadeModule]. +#[turbo_tasks::value(shared)] +pub struct EcmascriptModuleFacadeChunkItem { + pub(crate) module: Vc, + pub(crate) chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for EcmascriptModuleFacadeChunkItem { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("content() should never be called"); + } + + #[turbo_tasks::function] + async fn content_with_async_module_info( + &self, + async_module_info: Option>, + ) -> Result> { + let chunking_context = self.chunking_context; + let exports = self.module.get_exports(); + let EcmascriptExports::EsmExports(exports) = *exports.await? else { + bail!("Expected EsmExports"); + }; + + let externals = *chunking_context + .environment() + .supports_commonjs_externals() + .await?; + + let async_module_options = self + .module + .get_async_module() + .module_options(async_module_info); + + let async_module = async_module_options.await?.clone_value(); + + let mut code = RopeBuilder::default(); + + let references = self.module.references(); + let references_ref = references.await?; + let mut code_gens = Vec::with_capacity(references_ref.len() + 2); + for r in references_ref.iter() { + let r = r.resolve().await?; + if let Some(code_gen) = + Vc::try_resolve_sidecast::>(r).await? + { + code_gens.push(code_gen.code_generation(chunking_context, async_module_info)); + } else if let Some(code_gen) = + Vc::try_resolve_sidecast::>(r).await? + { + code_gens.push(code_gen.code_generation(chunking_context)); + } + } + code_gens.push(self.module.async_module().code_generation( + chunking_context, + async_module_info, + references, + )); + code_gens.push(exports.code_generation(chunking_context)); + let code_gens = code_gens.into_iter().try_join().await?; + let code_gens = code_gens.iter().map(|cg| &**cg).collect::>(); + + let mut visitors = Vec::new(); + let mut root_visitors = Vec::new(); + for code_gen in code_gens { + for (path, visitor) in code_gen.visitors.iter() { + if path.is_empty() { + root_visitors.push(&**visitor); + } else { + visitors.push((path, &**visitor)); + } + } + } + + let mut program = Program::Module(swc_core::ecma::ast::Module::dummy()); + GLOBALS.set(&Globals::new(), || { + if !visitors.is_empty() { + program.visit_mut_with_path( + &mut ApplyVisitors::new(visitors), + &mut Default::default(), + ); + } + for visitor in root_visitors { + program.visit_mut_with(&mut visitor.create()); + } + + program.visit_mut_with(&mut swc_core::ecma::transforms::base::hygiene::hygiene()); + program.visit_mut_with(&mut swc_core::ecma::transforms::base::fixer::fixer(None)); + }); + + let mut bytes: Vec = vec![]; + + let source_map: Arc = Default::default(); + + let mut emitter = Emitter { + cfg: swc_core::ecma::codegen::Config::default(), + cm: source_map.clone(), + comments: None, + wr: JsWriter::new(source_map.clone(), "\n", &mut bytes, None), + }; + + emitter.emit_program(&program)?; + + code.push_bytes(&bytes); + + Ok(EcmascriptChunkItemContent { + inner_code: code.build(), + source_map: None, + options: EcmascriptChunkItemOptions { + strict: true, + externals, + async_module, + ..Default::default() + }, + ..Default::default() + } + .cell()) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } +} + +#[turbo_tasks::value_impl] +impl ChunkItem for EcmascriptModuleFacadeChunkItem { + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + fn asset_ident(&self) -> Result> { + Ok(self.module.ident()) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } + + #[turbo_tasks::function] + async fn is_self_async(&self) -> Result> { + let module = self.module; + let async_module = module.async_module(); + let references = module.references(); + let is_self_async = async_module + .resolve() + .await? + .is_self_async(references.resolve().await?) + .resolve() + .await?; + Ok(is_self_async) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/mod.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/mod.rs new file mode 100644 index 0000000000000..dd8dfeedf3096 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/mod.rs @@ -0,0 +1,2 @@ +pub mod chunk_item; +pub mod module; diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs new file mode 100644 index 0000000000000..ba03e3357eafe --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/facade/module.rs @@ -0,0 +1,301 @@ +use std::collections::BTreeMap; + +use anyhow::{bail, Result}; +use turbo_tasks::Vc; +use turbo_tasks_fs::{glob::Glob, File, FileContent}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkableModule, ChunkingContext, EvaluatableAsset}, + ident::AssetIdent, + module::Module, + reference::ModuleReferences, + resolve::ModulePart, +}; + +use super::chunk_item::EcmascriptModuleFacadeChunkItem; +use crate::{ + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, + references::{ + async_module::{AsyncModule, OptionAsyncModule}, + esm::{EsmExport, EsmExports}, + }, + side_effect_optimization::reference::EcmascriptModulePartReference, + EcmascriptModuleAsset, +}; + +/// A module derived from an original ecmascript module that only contains all +/// the reexports from that module and also reexports the locals from +/// [EcmascriptModuleLocalsModule]. It allows to follow +#[turbo_tasks::value] +pub struct EcmascriptModuleFacadeModule { + pub module: Vc>, + pub ty: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptModuleFacadeModule { + #[turbo_tasks::function] + pub fn new(module: Vc>, ty: Vc) -> Vc { + EcmascriptModuleFacadeModule { module, ty }.cell() + } + + #[turbo_tasks::function] + pub async fn async_module(self: Vc) -> Result> { + let (import_externals, has_top_level_await) = + if let Some(async_module) = *self.await?.module.get_async_module().await? { + ( + async_module.await?.import_externals, + async_module.await?.has_top_level_await, + ) + } else { + (false, false) + }; + Ok(AsyncModule { + has_top_level_await, + import_externals, + } + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl Module for EcmascriptModuleFacadeModule { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let inner = self.module.ident(); + + Ok(inner.with_part(self.ty)) + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let references = match &*self.ty.await? { + ModulePart::Evaluation => { + let Some(module) = + Vc::try_resolve_downcast_type::(self.module).await? + else { + bail!( + "Expected EcmascriptModuleAsset for a EcmascriptModuleFacadeModule with \ + ModulePart::Evaluation" + ); + }; + let result = module.analyze().await?; + let references = result.evaluation_references; + let mut references = references.await?.clone_value(); + references.push(Vc::upcast(EcmascriptModulePartReference::new_part( + self.module, + ModulePart::locals(), + ))); + references + } + ModulePart::Exports => { + let Some(module) = + Vc::try_resolve_downcast_type::(self.module).await? + else { + bail!( + "Expected EcmascriptModuleAsset for a EcmascriptModuleFacadeModule with \ + ModulePart::Evaluation" + ); + }; + let result = module.analyze().await?; + let references = result.reexport_references; + let mut references = references.await?.clone_value(); + references.push(Vc::upcast(EcmascriptModulePartReference::new_part( + self.module, + ModulePart::locals(), + ))); + references + } + ModulePart::Facade => { + vec![ + Vc::upcast(EcmascriptModulePartReference::new_part( + self.module, + ModulePart::evaluation(), + )), + Vc::upcast(EcmascriptModulePartReference::new_part( + self.module, + ModulePart::exports(), + )), + ] + } + ModulePart::RenamedNamespace { .. } => { + vec![Vc::upcast(EcmascriptModulePartReference::new(self.module))] + } + ModulePart::RenamedExport { .. } => { + vec![Vc::upcast(EcmascriptModulePartReference::new(self.module))] + } + _ => { + bail!("Unexpected ModulePart for EcmascriptModuleFacadeModule"); + } + }; + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptModuleFacadeModule { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let f = File::from(""); + + Ok(AssetContent::file(FileContent::Content(f).cell())) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for EcmascriptModuleFacadeModule { + #[turbo_tasks::function] + async fn get_exports(&self) -> Result> { + let mut exports = BTreeMap::new(); + let mut star_exports = Vec::new(); + + match &*self.ty.await? { + ModulePart::Exports => { + let EcmascriptExports::EsmExports(esm_exports) = *self.module.get_exports().await? + else { + bail!( + "EcmascriptModuleFacadeModule must only be used on modules with EsmExports" + ); + }; + let esm_exports = esm_exports.await?; + for (name, export) in &esm_exports.exports { + let name = name.clone(); + match export { + EsmExport::LocalBinding(_, mutable) => { + exports.insert( + name.clone(), + EsmExport::ImportedBinding( + Vc::upcast(EcmascriptModulePartReference::new_part( + self.module, + ModulePart::locals(), + )), + name, + *mutable, + ), + ); + } + EsmExport::ImportedNamespace(reference) => { + exports.insert(name, EsmExport::ImportedNamespace(*reference)); + } + EsmExport::ImportedBinding(reference, imported_name, mutable) => { + exports.insert( + name, + EsmExport::ImportedBinding( + *reference, + imported_name.clone(), + *mutable, + ), + ); + } + EsmExport::Error => { + exports.insert(name, EsmExport::Error); + } + } + } + star_exports.extend(esm_exports.star_exports.iter().copied()); + } + ModulePart::Facade => { + // Reexport everything from the reexports module + // (including default export if any) + let EcmascriptExports::EsmExports(esm_exports) = *self.module.get_exports().await? + else { + bail!( + "EcmascriptModuleFacadeModule must only be used on modules with EsmExports" + ); + }; + let esm_exports = esm_exports.await?; + if esm_exports.exports.keys().any(|name| name == "default") { + exports.insert( + "default".into(), + EsmExport::ImportedBinding( + Vc::upcast(EcmascriptModulePartReference::new_part( + self.module, + ModulePart::exports(), + )), + "default".into(), + false, + ), + ); + } + star_exports.push(Vc::upcast(EcmascriptModulePartReference::new_part( + self.module, + ModulePart::exports(), + ))); + } + ModulePart::RenamedExport { + original_export, + export, + } => { + let original_export = original_export.await?; + exports.insert( + export.await?.clone_value(), + EsmExport::ImportedBinding( + Vc::upcast(EcmascriptModulePartReference::new(self.module)), + original_export.clone_value(), + false, + ), + ); + } + ModulePart::RenamedNamespace { export } => { + exports.insert( + export.await?.clone_value(), + EsmExport::ImportedNamespace(Vc::upcast(EcmascriptModulePartReference::new( + self.module, + ))), + ); + } + ModulePart::Evaluation => { + // no exports + } + _ => bail!("Unexpected ModulePart for EcmascriptModuleFacadeModule"), + } + + let exports = EsmExports { + exports, + star_exports, + } + .cell(); + Ok(EcmascriptExports::EsmExports(exports).cell()) + } + + #[turbo_tasks::function] + async fn is_marked_as_side_effect_free( + &self, + side_effect_free_packages: Vc, + ) -> Result> { + Ok(match *self.ty.await? { + ModulePart::Evaluation | ModulePart::Facade => self + .module + .is_marked_as_side_effect_free(side_effect_free_packages), + ModulePart::Exports + | ModulePart::RenamedExport { .. } + | ModulePart::RenamedNamespace { .. } => Vc::cell(true), + _ => bail!("Unexpected ModulePart for EcmascriptModuleFacadeModule"), + }) + } + + #[turbo_tasks::function] + fn get_async_module(self: Vc) -> Vc { + Vc::cell(Some(self.async_module())) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for EcmascriptModuleFacadeModule { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + EcmascriptModuleFacadeChunkItem { + module: self, + chunking_context, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EvaluatableAsset for EcmascriptModuleFacadeModule {} diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/chunk_item.rs new file mode 100644 index 0000000000000..d547bab77f80d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/chunk_item.rs @@ -0,0 +1,118 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbopack_core::{ + chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkingContext}, + ident::AssetIdent, + module::Module, + reference::ModuleReferences, +}; + +use super::module::EcmascriptModuleLocalsModule; +use crate::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkType, + }, + EcmascriptModuleContent, +}; + +/// The chunk item for [EcmascriptModuleLocalsModule]. +#[turbo_tasks::value(shared)] +pub struct EcmascriptModuleLocalsChunkItem { + pub(super) module: Vc, + pub(super) chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for EcmascriptModuleLocalsChunkItem { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("content() should never be called"); + } + + #[turbo_tasks::function] + async fn content_with_async_module_info( + &self, + async_module_info: Option>, + ) -> Result> { + let module = self.module.await?; + let chunking_context = self.chunking_context; + let exports = self.module.get_exports(); + let original_module = module.module; + let parsed = original_module.parse().resolve().await?; + + let analyze_result = original_module.analyze().await?; + let async_module_options = analyze_result + .async_module + .module_options(async_module_info); + + let module_type_result = *original_module.determine_module_type().await?; + + let content = EcmascriptModuleContent::new( + parsed, + self.module.ident(), + module_type_result.module_type, + chunking_context, + analyze_result.local_references, + analyze_result.code_generation, + analyze_result.async_module, + analyze_result.source_map, + exports, + async_module_info, + ); + + Ok(EcmascriptChunkItemContent::new( + content, + self.chunking_context, + original_module.await?.options, + async_module_options, + )) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } +} + +#[turbo_tasks::value_impl] +impl ChunkItem for EcmascriptModuleLocalsChunkItem { + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + fn asset_ident(&self) -> Result> { + Ok(self.module.ident()) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } + + #[turbo_tasks::function] + async fn is_self_async(&self) -> Result> { + let module = self.module.await?; + let analyze = module.module.analyze().await?; + if let Some(async_module) = *analyze.async_module.await? { + let is_self_async = async_module.is_self_async(analyze.local_references); + Ok(is_self_async) + } else { + Ok(Vc::cell(false)) + } + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/mod.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/mod.rs new file mode 100644 index 0000000000000..dd8dfeedf3096 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/mod.rs @@ -0,0 +1,2 @@ +pub mod chunk_item; +pub mod module; diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs new file mode 100644 index 0000000000000..0cc104ef0b999 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/locals/module.rs @@ -0,0 +1,127 @@ +use std::collections::BTreeMap; + +use anyhow::{bail, Result}; +use turbo_tasks::Vc; +use turbo_tasks_fs::glob::Glob; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkableModule, ChunkingContext}, + ident::AssetIdent, + module::Module, + reference::ModuleReferences, + resolve::ModulePart, +}; + +use super::chunk_item::EcmascriptModuleLocalsChunkItem; +use crate::{ + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, + references::{ + async_module::OptionAsyncModule, + esm::{EsmExport, EsmExports}, + }, + EcmascriptModuleAsset, +}; + +/// A module derived from an original ecmascript module that only contains the +/// local declarations, but excludes all reexports. These reexports are exposed +/// from [EcmascriptModuleFacadeModule] instead. +#[turbo_tasks::value] +pub struct EcmascriptModuleLocalsModule { + pub module: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptModuleLocalsModule { + #[turbo_tasks::function] + pub fn new(module: Vc) -> Vc { + EcmascriptModuleLocalsModule { module }.cell() + } +} + +#[turbo_tasks::value_impl] +impl Module for EcmascriptModuleLocalsModule { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let inner = self.module.ident(); + + Ok(inner.with_part(ModulePart::locals())) + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let result = self.module.analyze().await?; + Ok(result.local_references) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptModuleLocalsModule { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.module.content() + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for EcmascriptModuleLocalsModule { + #[turbo_tasks::function] + async fn get_exports(&self) -> Result> { + let EcmascriptExports::EsmExports(exports) = *self.module.get_exports().await? else { + bail!("EcmascriptModuleLocalsModule must only be used on modules with EsmExports"); + }; + let esm_exports = exports.await?; + let mut exports = BTreeMap::new(); + + for (name, export) in &esm_exports.exports { + match export { + EsmExport::ImportedBinding(..) | EsmExport::ImportedNamespace(..) => { + // not included in locals module + } + EsmExport::LocalBinding(local_name, mutable) => { + exports.insert( + name.clone(), + EsmExport::LocalBinding(local_name.clone(), *mutable), + ); + } + EsmExport::Error => { + exports.insert(name.clone(), EsmExport::Error); + } + } + } + + let exports = EsmExports { + exports, + star_exports: vec![], + } + .cell(); + Ok(EcmascriptExports::EsmExports(exports).cell()) + } + + #[turbo_tasks::function] + fn is_marked_as_side_effect_free(&self, side_effect_free_packages: Vc) -> Vc { + self.module + .is_marked_as_side_effect_free(side_effect_free_packages) + } + + #[turbo_tasks::function] + fn get_async_module(&self) -> Vc { + self.module.get_async_module() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for EcmascriptModuleLocalsModule { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + EcmascriptModuleLocalsChunkItem { + module: self, + chunking_context, + } + .cell(), + )) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/mod.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/mod.rs new file mode 100644 index 0000000000000..3be31d481dc0b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/mod.rs @@ -0,0 +1,3 @@ +pub mod facade; +pub mod locals; +pub(crate) mod reference; diff --git a/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs new file mode 100644 index 0000000000000..f83f8931daa65 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/side_effect_optimization/reference.rs @@ -0,0 +1,146 @@ +use anyhow::{bail, Context, Result}; +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{Expr, Ident}, + quote, +}; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ + ChunkItemExt, ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + ChunkingTypeOption, ModuleId, + }, + reference::ModuleReference, + resolve::{ModulePart, ModuleResolveResult}, +}; + +use super::{ + facade::module::EcmascriptModuleFacadeModule, locals::module::EcmascriptModuleLocalsModule, +}; +use crate::{ + chunk::EcmascriptChunkPlaceable, + code_gen::{CodeGenerateable, CodeGeneration}, + create_visitor, + references::esm::base::{insert_hoisted_stmt, ReferencedAsset}, +}; + +/// A reference to the [EcmascriptModuleLocalsModule] variant of an original +/// module. +#[turbo_tasks::value] +pub struct EcmascriptModulePartReference { + pub module: Vc>, + pub part: Option>, +} + +#[turbo_tasks::value_impl] +impl EcmascriptModulePartReference { + #[turbo_tasks::function] + pub fn new_part( + module: Vc>, + part: Vc, + ) -> Vc { + EcmascriptModulePartReference { + module, + part: Some(part), + } + .cell() + } + + #[turbo_tasks::function] + pub fn new(module: Vc>) -> Vc { + EcmascriptModulePartReference { module, part: None }.cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptModulePartReference { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + self.part + .map_or_else(|| Vc::cell("module".into()), |part| part.to_string()) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for EcmascriptModulePartReference { + #[turbo_tasks::function] + async fn resolve_reference(&self) -> Result> { + let module = if let Some(part) = self.part { + match *part.await? { + ModulePart::Locals => { + let Some(module) = Vc::try_resolve_downcast_type(self.module).await? else { + bail!( + "Expected EcmascriptModuleAsset for a EcmascriptModulePartReference \ + with ModulePart::Locals" + ); + }; + Vc::upcast(EcmascriptModuleLocalsModule::new(module)) + } + ModulePart::Exports + | ModulePart::Evaluation + | ModulePart::Facade + | ModulePart::RenamedExport { .. } + | ModulePart::RenamedNamespace { .. } => { + Vc::upcast(EcmascriptModuleFacadeModule::new(self.module, part)) + } + ModulePart::Export(..) | ModulePart::Internal(..) => { + bail!( + "Unexpected ModulePart {} for EcmascriptModulePartReference", + part.to_string().await? + ); + } + } + } else { + Vc::upcast(self.module) + }; + Ok(ModuleResolveResult::module(module).cell()) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for EcmascriptModulePartReference { + #[turbo_tasks::function] + fn chunking_type(self: Vc) -> Vc { + Vc::cell(Some(ChunkingType::ParallelInheritAsync)) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for EcmascriptModulePartReference { + #[turbo_tasks::function] + async fn code_generation( + self: Vc, + chunking_context: Vc>, + ) -> Result> { + let mut visitors = Vec::new(); + + let referenced_asset = ReferencedAsset::from_resolve_result(self.resolve_reference()); + let referenced_asset = referenced_asset.await?; + let ident = referenced_asset + .get_ident() + .await? + .context("part module reference should have an ident")?; + + let ReferencedAsset::Some(module) = *referenced_asset else { + bail!("part module reference should have an module reference"); + }; + let id = module + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?; + + visitors.push(create_visitor!(visit_mut_program(program: &mut Program) { + let stmt = quote!( + "var $name = __turbopack_import__($id);" as Stmt, + name = Ident::new(ident.clone().into(), DUMMY_SP), + id: Expr = Expr::Lit(match &*id { + ModuleId::String(s) => s.as_str().into(), + ModuleId::Number(n) => (*n as f64).into(), + }) + ); + insert_hoisted_stmt(program, stmt); + })); + + Ok(CodeGeneration { visitors }.into()) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/special_cases.rs b/turbopack/crates/turbopack-ecmascript/src/special_cases.rs new file mode 100644 index 0000000000000..659e07c07585c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/special_cases.rs @@ -0,0 +1,3 @@ +use crate::references::AnalyzeEcmascriptModuleResultBuilder; + +pub(crate) fn special_cases(_path: &str, _references: &mut AnalyzeEcmascriptModuleResultBuilder) {} diff --git a/turbopack/crates/turbopack-ecmascript/src/static_code.rs b/turbopack/crates/turbopack-ecmascript/src/static_code.rs new file mode 100644 index 0000000000000..382446f8dc955 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/static_code.rs @@ -0,0 +1,60 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{Value, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + code_builder::{Code, CodeBuilder}, + context::AssetContext, + file_source::FileSource, + reference_type::ReferenceType, +}; + +use crate::EcmascriptModuleAsset; + +/// Static ECMAScript file code, to be used as part of some code. +/// +/// Useful to transform partial runtime code files, which get concatenated into +/// the final runtime code, while keeping source map information. +#[turbo_tasks::value] +pub struct StaticEcmascriptCode { + asset_context: Vc>, + asset: Vc, +} + +#[turbo_tasks::value_impl] +impl StaticEcmascriptCode { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub async fn new( + asset_context: Vc>, + asset_path: Vc, + ) -> Result> { + let module = asset_context + .process( + Vc::upcast(FileSource::new(asset_path)), + Value::new(ReferenceType::Runtime), + ) + .module(); + let Some(asset) = Vc::try_resolve_downcast_type::(module).await? + else { + bail!("asset is not an Ecmascript module") + }; + Ok(Self::cell(StaticEcmascriptCode { + asset_context, + asset, + })) + } + + /// Computes the contents of the asset and pushes it to + /// the code builder, including the source map if available. + #[turbo_tasks::function] + pub async fn code(self: Vc) -> Result> { + let this = self.await?; + let runtime_base_content = this.asset.module_content_without_analysis().await?; + let mut code = CodeBuilder::default(); + code.push_source( + &runtime_base_content.inner_code, + runtime_base_content.source_map, + ); + Ok(Code::cell(code.build())) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/swc_comments.rs b/turbopack/crates/turbopack-ecmascript/src/swc_comments.rs new file mode 100644 index 0000000000000..c79dae272a006 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/swc_comments.rs @@ -0,0 +1,299 @@ +use std::{cell::RefCell, collections::HashMap, mem::take}; + +use swc_core::{ + base::SwcComments, + common::{ + comments::{Comment, Comments}, + BytePos, + }, +}; + +/// Immutable version of [SwcComments] which doesn't allow mutation. The `take` +/// variants are still implemented, but do not mutate the content. They are used +/// by the SWC Emitter. +pub struct ImmutableComments { + pub leading: HashMap>, + pub trailing: HashMap>, +} + +impl ImmutableComments { + pub fn new(comments: SwcComments) -> Self { + Self { + leading: comments + .leading + .iter_mut() + .filter_map(|mut r| { + let c = take(r.value_mut()); + (!c.is_empty()).then_some((*r.key(), c)) + }) + .collect(), + trailing: comments + .trailing + .iter_mut() + .filter_map(|mut r| { + let c = take(r.value_mut()); + (!c.is_empty()).then_some((*r.key(), c)) + }) + .collect(), + } + } + + pub fn consumable(&self) -> CowComments<'_> { + CowComments::new(self) + } +} + +impl Comments for ImmutableComments { + fn add_leading( + &self, + _pos: swc_core::common::BytePos, + _cmt: swc_core::common::comments::Comment, + ) { + panic!("Comments are immutable after parsing") + } + + fn add_leading_comments( + &self, + _pos: swc_core::common::BytePos, + _comments: Vec, + ) { + panic!("Comments are immutable after parsing") + } + + fn has_leading(&self, pos: swc_core::common::BytePos) -> bool { + self.leading.contains_key(&pos) + } + + fn move_leading(&self, _from: swc_core::common::BytePos, _to: swc_core::common::BytePos) { + panic!("Comments are immutable after parsing") + } + + fn take_leading( + &self, + _pos: swc_core::common::BytePos, + ) -> Option> { + panic!( + "Comments are immutable after parsing (Use ImmutableComments::consumable() to allow \ + taking out values)" + ) + } + + fn get_leading( + &self, + pos: swc_core::common::BytePos, + ) -> Option> { + self.leading.get(&pos).map(|v| v.to_owned()) + } + + fn add_trailing( + &self, + _pos: swc_core::common::BytePos, + _cmt: swc_core::common::comments::Comment, + ) { + panic!("Comments are immutable after parsing") + } + + fn add_trailing_comments( + &self, + _pos: swc_core::common::BytePos, + _comments: Vec, + ) { + panic!("Comments are immutable after parsing") + } + + fn has_trailing(&self, pos: swc_core::common::BytePos) -> bool { + self.trailing.contains_key(&pos) + } + + fn move_trailing(&self, _from: swc_core::common::BytePos, _to: swc_core::common::BytePos) { + panic!("Comments are immutable after parsing") + } + + fn take_trailing( + &self, + _pos: swc_core::common::BytePos, + ) -> Option> { + panic!( + "Comments are immutable after parsing (Use ImmutableComments::consumable() to allow \ + taking out values)" + ) + } + + fn get_trailing( + &self, + pos: swc_core::common::BytePos, + ) -> Option> { + self.trailing.get(&pos).map(|v| v.to_owned()) + } + + fn add_pure_comment(&self, _pos: swc_core::common::BytePos) { + panic!("Comments are immutable after parsing") + } + + fn with_leading(&self, pos: BytePos, f: F) -> Ret + where + Self: Sized, + F: FnOnce(&[Comment]) -> Ret, + { + let cmts = self.get_leading(pos); + + if let Some(cmts) = &cmts { + f(cmts) + } else { + f(&[]) + } + } + + fn with_trailing(&self, pos: BytePos, f: F) -> Ret + where + Self: Sized, + F: FnOnce(&[Comment]) -> Ret, + { + let cmts = self.get_trailing(pos); + + if let Some(cmts) = &cmts { + f(cmts) + } else { + f(&[]) + } + } +} + +pub struct CowComments<'a> { + leading: RefCell>>, + trailing: RefCell>>, +} + +impl<'a> CowComments<'a> { + fn new(comments: &'a ImmutableComments) -> Self { + Self { + leading: RefCell::new( + comments + .leading + .iter() + .map(|(&key, value)| (key, value)) + .collect(), + ), + trailing: RefCell::new( + comments + .trailing + .iter() + .map(|(&key, value)| (key, value)) + .collect(), + ), + } + } +} + +impl<'a> Comments for CowComments<'a> { + fn add_leading( + &self, + _pos: swc_core::common::BytePos, + _cmt: swc_core::common::comments::Comment, + ) { + panic!("Comments are immutable after parsing") + } + + fn add_leading_comments( + &self, + _pos: swc_core::common::BytePos, + _comments: Vec, + ) { + panic!("Comments are immutable after parsing") + } + + fn has_leading(&self, pos: swc_core::common::BytePos) -> bool { + self.leading.borrow().contains_key(&pos) + } + + fn move_leading(&self, _from: swc_core::common::BytePos, _to: swc_core::common::BytePos) { + panic!("Comments are immutable after parsing") + } + + fn take_leading( + &self, + pos: swc_core::common::BytePos, + ) -> Option> { + self.leading.borrow_mut().remove(&pos).map(|v| v.to_owned()) + } + + fn get_leading( + &self, + pos: swc_core::common::BytePos, + ) -> Option> { + self.leading.borrow().get(&pos).map(|&v| v.to_owned()) + } + + fn add_trailing( + &self, + _pos: swc_core::common::BytePos, + _cmt: swc_core::common::comments::Comment, + ) { + panic!("Comments are immutable after parsing") + } + + fn add_trailing_comments( + &self, + _pos: swc_core::common::BytePos, + _comments: Vec, + ) { + panic!("Comments are immutable after parsing") + } + + fn has_trailing(&self, pos: swc_core::common::BytePos) -> bool { + self.trailing.borrow().contains_key(&pos) + } + + fn move_trailing(&self, _from: swc_core::common::BytePos, _to: swc_core::common::BytePos) { + panic!("Comments are immutable after parsing") + } + + fn take_trailing( + &self, + pos: swc_core::common::BytePos, + ) -> Option> { + self.trailing + .borrow_mut() + .remove(&pos) + .map(|v| v.to_owned()) + } + + fn get_trailing( + &self, + pos: swc_core::common::BytePos, + ) -> Option> { + self.trailing.borrow().get(&pos).map(|&v| v.to_owned()) + } + + fn add_pure_comment(&self, _pos: swc_core::common::BytePos) { + panic!("Comments are immutable after parsing") + } + + fn with_leading(&self, pos: BytePos, f: F) -> Ret + where + Self: Sized, + F: FnOnce(&[Comment]) -> Ret, + { + let cmts = self.get_leading(pos); + + if let Some(cmts) = &cmts { + f(cmts) + } else { + f(&[]) + } + } + + fn with_trailing(&self, pos: BytePos, f: F) -> Ret + where + Self: Sized, + F: FnOnce(&[Comment]) -> Ret, + { + let cmts = self.get_trailing(pos); + + if let Some(cmts) = &cmts { + f(cmts) + } else { + f(&[]) + } + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/text/mod.rs b/turbopack/crates/turbopack-ecmascript/src/text/mod.rs new file mode 100644 index 0000000000000..d5d44f0be16e1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/text/mod.rs @@ -0,0 +1,56 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::FileContent; +use turbopack_core::{ + asset::{Asset, AssetContent}, + ident::AssetIdent, + source::Source, +}; + +use crate::utils::StringifyJs; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("text content".into()) +} + +/// A source asset that exports the string content of an asset as the default +/// export of a JS module. +#[turbo_tasks::value] +pub struct TextContentFileSource { + pub source: Vc>, +} + +#[turbo_tasks::value_impl] +impl TextContentFileSource { + #[turbo_tasks::function] + pub fn new(source: Vc>) -> Vc { + TextContentFileSource { source }.cell() + } +} + +#[turbo_tasks::value_impl] +impl Source for TextContentFileSource { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source + .ident() + .with_modifier(modifier()) + .rename_as("*.mjs".into()) + } +} + +#[turbo_tasks::value_impl] +impl Asset for TextContentFileSource { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let source = self.source.content().file_content(); + let FileContent::Content(content) = &*source.await? else { + return Ok(AssetContent::file(FileContent::NotFound.cell())); + }; + let text = content.content().to_str()?; + let code: RcStr = format!("export default {};", StringifyJs(&text)).into(); + let content = FileContent::Content(code.into()).cell(); + Ok(AssetContent::file(content)) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/transform/mod.rs b/turbopack/crates/turbopack-ecmascript/src/transform/mod.rs new file mode 100644 index 0000000000000..6bc59e13b12e4 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/transform/mod.rs @@ -0,0 +1,352 @@ +use std::{fmt::Debug, hash::Hash, sync::Arc}; + +use anyhow::Result; +use async_trait::async_trait; +use swc_core::{ + atoms::JsWord, + base::SwcComments, + common::{chain, collections::AHashMap, comments::Comments, util::take::Take, Mark, SourceMap}, + ecma::{ + ast::{Module, ModuleItem, Program, Script}, + preset_env::{self, Targets}, + transforms::{ + base::{feature::FeatureFlag, helpers::inject_helpers, Assumptions}, + optimization::inline_globals2, + react::react, + }, + visit::{FoldWith, VisitMutWith}, + }, + quote, +}; +use turbo_tasks::{RcStr, ValueDefault, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + environment::Environment, + issue::{Issue, IssueSeverity, IssueStage, StyledString}, +}; + +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Debug, Clone, Hash)] +pub enum EcmascriptInputTransform { + CommonJs, + Plugin(Vc), + PresetEnv(Vc), + React { + #[serde(default)] + development: bool, + #[serde(default)] + refresh: bool, + // swc.jsc.transform.react.importSource + import_source: Vc>, + // swc.jsc.transform.react.runtime, + runtime: Vc>, + }, + GlobalTypeofs { + window_value: String, + }, + // These options are subset of swc_core::ecma::transforms::typescript::Config, but + // it doesn't derive `Copy` so repeating values in here + TypeScript { + #[serde(default)] + use_define_for_class_fields: bool, + }, + Decorators { + #[serde(default)] + is_legacy: bool, + #[serde(default)] + is_ecma: bool, + #[serde(default)] + emit_decorators_metadata: bool, + #[serde(default)] + use_define_for_class_fields: bool, + }, +} + +/// The CustomTransformer trait allows you to implement your own custom SWC +/// transformer to run over all ECMAScript files imported in the graph. +#[async_trait] +pub trait CustomTransformer: Debug { + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()>; +} + +/// A wrapper around a TransformPlugin instance, allowing it to operate with +/// the turbo_task caching requirements. +#[turbo_tasks::value( + transparent, + serialization = "none", + eq = "manual", + into = "new", + cell = "new" +)] +#[derive(Debug)] +pub struct TransformPlugin(#[turbo_tasks(trace_ignore)] Box); + +#[turbo_tasks::value(transparent)] +pub struct OptionTransformPlugin(Option>); + +#[turbo_tasks::value_impl] +impl ValueDefault for OptionTransformPlugin { + #[turbo_tasks::function] + fn value_default() -> Vc { + Vc::cell(None) + } +} + +#[async_trait] +impl CustomTransformer for TransformPlugin { + async fn transform(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + self.0.transform(program, ctx).await + } +} + +#[turbo_tasks::value(transparent, serialization = "auto_for_input")] +#[derive(Debug, Clone, Hash)] +pub struct EcmascriptInputTransforms(Vec); + +#[turbo_tasks::value_impl] +impl EcmascriptInputTransforms { + #[turbo_tasks::function] + pub fn empty() -> Vc { + Vc::cell(Vec::new()) + } + + #[turbo_tasks::function] + pub async fn extend(self: Vc, other: Vc) -> Result> { + let mut transforms = self.await?.clone_value(); + transforms.extend(other.await?.clone_value()); + Ok(Vc::cell(transforms)) + } +} + +pub struct TransformContext<'a> { + pub comments: &'a SwcComments, + pub top_level_mark: Mark, + pub unresolved_mark: Mark, + pub source_map: &'a Arc, + pub file_path_str: &'a str, + pub file_name_str: &'a str, + pub file_name_hash: u128, + pub file_path: Vc, +} + +impl EcmascriptInputTransform { + pub async fn apply(&self, program: &mut Program, ctx: &TransformContext<'_>) -> Result<()> { + let &TransformContext { + comments, + source_map, + top_level_mark, + unresolved_mark, + .. + } = ctx; + match self { + EcmascriptInputTransform::GlobalTypeofs { window_value } => { + let mut typeofs: AHashMap = Default::default(); + typeofs.insert("window".into(), JsWord::from(&**window_value)); + + program.visit_mut_with(&mut inline_globals2( + Default::default(), + Default::default(), + Default::default(), + Arc::new(typeofs), + )); + } + EcmascriptInputTransform::React { + development, + refresh, + import_source, + runtime, + } => { + use swc_core::ecma::transforms::react::{Options, Runtime}; + let runtime = if let Some(runtime) = &*runtime.await? { + match runtime.as_str() { + "classic" => Runtime::Classic, + "automatic" => Runtime::Automatic, + _ => { + return Err(anyhow::anyhow!( + "Invalid value for swc.jsc.transform.react.runtime: {}", + runtime + )) + } + } + } else { + Runtime::Automatic + }; + + let config = Options { + runtime: Some(runtime), + development: Some(*development), + import_source: import_source.await?.as_deref().map(ToString::to_string), + refresh: if *refresh { + Some(swc_core::ecma::transforms::react::RefreshOptions { + refresh_reg: "__turbopack_refresh__.register".to_string(), + refresh_sig: "__turbopack_refresh__.signature".to_string(), + ..Default::default() + }) + } else { + None + }, + ..Default::default() + }; + + // Explicit type annotation to ensure that we don't duplicate transforms in the + // final binary + program.visit_mut_with(&mut react::<&dyn Comments>( + source_map.clone(), + Some(&comments), + config, + top_level_mark, + unresolved_mark, + )); + + if *refresh { + let stmt = quote!( + // AMP / No-JS mode does not inject these helpers + "\nif (typeof globalThis.$RefreshHelpers$ === 'object' && \ + globalThis.$RefreshHelpers !== null) { \ + __turbopack_refresh__.registerExports(module, \ + globalThis.$RefreshHelpers$); }\n" as Stmt + ); + + match program { + Program::Module(module) => { + module.body.push(ModuleItem::Stmt(stmt)); + } + Program::Script(script) => { + script.body.push(stmt); + } + } + } + } + EcmascriptInputTransform::CommonJs => { + // Explicit type annotation to ensure that we don't duplicate transforms in the + // final binary + program.visit_mut_with(&mut swc_core::ecma::transforms::module::common_js::< + &dyn Comments, + >( + unresolved_mark, + swc_core::ecma::transforms::module::util::Config { + allow_top_level_this: true, + import_interop: Some( + swc_core::ecma::transforms::module::util::ImportInterop::Swc, + ), + ..Default::default() + }, + swc_core::ecma::transforms::base::feature::FeatureFlag::all(), + Some(&comments), + )); + } + EcmascriptInputTransform::PresetEnv(env) => { + let versions = env.runtime_versions().await?; + let config = swc_core::ecma::preset_env::Config { + targets: Some(Targets::Versions(*versions)), + mode: None, // Don't insert core-js polyfills + ..Default::default() + }; + + let module_program = std::mem::replace(program, Program::Module(Module::dummy())); + + let module_program = if let Program::Script(Script { + span, + mut body, + shebang, + }) = module_program + { + Program::Module(Module { + span, + body: body.drain(..).map(ModuleItem::Stmt).collect(), + shebang, + }) + } else { + module_program + }; + + // Explicit type annotation to ensure that we don't duplicate transforms in the + // final binary + *program = module_program.fold_with(&mut chain!( + preset_env::preset_env::<&'_ dyn Comments>( + top_level_mark, + Some(&comments), + config, + Assumptions::default(), + &mut FeatureFlag::empty(), + ), + inject_helpers(unresolved_mark), + )); + } + EcmascriptInputTransform::TypeScript { + // TODO(WEB-1213) + use_define_for_class_fields: _use_define_for_class_fields, + } => { + use swc_core::ecma::transforms::typescript::typescript; + let config = Default::default(); + program.visit_mut_with(&mut typescript(config, unresolved_mark)); + } + EcmascriptInputTransform::Decorators { + is_legacy, + is_ecma: _, + emit_decorators_metadata, + // TODO(WEB-1213) + use_define_for_class_fields: _use_define_for_class_fields, + } => { + use swc_core::ecma::transforms::proposal::decorators::{decorators, Config}; + let config = Config { + legacy: *is_legacy, + emit_metadata: *emit_decorators_metadata, + ..Default::default() + }; + + let p = std::mem::replace(program, Program::Module(Module::dummy())); + *program = p.fold_with(&mut chain!( + decorators(config), + inject_helpers(unresolved_mark) + )); + } + EcmascriptInputTransform::Plugin(transform) => { + transform.await?.transform(program, ctx).await? + } + } + Ok(()) + } +} + +pub fn remove_shebang(program: &mut Program) { + match program { + Program::Module(m) => { + m.shebang = None; + } + Program::Script(s) => { + s.shebang = None; + } + } +} + +#[turbo_tasks::value(shared)] +pub struct UnsupportedServerActionIssue { + pub file_path: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for UnsupportedServerActionIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Error.into() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text( + "Server actions (\"use server\") are not yet supported in Turbopack".into(), + ) + .cell() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.file_path + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Transform.cell() + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs new file mode 100644 index 0000000000000..a3dca90851ee6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/asset.rs @@ -0,0 +1,226 @@ +use anyhow::{Context, Result}; +use turbo_tasks::Vc; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkableModule, ChunkingContext, EvaluatableAsset}, + ident::AssetIdent, + module::Module, + reference::{ModuleReferences, SingleModuleReference}, + resolve::ModulePart, +}; + +use super::{ + chunk_item::EcmascriptModulePartChunkItem, get_part_id, split_module, Key, SplitResult, +}; +use crate::{ + chunk::{EcmascriptChunkPlaceable, EcmascriptExports}, + references::analyse_ecmascript_module, + AnalyzeEcmascriptModuleResult, EcmascriptModuleAsset, +}; + +/// A reference to part of an ES module. +/// +/// This type is used for an advanced tree shkaing. +#[turbo_tasks::value] +pub struct EcmascriptModulePartAsset { + pub full_module: Vc, + pub(crate) part: Vc, + pub(crate) import_externals: bool, +} + +#[turbo_tasks::value_impl] +impl EcmascriptModulePartAsset { + /// Create a new instance of [Vc], whcih consists + /// of a pointer to the full module and the [ModulePart] pointing the part + /// of the module. + #[turbo_tasks::function] + pub fn new( + module: Vc, + part: Vc, + import_externals: bool, + ) -> Vc { + EcmascriptModulePartAsset { + full_module: module, + part, + import_externals, + } + .cell() + } + + #[turbo_tasks::function] + pub async fn is_async_module(self: Vc) -> Result> { + let this = self.await?; + let result = this.full_module.analyze(); + + if let Some(async_module) = *result.await?.async_module.await? { + Ok(async_module.is_self_async(self.references())) + } else { + Ok(Vc::cell(false)) + } + } +} + +#[turbo_tasks::value_impl] +impl Module for EcmascriptModulePartAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let inner = self.full_module.ident(); + let result = split_module(self.full_module); + + match &*result.await? { + SplitResult::Ok { .. } => Ok(inner.with_part(self.part)), + SplitResult::Failed { .. } => Ok(inner), + } + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let split_data = split_module(self.full_module).await?; + + let analyze = analyze(self.full_module, self.part).await?; + + let (deps, entrypoints) = match &*split_data { + SplitResult::Ok { + deps, entrypoints, .. + } => (deps, entrypoints), + SplitResult::Failed { .. } => return Ok(analyze.references), + }; + + // Facade depends on evaluation and re-exports + if matches!(&*self.part.await?, ModulePart::Facade) { + let mut references = vec![]; + + let reference = Vc::upcast(SingleModuleReference::new( + Vc::upcast(EcmascriptModulePartAsset::new( + self.full_module, + ModulePart::evaluation(), + self.import_externals, + )), + Vc::cell("ecmascript module evaluation".into()), + )); + + references.push(reference); + + let reference = Vc::upcast(SingleModuleReference::new( + Vc::upcast(EcmascriptModulePartAsset::new( + self.full_module, + ModulePart::exports(), + self.import_externals, + )), + Vc::cell("ecmascript reexports".into()), + )); + + references.push(reference); + + references.extend(analyze.references.await?.iter().cloned()); + + return Ok(Vc::cell(references)); + } + + // ModulePart::Exports contains all reexports and a reexport of the Locals + if matches!(&*self.part.await?, ModulePart::Exports) { + let mut references = vec![]; + + for key in entrypoints.keys() { + if let Key::Export(e) = key { + let reference = Vc::upcast(SingleModuleReference::new( + Vc::upcast(EcmascriptModulePartAsset::new( + self.full_module, + ModulePart::export(e.clone()), + self.import_externals, + )), + Vc::cell(format!("ecmascript export '{e}'").into()), + )); + + references.push(reference); + } + } + + references.extend(analyze.references.await?.iter().cloned()); + + return Ok(Vc::cell(references)); + } + let deps = { + let part_id = get_part_id(&split_data, self.part) + .await + .with_context(|| format!("part {:?} is not found in the module", self.part))?; + + match deps.get(&part_id) { + Some(v) => &**v, + None => &[], + } + }; + + let mut assets = deps + .iter() + .map(|&part_id| { + Ok(Vc::upcast(SingleModuleReference::new( + Vc::upcast(EcmascriptModulePartAsset::new( + self.full_module, + ModulePart::internal(part_id), + self.import_externals, + )), + Vc::cell("ecmascript module part".into()), + ))) + }) + .collect::>>()?; + + assets.extend(analyze.references.await?.iter().cloned()); + + Ok(Vc::cell(assets)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptModulePartAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + todo!() + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for EcmascriptModulePartAsset { + #[turbo_tasks::function] + async fn get_exports(self: Vc) -> Result> { + Ok(self.analyze().await?.exports) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for EcmascriptModulePartAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + EcmascriptModulePartChunkItem { + module: self, + chunking_context, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptModulePartAsset { + #[turbo_tasks::function] + pub(super) async fn analyze(self: Vc) -> Result> { + let this = self.await?; + + Ok(analyze(this.full_module, this.part)) + } +} + +#[turbo_tasks::function] +async fn analyze( + module: Vc, + part: Vc, +) -> Result> { + Ok(analyse_ecmascript_module(module, Some(part))) +} + +#[turbo_tasks::value_impl] +impl EvaluatableAsset for EcmascriptModulePartAsset {} diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs new file mode 100644 index 0000000000000..61095d9c1ba6e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/chunk_item.rs @@ -0,0 +1,109 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbopack_core::{ + chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkingContext}, + ident::AssetIdent, + module::Module, + reference::ModuleReferences, +}; + +use super::{asset::EcmascriptModulePartAsset, part_of_module, split_module}; +use crate::{ + chunk::{EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkType}, + EcmascriptModuleContent, +}; + +/// This is an implementation of [ChunkItem] for +/// [Vc]. +/// +/// This is a pointer to a part of an ES module. +#[turbo_tasks::value(shared)] +pub struct EcmascriptModulePartChunkItem { + pub(super) module: Vc, + pub(super) chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for EcmascriptModulePartChunkItem { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("content() should never be called"); + } + + #[turbo_tasks::function] + async fn content_with_async_module_info( + self: Vc, + async_module_info: Option>, + ) -> Result> { + let this = self.await?; + let module = this.module.await?; + + let split_data = split_module(module.full_module); + let parsed = part_of_module(split_data, module.part); + + let analyze = this.module.analyze().await?; + let async_module_options = analyze.async_module.module_options(async_module_info); + + let module_type_result = *module.full_module.determine_module_type().await?; + + let content = EcmascriptModuleContent::new( + parsed, + module.full_module.ident(), + module_type_result.module_type, + this.chunking_context, + analyze.references, + analyze.code_generation, + analyze.async_module, + analyze.source_map, + analyze.exports, + async_module_info, + ); + + Ok(EcmascriptChunkItemContent::new( + content, + this.chunking_context, + module.full_module.await?.options, + async_module_options, + )) + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } +} + +#[turbo_tasks::value_impl] +impl ChunkItem for EcmascriptModulePartChunkItem { + #[turbo_tasks::function] + async fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + async fn asset_ident(&self) -> Result> { + Ok(self.module.ident()) + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } + + #[turbo_tasks::function] + fn is_self_async(&self) -> Vc { + self.module.is_async_module() + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs new file mode 100644 index 0000000000000..12d837a35a4f6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/graph.rs @@ -0,0 +1,1188 @@ +use std::{ + fmt, + hash::{BuildHasherDefault, Hash}, +}; + +use indexmap::IndexSet; +use petgraph::{ + algo::{condensation, has_path_connecting}, + graphmap::GraphMap, + prelude::DiGraphMap, +}; +use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +use swc_core::{ + common::{util::take::Take, SyntaxContext, DUMMY_SP}, + ecma::{ + ast::{ + op, ClassDecl, Decl, DefaultDecl, ExportAll, ExportDecl, ExportNamedSpecifier, + ExportSpecifier, Expr, ExprStmt, FnDecl, Id, Ident, ImportDecl, ImportNamedSpecifier, + ImportSpecifier, ImportStarAsSpecifier, KeyValueProp, Lit, Module, ModuleDecl, + ModuleExportName, ModuleItem, NamedExport, ObjectLit, Prop, PropName, PropOrSpread, + Stmt, VarDecl, VarDeclKind, VarDeclarator, + }, + atoms::JsWord, + utils::{find_pat_ids, private_ident, quote_ident}, + }, +}; +use turbo_tasks::RcStr; + +use super::{ + util::{ + collect_top_level_decls, ids_captured_by, ids_used_by, ids_used_by_ignoring_nested, Vars, + }, + Key, TURBOPACK_PART_IMPORT_SOURCE, +}; +use crate::magic_identifier; + +/// The id of an item +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub(crate) enum ItemId { + Group(ItemIdGroupKind), + Item { index: usize, kind: ItemIdItemKind }, +} + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub(crate) enum ItemIdGroupKind { + ModuleEvaluation, + /// `(local, export_name)`` + Export(Id, JsWord), +} + +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub(crate) enum ItemIdItemKind { + Normal, + + ImportOfModule, + /// Imports are split as multiple items. + ImportBinding(u32), + VarDeclarator(u32), +} + +impl fmt::Debug for ItemId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + ItemId::Group(kind) => { + write!(f, "ItemId({:?})", kind) + } + ItemId::Item { index, kind } => { + write!(f, "ItemId({}, {:?})", index, kind) + } + } + } +} + +type FxBuildHasher = BuildHasherDefault; + +/// Data about a module item +pub(crate) struct ItemData { + /// Is the module item hoisted? + pub is_hoisted: bool, + + /// TOOD(PACK-3166): We can use this field to optimize tree shaking + #[allow(unused)] + pub pure: bool, + + /// Variables declared or bound by this module item + pub var_decls: IndexSet, + + /// Variables read by this module item during evaluation + pub read_vars: IndexSet, + + /// Variables read by this module item eventually + /// + /// - e.g. variables read in the body of function declarations are + /// considered as eventually read + /// - This is only used when reads are not trigger directly by this module + /// item, but require a side effect to be triggered. We don’t know when + /// this is executed. + /// - Note: This doesn’t mean they are only read “after” initial evaluation. + /// They might also be read “during” initial evaluation on any module item + /// with SIDE_EFFECTS. This kind of interaction is handled by the module + /// item with SIDE_EFFECTS. + pub eventual_read_vars: IndexSet, + + /// Side effects that are triggered on local variables during evaluation + pub write_vars: IndexSet, + + /// Side effects that are triggered on local variables eventually + pub eventual_write_vars: IndexSet, + + /// Any other unknown side effects that are trigger during evaluation + pub side_effects: bool, + + pub content: ModuleItem, + + pub export: Option, +} + +impl fmt::Debug for ItemData { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("ItemData") + .field("is_hoisted", &self.is_hoisted) + .field("pure", &self.pure) + .field("var_decls", &self.var_decls) + .field("read_vars", &self.read_vars) + .field("eventual_read_vars", &self.eventual_read_vars) + .field("write_vars", &self.write_vars) + .field("eventual_write_vars", &self.eventual_write_vars) + .field("side_effects", &self.side_effects) + .field("export", &self.export) + .finish() + } +} + +impl Default for ItemData { + fn default() -> Self { + Self { + is_hoisted: Default::default(), + var_decls: Default::default(), + read_vars: Default::default(), + eventual_read_vars: Default::default(), + write_vars: Default::default(), + eventual_write_vars: Default::default(), + side_effects: Default::default(), + content: ModuleItem::dummy(), + pure: Default::default(), + export: Default::default(), + } + } +} + +#[derive(Debug, Clone)] +pub struct InternedGraph +where + T: Eq + Hash + Clone, +{ + pub(super) idx_graph: DiGraphMap, + pub(super) graph_ix: IndexSet>, +} + +#[derive(Debug, Clone, Copy)] +pub enum Dependency { + Strong, + Weak, +} + +impl Default for InternedGraph +where + T: Eq + Hash + Clone, +{ + fn default() -> Self { + Self { + idx_graph: Default::default(), + graph_ix: Default::default(), + } + } +} + +impl InternedGraph +where + T: Eq + Hash + Clone, +{ + pub(super) fn node(&mut self, id: &T) -> u32 { + self.graph_ix.get_index_of(id).unwrap_or_else(|| { + let ix = self.graph_ix.len(); + self.graph_ix.insert_full(id.clone()); + ix + }) as _ + } + + /// Panics if `id` is not found. + pub(super) fn get_node(&self, id: &T) -> u32 { + self.graph_ix.get_index_of(id).unwrap() as _ + } +} + +#[derive(Debug, Clone, Default)] +pub struct DepGraph { + pub(super) g: InternedGraph, +} + +#[derive(Debug, Clone, Copy)] +pub(super) enum Mode { + #[allow(dead_code)] + Development, + Production, +} + +pub(super) struct SplitModuleResult { + pub entrypoints: FxHashMap, + + /// Dependency between parts. + pub part_deps: FxHashMap>, + pub modules: Vec, + + pub star_reexports: Vec, +} + +impl DepGraph { + /// Weak imports are imports only if it is referenced strongly. But this + /// is production-only, and weak dependencies are treated as strong + /// dependencies in development mode. + pub(super) fn handle_weak(&mut self, mode: Mode) { + if !matches!(mode, Mode::Production) { + return; + } + + for start in self.g.graph_ix.iter() { + let start = self.g.get_node(start); + for end in self.g.graph_ix.iter() { + let end = self.g.get_node(end); + + if let Some(Dependency::Weak) = self.g.idx_graph.edge_weight(start, end) { + self.g.idx_graph.remove_edge(start, end); + } + } + } + } + + /// Split modules into parts. Additionally, this function adds imports to + /// _connect_ variables. + /// + /// _connect_ here means if a variable is declared in a different part than + /// a usage side, `import` and `export` will be added. + /// + /// Note: ESM imports are immutable, but we do not handle it. + pub(super) fn split_module(&self, data: &FxHashMap) -> SplitModuleResult { + let groups = self.finalize(); + let mut exports = FxHashMap::default(); + let mut part_deps = FxHashMap::<_, Vec<_>>::default(); + + let star_reexports: Vec<_> = data + .values() + .filter_map(|v| v.content.as_module_decl()?.as_export_all()) + .cloned() + .collect(); + let mut modules = vec![]; + let mut exports_module = Module::dummy(); + + if groups.graph_ix.is_empty() { + // If there's no dependency, all nodes are in the module evaluaiotn group. + modules.push(Module { + span: DUMMY_SP, + body: data.values().map(|v| v.content.clone()).collect(), + shebang: None, + }); + exports.insert(Key::ModuleEvaluation, 0); + } + + let mut declarator = FxHashMap::default(); + + for (ix, group) in groups.graph_ix.iter().enumerate() { + for id in group { + let item = data.get(id).unwrap(); + + for var in item.var_decls.iter() { + declarator.entry(var.clone()).or_insert_with(|| ix as u32); + } + } + } + + for (ix, group) in groups.graph_ix.iter().enumerate() { + let mut chunk = Module { + span: DUMMY_SP, + body: vec![], + shebang: None, + }; + + let mut required_vars = group + .iter() + .flat_map(|id| { + let data = data.get(id).unwrap(); + + data.read_vars + .iter() + .chain(data.write_vars.iter()) + .chain(data.eventual_read_vars.iter()) + .chain(data.eventual_write_vars.iter()) + }) + .collect::>(); + + for item in group { + if let ItemId::Group(ItemIdGroupKind::Export(id, _)) = item { + required_vars.insert(id); + } + } + + for id in group { + let data = data.get(id).unwrap(); + + for var in data.var_decls.iter() { + required_vars.remove(var); + } + } + + for item in group { + match item { + ItemId::Group(ItemIdGroupKind::Export(..)) => { + if let Some(export) = &data[item].export { + exports.insert(Key::Export(export.as_str().into()), ix as u32); + + let s = ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: ModuleExportName::Ident(Ident::new(export.clone(), DUMMY_SP)), + exported: None, + is_type_only: false, + }); + exports_module.body.push(ModuleItem::ModuleDecl( + ModuleDecl::ExportNamed(NamedExport { + span: DUMMY_SP, + specifiers: vec![s], + src: Some(Box::new(TURBOPACK_PART_IMPORT_SOURCE.into())), + type_only: false, + with: Some(Box::new(create_turbopack_part_id_assert( + PartId::Export(export.to_string().into()), + ))), + }), + )); + } + } + ItemId::Group(ItemIdGroupKind::ModuleEvaluation) => { + exports.insert(Key::ModuleEvaluation, ix as u32); + } + + _ => {} + } + } + + // Depend on direct dependencies so that they are executed before this module. + for dep in groups + .idx_graph + .neighbors_directed(ix as u32, petgraph::Direction::Outgoing) + { + chunk + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + span: DUMMY_SP, + specifiers: vec![], + src: Box::new(TURBOPACK_PART_IMPORT_SOURCE.into()), + type_only: false, + with: Some(Box::new(create_turbopack_part_id_assert(PartId::Internal( + dep, + )))), + phase: Default::default(), + }))); + } + + // Import variables + for var in required_vars { + let Some(&dep) = declarator.get(var) else { + continue; + }; + + if dep == ix as u32 { + continue; + } + + let specifiers = vec![ImportSpecifier::Named(ImportNamedSpecifier { + span: DUMMY_SP, + local: var.clone().into(), + imported: None, + is_type_only: false, + })]; + + part_deps.entry(ix as u32).or_default().push(dep); + + chunk + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + span: DUMMY_SP, + specifiers, + src: Box::new(TURBOPACK_PART_IMPORT_SOURCE.into()), + type_only: false, + with: Some(Box::new(create_turbopack_part_id_assert(PartId::Internal( + dep, + )))), + phase: Default::default(), + }))); + } + + for g in group { + chunk.body.push(data[g].content.clone()); + } + + for g in group { + let data = data.get(g).unwrap(); + + // Emit `export { foo }` + for var in data.var_decls.iter() { + let assertion_prop = + PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: quote_ident!("__turbopack_var__").into(), + value: Box::new(true.into()), + }))); + + chunk + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( + NamedExport { + span: DUMMY_SP, + specifiers: vec![ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: ModuleExportName::Ident(var.clone().into()), + exported: None, + is_type_only: false, + })], + src: if cfg!(test) { + Some(Box::new("__TURBOPACK_VAR__".into())) + } else { + None + }, + type_only: false, + with: Some(Box::new(ObjectLit { + span: DUMMY_SP, + props: vec![assertion_prop], + })), + }, + ))); + } + } + + modules.push(chunk); + } + + exports.insert(Key::Exports, modules.len() as u32); + + for star in &star_reexports { + exports_module + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::ExportAll(star.clone()))); + } + + modules.push(exports_module); + + SplitModuleResult { + entrypoints: exports, + part_deps, + modules, + star_reexports, + } + } + + /// Merges a dependency group between [ModuleItem]s into a dependency graph + /// of [Module]s. + /// + /// Note that [ModuleItem] and [Module] are represented as [ItemId] for + /// performance. + pub(super) fn finalize(&self) -> InternedGraph> { + let graph = self.g.idx_graph.clone().into_graph::(); + + let condensed = condensation(graph, false); + + let mut new_graph = InternedGraph::default(); + let mut done = FxHashSet::default(); + + let mapped = condensed.map( + |_, node| { + let mut item_ids = node + .iter() + .map(|&ix| { + done.insert(ix); + + self.g.graph_ix[ix as usize].clone() + }) + .collect::>(); + item_ids.sort(); + + new_graph.node(&item_ids) + }, + |_, edge| *edge, + ); + + let map = GraphMap::from_graph(mapped); + + // Insert nodes without any edges + + for node in self.g.graph_ix.iter() { + let ix = self.g.get_node(node); + if !done.contains(&ix) { + let item_ids = vec![node.clone()]; + new_graph.node(&item_ids); + } + } + + InternedGraph { + idx_graph: map, + graph_ix: new_graph.graph_ix, + } + } + + /// Fills information per module items + pub(super) fn init( + &mut self, + module: &Module, + unresolved_ctxt: SyntaxContext, + top_level_ctxt: SyntaxContext, + ) -> (Vec, FxHashMap) { + let top_level_vars = collect_top_level_decls(module); + let mut exports = vec![]; + let mut items = FxHashMap::default(); + let mut ids = vec![]; + + for (index, item) in module.body.iter().enumerate() { + // Fill exports + if let ModuleItem::ModuleDecl(item) = item { + match item { + ModuleDecl::ExportDecl(item) => match &item.decl { + Decl::Fn(FnDecl { ident, .. }) | Decl::Class(ClassDecl { ident, .. }) => { + exports.push((ident.to_id(), None)); + } + Decl::Var(v) => { + for decl in &v.decls { + let ids: Vec = find_pat_ids(&decl.name); + for id in ids { + exports.push((id, None)); + } + } + } + _ => {} + }, + ModuleDecl::ExportNamed(item) => { + if let Some(src) = &item.src { + // One item for the import for re-export + let id = ItemId::Item { + index, + kind: ItemIdItemKind::ImportOfModule, + }; + ids.push(id.clone()); + items.insert( + id, + ItemData { + is_hoisted: true, + side_effects: true, + content: ModuleItem::ModuleDecl(ModuleDecl::Import( + ImportDecl { + specifiers: Default::default(), + src: src.clone(), + ..ImportDecl::dummy() + }, + )), + ..Default::default() + }, + ); + } + + for (si, s) in item.specifiers.iter().enumerate() { + let (orig, mut local, exported) = match s { + ExportSpecifier::Named(s) => ( + Some(s.orig.clone()), + match &s.orig { + ModuleExportName::Ident(i) => i.clone(), + ModuleExportName::Str(..) => quote_ident!("_tmp"), + }, + Some(s.exported.clone().unwrap_or_else(|| s.orig.clone())), + ), + ExportSpecifier::Default(s) => ( + Some(ModuleExportName::Ident(Ident::new( + "default".into(), + DUMMY_SP, + ))), + quote_ident!("default"), + Some(ModuleExportName::Ident(s.exported.clone())), + ), + ExportSpecifier::Namespace(s) => ( + None, + match &s.name { + ModuleExportName::Ident(i) => i.clone(), + ModuleExportName::Str(..) => quote_ident!("_tmp"), + }, + Some(s.name.clone()), + ), + }; + + if item.src.is_some() { + local.sym = + magic_identifier::mangle(&format!("reexport {}", local.sym)) + .into(); + local = local.into_private(); + } + + exports.push((local.to_id(), exported.clone())); + + if let Some(src) = &item.src { + let id = ItemId::Item { + index, + kind: ItemIdItemKind::ImportBinding(si as _), + }; + ids.push(id.clone()); + + let import = match s { + ExportSpecifier::Namespace(..) => { + ImportSpecifier::Namespace(ImportStarAsSpecifier { + span: DUMMY_SP, + local: local.clone(), + }) + } + _ => ImportSpecifier::Named(ImportNamedSpecifier { + span: DUMMY_SP, + local: local.clone(), + imported: orig, + is_type_only: false, + }), + }; + items.insert( + id, + ItemData { + is_hoisted: true, + var_decls: [local.to_id()].into_iter().collect(), + pure: true, + content: ModuleItem::ModuleDecl(ModuleDecl::Import( + ImportDecl { + span: DUMMY_SP, + specifiers: vec![import], + src: src.clone(), + type_only: false, + with: None, + phase: Default::default(), + }, + )), + ..Default::default() + }, + ); + } + } + } + + ModuleDecl::ExportDefaultDecl(export) => { + let id = match &export.decl { + DefaultDecl::Class(c) => c.ident.clone(), + DefaultDecl::Fn(f) => f.ident.clone(), + DefaultDecl::TsInterfaceDecl(_) => unreachable!(), + }; + + let default_var = id.unwrap_or_else(|| { + private_ident!(magic_identifier::mangle("default export")) + }); + + { + let mut used_ids = if export.decl.is_fn_expr() { + ids_used_by_ignoring_nested( + &export.decl, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ) + } else { + ids_used_by( + &export.decl, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ) + }; + used_ids.read.remove(&default_var.to_id()); + used_ids.write.insert(default_var.to_id()); + let mut captured_ids = if export.decl.is_fn_expr() { + ids_captured_by( + &export.decl, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ) + } else { + Vars::default() + }; + captured_ids.read.remove(&default_var.to_id()); + + let data = ItemData { + read_vars: used_ids.read, + eventual_read_vars: captured_ids.read, + write_vars: used_ids.write, + eventual_write_vars: captured_ids.write, + var_decls: [default_var.to_id()].into_iter().collect(), + content: ModuleItem::ModuleDecl(item.clone()), + ..Default::default() + }; + + let id = ItemId::Item { + index, + kind: ItemIdItemKind::Normal, + }; + ids.push(id.clone()); + items.insert(id, data); + } + + exports.push(( + default_var.to_id(), + Some(ModuleExportName::Ident(quote_ident!("default"))), + )); + } + ModuleDecl::ExportDefaultExpr(export) => { + let default_var = + private_ident!(magic_identifier::mangle("default export")); + + { + // For + // let __TURBOPACK_default_export__ = expr; + + let mut used_ids = ids_used_by_ignoring_nested( + &export.expr, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ); + let captured_ids = ids_captured_by( + &export.expr, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ); + + used_ids.write.insert(default_var.to_id()); + + let data = ItemData { + read_vars: used_ids.read, + eventual_read_vars: captured_ids.read, + write_vars: used_ids.write, + eventual_write_vars: captured_ids.write, + var_decls: [default_var.to_id()].into_iter().collect(), + side_effects: true, + content: ModuleItem::Stmt(Stmt::Decl(Decl::Var(Box::new( + VarDecl { + span: DUMMY_SP, + kind: VarDeclKind::Const, + declare: false, + decls: vec![VarDeclarator { + span: DUMMY_SP, + name: default_var.clone().into(), + init: Some(export.expr.clone()), + definite: false, + }], + }, + )))), + ..Default::default() + }; + + let id = ItemId::Item { + index, + kind: ItemIdItemKind::Normal, + }; + ids.push(id.clone()); + items.insert(id, data); + } + + { + // For export default __TURBOPACK__default__export__ + + exports.push(( + default_var.to_id(), + Some(ModuleExportName::Ident(quote_ident!("default"))), + )); + } + } + + ModuleDecl::ExportAll(item) => { + // One item for the import for re-export + let id = ItemId::Item { + index, + kind: ItemIdItemKind::ImportOfModule, + }; + ids.push(id.clone()); + items.insert( + id, + ItemData { + is_hoisted: true, + side_effects: true, + content: ModuleItem::ModuleDecl(ModuleDecl::ExportAll( + item.clone(), + )), + ..Default::default() + }, + ); + } + _ => {} + } + } + + match item { + ModuleItem::ModuleDecl(ModuleDecl::Import(item)) => { + // We create multiple items for each import. + + { + // One item for the import itself + let id = ItemId::Item { + index, + kind: ItemIdItemKind::ImportOfModule, + }; + ids.push(id.clone()); + items.insert( + id, + ItemData { + is_hoisted: true, + side_effects: true, + content: ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + specifiers: Default::default(), + ..item.clone() + })), + ..Default::default() + }, + ); + } + + // One per binding + for (si, s) in item.specifiers.iter().enumerate() { + let id = ItemId::Item { + index, + kind: ItemIdItemKind::ImportBinding(si as _), + }; + ids.push(id.clone()); + let local = s.local().to_id(); + items.insert( + id, + ItemData { + is_hoisted: true, + var_decls: [local].into_iter().collect(), + pure: true, + content: ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + specifiers: vec![s.clone()], + ..item.clone() + })), + ..Default::default() + }, + ); + } + } + + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { + decl: Decl::Fn(f), + .. + })) + | ModuleItem::Stmt(Stmt::Decl(Decl::Fn(f))) => { + let id = ItemId::Item { + index, + kind: ItemIdItemKind::Normal, + }; + ids.push(id.clone()); + + let vars = ids_used_by( + &f.function, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ); + let var_decls = { + let mut v = IndexSet::with_capacity_and_hasher(1, Default::default()); + v.insert(f.ident.to_id()); + v + }; + items.insert( + id, + ItemData { + is_hoisted: true, + eventual_read_vars: vars.read, + eventual_write_vars: vars.write, + write_vars: var_decls.clone(), + var_decls, + content: ModuleItem::Stmt(Stmt::Decl(Decl::Fn(f.clone()))), + ..Default::default() + }, + ); + } + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { + decl: Decl::Class(c), + .. + })) + | ModuleItem::Stmt(Stmt::Decl(Decl::Class(c))) => { + let id = ItemId::Item { + index, + kind: ItemIdItemKind::Normal, + }; + ids.push(id.clone()); + + let mut vars = + ids_used_by(&c.class, unresolved_ctxt, top_level_ctxt, &top_level_vars); + let var_decls = { + let mut v = IndexSet::with_capacity_and_hasher(1, Default::default()); + v.insert(c.ident.to_id()); + v + }; + vars.write.insert(c.ident.to_id()); + items.insert( + id, + ItemData { + read_vars: vars.read, + write_vars: vars.write, + var_decls, + content: ModuleItem::Stmt(Stmt::Decl(Decl::Class(c.clone()))), + ..Default::default() + }, + ); + } + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { + decl: Decl::Var(v), + .. + })) + | ModuleItem::Stmt(Stmt::Decl(Decl::Var(v))) => { + for (i, decl) in v.decls.iter().enumerate() { + let id = ItemId::Item { + index, + kind: ItemIdItemKind::VarDeclarator(i as _), + }; + ids.push(id.clone()); + + let decl_ids: Vec = find_pat_ids(&decl.name); + let mut vars = ids_used_by_ignoring_nested( + &decl.init, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ); + let mut eventual_vars = ids_captured_by( + &decl.init, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ); + + vars.read.retain(|id| !decl_ids.contains(id)); + eventual_vars.read.retain(|id| !decl_ids.contains(id)); + + let side_effects = vars.found_unresolved; + + let var_decl = Box::new(VarDecl { + decls: vec![decl.clone()], + ..*v.clone() + }); + vars.write.extend(decl_ids.iter().cloned()); + let content = ModuleItem::Stmt(Stmt::Decl(Decl::Var(var_decl))); + items.insert( + id, + ItemData { + var_decls: decl_ids.clone().into_iter().collect(), + read_vars: vars.read, + eventual_read_vars: eventual_vars.read, + write_vars: vars.write, + eventual_write_vars: eventual_vars.write, + content, + side_effects, + ..Default::default() + }, + ); + } + } + + ModuleItem::Stmt(Stmt::Expr(ExprStmt { + expr: box Expr::Assign(assign), + .. + })) => { + let mut used_ids = ids_used_by_ignoring_nested( + item, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ); + let captured_ids = + ids_captured_by(item, unresolved_ctxt, top_level_ctxt, &top_level_vars); + + if assign.op != op!("=") { + let ids_used_by_left = ids_used_by_ignoring_nested( + &assign.left, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ); + + used_ids.read.extend(used_ids.write.iter().cloned()); + + used_ids.read.extend(ids_used_by_left.read); + used_ids.write.extend(ids_used_by_left.write); + } + + let side_effects = used_ids.found_unresolved; + + let data = ItemData { + read_vars: used_ids.read, + eventual_read_vars: captured_ids.read, + write_vars: used_ids.write, + eventual_write_vars: captured_ids.write, + content: item.clone(), + side_effects, + ..Default::default() + }; + + let id = ItemId::Item { + index, + kind: ItemIdItemKind::Normal, + }; + ids.push(id.clone()); + items.insert(id, data); + } + + ModuleItem::ModuleDecl( + ModuleDecl::ExportDefaultDecl(..) + | ModuleDecl::ExportDefaultExpr(..) + | ModuleDecl::ExportNamed(NamedExport { .. }) + | ModuleDecl::ExportAll(..), + ) => {} + + _ => { + // Default to normal + + let used_ids = ids_used_by_ignoring_nested( + item, + unresolved_ctxt, + top_level_ctxt, + &top_level_vars, + ); + let captured_ids = + ids_captured_by(item, unresolved_ctxt, top_level_ctxt, &top_level_vars); + let data = ItemData { + read_vars: used_ids.read, + eventual_read_vars: captured_ids.read, + write_vars: used_ids.write, + eventual_write_vars: captured_ids.write, + side_effects: true, + content: item.clone(), + ..Default::default() + }; + + let id = ItemId::Item { + index, + kind: ItemIdItemKind::Normal, + }; + ids.push(id.clone()); + items.insert(id, data); + } + } + } + + { + // `module evaluation side effects` Node + let id = ItemId::Group(ItemIdGroupKind::ModuleEvaluation); + ids.push(id.clone()); + items.insert( + id, + ItemData { + content: ModuleItem::Stmt(Stmt::Expr(ExprStmt { + span: DUMMY_SP, + expr: "module evaluation".into(), + })), + ..Default::default() + }, + ); + } + + for (local, export_name) in exports { + let name = match &export_name { + Some(ModuleExportName::Ident(v)) => v.sym.clone(), + _ => local.0.clone(), + }; + let id = ItemId::Group(ItemIdGroupKind::Export(local.clone(), name.clone())); + ids.push(id.clone()); + items.insert( + id.clone(), + ItemData { + content: ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport { + span: DUMMY_SP, + specifiers: vec![ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: ModuleExportName::Ident(local.clone().into()), + exported: export_name, + is_type_only: false, + })], + src: None, + type_only: false, + with: None, + })), + read_vars: [local.clone()].into_iter().collect(), + export: Some(name), + ..Default::default() + }, + ); + } + + (ids, items) + } + + pub(super) fn add_strong_deps<'a, T>(&mut self, from: &ItemId, to: T) + where + T: IntoIterator, + { + // This value cannot be lazily initialized because we need to ensure that + // ModuleEvaluation exists even if there's no side effect. + let from = self.g.node(from); + + for to in to { + let to = self.g.node(to); + + self.g.idx_graph.add_edge(from, to, Dependency::Strong); + } + } + pub(super) fn add_weak_deps<'a, T>(&mut self, from: &ItemId, to: T) + where + T: IntoIterator, + { + let from = self.g.node(from); + + for to in to { + let to = self.g.node(to); + + if let Some(Dependency::Strong) = self.g.idx_graph.edge_weight(from, to) { + continue; + } + self.g.idx_graph.add_edge(from, to, Dependency::Weak); + } + } + + pub(crate) fn has_dep(&mut self, id: &ItemId, dep: &ItemId, only_strong: bool) -> bool { + let from = self.g.node(id); + let to = self.g.node(dep); + self.g + .idx_graph + .edge_weight(from, to) + .map(|d| matches!(d, Dependency::Strong) || !only_strong) + .unwrap_or(false) + } + + pub(crate) fn has_path_connecting(&mut self, from: &ItemId, to: &ItemId) -> bool { + let from = self.g.node(from); + let to = self.g.node(to); + + has_path_connecting(&self.g.idx_graph, from, to, None) + } +} + +const ASSERT_CHUNK_KEY: &str = "__turbopack_part__"; + +#[derive(Debug, Clone)] +pub(crate) enum PartId { + ModuleEvaluation, + Exports, + Export(RcStr), + Internal(u32), +} + +pub(crate) fn create_turbopack_part_id_assert(dep: PartId) -> ObjectLit { + // We can't use quote! as `with` is not standard yet + ObjectLit { + span: DUMMY_SP, + props: vec![PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(Ident::new(ASSERT_CHUNK_KEY.into(), DUMMY_SP)), + value: match dep { + PartId::ModuleEvaluation => "module evaluation".into(), + PartId::Exports => "exports".into(), + PartId::Export(e) => format!("export {e}").into(), + PartId::Internal(dep) => (dep as f64).into(), + }, + })))], + } +} + +pub(crate) fn find_turbopack_part_id_in_asserts(asserts: &ObjectLit) -> Option { + asserts.props.iter().find_map(|prop| match prop { + PropOrSpread::Prop(box Prop::KeyValue(KeyValueProp { + key: PropName::Ident(key), + value: box Expr::Lit(Lit::Num(chunk_id)), + })) if &*key.sym == ASSERT_CHUNK_KEY => Some(PartId::Internal(chunk_id.value as u32)), + + PropOrSpread::Prop(box Prop::KeyValue(KeyValueProp { + key: PropName::Ident(key), + value: box Expr::Lit(Lit::Str(s)), + })) if &*key.sym == ASSERT_CHUNK_KEY => match &*s.value { + "module evaluation" => Some(PartId::ModuleEvaluation), + "exports" => Some(PartId::Exports), + _ => None, + }, + _ => None, + }) +} diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/merge.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/merge.rs new file mode 100644 index 0000000000000..282b1bb3fab3e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/merge.rs @@ -0,0 +1,85 @@ +use anyhow::Error; +use rustc_hash::FxHashSet; +use swc_core::ecma::{ + ast::{Module, ModuleDecl, ModuleItem}, + atoms::JsWord, +}; + +use super::{graph::find_turbopack_part_id_in_asserts, PartId}; + +/// A loader used to merge module items after splitting. +pub trait Load { + /// Loads a module while returning [None] if the module is already loaded. + fn load(&mut self, uri: &str, part_id: u32) -> Result, Error>; +} + +/// A module merger. +/// +/// This ensures that a module is loaded only once. +pub struct Merger +where + L: Load, +{ + loader: L, + + done: FxHashSet<(JsWord, u32)>, +} + +impl Merger +where + L: Load, +{ + /// Creates a module merger. + pub fn new(loader: L) -> Self { + Merger { + loader, + done: Default::default(), + } + } + + /// Merges module content by appending the content of imported modules. This + /// is recursive, so a single call is enoguh. + pub fn merge_recursively(&mut self, entry: Module) -> Result { + let mut content = vec![]; + let mut extra_body = vec![]; + + for stmt in entry.body { + match stmt { + ModuleItem::ModuleDecl(ModuleDecl::Import(import)) => { + // Try to prepend the content of module + + let part_id = import + .with + .as_deref() + .and_then(find_turbopack_part_id_in_asserts); + + if let Some(PartId::Internal(part_id)) = part_id { + if self.done.insert((import.src.value.clone(), part_id)) { + if let Some(dep) = self.loader.load(&import.src.value, part_id)? { + let mut dep = self.merge_recursively(dep)?; + + extra_body.append(&mut dep.body); + } else { + content.push(ModuleItem::ModuleDecl(ModuleDecl::Import(import))); + } + } else { + // Remove import + } + } else { + // Preserve normal imports + content.push(ModuleItem::ModuleDecl(ModuleDecl::Import(import))); + } + } + _ => extra_body.push(stmt), + } + } + + content.append(&mut extra_body); + + Ok(Module { + span: entry.span, + body: content, + shebang: entry.shebang, + }) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs new file mode 100644 index 0000000000000..c68a2b747eeeb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/mod.rs @@ -0,0 +1,742 @@ +use std::{borrow::Cow, fmt::Write}; + +use anyhow::{bail, Result}; +use indexmap::IndexSet; +use rustc_hash::FxHashMap; +use swc_core::{ + common::{util::take::Take, SyntaxContext, DUMMY_SP, GLOBALS}, + ecma::{ + ast::{ + ExportAll, ExportNamedSpecifier, Id, Ident, ImportDecl, Module, ModuleDecl, + ModuleExportName, ModuleItem, NamedExport, Program, + }, + codegen::{text_writer::JsWriter, Emitter}, + }, +}; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ident::AssetIdent, resolve::ModulePart, source::Source}; + +pub(crate) use self::graph::{ + create_turbopack_part_id_assert, find_turbopack_part_id_in_asserts, PartId, +}; +use self::graph::{DepGraph, ItemData, ItemId, ItemIdGroupKind, Mode, SplitModuleResult}; +use crate::{analyzer::graph::EvalContext, parse::ParseResult, EcmascriptModuleAsset}; + +pub mod asset; +pub mod chunk_item; +mod graph; +pub mod merge; +#[cfg(test)] +mod tests; +mod util; + +pub(crate) const TURBOPACK_PART_IMPORT_SOURCE: &str = "__TURBOPACK_PART__"; + +pub struct Analyzer<'a> { + g: &'a mut DepGraph, + item_ids: &'a Vec, + items: &'a mut FxHashMap, + + last_side_effects: Vec, + + vars: FxHashMap, +} + +#[derive(Debug, Default, Clone)] +struct VarState { + declarator: Option, + + /// The module items that might trigger side effects on that variable. + /// We also store if this is a `const` write, so no further change will + /// happen to this var. + last_writes: Vec, + /// The module items that might read that variable. + last_reads: Vec, +} + +fn get_var<'a>(map: &'a FxHashMap, id: &Id) -> Cow<'a, VarState> { + let v = map.get(id); + match v { + Some(v) => Cow::Borrowed(v), + None => Cow::Owned(Default::default()), + } +} + +impl Analyzer<'_> { + pub(super) fn analyze( + module: &Module, + unresolved_ctxt: SyntaxContext, + top_level_ctxt: SyntaxContext, + ) -> (DepGraph, FxHashMap) { + let mut g = DepGraph::default(); + let (item_ids, mut items) = g.init(module, unresolved_ctxt, top_level_ctxt); + + let mut analyzer = Analyzer { + g: &mut g, + item_ids: &item_ids, + items: &mut items, + last_side_effects: Default::default(), + vars: Default::default(), + }; + + let eventual_ids = analyzer.hoist_vars_and_bindings(); + + analyzer.evaluate_immediate(module, &eventual_ids); + + analyzer.evaluate_eventual(module); + + analyzer.handle_exports(module); + + (g, items) + } + + /// Phase 1: Hoisted Variables and Bindings + /// + /// + /// Returns all (EVENTUAL_READ/WRITE_VARS) in the module. + fn hoist_vars_and_bindings(&mut self) -> IndexSet { + let mut eventual_ids = IndexSet::default(); + + for item_id in self.item_ids.iter() { + if let Some(item) = self.items.get(item_id) { + eventual_ids.extend(item.eventual_read_vars.iter().cloned()); + eventual_ids.extend(item.eventual_write_vars.iter().cloned()); + + if item.is_hoisted && item.side_effects { + self.g + .add_strong_deps(item_id, self.last_side_effects.iter()); + + self.last_side_effects.push(item_id.clone()); + } + + for id in item.var_decls.iter() { + let state = self.vars.entry(id.clone()).or_default(); + + if state.declarator.is_none() { + state.declarator = Some(item_id.clone()); + } + + if item.is_hoisted { + state.last_writes.push(item_id.clone()); + } else { + // TODO(WEB-705): Create a fake module item + // state.last_writes.push(item_id.clone()); + } + } + } + } + + eventual_ids + } + + /// Phase 2: Immediate evaluation + fn evaluate_immediate(&mut self, _module: &Module, eventual_ids: &IndexSet) { + for item_id in self.item_ids.iter() { + if let Some(item) = self.items.get(item_id) { + // Ignore HOISTED module items, they have been processed in phase 1 already. + if item.is_hoisted { + continue; + } + + for id in item.var_decls.iter() { + let state = self.vars.entry(id.clone()).or_default(); + if state.declarator.is_none() { + state.declarator = Some(item_id.clone()); + } + } + + // For each var in READ_VARS: + for id in item.read_vars.iter() { + // Create a strong dependency to all module items listed in LAST_WRITES for that + // var. + + // (the writes need to be executed before this read) + let state = get_var(&self.vars, id); + self.g.add_strong_deps(item_id, state.last_writes.iter()); + + if let Some(declarator) = &state.declarator { + if declarator != item_id { + // A read also depends on the declaration. + self.g + .add_strong_deps(item_id, [declarator].iter().copied()); + } + } + } + + // For each var in WRITE_VARS: + for id in item.write_vars.iter() { + // Create a weak dependency to all module items listed in + // LAST_READS for that var. + + // (the reads need to be executed before this write, when + // it’s needed) + + let state = get_var(&self.vars, id); + self.g.add_weak_deps(item_id, state.last_reads.iter()); + + if let Some(declarator) = &state.declarator { + if declarator != item_id { + // A write also depends on the declaration. + self.g.add_strong_deps(item_id, [declarator]); + } + } + } + + if item.side_effects { + // Create a strong dependency to LAST_SIDE_EFFECT. + + self.g + .add_strong_deps(item_id, self.last_side_effects.iter()); + + // Create weak dependencies to all LAST_WRITES and + // LAST_READS. + for id in eventual_ids.iter() { + let state = get_var(&self.vars, id); + + self.g.add_weak_deps(item_id, state.last_writes.iter()); + self.g.add_weak_deps(item_id, state.last_reads.iter()); + } + } + + // For each var in WRITE_VARS: + for id in item.write_vars.iter() { + // Add this module item to LAST_WRITES + + let state = self.vars.entry(id.clone()).or_default(); + state.last_writes.push(item_id.clone()); + + // Optimization: Remove each module item to which we + // just created a strong dependency from LAST_WRITES + + state + .last_writes + .retain(|last_write| !self.g.has_dep(item_id, last_write, true)); + + // Drop all writes which are not reachable from this item. + // + // For + // + // var x = 0 + // x = 1 + // x = 2 + // x += 3 + // + // this will drop `x = 1` as not reachable from `x += 3`. + + state + .last_writes + .retain(|last_write| self.g.has_path_connecting(item_id, last_write)); + } + + // For each var in READ_VARS: + for id in item.read_vars.iter() { + // Add this module item to LAST_READS + + let state = self.vars.entry(id.clone()).or_default(); + state.last_reads.push(item_id.clone()); + + // Optimization: Remove each module item to which we + // have a strong dependency + + state + .last_reads + .retain(|last_read| !self.g.has_dep(item_id, last_read, true)); + } + + if item.side_effects { + self.last_side_effects.push(item_id.clone()); + } + } + } + } + + /// Phase 3: Eventual evaluation + fn evaluate_eventual(&mut self, _module: &Module) { + for item_id in self.item_ids.iter() { + if let Some(item) = self.items.get(item_id) { + // For each var in EVENTUAL_READ_VARS: + + for id in item.eventual_read_vars.iter() { + // Create a strong dependency to all module items listed in + // LAST_WRITES for that var. + + let state = get_var(&self.vars, id); + self.g.add_strong_deps(item_id, state.last_writes.iter()); + + if let Some(declarator) = &state.declarator { + if declarator != item_id { + // A read also depends on the declaration. + self.g.add_strong_deps(item_id, [declarator]); + } + } + } + + // For each var in EVENTUAL_WRITE_VARS: + for id in item.eventual_write_vars.iter() { + // Create a weak dependency to all module items listed in + // LAST_READS for that var. + + let state = get_var(&self.vars, id); + + self.g.add_weak_deps(item_id, state.last_reads.iter()); + + if let Some(declarator) = &state.declarator { + if declarator != item_id { + // A write also depends on the declaration. + self.g.add_strong_deps(item_id, [declarator]); + } + } + } + + // (no state update happens, since this is only triggered by + // side effects, which we already handled) + } + } + } + + /// Phase 4: Exports + fn handle_exports(&mut self, _module: &Module) { + for item_id in self.item_ids.iter() { + if let ItemId::Group(kind) = item_id { + match kind { + ItemIdGroupKind::ModuleEvaluation => { + // Create a strong dependency to LAST_SIDE_EFFECTS + + self.g + .add_strong_deps(item_id, self.last_side_effects.iter()); + } + ItemIdGroupKind::Export(local, _) => { + // Create a strong dependency to LAST_WRITES for this var + + let state = get_var(&self.vars, local); + + self.g.add_strong_deps(item_id, state.last_writes.iter()); + } + } + } + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub(crate) enum Key { + ModuleEvaluation, + Export(RcStr), + Exports, +} + +/// Converts [Vc] to the index. +async fn get_part_id(result: &SplitResult, part: Vc) -> Result { + let part = part.await?; + + // TODO implement ModulePart::Facade + let key = match &*part { + ModulePart::Evaluation => Key::ModuleEvaluation, + ModulePart::Export(export) => Key::Export(export.await?.as_str().into()), + ModulePart::Exports => Key::Exports, + ModulePart::Internal(part_id) => return Ok(*part_id), + ModulePart::Locals + | ModulePart::Facade + | ModulePart::RenamedExport { .. } + | ModulePart::RenamedNamespace { .. } => { + bail!("invalid module part") + } + }; + + let SplitResult::Ok { + entrypoints, + modules, + .. + } = &result + else { + bail!("split failed") + }; + + if let Some(id) = entrypoints.get(&key) { + return Ok(*id); + } + + // This is required to handle `export * from 'foo'` + if let ModulePart::Export(..) = &*part { + if let Some(&v) = entrypoints.get(&Key::Exports) { + return Ok(v); + } + } + + let mut dump = String::new(); + + for (idx, m) in modules.iter().enumerate() { + let ParseResult::Ok { + program, + source_map, + .. + } = &*m.await? + else { + bail!("failed to get module") + }; + + { + let mut buf = vec![]; + + { + let wr = JsWriter::new(Default::default(), "\n", &mut buf, None); + + let mut emitter = Emitter { + cfg: Default::default(), + comments: None, + cm: source_map.clone(), + wr, + }; + + emitter.emit_program(program).unwrap(); + } + let code = String::from_utf8(buf).unwrap(); + + writeln!(dump, "# Module #{idx}:\n{code}\n\n\n")?; + } + } + + bail!( + "could not find part id for module part {:?} in {:?}\n\nModule dump:\n{dump}", + key, + entrypoints + ) +} + +#[turbo_tasks::value(shared, serialization = "none", eq = "manual")] +pub(crate) enum SplitResult { + Ok { + asset_ident: Vc, + + /// `u32` is a index to `modules`. + #[turbo_tasks(trace_ignore)] + entrypoints: FxHashMap, + + #[turbo_tasks(debug_ignore, trace_ignore)] + modules: Vec>, + + #[turbo_tasks(trace_ignore)] + deps: FxHashMap>, + + #[turbo_tasks(debug_ignore, trace_ignore)] + star_reexports: Vec, + }, + Failed { + parse_result: Vc, + }, +} + +impl PartialEq for SplitResult { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::Ok { .. }, Self::Ok { .. }) => false, + _ => core::mem::discriminant(self) == core::mem::discriminant(other), + } + } +} + +#[turbo_tasks::function] +pub(super) async fn split_module(asset: Vc) -> Result> { + Ok(split( + asset.source().ident(), + asset.source(), + asset.parse(), + asset.options().await?.special_exports, + )) +} + +#[turbo_tasks::function] +pub(super) async fn split( + ident: Vc, + source: Vc>, + parsed: Vc, + special_exports: Vc>, +) -> Result> { + let parse_result = parsed.await?; + + match &*parse_result { + ParseResult::Ok { + program, + comments, + eval_context, + source_map, + globals, + .. + } => { + // If the script file is a common js file, we cannot split the module + if util::should_skip_tree_shaking(program, &special_exports.await?) { + return Ok(SplitResult::Failed { + parse_result: parsed, + } + .cell()); + } + + let module = match program { + Program::Module(module) => module, + Program::Script(..) => unreachable!("CJS is already handled"), + }; + + let (mut dep_graph, items) = GLOBALS.set(globals, || { + Analyzer::analyze( + module, + SyntaxContext::empty().apply_mark(eval_context.unresolved_mark), + SyntaxContext::empty().apply_mark(eval_context.top_level_mark), + ) + }); + + dep_graph.handle_weak(Mode::Production); + + let SplitModuleResult { + entrypoints, + part_deps, + modules, + star_reexports, + } = dep_graph.split_module(&items); + + assert_ne!(modules.len(), 0, "modules.len() == 0;\nModule: {module:?}",); + + for &v in entrypoints.values() { + debug_assert!( + v < modules.len() as u32, + "Invalid entrypoint '{}' while there are only '{}' modules", + v, + modules.len() + ); + } + let modules = modules + .into_iter() + .map(|module| { + let program = Program::Module(module); + let eval_context = EvalContext::new( + &program, + eval_context.unresolved_mark, + eval_context.top_level_mark, + Some(source), + ); + + ParseResult::cell(ParseResult::Ok { + program, + globals: globals.clone(), + comments: comments.clone(), + source_map: source_map.clone(), + eval_context, + }) + }) + .collect(); + + Ok(SplitResult::Ok { + asset_ident: ident, + entrypoints, + deps: part_deps, + modules, + star_reexports, + } + .cell()) + } + + _ => Ok(SplitResult::Failed { + parse_result: parsed, + } + .cell()), + } +} + +#[turbo_tasks::function] +pub(super) async fn part_of_module( + split_data: Vc, + part: Vc, +) -> Result> { + let split_data = split_data.await?; + + match &*split_data { + SplitResult::Ok { + asset_ident, + modules, + entrypoints, + deps, + star_reexports, + .. + } => { + debug_assert_ne!(modules.len(), 0, "modules.len() == 0"); + + if matches!(&*part.await?, ModulePart::Facade) { + if let ParseResult::Ok { + comments, + eval_context, + globals, + source_map, + .. + } = &*modules[0].await? + { + let mut module = Module::dummy(); + + let mut export_names = entrypoints + .keys() + .filter_map(|key| { + if let Key::Export(v) = key { + Some(v.clone()) + } else { + None + } + }) + .collect::>(); + export_names.sort(); + + module + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + span: DUMMY_SP, + specifiers: vec![], + src: Box::new(TURBOPACK_PART_IMPORT_SOURCE.into()), + type_only: false, + with: Some(Box::new(create_turbopack_part_id_assert( + PartId::ModuleEvaluation, + ))), + phase: Default::default(), + }))); + + let specifiers = export_names + .into_iter() + .map(|export_name| { + swc_core::ecma::ast::ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: ModuleExportName::Ident(Ident::new( + export_name.as_str().into(), + DUMMY_SP, + )), + exported: None, + is_type_only: false, + }) + }) + .collect::>(); + + module + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( + NamedExport { + span: DUMMY_SP, + specifiers, + src: Some(Box::new(TURBOPACK_PART_IMPORT_SOURCE.into())), + type_only: false, + with: Some(Box::new(create_turbopack_part_id_assert( + PartId::Exports, + ))), + }, + ))); + + module.body.extend(star_reexports.iter().map(|export_all| { + ModuleItem::ModuleDecl(ModuleDecl::ExportAll(export_all.clone())) + })); + + let program = Program::Module(module); + let eval_context = EvalContext::new( + &program, + eval_context.unresolved_mark, + eval_context.top_level_mark, + None, + ); + + return Ok(ParseResult::Ok { + program, + comments: comments.clone(), + eval_context, + globals: globals.clone(), + source_map: source_map.clone(), + } + .cell()); + } else { + unreachable!() + } + } + + if matches!(&*part.await?, ModulePart::Exports) { + if let ParseResult::Ok { + comments, + eval_context, + globals, + source_map, + .. + } = &*modules[0].await? + { + let mut export_names = entrypoints + .keys() + .filter_map(|key| { + if let Key::Export(v) = key { + Some(v.clone()) + } else { + None + } + }) + .collect::>(); + export_names.sort(); + + let mut module = Module::dummy(); + + for export_name in export_names { + // We can't use quote! as `with` is not standard yet + let chunk_prop = + create_turbopack_part_id_assert(PartId::Export(export_name.clone())); + + let specifier = + swc_core::ecma::ast::ExportSpecifier::Named(ExportNamedSpecifier { + span: DUMMY_SP, + orig: ModuleExportName::Ident(Ident::new( + export_name.as_str().into(), + DUMMY_SP, + )), + exported: None, + is_type_only: false, + }); + module + .body + .push(ModuleItem::ModuleDecl(ModuleDecl::ExportNamed( + NamedExport { + span: DUMMY_SP, + specifiers: vec![specifier], + src: Some(Box::new(TURBOPACK_PART_IMPORT_SOURCE.into())), + type_only: false, + with: Some(Box::new(chunk_prop)), + }, + ))); + } + + module.body.extend(star_reexports.iter().map(|export_all| { + ModuleItem::ModuleDecl(ModuleDecl::ExportAll(export_all.clone())) + })); + + let program = Program::Module(module); + let eval_context = EvalContext::new( + &program, + eval_context.unresolved_mark, + eval_context.top_level_mark, + None, + ); + return Ok(ParseResult::Ok { + program, + comments: comments.clone(), + eval_context, + globals: globals.clone(), + source_map: source_map.clone(), + } + .cell()); + } else { + unreachable!() + } + } + + let part_id = get_part_id(&split_data, part).await?; + + if part_id as usize >= modules.len() { + bail!( + "part_id is out of range: {part_id} >= {}; asset = {}; entrypoints = \ + {entrypoints:?}: part_deps = {deps:?}", + asset_ident.to_string().await?, + modules.len(), + ); + } + + Ok(modules[part_id as usize]) + } + SplitResult::Failed { parse_result } => Ok(*parse_result), + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/tests.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/tests.rs new file mode 100644 index 0000000000000..12c3d572b0961 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/tests.rs @@ -0,0 +1,367 @@ +use std::{ + fmt::Write, + hash::{BuildHasherDefault, Hash}, + path::PathBuf, + sync::Arc, +}; + +use anyhow::Error; +use indexmap::IndexSet; +use rustc_hash::FxHasher; +use serde::Deserialize; +use swc_core::{ + common::{util::take::Take, Mark, SourceMap, SyntaxContext}, + ecma::{ + ast::{EsVersion, Id, Module}, + atoms::JsWord, + codegen::text_writer::JsWriter, + parser::parse_file_as_module, + visit::VisitMutWith, + }, + testing::{self, fixture, NormalizedOutput}, +}; + +use super::{ + graph::{ + DepGraph, Dependency, InternedGraph, ItemId, ItemIdGroupKind, Mode, SplitModuleResult, + }, + merge::Merger, + Analyzer, Key, +}; + +#[fixture("tests/tree-shaker/analyzer/**/input.js")] +fn test_fixture(input: PathBuf) { + run(input); +} + +#[derive(Deserialize)] +struct TestConfig { + /// Enabled exports. This is `Vec>` because we test multiple + /// exports at once. + #[serde(default)] + exports: Vec>, +} + +fn run(input: PathBuf) { + let config = input.with_file_name("config.json"); + let config = std::fs::read_to_string(config).unwrap_or_else(|_| "{}".into()); + let config = serde_json::from_str::(&config).unwrap_or_else(|_e| { + panic!("failed to parse config.json: {}", config); + }); + + testing::run_test(false, |cm, _handler| { + let fm = cm.load_file(&input).unwrap(); + + let mut module = parse_file_as_module( + &fm, + Default::default(), + EsVersion::latest(), + None, + &mut vec![], + ) + .unwrap(); + + let unresolved_mark = Mark::new(); + let top_level_mark = Mark::new(); + let unresolved_ctxt = SyntaxContext::empty().apply_mark(unresolved_mark); + let top_level_ctxt = SyntaxContext::empty().apply_mark(top_level_mark); + + module.visit_mut_with(&mut swc_core::ecma::transforms::base::resolver( + unresolved_mark, + top_level_mark, + false, + )); + + let mut g = DepGraph::default(); + let (item_ids, mut items) = g.init(&module, unresolved_ctxt, top_level_ctxt); + + let mut s = String::new(); + + writeln!(s, "# Items\n").unwrap(); + writeln!(s, "Count: {}", item_ids.len()).unwrap(); + writeln!(s).unwrap(); + + for (i, id) in item_ids.iter().enumerate() { + let item = &items[id]; + + let (index, kind) = match id { + ItemId::Group(_) => continue, + ItemId::Item { index, kind } => (*index, kind), + }; + + writeln!(s, "## Item {}: Stmt {}, `{:?}`", i + 1, index, kind).unwrap(); + writeln!(s, "\n```js\n{}\n```\n", print(&cm, &[&module.body[index]])).unwrap(); + + if item.is_hoisted { + writeln!(s, "- Hoisted").unwrap(); + } + + if item.side_effects { + writeln!(s, "- Side effects").unwrap(); + } + + let f = |ids: &IndexSet>| { + let mut s = String::new(); + for (i, id) in ids.iter().enumerate() { + if i == 0 { + write!(s, "`{}`", id.0).unwrap(); + } else { + write!(s, ", `{}`", id.0).unwrap(); + } + } + s + }; + + if !item.var_decls.is_empty() { + writeln!(s, "- Declares: {}", f(&item.var_decls)).unwrap(); + } + + if !item.read_vars.is_empty() { + writeln!(s, "- Reads: {}", f(&item.read_vars)).unwrap(); + } + + if !item.eventual_read_vars.is_empty() { + writeln!(s, "- Reads (eventual): {}", f(&item.eventual_read_vars)).unwrap(); + } + + if !item.write_vars.is_empty() { + writeln!(s, "- Write: {}", f(&item.write_vars)).unwrap(); + } + + if !item.eventual_write_vars.is_empty() { + writeln!(s, "- Write (eventual): {}", f(&item.eventual_write_vars)).unwrap(); + } + + writeln!(s).unwrap(); + } + + let mut analyzer = Analyzer { + g: &mut g, + item_ids: &item_ids, + items: &mut items, + last_side_effects: Default::default(), + vars: Default::default(), + }; + + let eventual_ids = analyzer.hoist_vars_and_bindings(); + + writeln!(s, "# Phase 1").unwrap(); + writeln!(s, "```mermaid\n{}```", render_graph(&item_ids, analyzer.g)).unwrap(); + + analyzer.evaluate_immediate(&module, &eventual_ids); + + writeln!(s, "# Phase 2").unwrap(); + writeln!(s, "```mermaid\n{}```", render_graph(&item_ids, analyzer.g)).unwrap(); + + analyzer.evaluate_eventual(&module); + + writeln!(s, "# Phase 3").unwrap(); + writeln!(s, "```mermaid\n{}```", render_graph(&item_ids, analyzer.g)).unwrap(); + + analyzer.handle_exports(&module); + + writeln!(s, "# Phase 4").unwrap(); + writeln!(s, "```mermaid\n{}```", render_graph(&item_ids, analyzer.g)).unwrap(); + + let mut condensed = analyzer.g.finalize(); + + writeln!(s, "# Final").unwrap(); + writeln!( + s, + "```mermaid\n{}```", + render_mermaid(&mut condensed, &|buf: &Vec| format!( + "Items: {:?}", + buf + )) + ) + .unwrap(); + + let uri_of_module: JsWord = "entry.js".into(); + + let mut describe = + |is_debug: bool, title: &str, entries: Vec, skip_parts: bool| { + let mut g = analyzer.g.clone(); + g.handle_weak(if is_debug { + Mode::Development + } else { + Mode::Production + }); + let SplitModuleResult { + modules, + entrypoints, + .. + } = g.split_module(analyzer.items); + + writeln!(s, "# Entrypoints\n\n```\n{:#?}\n```\n\n", entrypoints).unwrap(); + + if !skip_parts { + writeln!(s, "# Modules ({})", if is_debug { "dev" } else { "prod" }).unwrap(); + for (i, module) in modules.iter().enumerate() { + writeln!(s, "## Part {}", i).unwrap(); + writeln!(s, "```js\n{}\n```", print(&cm, &[module])).unwrap(); + } + } + + let mut merger = Merger::new(SingleModuleLoader { + modules: &modules, + entry_module_uri: &uri_of_module, + }); + let mut entry = Module::dummy(); + + for e in &entries { + let key = match e { + ItemIdGroupKind::ModuleEvaluation => Key::ModuleEvaluation, + ItemIdGroupKind::Export(_, name) => Key::Export(name.as_str().into()), + }; + + let index = entrypoints[&key]; + entry.body.extend(modules[index as usize].body.clone()); + } + + let module = merger.merge_recursively(entry).unwrap(); + + writeln!(s, "## Merged ({})", title).unwrap(); + writeln!(s, "```js\n{}\n```", print(&cm, &[&module])).unwrap(); + }; + describe( + true, + "module eval", + vec![ItemIdGroupKind::ModuleEvaluation], + false, + ); + describe( + false, + "module eval", + vec![ItemIdGroupKind::ModuleEvaluation], + false, + ); + + for exports in config.exports { + describe( + false, + &exports.join(","), + exports + .into_iter() + .map(|e| ItemIdGroupKind::Export(((*e).into(), Default::default()), e.into())) + .collect(), + true, + ); + } + + NormalizedOutput::from(s) + .compare_to_file(input.with_file_name("output.md")) + .unwrap(); + + Ok(()) + }) + .unwrap(); +} + +struct SingleModuleLoader<'a> { + entry_module_uri: &'a str, + modules: &'a [Module], +} + +impl super::merge::Load for SingleModuleLoader<'_> { + fn load(&mut self, uri: &str, chunk_id: u32) -> Result, Error> { + if self.entry_module_uri == uri { + return Ok(Some(self.modules[chunk_id as usize].clone())); + } + + Ok(None) + } +} + +fn print(cm: &Arc, nodes: &[&N]) -> String { + let mut buf = vec![]; + + { + let mut emitter = swc_core::ecma::codegen::Emitter { + cfg: swc_core::ecma::codegen::Config::default() + .with_emit_assert_for_import_attributes(true), + cm: cm.clone(), + comments: None, + wr: Box::new(JsWriter::new(cm.clone(), "\n", &mut buf, None)), + }; + + for n in nodes { + n.emit_with(&mut emitter).unwrap(); + } + } + + String::from_utf8(buf).unwrap() +} + +fn render_graph(item_ids: &[ItemId], g: &mut DepGraph) -> String { + let mut mermaid = String::from("graph TD\n"); + + for id in item_ids.iter() { + let i = g.g.node(id); + + writeln!(mermaid, " Item{};", i + 1).unwrap(); + + if let Some(item_id) = render_item_id(id) { + writeln!(mermaid, " Item{}[\"{}\"];", i + 1, item_id).unwrap(); + } + } + + for (from, to, kind) in g.g.idx_graph.all_edges() { + writeln!( + mermaid, + " Item{} -{}-> Item{};", + from + 1, + match kind { + Dependency::Strong => "", + Dependency::Weak => ".", + }, + to + 1, + ) + .unwrap(); + } + + mermaid +} + +fn render_mermaid(g: &mut InternedGraph, render: &dyn Fn(&T) -> String) -> String +where + T: Clone + Eq + Hash, +{ + let mut mermaid = String::from("graph TD\n"); + let ix = g.graph_ix.clone(); + + for item in &ix { + let i = g.node(item); + + writeln!( + mermaid, + " N{}[\"{}\"];", + i, + render(item).replace([';', '\n'], "").replace('"', """) + ) + .unwrap(); + } + + for (from, to, kind) in g.idx_graph.all_edges() { + writeln!( + mermaid, + " N{} -{}-> N{};", + from, + match kind { + Dependency::Strong => "", + Dependency::Weak => ".", + }, + to, + ) + .unwrap(); + } + + mermaid +} + +fn render_item_id(id: &ItemId) -> Option { + match id { + ItemId::Group(ItemIdGroupKind::ModuleEvaluation) => Some("ModuleEvaluation".into()), + ItemId::Group(ItemIdGroupKind::Export(_, name)) => Some(format!("export {name}")), + _ => None, + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/tree_shake/util.rs b/turbopack/crates/turbopack-ecmascript/src/tree_shake/util.rs new file mode 100644 index 0000000000000..76f0d2d0be46d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/tree_shake/util.rs @@ -0,0 +1,536 @@ +use std::hash::BuildHasherDefault; + +use indexmap::IndexSet; +use rustc_hash::{FxHashSet, FxHasher}; +use swc_core::{ + common::SyntaxContext, + ecma::{ + ast::{ + ArrowExpr, AssignPatProp, AssignTarget, ClassDecl, ClassExpr, Constructor, DefaultDecl, + ExportDefaultDecl, ExportNamedSpecifier, ExportSpecifier, Expr, FnDecl, FnExpr, + Function, Id, Ident, ImportSpecifier, MemberExpr, MemberProp, NamedExport, Param, Pat, + Prop, PropName, VarDeclarator, *, + }, + visit::{noop_visit_type, Visit, VisitWith}, + }, +}; +use turbo_tasks::RcStr; + +use crate::TURBOPACK_HELPER; + +#[derive(Debug, Default, Clone, Copy)] +enum Mode { + Read, + #[default] + Write, +} + +#[derive(Default)] +struct Target { + direct: bool, + eventual: bool, +} + +/// A visitor which collects variables which are read or written. +pub(crate) struct IdentUsageCollector<'a> { + unresolved: SyntaxContext, + top_level: SyntaxContext, + top_level_vars: &'a FxHashSet, + + vars: Vars, + + is_nested: bool, + target: Target, + /// None means both read and write + mode: Option, +} + +impl IdentUsageCollector<'_> { + fn with_nested(&mut self, f: impl FnOnce(&mut Self)) { + if !self.target.eventual { + return; + } + + let old = self.is_nested; + self.is_nested = true; + f(self); + self.is_nested = old; + } + fn with_mode(&mut self, mode: Option, f: impl FnOnce(&mut Self)) { + let old = self.mode; + self.mode = mode; + f(self); + self.mode = old; + } +} + +impl Visit for IdentUsageCollector<'_> { + fn visit_assign_target(&mut self, n: &AssignTarget) { + self.with_mode(Some(Mode::Write), |this| { + n.visit_children_with(this); + }) + } + + fn visit_class(&mut self, n: &Class) { + n.super_class.visit_with(self); + + self.with_nested(|this| { + n.decorators.visit_with(this); + + n.body.visit_with(this); + }); + } + + fn visit_constructor(&mut self, n: &Constructor) { + self.with_nested(|this| { + n.visit_children_with(this); + }) + } + + fn visit_export_named_specifier(&mut self, n: &ExportNamedSpecifier) { + n.orig.visit_with(self); + } + + fn visit_export_specifier(&mut self, n: &ExportSpecifier) { + self.with_mode(Some(Mode::Read), |this| { + n.visit_children_with(this); + }) + } + + fn visit_expr(&mut self, e: &Expr) { + self.with_mode(Some(Mode::Read), |this| { + e.visit_children_with(this); + }) + } + fn visit_function(&mut self, n: &Function) { + self.with_nested(|this| { + n.visit_children_with(this); + }) + } + + fn visit_ident(&mut self, n: &Ident) { + if !self.target.direct && !self.is_nested { + return; + } + + if n.span.ctxt == self.unresolved { + self.vars.found_unresolved = true; + return; + } + + // We allow SyntaxContext::empty() because Some built-in files do not go into + // resolver() + if n.span.ctxt != self.unresolved + && n.span.ctxt != self.top_level + && n.span.ctxt != SyntaxContext::empty() + && !self.top_level_vars.contains(&n.to_id()) + { + return; + } + + match self.mode { + Some(Mode::Read) => { + self.vars.read.insert(n.to_id()); + } + Some(Mode::Write) => { + self.vars.write.insert(n.to_id()); + } + None => { + self.vars.read.insert(n.to_id()); + self.vars.write.insert(n.to_id()); + } + } + } + + fn visit_member_expr(&mut self, e: &MemberExpr) { + self.with_mode(None, |this| { + // Skip visit_expr + e.obj.visit_children_with(this); + }); + + e.prop.visit_with(self); + } + + fn visit_member_prop(&mut self, n: &MemberProp) { + if let MemberProp::Computed(..) = n { + self.with_mode(Some(Mode::Read), |v| { + n.visit_children_with(v); + }) + } + } + fn visit_named_export(&mut self, n: &NamedExport) { + if n.src.is_some() { + return; + } + + n.visit_children_with(self); + } + + fn visit_pat(&mut self, p: &Pat) { + self.with_mode(Some(Mode::Write), |this| { + p.visit_children_with(this); + }) + } + + fn visit_prop(&mut self, n: &Prop) { + match n { + Prop::Shorthand(v) => { + self.with_mode(None, |c| c.visit_ident(v)); + } + + _ => n.visit_children_with(self), + } + } + + fn visit_prop_name(&mut self, n: &PropName) { + if let PropName::Computed(..) = n { + n.visit_children_with(self); + } + } + + noop_visit_type!(); +} + +/// The list of variables which are read or written. +#[derive(Debug, Default)] +pub(crate) struct Vars { + /// Variables which are read. + pub read: IndexSet>, + /// Variables which are written. + pub write: IndexSet>, + + pub found_unresolved: bool, +} + +/// Returns `(read, write)` +/// +/// Note: This functions accept `SyntaxContext` to filter out variables which +/// are not interesting. We only need to analyze top-level variables. +pub(crate) fn ids_captured_by<'a, N>( + n: &N, + unresolved: SyntaxContext, + top_level: SyntaxContext, + top_level_vars: &'a FxHashSet, +) -> Vars +where + N: VisitWith>, +{ + let mut v = IdentUsageCollector { + unresolved, + top_level, + top_level_vars, + target: Target { + direct: false, + eventual: true, + }, + vars: Vars::default(), + is_nested: false, + mode: None, + }; + n.visit_with(&mut v); + v.vars +} + +/// Returns `(read, write)` +/// +/// Note: This functions accept `SyntaxContext` to filter out variables which +/// are not interesting. We only need to analyze top-level variables. +pub(crate) fn ids_used_by<'a, N>( + n: &N, + unresolved: SyntaxContext, + top_level: SyntaxContext, + top_level_vars: &'a FxHashSet, +) -> Vars +where + N: VisitWith>, +{ + let mut v = IdentUsageCollector { + unresolved, + top_level, + top_level_vars, + target: Target { + direct: true, + eventual: true, + }, + vars: Vars::default(), + is_nested: false, + mode: None, + }; + n.visit_with(&mut v); + v.vars +} + +/// Returns `(read, write)` +/// +/// Note: This functions accept `SyntaxContext` to filter out variables which +/// are not interesting. We only need to analyze top-level variables. +pub(crate) fn ids_used_by_ignoring_nested<'a, N>( + n: &N, + unresolved: SyntaxContext, + top_level: SyntaxContext, + top_level_vars: &'a FxHashSet, +) -> Vars +where + N: VisitWith>, +{ + let mut v = IdentUsageCollector { + unresolved, + top_level, + top_level_vars, + target: Target { + direct: true, + eventual: false, + }, + vars: Vars::default(), + is_nested: false, + mode: None, + }; + n.visit_with(&mut v); + v.vars +} + +pub struct TopLevelBindingCollector { + bindings: FxHashSet, + is_pat_decl: bool, +} + +impl TopLevelBindingCollector { + fn add(&mut self, i: &Ident) { + self.bindings.insert(i.to_id()); + } +} + +impl Visit for TopLevelBindingCollector { + noop_visit_type!(); + + fn visit_arrow_expr(&mut self, _: &ArrowExpr) {} + + fn visit_assign_pat_prop(&mut self, node: &AssignPatProp) { + node.value.visit_with(self); + + if self.is_pat_decl { + self.add(&node.key); + } + } + + fn visit_class_decl(&mut self, node: &ClassDecl) { + self.add(&node.ident); + } + + fn visit_expr(&mut self, _: &Expr) {} + + fn visit_export_default_decl(&mut self, e: &ExportDefaultDecl) { + match &e.decl { + DefaultDecl::Class(ClassExpr { + ident: Some(ident), .. + }) => { + self.add(ident); + } + DefaultDecl::Fn(FnExpr { + ident: Some(ident), + function: f, + }) if f.body.is_some() => { + self.add(ident); + } + _ => {} + } + } + + fn visit_fn_decl(&mut self, node: &FnDecl) { + self.add(&node.ident); + } + + fn visit_import_specifier(&mut self, node: &ImportSpecifier) { + match node { + ImportSpecifier::Named(s) => self.add(&s.local), + ImportSpecifier::Default(s) => { + self.add(&s.local); + } + ImportSpecifier::Namespace(s) => { + self.add(&s.local); + } + } + } + + fn visit_param(&mut self, node: &Param) { + let old = self.is_pat_decl; + self.is_pat_decl = true; + node.visit_children_with(self); + self.is_pat_decl = old; + } + + fn visit_pat(&mut self, node: &Pat) { + node.visit_children_with(self); + + if self.is_pat_decl { + if let Pat::Ident(i) = node { + self.add(&i.id) + } + } + } + + fn visit_var_declarator(&mut self, node: &VarDeclarator) { + let old = self.is_pat_decl; + self.is_pat_decl = true; + node.name.visit_with(self); + + self.is_pat_decl = false; + node.init.visit_with(self); + self.is_pat_decl = old; + } +} + +/// Collects binding identifiers. +pub fn collect_top_level_decls(n: &N) -> FxHashSet +where + N: VisitWith, +{ + let mut v = TopLevelBindingCollector { + bindings: Default::default(), + is_pat_decl: false, + }; + n.visit_with(&mut v); + v.bindings +} + +pub fn should_skip_tree_shaking(m: &Program, special_exports: &[RcStr]) -> bool { + if let Program::Module(m) = m { + for item in m.body.iter() { + match item { + // Skip turbopack helpers. + ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { + with, specifiers, .. + })) => { + if let Some(with) = with.as_deref().and_then(|v| v.as_import_with()) { + for item in with.values.iter() { + if item.key.sym == *TURBOPACK_HELPER { + // Skip tree shaking if the import is from turbopack-helper + return true; + } + } + } + + // TODO(PACK-3150): Tree shaking has a bug related to ModuleExportName::Str + for s in specifiers.iter() { + if let ImportSpecifier::Named(is) = s { + if matches!(is.imported, Some(ModuleExportName::Str(..))) { + return true; + } + } + } + } + + // Tree shaking has a bug related to ModuleExportName::Str + ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport { + src: Some(..), + specifiers, + .. + })) => { + for s in specifiers { + if let ExportSpecifier::Named(es) = s { + if matches!(es.orig, ModuleExportName::Str(..)) + || matches!(es.exported, Some(ModuleExportName::Str(..))) + { + return true; + } + } + } + } + + // Skip sever actions + ModuleItem::Stmt(Stmt::Expr(ExprStmt { + expr: box Expr::Lit(Lit::Str(Str { value, .. })), + .. + })) => { + if value == "use server" { + return true; + } + } + + // Skip special reexports that are recognized by next.js + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { + decl: Decl::Var(box VarDecl { decls, .. }), + .. + })) => { + for decl in decls { + if let Pat::Ident(name) = &decl.name { + if special_exports.iter().any(|s| **s == *name.sym) { + return true; + } + } + } + } + + // Skip special reexports that are recognized by next.js + ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { + decl: Decl::Fn(f), + .. + })) => { + if special_exports.iter().any(|s| **s == *f.ident.sym) { + return true; + } + } + + _ => {} + } + } + + let mut visitor = ShouldSkip::default(); + m.visit_with(&mut visitor); + if visitor.skip { + return true; + } + + for item in m.body.iter() { + if item.is_module_decl() { + return false; + } + } + } + + true +} + +#[derive(Default)] +struct ShouldSkip { + skip: bool, +} + +impl Visit for ShouldSkip { + fn visit_expr_stmt(&mut self, e: &ExprStmt) { + e.visit_children_with(self); + + if let Expr::Lit(Lit::Str(Str { value, .. })) = &*e.expr { + if value == "use server" { + self.skip = true; + } + } + } + + fn visit_stmt(&mut self, n: &Stmt) { + if self.skip { + return; + } + + n.visit_children_with(self); + } + + fn visit_await_expr(&mut self, n: &AwaitExpr) { + // __turbopack_wasm_module__ is not analyzable because __turbopack_wasm_module__ + // is injected global. + if let Expr::Call(CallExpr { + callee: Callee::Expr(expr), + .. + }) = &*n.arg + { + if expr.is_ident_ref_to("__turbopack_wasm_module__") { + self.skip = true; + return; + } + } + + n.visit_children_with(self); + } + + noop_visit_type!(); +} diff --git a/turbopack/crates/turbopack-ecmascript/src/typescript/mod.rs b/turbopack/crates/turbopack-ecmascript/src/typescript/mod.rs new file mode 100644 index 0000000000000..f9f5da82b40a5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/typescript/mod.rs @@ -0,0 +1,303 @@ +use anyhow::Result; +use serde_json::Value as JsonValue; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::DirectoryContent; +use turbopack_core::{ + asset::{Asset, AssetContent}, + ident::AssetIdent, + issue::IssueSeverity, + module::Module, + raw_module::RawModule, + reference::{ModuleReference, ModuleReferences}, + reference_type::{CommonJsReferenceSubType, ReferenceType}, + resolve::{ + origin::{ResolveOrigin, ResolveOriginExt}, + parse::Request, + ModuleResolveResult, + }, + source::Source, +}; +// TODO remove this +pub use turbopack_resolve::typescript as resolve; +use turbopack_resolve::{ + ecmascript::{apply_cjs_specific_options, cjs_resolve}, + typescript::{read_from_tsconfigs, read_tsconfigs, type_resolve}, +}; + +#[turbo_tasks::value] +pub struct TsConfigModuleAsset { + pub source: Vc>, + pub origin: Vc>, +} + +#[turbo_tasks::value_impl] +impl TsConfigModuleAsset { + #[turbo_tasks::function] + pub fn new(origin: Vc>, source: Vc>) -> Vc { + Self::cell(TsConfigModuleAsset { origin, source }) + } +} + +#[turbo_tasks::value_impl] +impl Module for TsConfigModuleAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source.ident() + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let mut references = Vec::new(); + let configs = read_tsconfigs( + self.source.content().file_content(), + self.source, + apply_cjs_specific_options(self.origin.resolve_options(Value::new( + ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined), + ))), + ) + .await?; + for (_, config_asset) in configs[1..].iter() { + references.push(Vc::upcast(TsExtendsReference::new(*config_asset))); + } + // ts-node options + { + let compiler = read_from_tsconfigs(&configs, |json, source| { + json["ts-node"]["compiler"] + .as_str() + .map(|s| (source, s.to_string())) + }) + .await?; + let compiler: RcStr = compiler + .map(|(_, c)| c) + .unwrap_or_else(|| "typescript".to_string()) + .into(); + references.push(Vc::upcast(CompilerReference::new( + self.origin, + Request::parse(Value::new(compiler.into())), + ))); + let require = read_from_tsconfigs(&configs, |json, source| { + if let JsonValue::Array(array) = &json["ts-node"]["require"] { + Some( + array + .iter() + .filter_map(|name| name.as_str().map(|s| (source, RcStr::from(s)))) + .collect::>(), + ) + } else { + None + } + }) + .await?; + if let Some(require) = require { + for (_, request) in require { + references.push(Vc::upcast(TsNodeRequireReference::new( + self.origin, + Request::parse(Value::new(request.into())), + ))); + } + } + } + // compilerOptions + { + let types = read_from_tsconfigs(&configs, |json, source| { + if let JsonValue::Array(array) = &json["compilerOptions"]["types"] { + Some( + array + .iter() + .filter_map(|name| name.as_str().map(|s| (source, RcStr::from(s)))) + .collect::>(), + ) + } else { + None + } + }) + .await?; + let types = if let Some(types) = types { + types + } else { + let mut all_types = Vec::new(); + let mut current = self.source.ident().path().parent().resolve().await?; + loop { + if let DirectoryContent::Entries(entries) = &*current + .join("node_modules/@types".into()) + .read_dir() + .await? + { + all_types.extend(entries.iter().filter_map(|(name, _)| { + if name.starts_with('.') { + None + } else { + Some((self.source, name.clone())) + } + })); + } + let parent = current.parent().resolve().await?; + if parent == current { + break; + } + current = parent; + } + all_types + }; + for (_, name) in types { + references.push(Vc::upcast(TsConfigTypesReference::new( + self.origin, + Request::module( + name, + Value::new(RcStr::default().into()), + Vc::::default(), + Vc::::default(), + ), + ))); + } + } + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for TsConfigModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct CompilerReference { + pub origin: Vc>, + pub request: Vc, +} + +#[turbo_tasks::value_impl] +impl CompilerReference { + #[turbo_tasks::function] + pub fn new(origin: Vc>, request: Vc) -> Vc { + Self::cell(CompilerReference { origin, request }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for CompilerReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + cjs_resolve(self.origin, self.request, None, IssueSeverity::Error.cell()) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for CompilerReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("compiler reference {}", self.request.to_string().await?).into(), + )) + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct TsExtendsReference { + pub config: Vc>, +} + +#[turbo_tasks::value_impl] +impl TsExtendsReference { + #[turbo_tasks::function] + pub fn new(config: Vc>) -> Vc { + Self::cell(TsExtendsReference { config }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for TsExtendsReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + ModuleResolveResult::module(Vc::upcast(RawModule::new(Vc::upcast(self.config)))).cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for TsExtendsReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!( + "tsconfig extends {}", + self.config.ident().to_string().await?, + ) + .into(), + )) + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct TsNodeRequireReference { + pub origin: Vc>, + pub request: Vc, +} + +#[turbo_tasks::value_impl] +impl TsNodeRequireReference { + #[turbo_tasks::function] + pub fn new(origin: Vc>, request: Vc) -> Vc { + Self::cell(TsNodeRequireReference { origin, request }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for TsNodeRequireReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + cjs_resolve(self.origin, self.request, None, IssueSeverity::Error.cell()) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for TsNodeRequireReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!( + "tsconfig tsnode require {}", + self.request.to_string().await? + ) + .into(), + )) + } +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct TsConfigTypesReference { + pub origin: Vc>, + pub request: Vc, +} + +#[turbo_tasks::value_impl] +impl TsConfigTypesReference { + #[turbo_tasks::function] + pub fn new(origin: Vc>, request: Vc) -> Vc { + Self::cell(TsConfigTypesReference { origin, request }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for TsConfigTypesReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + type_resolve(self.origin, self.request) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for TsConfigTypesReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("tsconfig types {}", self.request.to_string().await?,).into(), + )) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/utils.rs b/turbopack/crates/turbopack-ecmascript/src/utils.rs new file mode 100644 index 0000000000000..0ac4b67e81199 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/utils.rs @@ -0,0 +1,126 @@ +use serde::Serialize; +use swc_core::{ + common::DUMMY_SP, + ecma::ast::{Expr, Lit, Str}, +}; +use turbopack_core::{chunk::ModuleId, resolve::pattern::Pattern}; + +use crate::analyzer::{ConstantNumber, ConstantValue, JsValue}; + +pub fn unparen(expr: &Expr) -> &Expr { + if let Some(expr) = expr.as_paren() { + return unparen(&expr.expr); + } + if let Expr::Seq(seq) = expr { + return unparen(seq.exprs.last().unwrap()); + } + expr +} + +pub fn js_value_to_pattern(value: &JsValue) -> Pattern { + let mut result = match value { + JsValue::Constant(v) => Pattern::Constant(match v { + ConstantValue::Str(str) => str.as_str().into(), + ConstantValue::True => "true".into(), + ConstantValue::False => "false".into(), + ConstantValue::Null => "null".into(), + ConstantValue::Num(ConstantNumber(n)) => n.to_string().into(), + ConstantValue::BigInt(n) => n.to_string().into(), + ConstantValue::Regex(exp, flags) => format!("/{exp}/{flags}").into(), + ConstantValue::Undefined => "undefined".into(), + }), + JsValue::Alternatives(_, alts) => { + Pattern::Alternatives(alts.iter().map(js_value_to_pattern).collect()) + } + JsValue::Concat(_, parts) => { + Pattern::Concatenation(parts.iter().map(js_value_to_pattern).collect()) + } + JsValue::Add(..) => { + // TODO do we need to handle that here + // or is that already covered by normalization of JsValue + Pattern::Dynamic + } + _ => Pattern::Dynamic, + }; + result.normalize(); + result +} + +pub fn module_id_to_lit(module_id: &ModuleId) -> Expr { + Expr::Lit(match module_id { + ModuleId::Number(n) => Lit::Num((*n as f64).into()), + ModuleId::String(s) => Lit::Str(Str { + span: DUMMY_SP, + value: (s as &str).into(), + raw: None, + }), + }) +} + +pub struct StringifyJs<'a, T>(pub &'a T) +where + T: ?Sized; + +impl<'a, T> std::fmt::Display for StringifyJs<'a, T> +where + T: Serialize + ?Sized, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + /// [`std::fmt::Formatter`] does not implement [`std::io::Write`], + /// so we need to wrap it in a struct that does. + struct DisplayWriter<'a, 'b> { + f: &'a mut std::fmt::Formatter<'b>, + } + + impl<'a, 'b> std::io::Write for DisplayWriter<'a, 'b> { + fn write(&mut self, bytes: &[u8]) -> std::result::Result { + self.f + .write_str( + std::str::from_utf8(bytes) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?, + ) + .map_err(|err| std::io::Error::new(std::io::ErrorKind::Other, err))?; + Ok(bytes.len()) + } + + fn flush(&mut self) -> std::result::Result<(), std::io::Error> { + unreachable!() + } + } + + let to_writer = match f.alternate() { + true => serde_json::to_writer_pretty, + false => serde_json::to_writer, + }; + + to_writer(DisplayWriter { f }, self.0).map_err(|_err| std::fmt::Error) + } +} + +pub struct FormatIter T>(pub F); + +macro_rules! format_iter { + ($trait:path) => { + impl T> $trait for FormatIter + where + T::Item: $trait, + { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for item in self.0() { + item.fmt(f)?; + } + Ok(()) + } + } + }; +} + +format_iter!(std::fmt::Binary); +format_iter!(std::fmt::Debug); +format_iter!(std::fmt::Display); +format_iter!(std::fmt::LowerExp); +format_iter!(std::fmt::LowerHex); +format_iter!(std::fmt::Octal); +format_iter!(std::fmt::Pointer); +format_iter!(std::fmt::UpperExp); +format_iter!(std::fmt::UpperHex); diff --git a/turbopack/crates/turbopack-ecmascript/src/webpack/mod.rs b/turbopack/crates/turbopack-ecmascript/src/webpack/mod.rs new file mode 100644 index 0000000000000..8e0630f76ef74 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/webpack/mod.rs @@ -0,0 +1,199 @@ +use anyhow::Result; +use swc_core::ecma::ast::Lit; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + file_source::FileSource, + ident::AssetIdent, + module::Module, + reference::{ModuleReference, ModuleReferences}, + reference_type::{CommonJsReferenceSubType, ReferenceType}, + resolve::{ + origin::{ResolveOrigin, ResolveOriginExt}, + parse::Request, + resolve, ModuleResolveResult, ModuleResolveResultItem, + }, + source::Source, +}; +use turbopack_resolve::ecmascript::apply_cjs_specific_options; + +use self::{parse::WebpackRuntime, references::module_references}; +use crate::EcmascriptInputTransforms; + +pub mod parse; +pub(crate) mod references; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("webpack".into()) +} + +#[turbo_tasks::value] +pub struct WebpackModuleAsset { + pub source: Vc>, + pub runtime: Vc, + pub transforms: Vc, +} + +#[turbo_tasks::value_impl] +impl WebpackModuleAsset { + #[turbo_tasks::function] + pub fn new( + source: Vc>, + runtime: Vc, + transforms: Vc, + ) -> Vc { + Self::cell(WebpackModuleAsset { + source, + runtime, + transforms, + }) + } +} + +#[turbo_tasks::value_impl] +impl Module for WebpackModuleAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source.ident().with_modifier(modifier()) + } + + #[turbo_tasks::function] + fn references(&self) -> Vc { + module_references(self.source, self.runtime, self.transforms) + } +} + +#[turbo_tasks::value_impl] +impl Asset for WebpackModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value(shared)] +pub struct WebpackChunkAssetReference { + #[turbo_tasks(trace_ignore)] + pub chunk_id: Lit, + pub runtime: Vc, + pub transforms: Vc, +} + +#[turbo_tasks::value_impl] +impl ModuleReference for WebpackChunkAssetReference { + #[turbo_tasks::function] + async fn resolve_reference(&self) -> Result> { + let runtime = self.runtime.await?; + Ok(match &*runtime { + WebpackRuntime::Webpack5 { + chunk_request_expr: _, + context_path, + } => { + // TODO determine filename from chunk_request_expr + let chunk_id = match &self.chunk_id { + Lit::Str(str) => str.value.to_string(), + Lit::Num(num) => format!("{num}"), + _ => todo!(), + }; + let filename = format!("./chunks/{}.js", chunk_id).into(); + let source = Vc::upcast(FileSource::new(context_path.join(filename))); + + ModuleResolveResult::module(Vc::upcast(WebpackModuleAsset::new( + source, + self.runtime, + self.transforms, + ))) + .into() + } + WebpackRuntime::None => ModuleResolveResult::unresolveable().into(), + }) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for WebpackChunkAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + let chunk_id = match &self.chunk_id { + Lit::Str(str) => str.value.to_string(), + Lit::Num(num) => format!("{num}"), + _ => todo!(), + }; + Ok(Vc::cell(format!("webpack chunk {}", chunk_id).into())) + } +} + +#[turbo_tasks::value(shared)] +pub struct WebpackEntryAssetReference { + pub source: Vc>, + pub runtime: Vc, + pub transforms: Vc, +} + +#[turbo_tasks::value_impl] +impl ModuleReference for WebpackEntryAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + ModuleResolveResult::module(Vc::upcast(WebpackModuleAsset::new( + self.source, + self.runtime, + self.transforms, + ))) + .into() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for WebpackEntryAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("webpack entry".into())) + } +} + +#[turbo_tasks::value(shared)] +pub struct WebpackRuntimeAssetReference { + pub origin: Vc>, + pub request: Vc, + pub runtime: Vc, + pub transforms: Vc, +} + +#[turbo_tasks::value_impl] +impl ModuleReference for WebpackRuntimeAssetReference { + #[turbo_tasks::function] + async fn resolve_reference(&self) -> Result> { + let ty = Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)); + let options = self.origin.resolve_options(ty.clone()); + + let options = apply_cjs_specific_options(options); + + let resolved = resolve( + self.origin.origin_path().parent().resolve().await?, + Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), + self.request, + options, + ); + + Ok(resolved + .await? + .map_module(|source| async move { + Ok(ModuleResolveResultItem::Module(Vc::upcast( + WebpackModuleAsset::new(source, self.runtime, self.transforms), + ))) + }) + .await? + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for WebpackRuntimeAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("webpack {}", self.request.to_string().await?,).into(), + )) + } +} diff --git a/turbopack/crates/turbopack-ecmascript/src/webpack/parse.rs b/turbopack/crates/turbopack-ecmascript/src/webpack/parse.rs new file mode 100644 index 0000000000000..50567b3fc4ce7 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/webpack/parse.rs @@ -0,0 +1,245 @@ +use std::borrow::Cow; + +use anyhow::Result; +use swc_core::{ + common::GLOBALS, + ecma::{ + ast::{ + ArrowExpr, AssignOp, AssignTarget, BinExpr, BinaryOp, CallExpr, Callee, Expr, + ExprOrSpread, ExprStmt, FnExpr, Lit, Module, ModuleItem, Program, Script, + SimpleAssignTarget, Stmt, + }, + visit::{Visit, VisitWith}, + }, +}; +use turbo_tasks::{Value, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::source::Source; + +use crate::{ + analyzer::{graph::EvalContext, JsValue}, + parse::{parse, ParseResult}, + utils::unparen, + EcmascriptInputTransforms, EcmascriptModuleAssetType, +}; + +#[turbo_tasks::value(shared, serialization = "none")] +#[derive(Debug)] +pub enum WebpackRuntime { + Webpack5 { + /// There is a [JsValue]::FreeVar("chunkId") that need to be replaced + /// before converting to string + #[turbo_tasks(trace_ignore)] + chunk_request_expr: JsValue, + context_path: Vc, + }, + None, +} + +fn iife(stmt: &Stmt) -> Option<&Vec> { + if let Stmt::Expr(ExprStmt { expr, .. }) = &stmt { + if let Expr::Call(CallExpr { + callee: Callee::Expr(callee), + args, + .. + }) = unparen(expr) + { + if !args.is_empty() { + return None; + } + return get_fn_body(callee); + } + } + None +} + +fn program_iife(program: &Program) -> Option<&Vec> { + match program { + Program::Module(Module { body, .. }) => { + if let [ModuleItem::Stmt(stmt)] = &body[..] { + return iife(stmt); + } + } + Program::Script(Script { body, .. }) => { + if let [stmt] = &body[..] { + return iife(stmt); + } + } + } + None +} + +fn is_webpack_require_decl(stmt: &Stmt) -> bool { + if let Some(decl) = stmt.as_decl() { + if let Some(fn_decl) = decl.as_fn_decl() { + return &*fn_decl.ident.sym == "__webpack_require__"; + } + } + false +} + +fn get_assign_target_identifier(expr: &AssignTarget) -> Option> { + match expr.as_simple()? { + SimpleAssignTarget::Ident(ident) => Some(Cow::Borrowed(&*ident.sym)), + SimpleAssignTarget::Member(member) => { + if let Some(obj_name) = get_expr_identifier(&member.obj) { + if let Some(ident) = member.prop.as_ident() { + return Some(Cow::Owned(obj_name.into_owned() + "." + &*ident.sym)); + } + } + None + } + SimpleAssignTarget::Paren(p) => get_expr_identifier(&p.expr), + + _ => None, + } +} + +fn get_expr_identifier(expr: &Expr) -> Option> { + let expr = unparen(expr); + if let Some(ident) = expr.as_ident() { + return Some(Cow::Borrowed(&*ident.sym)); + } + if let Some(member) = expr.as_member() { + if let Some(ident) = member.prop.as_ident() { + if let Some(obj_name) = get_expr_identifier(&member.obj) { + return Some(Cow::Owned(obj_name.into_owned() + "." + &*ident.sym)); + } + } + } + None +} + +fn get_assignment<'a>(stmts: &'a Vec, property: &str) -> Option<&'a Expr> { + for stmt in stmts { + if let Some(stmts) = iife(stmt) { + if let Some(result) = get_assignment(stmts, property) { + return Some(result); + } + } + if let Some(expr_stmt) = stmt.as_expr() { + if let Some(assign) = unparen(&expr_stmt.expr).as_assign() { + if assign.op == AssignOp::Assign { + if let Some(name) = get_assign_target_identifier(&assign.left) { + if name == property { + return Some(unparen(&assign.right)); + } + } + } + } + } + } + None +} + +fn get_fn_body(expr: &Expr) -> Option<&Vec> { + let expr = unparen(expr); + if let Some(FnExpr { function, .. }) = expr.as_fn_expr() { + if let Some(body) = &function.body { + return Some(&body.stmts); + } + } + if let Some(ArrowExpr { body, .. }) = expr.as_arrow() { + if let Some(block) = body.as_block_stmt() { + return Some(&block.stmts); + } + } + None +} + +fn get_javascript_chunk_filename(stmts: &Vec, eval_context: &EvalContext) -> Option { + if let Some(expr) = get_assignment(stmts, "__webpack_require__.u") { + if let Some(stmts) = get_fn_body(expr) { + if let Some(ret) = stmts.iter().find_map(|stmt| stmt.as_return_stmt()) { + if let Some(expr) = &ret.arg { + return Some(eval_context.eval(expr)); + } + } + } + } + None +} + +struct RequirePrefixVisitor { + result: Option, +} + +impl Visit for RequirePrefixVisitor { + fn visit_call_expr(&mut self, call: &CallExpr) { + if let Some(expr) = call.callee.as_expr() { + if let Some(name) = get_expr_identifier(expr) { + if name == "require" { + if let [ExprOrSpread { spread: None, expr }] = &call.args[..] { + if let Some(BinExpr { + op: BinaryOp::Add, + left, + .. + }) = expr.as_bin() + { + self.result = left.as_lit().cloned(); + return; + } + } + } + } + } + call.visit_children_with(self); + } +} + +fn get_require_prefix(stmts: &Vec) -> Option { + if let Some(expr) = get_assignment(stmts, "__webpack_require__.f.require") { + let mut visitor = RequirePrefixVisitor { result: None }; + expr.visit_children_with(&mut visitor); + return visitor.result; + } + None +} + +#[turbo_tasks::function] +pub async fn webpack_runtime( + source: Vc>, + transforms: Vc, +) -> Result> { + let parsed = parse( + source, + Value::new(EcmascriptModuleAssetType::Ecmascript), + transforms, + ) + .await?; + match &*parsed { + ParseResult::Ok { + program, + eval_context, + globals, + .. + } => { + if let Some(stmts) = program_iife(program) { + if stmts.iter().any(is_webpack_require_decl) { + // extract webpack/runtime/get javascript chunk filename + let chunk_filename = GLOBALS.set(globals, || { + get_javascript_chunk_filename(stmts, eval_context) + }); + + let prefix_path = get_require_prefix(stmts); + + if let (Some(chunk_filename), Some(prefix_path)) = (chunk_filename, prefix_path) + { + let value = JsValue::concat(vec![ + JsValue::Constant(prefix_path.into()), + chunk_filename, + ]); + + return Ok(WebpackRuntime::Webpack5 { + chunk_request_expr: value, + context_path: source.ident().path().parent().resolve().await?, + } + .into()); + } + } + } + } + ParseResult::Unparseable { .. } | ParseResult::NotFound => {} + } + Ok(WebpackRuntime::None.into()) +} diff --git a/turbopack/crates/turbopack-ecmascript/src/webpack/references.rs b/turbopack/crates/turbopack-ecmascript/src/webpack/references.rs new file mode 100644 index 0000000000000..e2e1dc2dead92 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/src/webpack/references.rs @@ -0,0 +1,92 @@ +use anyhow::Result; +use swc_core::{ + common::errors::{Handler, HANDLER}, + ecma::{ + ast::{CallExpr, Expr, ExprOrSpread}, + visit::{Visit, VisitWith}, + }, +}; +use turbo_tasks::{Value, Vc}; +use turbopack_core::{ + reference::{ModuleReference, ModuleReferences}, + source::Source, +}; +use turbopack_swc_utils::emitter::IssueEmitter; + +use super::{parse::WebpackRuntime, WebpackChunkAssetReference}; +use crate::{ + parse::{parse, ParseResult}, + EcmascriptInputTransforms, EcmascriptModuleAssetType, +}; + +#[turbo_tasks::function] +pub async fn module_references( + source: Vc>, + runtime: Vc, + transforms: Vc, +) -> Result> { + let parsed = parse( + source, + Value::new(EcmascriptModuleAssetType::Ecmascript), + transforms, + ) + .await?; + match &*parsed { + ParseResult::Ok { + program, + source_map, + .. + } => { + let mut references = Vec::new(); + let mut visitor = ModuleReferencesVisitor { + references: &mut references, + runtime, + transforms, + }; + let handler = Handler::with_emitter( + true, + false, + Box::new(IssueEmitter::new( + source, + source_map.clone(), + Some("Parsing webpack bundle failed".into()), + )), + ); + HANDLER.set(&handler, || { + program.visit_with(&mut visitor); + }); + Ok(Vc::cell(references)) + } + ParseResult::Unparseable { .. } | ParseResult::NotFound => Ok(Vc::cell(Vec::new())), + } +} + +struct ModuleReferencesVisitor<'a> { + runtime: Vc, + references: &'a mut Vec>>, + transforms: Vc, +} + +impl<'a> Visit for ModuleReferencesVisitor<'a> { + fn visit_call_expr(&mut self, call: &CallExpr) { + if let Some(member) = call.callee.as_expr().and_then(|e| e.as_member()) { + if let (Some(obj), Some(prop)) = (member.obj.as_ident(), member.prop.as_ident()) { + if &*obj.sym == "__webpack_require__" && &*prop.sym == "e" { + if let [ExprOrSpread { spread: None, expr }] = &call.args[..] { + if let Expr::Lit(lit) = &**expr { + self.references.push(Vc::upcast( + WebpackChunkAssetReference { + chunk_id: lit.clone(), + runtime: self.runtime, + transforms: self.transforms, + } + .cell(), + )); + } + } + } + } + } + call.visit_children_with(self); + } +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph-effects.snapshot new file mode 100644 index 0000000000000..8d087befad4da --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph-effects.snapshot @@ -0,0 +1,119 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 54..61#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Variable( + ( + "x", + #2, + ), + ), + ), + ], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 54..64#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph-explained.snapshot new file mode 100644 index 0000000000000..62bddd8b1d963 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph-explained.snapshot @@ -0,0 +1,9 @@ +a = (...) => undefined + +b = (...) => undefined + +c = (...) => undefined + +x = (1 | `${y}.js`) + +y = ("hello" | "world") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph.snapshot new file mode 100644 index 0000000000000..369ce887263d6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/graph.snapshot @@ -0,0 +1,87 @@ +[ + ( + "a", + Function( + 2, + 37, + Constant( + Undefined, + ), + ), + ), + ( + "b", + Function( + 2, + 76, + Constant( + Undefined, + ), + ), + ), + ( + "c", + Function( + 2, + 116, + Constant( + Undefined, + ), + ), + ), + ( + "x", + Alternatives( + 5, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Concat( + 3, + [ + Variable( + ( + "y", + #2, + ), + ), + Constant( + Str( + Word( + ".js", + ), + ), + ), + ], + ), + ], + ), + ), + ( + "y", + Alternatives( + 3, + [ + Constant( + Str( + Word( + "hello", + ), + ), + ), + Constant( + Str( + Word( + "world", + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/input.js new file mode 100644 index 0000000000000..502e5e96c0452 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/input.js @@ -0,0 +1,14 @@ +let x = 1; +let y = "hello"; + +export function a() { + require(x); +} + +export function b() { + y = "world"; +} + +export function c() { + x = y + ".js"; +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/resolved-effects.snapshot new file mode 100644 index 0000000000000..9104e87ad0287 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/resolved-effects.snapshot @@ -0,0 +1,4 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 call = require*0*((1 | `${("hello" | "world")}.js`)) +- *0* require: The require method from CommonJS diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/resolved-explained.snapshot new file mode 100644 index 0000000000000..de2d517105570 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/1/resolved-explained.snapshot @@ -0,0 +1,9 @@ +a = (...) => undefined + +b = (...) => undefined + +c = (...) => undefined + +x = (1 | `${("hello" | "world")}.js`) + +y = ("hello" | "world") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph-effects.snapshot new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph-effects.snapshot @@ -0,0 +1 @@ +[] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph-explained.snapshot new file mode 100644 index 0000000000000..88c5e95a4ce5e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph-explained.snapshot @@ -0,0 +1,5 @@ +x = (1 | y) + +y = x + +z = x diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph.snapshot new file mode 100644 index 0000000000000..7a10306bbc2fe --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/graph.snapshot @@ -0,0 +1,41 @@ +[ + ( + "x", + Alternatives( + 3, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Variable( + ( + "y", + #2, + ), + ), + ], + ), + ), + ( + "y", + Variable( + ( + "x", + #2, + ), + ), + ), + ( + "z", + Variable( + ( + "x", + #2, + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/input.js new file mode 100644 index 0000000000000..afc59ff4f9113 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/input.js @@ -0,0 +1,4 @@ +let x = 1; +let y = x; +x = y; +let z = x; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/resolved-explained.snapshot new file mode 100644 index 0000000000000..b682b0e7c24e7 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/2/resolved-explained.snapshot @@ -0,0 +1,11 @@ +x = (1 | ???*0*) +- *0* y + ⚠️ circular variable reference + +y = (1 | ???*0*) +- *0* x + ⚠️ circular variable reference + +z = (1 | ???*0*) +- *0* x + ⚠️ circular variable reference diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph-effects.snapshot new file mode 100644 index 0000000000000..e68b8967c1f18 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph-effects.snapshot @@ -0,0 +1,969 @@ +[ + Member { + obj: Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + prop: Constant( + Str( + Atom( + "map", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 53..87#0, + in_try: false, + }, + MemberCall { + obj: Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + prop: Constant( + Str( + Atom( + "map", + ), + ), + ), + args: [ + Closure( + Variable( + ( + "*anonymous function 88*", + #0, + ), + ), + EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + ], + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 53..123#0, + in_try: false, + }, + Member { + obj: Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + prop: Constant( + Str( + Atom( + "map", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 135..169#0, + in_try: false, + }, + MemberCall { + obj: Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + prop: Constant( + Str( + Atom( + "map", + ), + ), + ), + args: [ + Closure( + Variable( + ( + "*anonymous function 170*", + #0, + ), + ), + EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + ], + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 135..207#0, + in_try: false, + }, + Member { + obj: Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + prop: Constant( + Str( + Atom( + "map", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 219..253#0, + in_try: false, + }, + MemberCall { + obj: Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + prop: Constant( + Str( + Atom( + "map", + ), + ), + ), + args: [ + Closure( + Variable( + ( + "*anonymous function 254*", + #0, + ), + ), + EffectsBlock { + effects: [ + Member { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 281..296#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 281..288#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + args: [ + Value( + Variable( + ( + "file", + #5, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 281..302#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + ], + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 219..306#0, + in_try: false, + }, + Member { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 339..354#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 339..346#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + args: [ + Value( + Variable( + ( + "file", + #6, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 339..360#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph-explained.snapshot new file mode 100644 index 0000000000000..ee2b7e47659e5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph-explained.snapshot @@ -0,0 +1,23 @@ +*anonymous function 170* = (...) => [file] + +*anonymous function 254* = (...) => FreeVar(require)["resolve"](file) + +*anonymous function 88* = (...) => file + +a = ["../lib/a.js", "../lib/b.js"] + +b = ["../lib/a.js", "../lib/b.js"]["map"](*anonymous function 88*) + +c = ["../lib/a.js", "../lib/b.js"]["map"](*anonymous function 170*) + +d = ["../lib/a.js", "../lib/b.js"]["map"](*anonymous function 254*) + +file#3 = arguments[0] + +file#4 = arguments[0] + +file#5 = arguments[0] + +file#6 = arguments[0] + +func = (...) => FreeVar(require)["resolve"](file) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph.snapshot new file mode 100644 index 0000000000000..a7dd833044bdc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/graph.snapshot @@ -0,0 +1,264 @@ +[ + ( + "*anonymous function 170*", + Function( + 3, + 170, + Array { + total_nodes: 2, + items: [ + Variable( + ( + "file", + #4, + ), + ), + ], + mutable: true, + }, + ), + ), + ( + "*anonymous function 254*", + Function( + 5, + 254, + MemberCall( + 4, + FreeVar( + "require", + ), + Constant( + Str( + Atom( + "resolve", + ), + ), + ), + [ + Variable( + ( + "file", + #5, + ), + ), + ], + ), + ), + ), + ( + "*anonymous function 88*", + Function( + 2, + 88, + Variable( + ( + "file", + #3, + ), + ), + ), + ), + ( + "a", + Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "b", + MemberCall( + 6, + Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + Constant( + Str( + Atom( + "map", + ), + ), + ), + [ + Variable( + ( + "*anonymous function 88*", + #0, + ), + ), + ], + ), + ), + ( + "c", + MemberCall( + 6, + Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + Constant( + Str( + Atom( + "map", + ), + ), + ), + [ + Variable( + ( + "*anonymous function 170*", + #0, + ), + ), + ], + ), + ), + ( + "d", + MemberCall( + 6, + Array { + total_nodes: 3, + items: [ + Constant( + Str( + Word( + "../lib/a.js", + ), + ), + ), + Constant( + Str( + Word( + "../lib/b.js", + ), + ), + ), + ], + mutable: true, + }, + Constant( + Str( + Atom( + "map", + ), + ), + ), + [ + Variable( + ( + "*anonymous function 254*", + #0, + ), + ), + ], + ), + ), + ( + "file#3", + Argument( + 88, + 0, + ), + ), + ( + "file#4", + Argument( + 170, + 0, + ), + ), + ( + "file#5", + Argument( + 254, + 0, + ), + ), + ( + "file#6", + Argument( + 308, + 0, + ), + ), + ( + "func", + Function( + 5, + 308, + MemberCall( + 4, + FreeVar( + "require", + ), + Constant( + Str( + Atom( + "resolve", + ), + ), + ), + [ + Variable( + ( + "file", + #6, + ), + ), + ], + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/input.js new file mode 100644 index 0000000000000..e77e55a04f10b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/input.js @@ -0,0 +1,13 @@ +const a = ["../lib/a.js", "../lib/b.js"]; +const b = ["../lib/a.js", "../lib/b.js"].map(function (file) { + return file; +}); +const c = ["../lib/a.js", "../lib/b.js"].map(function (file) { + return [file]; +}); +const d = ["../lib/a.js", "../lib/b.js"].map(function (file) { + return require.resolve(file); +}); +function func(file) { + return require.resolve(file); +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/resolved-effects.snapshot new file mode 100644 index 0000000000000..de46b90acf8ae --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/resolved-effects.snapshot @@ -0,0 +1,19 @@ +0 -> 2 member call = ["../lib/a.js", "../lib/b.js"]["map"]((...) => file) + +0 -> 4 member call = ["../lib/a.js", "../lib/b.js"]["map"]((...) => [file]) + +0 -> 6 member call = ["../lib/a.js", "../lib/b.js"]["map"]((...) => FreeVar(require)["resolve"](file)) + +6 -> 8 free var = FreeVar(require) + +6 -> 9 member call = require*0*["resolve"](???*1*) +- *0* require: The require method from CommonJS +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 11 free var = FreeVar(require) + +0 -> 12 member call = require*0*["resolve"](???*1*) +- *0* require: The require method from CommonJS +- *1* arguments[0] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/resolved-explained.snapshot new file mode 100644 index 0000000000000..9dfca3fb90a2a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array-map/resolved-explained.snapshot @@ -0,0 +1,31 @@ +*anonymous function 170* = (...) => [file] + +*anonymous function 254* = (...) => FreeVar(require)["resolve"](file) + +*anonymous function 88* = (...) => file + +a = ["../lib/a.js", "../lib/b.js"] + +b = ["../lib/a.js", "../lib/b.js"] + +c = [["../lib/a.js"], ["../lib/b.js"]] + +d = ["\"../lib/a.js\"/resolved/lib/index.js", "\"../lib/b.js\"/resolved/lib/index.js"] + +file#3 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +file#4 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +file#5 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +file#6 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +func = (...) => FreeVar(require)["resolve"](file) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph-effects.snapshot new file mode 100644 index 0000000000000..a58d6868a7add --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph-effects.snapshot @@ -0,0 +1,414 @@ +[ + Member { + obj: Array { + total_nodes: 3, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Str( + Word( + "foo", + ), + ), + ), + ], + mutable: true, + }, + prop: Member( + 3, + FreeVar( + "global", + ), + Constant( + Str( + Atom( + "index", + ), + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 39..63#0, + in_try: false, + }, + Member { + obj: FreeVar( + "global", + ), + prop: Constant( + Str( + Atom( + "index", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + MemberExpr( + Prop, + ), + MemberProp( + Computed, + ), + ComputedPropName( + Expr, + ), + Expr( + Member, + ), + ], + span: 50..62#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + MemberExpr( + Prop, + ), + MemberProp( + Computed, + ), + ComputedPropName( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 50..56#1, + in_try: false, + }, + Member { + obj: Variable( + ( + "d1", + #2, + ), + ), + prop: Member( + 3, + FreeVar( + "global", + ), + Constant( + Str( + Atom( + "index", + ), + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 100..116#0, + in_try: false, + }, + Member { + obj: FreeVar( + "global", + ), + prop: Constant( + Str( + Atom( + "index", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + MemberExpr( + Prop, + ), + MemberProp( + Computed, + ), + ComputedPropName( + Expr, + ), + Expr( + Member, + ), + ], + span: 103..115#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + MemberExpr( + Prop, + ), + MemberProp( + Computed, + ), + ComputedPropName( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 103..109#1, + in_try: false, + }, + Member { + obj: Variable( + ( + "d1", + #2, + ), + ), + prop: Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 129..134#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "d1", + #2, + ), + ), + prop: Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 147..152#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph-explained.snapshot new file mode 100644 index 0000000000000..0c164c5adf3c0 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph-explained.snapshot @@ -0,0 +1,13 @@ +a = 1 + +b = "foo" + +c = [1, "foo"][FreeVar(global)["index"]] + +d1 = [1, "foo"] + +d2 = d1[FreeVar(global)["index"]] + +d3 = d1[1] + +d4 = d1[2] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph.snapshot new file mode 100644 index 0000000000000..aa0d060bcf325 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/graph.snapshot @@ -0,0 +1,147 @@ +[ + ( + "a", + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ( + "b", + Constant( + Str( + Word( + "foo", + ), + ), + ), + ), + ( + "c", + Member( + 7, + Array { + total_nodes: 3, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Str( + Word( + "foo", + ), + ), + ), + ], + mutable: true, + }, + Member( + 3, + FreeVar( + "global", + ), + Constant( + Str( + Atom( + "index", + ), + ), + ), + ), + ), + ), + ( + "d1", + Array { + total_nodes: 3, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Str( + Word( + "foo", + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "d2", + Member( + 5, + Variable( + ( + "d1", + #2, + ), + ), + Member( + 3, + FreeVar( + "global", + ), + Constant( + Str( + Atom( + "index", + ), + ), + ), + ), + ), + ), + ( + "d3", + Member( + 3, + Variable( + ( + "d1", + #2, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "d4", + Member( + 3, + Variable( + ( + "d1", + #2, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/input.js new file mode 100644 index 0000000000000..7c89fbf41e02f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/input.js @@ -0,0 +1,8 @@ +const [a, b] = [1, "foo"]; + +const c = [1, "foo"][global.index]; + +const d1 = [1, "foo"]; +const d2 = d1[global.index]; +const d3 = d1[1]; +const d4 = d1[2]; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/resolved-effects.snapshot new file mode 100644 index 0000000000000..030af945f2bed --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/resolved-effects.snapshot @@ -0,0 +1,3 @@ +0 -> 3 free var = FreeVar(global) + +0 -> 6 free var = FreeVar(global) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/resolved-explained.snapshot new file mode 100644 index 0000000000000..f9f84f2b349e6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/array/resolved-explained.snapshot @@ -0,0 +1,33 @@ +a = 1 + +b = "foo" + +c = (1 | "foo" | ???*0*) +- *0* [][???*1*] + ⚠️ unknown array prototype methods or values +- *1* ???*2*["index"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +d1 = [1, "foo"] + +d2 = (1 | "foo" | ???*0*) +- *0* [][???*1*] + ⚠️ unknown array prototype methods or values +- *1* ???*2*["index"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +d3 = ("foo" | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +d4 = ???*0* +- *0* [1, "foo"][2] + ⚠️ invalid index diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph-effects.snapshot new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph-effects.snapshot @@ -0,0 +1 @@ +[] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph-explained.snapshot new file mode 100644 index 0000000000000..14f76a32b23c0 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph-explained.snapshot @@ -0,0 +1,49 @@ +*anonymous function 116* = (...) => 3 + +*anonymous function 339* = (...) => 3 + +*arrow function 11* = (...) => 1 + +*arrow function 214* = (...) => 1 + +*arrow function 236* = (...) => 2 + +*arrow function 259* = (...) => 1 + +*arrow function 299* = (...) => 2 + +*arrow function 30* = (...) => 2 + +*arrow function 50* = (...) => 1 + +*arrow function 83* = (...) => 2 + +a = *arrow function 11* + +b = *arrow function 30* + +c = *arrow function 50* + +d = *arrow function 83* + +e#2 = *anonymous function 116* + +e#6 = (...) => 4 + +f = e + +x = (...) => undefined + +xa = *arrow function 214* + +xb = *arrow function 236* + +xc = *arrow function 259* + +xd = *arrow function 299* + +xe#12 = (...) => 4 + +xe#8 = *anonymous function 339* + +xf = xe diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph.snapshot new file mode 100644 index 0000000000000..ccf8fa15f2fec --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/graph.snapshot @@ -0,0 +1,288 @@ +[ + ( + "*anonymous function 116*", + Function( + 2, + 116, + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ), + ), + ( + "*anonymous function 339*", + Function( + 2, + 339, + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ), + ), + ( + "*arrow function 11*", + Function( + 2, + 11, + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "*arrow function 214*", + Function( + 2, + 214, + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "*arrow function 236*", + Function( + 2, + 236, + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ), + ( + "*arrow function 259*", + Function( + 2, + 259, + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "*arrow function 299*", + Function( + 2, + 299, + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ), + ( + "*arrow function 30*", + Function( + 2, + 30, + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ), + ( + "*arrow function 50*", + Function( + 2, + 50, + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "*arrow function 83*", + Function( + 2, + 83, + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ), + ( + "a", + Variable( + ( + "*arrow function 11*", + #0, + ), + ), + ), + ( + "b", + Variable( + ( + "*arrow function 30*", + #0, + ), + ), + ), + ( + "c", + Variable( + ( + "*arrow function 50*", + #0, + ), + ), + ), + ( + "d", + Variable( + ( + "*arrow function 83*", + #0, + ), + ), + ), + ( + "e#2", + Variable( + ( + "*anonymous function 116*", + #0, + ), + ), + ), + ( + "e#6", + Function( + 2, + 155, + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + ), + ( + "f", + Variable( + ( + "e", + #6, + ), + ), + ), + ( + "x", + Function( + 2, + 186, + Constant( + Undefined, + ), + ), + ), + ( + "xa", + Variable( + ( + "*arrow function 214*", + #0, + ), + ), + ), + ( + "xb", + Variable( + ( + "*arrow function 236*", + #0, + ), + ), + ), + ( + "xc", + Variable( + ( + "*arrow function 259*", + #0, + ), + ), + ), + ( + "xd", + Variable( + ( + "*arrow function 299*", + #0, + ), + ), + ), + ( + "xe#12", + Function( + 2, + 385, + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + ), + ( + "xe#8", + Variable( + ( + "*anonymous function 339*", + #0, + ), + ), + ), + ( + "xf", + Variable( + ( + "xe", + #12, + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/input.js new file mode 100644 index 0000000000000..70667a80676aa --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/input.js @@ -0,0 +1,33 @@ +const a = () => 1; +const b = () => 2; + +const c = () => { + return 1; +}; +const d = () => { + return 2; +}; +const e = function () { + return 3; +}; +const f = function e() { + return 4; +}; + +function x() { + const xa = () => 1; + const xb = () => 2; + + const xc = () => { + return 1; + }; + const xd = () => { + return 2; + }; + const xe = function () { + return 3; + }; + const xf = function xe() { + return 4; + }; +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/resolved-explained.snapshot new file mode 100644 index 0000000000000..5c6a14b08d961 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/arrow/resolved-explained.snapshot @@ -0,0 +1,49 @@ +*anonymous function 116* = (...) => 3 + +*anonymous function 339* = (...) => 3 + +*arrow function 11* = (...) => 1 + +*arrow function 214* = (...) => 1 + +*arrow function 236* = (...) => 2 + +*arrow function 259* = (...) => 1 + +*arrow function 299* = (...) => 2 + +*arrow function 30* = (...) => 2 + +*arrow function 50* = (...) => 1 + +*arrow function 83* = (...) => 2 + +a = (...) => 1 + +b = (...) => 2 + +c = (...) => 1 + +d = (...) => 2 + +e#2 = (...) => 3 + +e#6 = (...) => 4 + +f = (...) => 4 + +x = (...) => undefined + +xa = (...) => 1 + +xb = (...) => 2 + +xc = (...) => 1 + +xd = (...) => 2 + +xe#12 = (...) => 4 + +xe#8 = (...) => 3 + +xf = (...) => 4 diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph-effects.snapshot new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph-effects.snapshot @@ -0,0 +1 @@ +[] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph-explained.snapshot new file mode 100644 index 0000000000000..1dfd7ca9bed2b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph-explained.snapshot @@ -0,0 +1,15 @@ +a = ("" | `${a}x`) + +b = (0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +c = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d = (0 | 1) + +e = (1 | 2) + +f = (1 | 2) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph.snapshot new file mode 100644 index 0000000000000..77eb8603179aa --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/graph.snapshot @@ -0,0 +1,141 @@ +[ + ( + "a", + Alternatives( + 5, + [ + Constant( + Str( + Word( + "", + ), + ), + ), + Concat( + 3, + [ + Variable( + ( + "a", + #2, + ), + ), + Constant( + Str( + Word( + "x", + ), + ), + ), + ], + ), + ], + ), + ), + ( + "b", + Alternatives( + 3, + [ + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported assign operation", + has_side_effects: true, + }, + ], + ), + ), + ( + "c", + Alternatives( + 3, + [ + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "updated with update expression", + has_side_effects: true, + }, + ], + ), + ), + ( + "d", + Alternatives( + 3, + [ + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + ( + "e", + Alternatives( + 3, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + ( + "f", + Alternatives( + 3, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/input.js new file mode 100644 index 0000000000000..0557cd178145b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/input.js @@ -0,0 +1,12 @@ +let a = ""; +a += "x"; +let b = 0; +b -= 1; +let c = 0; +c++; +let d = 0; +d ||= 1; +let e = 1; +e &&= 2; +let f = 1; +f ??= 2; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/resolved-effects.snapshot new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/resolved-explained.snapshot new file mode 100644 index 0000000000000..4b324f0467e8b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/assign/resolved-explained.snapshot @@ -0,0 +1,19 @@ +a = ("" | `${("" | ???*0*)}x`) +- *0* `${???*1*}x` + ⚠️ nested operation +- *1* a + ⚠️ circular variable reference + +b = (0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +c = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d = (0 | 1) + +e = (1 | 2) + +f = (1 | 2) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph-effects.snapshot new file mode 100644 index 0000000000000..99bc32cbd669b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph-effects.snapshot @@ -0,0 +1,338 @@ +[ + Call { + func: SuperCall( + 2, + [ + Variable( + ( + "*arrow function 138*", + #0, + ), + ), + ], + ), + args: [ + Closure( + Variable( + ( + "*arrow function 138*", + #0, + ), + ), + EffectsBlock { + effects: [ + ImportedBinding { + esm_reference_index: 1, + export: Some( + "named", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Class, + ), + ClassDecl( + Class, + ), + Class( + Body( + 0, + ), + ), + ClassMember( + Constructor, + ), + Constructor( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 152..157#2, + in_try: false, + }, + Call { + func: Member( + 3, + Module( + ModuleValue { + module: "./module.js", + annotations: ImportAnnotations { + map: {}, + }, + }, + ), + Constant( + Str( + Atom( + "named", + ), + ), + ), + ), + args: [], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Class, + ), + ClassDecl( + Class, + ), + Class( + Body( + 0, + ), + ), + ClassMember( + Constructor, + ), + Constructor( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 152..159#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Class, + ), + ClassDecl( + Class, + ), + Class( + Body( + 0, + ), + ), + ClassMember( + Constructor, + ), + Constructor( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + ], + }, + ), + ], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Class, + ), + ClassDecl( + Class, + ), + Class( + Body( + 0, + ), + ), + ClassMember( + Constructor, + ), + Constructor( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 132..167#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph-explained.snapshot new file mode 100644 index 0000000000000..d69f842c26d3f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph-explained.snapshot @@ -0,0 +1,11 @@ +*arrow function 138* = (...) => undefined + +BaseClass = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +SubClass = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +fn = arguments[0] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph.snapshot new file mode 100644 index 0000000000000..fe8e4d080df45 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/graph.snapshot @@ -0,0 +1,35 @@ +[ + ( + "*arrow function 138*", + Function( + 2, + 138, + Constant( + Undefined, + ), + ), + ), + ( + "BaseClass", + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ( + "SubClass", + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ( + "fn", + Argument( + 0, + 0, + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/input.js new file mode 100644 index 0000000000000..bf2dc46c23c6f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/input.js @@ -0,0 +1,13 @@ +import { named } from "./module.js"; + +class BaseClass { + super(fn) {} +} + +class SubClass extends BaseClass { + constructor() { + super(() => { + named(); + }); + } +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/resolved-effects.snapshot new file mode 100644 index 0000000000000..3838a8dbb7e10 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/resolved-effects.snapshot @@ -0,0 +1,3 @@ +0 -> 1 call = super((...) => undefined)((...) => undefined) + +1 -> 3 call = module<./module.js, {}>["named"]() diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/resolved-explained.snapshot new file mode 100644 index 0000000000000..5adc33d03baad --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/class_super/resolved-explained.snapshot @@ -0,0 +1,13 @@ +*arrow function 138* = (...) => undefined + +BaseClass = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +SubClass = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +fn = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph-effects.snapshot new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph-effects.snapshot @@ -0,0 +1 @@ +[] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph-explained.snapshot new file mode 100644 index 0000000000000..b1246f5e35e24 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph-explained.snapshot @@ -0,0 +1,7 @@ +a = "" + +b = "hello" + +c = "--service=0.14.12" + +d = "--service=0.14.12" diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph.snapshot new file mode 100644 index 0000000000000..d022def9690bb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/graph.snapshot @@ -0,0 +1,42 @@ +[ + ( + "a", + Constant( + Str( + Atom( + "", + ), + ), + ), + ), + ( + "b", + Constant( + Str( + Atom( + "hello", + ), + ), + ), + ), + ( + "c", + Constant( + Str( + RcStr( + "--service=0.14.12", + ), + ), + ), + ), + ( + "d", + Constant( + Str( + RcStr( + "--service=0.14.12", + ), + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/input.js new file mode 100644 index 0000000000000..1de4603e1e502 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/input.js @@ -0,0 +1,4 @@ +const a = ``; +const b = `hello`; +const c = `--service=${"0.14.12"}`; +const d = `${"--service="}${"0.14.12"}`; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/resolved-explained.snapshot new file mode 100644 index 0000000000000..b1246f5e35e24 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/concat/resolved-explained.snapshot @@ -0,0 +1,7 @@ +a = "" + +b = "hello" + +c = "--service=0.14.12" + +d = "--service=0.14.12" diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph-effects.snapshot new file mode 100644 index 0000000000000..64eed55d89c43 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph-effects.snapshot @@ -0,0 +1,835 @@ +[ + Conditional { + condition: Constant( + True, + ), + kind: Ternary { + then: EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + ], + span: 18..34#0, + in_try: false, + }, + Call { + func: FreeVar( + "import", + ), + args: [ + Value( + Constant( + Str( + Word( + "a", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 11..35#0, + in_try: false, + }, + Member { + obj: Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "env", + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "NEXT_RUNTIME", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 53..77#0, + in_try: false, + }, + Member { + obj: FreeVar( + "process", + ), + prop: Constant( + Str( + Atom( + "env", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + ], + span: 53..64#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "process", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 53..60#1, + in_try: false, + }, + Conditional { + condition: Binary( + 7, + Member( + 5, + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "env", + ), + ), + ), + ), + Constant( + Str( + Atom( + "NEXT_RUNTIME", + ), + ), + ), + ), + StrictEqual, + Constant( + Str( + Word( + "edge", + ), + ), + ), + ), + kind: Ternary { + then: EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + ], + span: 53..188#0, + in_try: false, + }, + Call { + func: FreeVar( + "import", + ), + args: [ + Value( + Tenary( + 10, + Binary( + 7, + Member( + 5, + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "env", + ), + ), + ), + ), + Constant( + Str( + Atom( + "NEXT_RUNTIME", + ), + ), + ), + ), + StrictEqual, + Constant( + Str( + Word( + "edge", + ), + ), + ), + ), + Constant( + Str( + Word( + "next/dist/compiled/@vercel/og/index.edge.js", + ), + ), + ), + Constant( + Str( + Word( + "next/dist/compiled/@vercel/og/index.node.js", + ), + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 46..189#0, + in_try: false, + }, + Conditional { + condition: Constant( + True, + ), + kind: IfElse { + then: EffectsBlock { + effects: [ + Call { + func: FreeVar( + "import", + ), + args: [ + Value( + Constant( + Str( + Word( + "a", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 216..227#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [ + Call { + func: FreeVar( + "import", + ), + args: [ + Value( + Constant( + Str( + Word( + "b", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 243..254#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 198..256#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph-explained.snapshot new file mode 100644 index 0000000000000..f235469d75217 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph-explained.snapshot @@ -0,0 +1,9 @@ +a = FreeVar(import)("a") + +b = (???*0* | FreeVar(import)("a") | FreeVar(import)("b")) +- *0* b + ⚠️ pattern without value + +c = FreeVar(import)( + ((FreeVar(process)["env"]["NEXT_RUNTIME"] === "edge") ? "next/dist/compiled/@vercel/og/index.edge.js" : "next/dist/compiled/@vercel/og/index.node.js") +) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph.snapshot new file mode 100644 index 0000000000000..20c20d629caab --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/graph.snapshot @@ -0,0 +1,132 @@ +[ + ( + "a", + Call( + 3, + FreeVar( + "import", + ), + [ + Constant( + Str( + Word( + "a", + ), + ), + ), + ], + ), + ), + ( + "b", + Alternatives( + 8, + [ + Unknown { + original_value: Some( + Variable( + ( + "b", + #2, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Call( + 3, + FreeVar( + "import", + ), + [ + Constant( + Str( + Word( + "a", + ), + ), + ), + ], + ), + Call( + 3, + FreeVar( + "import", + ), + [ + Constant( + Str( + Word( + "b", + ), + ), + ), + ], + ), + ], + ), + ), + ( + "c", + Call( + 12, + FreeVar( + "import", + ), + [ + Tenary( + 10, + Binary( + 7, + Member( + 5, + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "env", + ), + ), + ), + ), + Constant( + Str( + Atom( + "NEXT_RUNTIME", + ), + ), + ), + ), + StrictEqual, + Constant( + Str( + Word( + "edge", + ), + ), + ), + ), + Constant( + Str( + Word( + "next/dist/compiled/@vercel/og/index.edge.js", + ), + ), + ), + Constant( + Str( + Word( + "next/dist/compiled/@vercel/og/index.node.js", + ), + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/input.js new file mode 100644 index 0000000000000..4fe69c7f6bc6d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/input.js @@ -0,0 +1,11 @@ +const a = import(true ? "a" : "b") +const c = import(process.env.NEXT_RUNTIME === 'edge' + ? 'next/dist/compiled/@vercel/og/index.edge.js' + : 'next/dist/compiled/@vercel/og/index.node.js') +let b; + +if (true) { + b = import("a") +} else { + b = import("b") +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/resolved-effects.snapshot new file mode 100644 index 0000000000000..a79f0a9546548 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/resolved-effects.snapshot @@ -0,0 +1,25 @@ +0 -> 1 conditional = true + +0 -> 2 call = import*0*("a") +- *0* import: The dynamic import() method from the ESM specification: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports + +0 -> 5 free var = FreeVar(process) + +0 -> 6 conditional = (process.env*0*["NEXT_RUNTIME"] === "edge") +- *0* process.env: The Node.js process.env property: https://nodejs.org/api/process.html#processenv + +0 -> 7 call = import*0*( + (???*1* ? "next/dist/compiled/@vercel/og/index.edge.js" : "next/dist/compiled/@vercel/og/index.node.js") +) +- *0* import: The dynamic import() method from the ESM specification: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports +- *1* (process.env*2*["NEXT_RUNTIME"] === "edge") + ⚠️ nested operation +- *2* process.env: The Node.js process.env property: https://nodejs.org/api/process.html#processenv + +0 -> 8 conditional = true + +8 -> 9 call = import*0*("a") +- *0* import: The dynamic import() method from the ESM specification: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports + +8 -> 10 call = import*0*("b") +- *0* import: The dynamic import() method from the ESM specification: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/resolved-explained.snapshot new file mode 100644 index 0000000000000..666a893d17dce --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/conditional-import/resolved-explained.snapshot @@ -0,0 +1,16 @@ +a = module<"a", {}> + +b = (???*0* | module<"a", {}> | module<"b", {}>) +- *0* b + ⚠️ pattern without value + +c = ???*0* +- *0* import*1*( + (???*2* ? "next/dist/compiled/@vercel/og/index.edge.js" : "next/dist/compiled/@vercel/og/index.node.js") + ) + ⚠️ import() non constant + ⚠️ This value might have side effects +- *1* import: The dynamic import() method from the ESM specification: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports +- *2* (process.env*3*["NEXT_RUNTIME"] === "edge") + ⚠️ nested operation +- *3* process.env: The Node.js process.env property: https://nodejs.org/api/process.html#processenv diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph-effects.snapshot new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph-effects.snapshot @@ -0,0 +1 @@ +[] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph-explained.snapshot new file mode 100644 index 0000000000000..bee39e2006c85 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph-explained.snapshot @@ -0,0 +1,189 @@ +*arrow function 425* = (...) => *arrow function 431* + +*arrow function 431* = (...) => *arrow function 437* + +*arrow function 437* = (...) => *arrow function 443* + +*arrow function 443* = (...) => *arrow function 449* + +*arrow function 449* = (...) => 1 + +*arrow function 468* = (...) => *arrow function 474* + +*arrow function 474* = (...) => *arrow function 480* + +*arrow function 480* = (...) => *arrow function 486* + +*arrow function 486* = (...) => *arrow function 492* + +*arrow function 492* = (...) => 2 + +*arrow function 511* = (...) => *arrow function 517* + +*arrow function 517* = (...) => *arrow function 523* + +*arrow function 523* = (...) => *arrow function 529* + +*arrow function 529* = (...) => *arrow function 535* + +*arrow function 535* = (...) => 2 + +*arrow function 554* = (...) => *arrow function 560* + +*arrow function 560* = (...) => *arrow function 566* + +*arrow function 566* = (...) => *arrow function 572* + +*arrow function 572* = (...) => *arrow function 578* + +*arrow function 578* = (...) => 1 + +a = (1 | 2 | 3 | b) + +b = (4 | 5 | 6 | c) + +c = (7 | 8 | 9 | a) + +d = ( + | f11 + | f22 + | f32 + | f42 + | f52 + | f62 + | f72 + | f82 + | f92 + | fa2 + | fb2 + | fc2 + | fd2 + | fe2 + | ff2 + | fg2 + | fh2 + | fi2 + | fj2 + | fk2 + | fl2 +) + +f11 = (*arrow function 425* | *arrow function 468*) + +f12 = (*arrow function 511* | *arrow function 554*) + +f21 = (f11 | f12) + +f22 = (f12 | f11) + +f31 = (f21 | f22) + +f32 = (f22 | f21) + +f41 = (f31 | f32) + +f42 = (f32 | f31) + +f51 = (f41 | f42) + +f52 = (f42 | f41) + +f61 = (f51 | f52) + +f62 = (f52 | f51) + +f71 = (f61 | f62) + +f72 = (f62 | f61) + +f81 = (f71 | f72) + +f82 = (f72 | f71) + +f91 = (f81 | f82) + +f92 = (f82 | f81) + +fa1 = (f91 | f92) + +fa2 = (f92 | f91) + +fb1 = (fa1 | fa2) + +fb2 = (fa2 | fa1) + +fc1 = (fb1 | fb2) + +fc2 = (fb2 | fb1) + +fd1 = (fc1 | fc2) + +fd2 = (fc2 | fc1) + +fe1 = (fd1 | fd2) + +fe2 = (fd2 | fd1) + +ff1 = (fe1 | fe2) + +ff2 = (fe2 | fe1) + +fg1 = (ff1 | ff2) + +fg2 = (ff2 | ff1) + +fh1 = (fg1 | fg2) + +fh2 = (fg2 | fg1) + +fi1 = (fh1 | fh2) + +fi2 = (fh2 | fh1) + +fj1 = (fi1 | fi2) + +fj2 = (fi2 | fi1) + +fk1 = (fj1 | fj2) + +fk2 = (fj2 | fj1) + +fl1 = (fk1 | fk2) + +fl2 = (fk2 | fk1) + +x = (a | b | c) + +x1 = (x1 | x2 | x3 | x4 | x5 | x6) + +x2 = (x1 | x2 | x3 | x4 | x5 | x6) + +x3 = (x1 | x2 | x3 | x4 | x5 | x6) + +x4 = (x1 | x2 | x3 | x4 | x5 | x6) + +x5 = (x1 | x2 | x3 | x4 | x5 | x6) + +x6 = (x1 | x2 | x3 | x4 | x5 | x6) + +y = (a | b | c | x) + +z = (a | b | c | y) + +z1 = z + +z2 = z1 + +z3 = z2 + +z4 = z3 + +z5 = z4 + +z6 = z5 + +z7 = z6 + +z8 = z7 + +z9 = z8 diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph.snapshot new file mode 100644 index 0000000000000..71b4766e54064 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/graph.snapshot @@ -0,0 +1,1780 @@ +[ + ( + "*arrow function 425*", + Function( + 2, + 425, + Variable( + ( + "*arrow function 431*", + #0, + ), + ), + ), + ), + ( + "*arrow function 431*", + Function( + 2, + 431, + Variable( + ( + "*arrow function 437*", + #0, + ), + ), + ), + ), + ( + "*arrow function 437*", + Function( + 2, + 437, + Variable( + ( + "*arrow function 443*", + #0, + ), + ), + ), + ), + ( + "*arrow function 443*", + Function( + 2, + 443, + Variable( + ( + "*arrow function 449*", + #0, + ), + ), + ), + ), + ( + "*arrow function 449*", + Function( + 2, + 449, + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "*arrow function 468*", + Function( + 2, + 468, + Variable( + ( + "*arrow function 474*", + #0, + ), + ), + ), + ), + ( + "*arrow function 474*", + Function( + 2, + 474, + Variable( + ( + "*arrow function 480*", + #0, + ), + ), + ), + ), + ( + "*arrow function 480*", + Function( + 2, + 480, + Variable( + ( + "*arrow function 486*", + #0, + ), + ), + ), + ), + ( + "*arrow function 486*", + Function( + 2, + 486, + Variable( + ( + "*arrow function 492*", + #0, + ), + ), + ), + ), + ( + "*arrow function 492*", + Function( + 2, + 492, + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ), + ( + "*arrow function 511*", + Function( + 2, + 511, + Variable( + ( + "*arrow function 517*", + #0, + ), + ), + ), + ), + ( + "*arrow function 517*", + Function( + 2, + 517, + Variable( + ( + "*arrow function 523*", + #0, + ), + ), + ), + ), + ( + "*arrow function 523*", + Function( + 2, + 523, + Variable( + ( + "*arrow function 529*", + #0, + ), + ), + ), + ), + ( + "*arrow function 529*", + Function( + 2, + 529, + Variable( + ( + "*arrow function 535*", + #0, + ), + ), + ), + ), + ( + "*arrow function 535*", + Function( + 2, + 535, + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ), + ( + "*arrow function 554*", + Function( + 2, + 554, + Variable( + ( + "*arrow function 560*", + #0, + ), + ), + ), + ), + ( + "*arrow function 560*", + Function( + 2, + 560, + Variable( + ( + "*arrow function 566*", + #0, + ), + ), + ), + ), + ( + "*arrow function 566*", + Function( + 2, + 566, + Variable( + ( + "*arrow function 572*", + #0, + ), + ), + ), + ), + ( + "*arrow function 572*", + Function( + 2, + 572, + Variable( + ( + "*arrow function 578*", + #0, + ), + ), + ), + ), + ( + "*arrow function 578*", + Function( + 2, + 578, + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "a", + Alternatives( + 5, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + Variable( + ( + "b", + #2, + ), + ), + ], + ), + ), + ( + "b", + Alternatives( + 5, + [ + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + Variable( + ( + "c", + #2, + ), + ), + ], + ), + ), + ( + "c", + Alternatives( + 5, + [ + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + Variable( + ( + "a", + #2, + ), + ), + ], + ), + ), + ( + "d", + Alternatives( + 22, + [ + Variable( + ( + "f11", + #2, + ), + ), + Variable( + ( + "f22", + #2, + ), + ), + Variable( + ( + "f32", + #2, + ), + ), + Variable( + ( + "f42", + #2, + ), + ), + Variable( + ( + "f52", + #2, + ), + ), + Variable( + ( + "f62", + #2, + ), + ), + Variable( + ( + "f72", + #2, + ), + ), + Variable( + ( + "f82", + #2, + ), + ), + Variable( + ( + "f92", + #2, + ), + ), + Variable( + ( + "fa2", + #2, + ), + ), + Variable( + ( + "fb2", + #2, + ), + ), + Variable( + ( + "fc2", + #2, + ), + ), + Variable( + ( + "fd2", + #2, + ), + ), + Variable( + ( + "fe2", + #2, + ), + ), + Variable( + ( + "ff2", + #2, + ), + ), + Variable( + ( + "fg2", + #2, + ), + ), + Variable( + ( + "fh2", + #2, + ), + ), + Variable( + ( + "fi2", + #2, + ), + ), + Variable( + ( + "fj2", + #2, + ), + ), + Variable( + ( + "fk2", + #2, + ), + ), + Variable( + ( + "fl2", + #2, + ), + ), + ], + ), + ), + ( + "f11", + Alternatives( + 3, + [ + Variable( + ( + "*arrow function 425*", + #0, + ), + ), + Variable( + ( + "*arrow function 468*", + #0, + ), + ), + ], + ), + ), + ( + "f12", + Alternatives( + 3, + [ + Variable( + ( + "*arrow function 511*", + #0, + ), + ), + Variable( + ( + "*arrow function 554*", + #0, + ), + ), + ], + ), + ), + ( + "f21", + Alternatives( + 3, + [ + Variable( + ( + "f11", + #2, + ), + ), + Variable( + ( + "f12", + #2, + ), + ), + ], + ), + ), + ( + "f22", + Alternatives( + 3, + [ + Variable( + ( + "f12", + #2, + ), + ), + Variable( + ( + "f11", + #2, + ), + ), + ], + ), + ), + ( + "f31", + Alternatives( + 3, + [ + Variable( + ( + "f21", + #2, + ), + ), + Variable( + ( + "f22", + #2, + ), + ), + ], + ), + ), + ( + "f32", + Alternatives( + 3, + [ + Variable( + ( + "f22", + #2, + ), + ), + Variable( + ( + "f21", + #2, + ), + ), + ], + ), + ), + ( + "f41", + Alternatives( + 3, + [ + Variable( + ( + "f31", + #2, + ), + ), + Variable( + ( + "f32", + #2, + ), + ), + ], + ), + ), + ( + "f42", + Alternatives( + 3, + [ + Variable( + ( + "f32", + #2, + ), + ), + Variable( + ( + "f31", + #2, + ), + ), + ], + ), + ), + ( + "f51", + Alternatives( + 3, + [ + Variable( + ( + "f41", + #2, + ), + ), + Variable( + ( + "f42", + #2, + ), + ), + ], + ), + ), + ( + "f52", + Alternatives( + 3, + [ + Variable( + ( + "f42", + #2, + ), + ), + Variable( + ( + "f41", + #2, + ), + ), + ], + ), + ), + ( + "f61", + Alternatives( + 3, + [ + Variable( + ( + "f51", + #2, + ), + ), + Variable( + ( + "f52", + #2, + ), + ), + ], + ), + ), + ( + "f62", + Alternatives( + 3, + [ + Variable( + ( + "f52", + #2, + ), + ), + Variable( + ( + "f51", + #2, + ), + ), + ], + ), + ), + ( + "f71", + Alternatives( + 3, + [ + Variable( + ( + "f61", + #2, + ), + ), + Variable( + ( + "f62", + #2, + ), + ), + ], + ), + ), + ( + "f72", + Alternatives( + 3, + [ + Variable( + ( + "f62", + #2, + ), + ), + Variable( + ( + "f61", + #2, + ), + ), + ], + ), + ), + ( + "f81", + Alternatives( + 3, + [ + Variable( + ( + "f71", + #2, + ), + ), + Variable( + ( + "f72", + #2, + ), + ), + ], + ), + ), + ( + "f82", + Alternatives( + 3, + [ + Variable( + ( + "f72", + #2, + ), + ), + Variable( + ( + "f71", + #2, + ), + ), + ], + ), + ), + ( + "f91", + Alternatives( + 3, + [ + Variable( + ( + "f81", + #2, + ), + ), + Variable( + ( + "f82", + #2, + ), + ), + ], + ), + ), + ( + "f92", + Alternatives( + 3, + [ + Variable( + ( + "f82", + #2, + ), + ), + Variable( + ( + "f81", + #2, + ), + ), + ], + ), + ), + ( + "fa1", + Alternatives( + 3, + [ + Variable( + ( + "f91", + #2, + ), + ), + Variable( + ( + "f92", + #2, + ), + ), + ], + ), + ), + ( + "fa2", + Alternatives( + 3, + [ + Variable( + ( + "f92", + #2, + ), + ), + Variable( + ( + "f91", + #2, + ), + ), + ], + ), + ), + ( + "fb1", + Alternatives( + 3, + [ + Variable( + ( + "fa1", + #2, + ), + ), + Variable( + ( + "fa2", + #2, + ), + ), + ], + ), + ), + ( + "fb2", + Alternatives( + 3, + [ + Variable( + ( + "fa2", + #2, + ), + ), + Variable( + ( + "fa1", + #2, + ), + ), + ], + ), + ), + ( + "fc1", + Alternatives( + 3, + [ + Variable( + ( + "fb1", + #2, + ), + ), + Variable( + ( + "fb2", + #2, + ), + ), + ], + ), + ), + ( + "fc2", + Alternatives( + 3, + [ + Variable( + ( + "fb2", + #2, + ), + ), + Variable( + ( + "fb1", + #2, + ), + ), + ], + ), + ), + ( + "fd1", + Alternatives( + 3, + [ + Variable( + ( + "fc1", + #2, + ), + ), + Variable( + ( + "fc2", + #2, + ), + ), + ], + ), + ), + ( + "fd2", + Alternatives( + 3, + [ + Variable( + ( + "fc2", + #2, + ), + ), + Variable( + ( + "fc1", + #2, + ), + ), + ], + ), + ), + ( + "fe1", + Alternatives( + 3, + [ + Variable( + ( + "fd1", + #2, + ), + ), + Variable( + ( + "fd2", + #2, + ), + ), + ], + ), + ), + ( + "fe2", + Alternatives( + 3, + [ + Variable( + ( + "fd2", + #2, + ), + ), + Variable( + ( + "fd1", + #2, + ), + ), + ], + ), + ), + ( + "ff1", + Alternatives( + 3, + [ + Variable( + ( + "fe1", + #2, + ), + ), + Variable( + ( + "fe2", + #2, + ), + ), + ], + ), + ), + ( + "ff2", + Alternatives( + 3, + [ + Variable( + ( + "fe2", + #2, + ), + ), + Variable( + ( + "fe1", + #2, + ), + ), + ], + ), + ), + ( + "fg1", + Alternatives( + 3, + [ + Variable( + ( + "ff1", + #2, + ), + ), + Variable( + ( + "ff2", + #2, + ), + ), + ], + ), + ), + ( + "fg2", + Alternatives( + 3, + [ + Variable( + ( + "ff2", + #2, + ), + ), + Variable( + ( + "ff1", + #2, + ), + ), + ], + ), + ), + ( + "fh1", + Alternatives( + 3, + [ + Variable( + ( + "fg1", + #2, + ), + ), + Variable( + ( + "fg2", + #2, + ), + ), + ], + ), + ), + ( + "fh2", + Alternatives( + 3, + [ + Variable( + ( + "fg2", + #2, + ), + ), + Variable( + ( + "fg1", + #2, + ), + ), + ], + ), + ), + ( + "fi1", + Alternatives( + 3, + [ + Variable( + ( + "fh1", + #2, + ), + ), + Variable( + ( + "fh2", + #2, + ), + ), + ], + ), + ), + ( + "fi2", + Alternatives( + 3, + [ + Variable( + ( + "fh2", + #2, + ), + ), + Variable( + ( + "fh1", + #2, + ), + ), + ], + ), + ), + ( + "fj1", + Alternatives( + 3, + [ + Variable( + ( + "fi1", + #2, + ), + ), + Variable( + ( + "fi2", + #2, + ), + ), + ], + ), + ), + ( + "fj2", + Alternatives( + 3, + [ + Variable( + ( + "fi2", + #2, + ), + ), + Variable( + ( + "fi1", + #2, + ), + ), + ], + ), + ), + ( + "fk1", + Alternatives( + 3, + [ + Variable( + ( + "fj1", + #2, + ), + ), + Variable( + ( + "fj2", + #2, + ), + ), + ], + ), + ), + ( + "fk2", + Alternatives( + 3, + [ + Variable( + ( + "fj2", + #2, + ), + ), + Variable( + ( + "fj1", + #2, + ), + ), + ], + ), + ), + ( + "fl1", + Alternatives( + 3, + [ + Variable( + ( + "fk1", + #2, + ), + ), + Variable( + ( + "fk2", + #2, + ), + ), + ], + ), + ), + ( + "fl2", + Alternatives( + 3, + [ + Variable( + ( + "fk2", + #2, + ), + ), + Variable( + ( + "fk1", + #2, + ), + ), + ], + ), + ), + ( + "x", + Alternatives( + 4, + [ + Variable( + ( + "a", + #2, + ), + ), + Variable( + ( + "b", + #2, + ), + ), + Variable( + ( + "c", + #2, + ), + ), + ], + ), + ), + ( + "x1", + Alternatives( + 7, + [ + Variable( + ( + "x1", + #2, + ), + ), + Variable( + ( + "x2", + #2, + ), + ), + Variable( + ( + "x3", + #2, + ), + ), + Variable( + ( + "x4", + #2, + ), + ), + Variable( + ( + "x5", + #2, + ), + ), + Variable( + ( + "x6", + #2, + ), + ), + ], + ), + ), + ( + "x2", + Alternatives( + 7, + [ + Variable( + ( + "x1", + #2, + ), + ), + Variable( + ( + "x2", + #2, + ), + ), + Variable( + ( + "x3", + #2, + ), + ), + Variable( + ( + "x4", + #2, + ), + ), + Variable( + ( + "x5", + #2, + ), + ), + Variable( + ( + "x6", + #2, + ), + ), + ], + ), + ), + ( + "x3", + Alternatives( + 7, + [ + Variable( + ( + "x1", + #2, + ), + ), + Variable( + ( + "x2", + #2, + ), + ), + Variable( + ( + "x3", + #2, + ), + ), + Variable( + ( + "x4", + #2, + ), + ), + Variable( + ( + "x5", + #2, + ), + ), + Variable( + ( + "x6", + #2, + ), + ), + ], + ), + ), + ( + "x4", + Alternatives( + 7, + [ + Variable( + ( + "x1", + #2, + ), + ), + Variable( + ( + "x2", + #2, + ), + ), + Variable( + ( + "x3", + #2, + ), + ), + Variable( + ( + "x4", + #2, + ), + ), + Variable( + ( + "x5", + #2, + ), + ), + Variable( + ( + "x6", + #2, + ), + ), + ], + ), + ), + ( + "x5", + Alternatives( + 7, + [ + Variable( + ( + "x1", + #2, + ), + ), + Variable( + ( + "x2", + #2, + ), + ), + Variable( + ( + "x3", + #2, + ), + ), + Variable( + ( + "x4", + #2, + ), + ), + Variable( + ( + "x5", + #2, + ), + ), + Variable( + ( + "x6", + #2, + ), + ), + ], + ), + ), + ( + "x6", + Alternatives( + 7, + [ + Variable( + ( + "x1", + #2, + ), + ), + Variable( + ( + "x2", + #2, + ), + ), + Variable( + ( + "x3", + #2, + ), + ), + Variable( + ( + "x4", + #2, + ), + ), + Variable( + ( + "x5", + #2, + ), + ), + Variable( + ( + "x6", + #2, + ), + ), + ], + ), + ), + ( + "y", + Alternatives( + 5, + [ + Variable( + ( + "a", + #2, + ), + ), + Variable( + ( + "b", + #2, + ), + ), + Variable( + ( + "c", + #2, + ), + ), + Variable( + ( + "x", + #2, + ), + ), + ], + ), + ), + ( + "z", + Alternatives( + 5, + [ + Variable( + ( + "a", + #2, + ), + ), + Variable( + ( + "b", + #2, + ), + ), + Variable( + ( + "c", + #2, + ), + ), + Variable( + ( + "y", + #2, + ), + ), + ], + ), + ), + ( + "z1", + Variable( + ( + "z", + #2, + ), + ), + ), + ( + "z2", + Variable( + ( + "z1", + #2, + ), + ), + ), + ( + "z3", + Variable( + ( + "z2", + #2, + ), + ), + ), + ( + "z4", + Variable( + ( + "z3", + #2, + ), + ), + ), + ( + "z5", + Variable( + ( + "z4", + #2, + ), + ), + ), + ( + "z6", + Variable( + ( + "z5", + #2, + ), + ), + ), + ( + "z7", + Variable( + ( + "z6", + #2, + ), + ), + ), + ( + "z8", + Variable( + ( + "z7", + #2, + ), + ), + ), + ( + "z9", + Variable( + ( + "z8", + #2, + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/input.js new file mode 100644 index 0000000000000..8dc02acd68844 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/input.js @@ -0,0 +1,182 @@ +// cycle +var a = 1; +var a = 2; +var a = 3; +var a = b; +var b = 4; +var b = 5; +var b = 6; +var b = c; +var c = 7; +var c = 8; +var c = 9; +var c = a; + +// cached +var x = a; +var x = b; +var x = c; +var y = a; +var y = b; +var y = c; +var z = a; +var z = b; +var z = c; + +// chaining +var y = x; +var z = y; +var z1 = z; +var z2 = z1; +var z3 = z2; +var z4 = z3; +var z5 = z4; +var z6 = z5; +var z7 = z6; +var z8 = z7; +var z9 = z8; + +// forking +var f11 = () => () => () => () => () => 1; +var f11 = () => () => () => () => () => 2; +var f12 = () => () => () => () => () => 2; +var f12 = () => () => () => () => () => 1; +var f21 = f11; +var f21 = f12; +var f22 = f12; +var f22 = f11; +var f31 = f21; +var f31 = f22; +var f32 = f22; +var f32 = f21; +var f41 = f31; +var f41 = f32; +var f42 = f32; +var f42 = f31; +var f51 = f41; +var f51 = f42; +var f52 = f42; +var f52 = f41; +var f61 = f51; +var f61 = f52; +var f62 = f52; +var f62 = f51; +var f71 = f61; +var f71 = f62; +var f72 = f62; +var f72 = f61; +var f81 = f71; +var f81 = f72; +var f82 = f72; +var f82 = f71; +var f91 = f81; +var f91 = f82; +var f92 = f82; +var f92 = f81; +var fa1 = f91; +var fa1 = f92; +var fa2 = f92; +var fa2 = f91; +var fb1 = fa1; +var fb1 = fa2; +var fb2 = fa2; +var fb2 = fa1; +var fc1 = fb1; +var fc1 = fb2; +var fc2 = fb2; +var fc2 = fb1; +var fd1 = fc1; +var fd1 = fc2; +var fd2 = fc2; +var fd2 = fc1; +var fe1 = fd1; +var fe1 = fd2; +var fe2 = fd2; +var fe2 = fd1; +var ff1 = fe1; +var ff1 = fe2; +var ff2 = fe2; +var ff2 = fe1; +var fg1 = ff1; +var fg1 = ff2; +var fg2 = ff2; +var fg2 = ff1; +var fh1 = fg1; +var fh1 = fg2; +var fh2 = fg2; +var fh2 = fg1; +var fi1 = fh1; +var fi1 = fh2; +var fi2 = fh2; +var fi2 = fh1; +var fj1 = fi1; +var fj1 = fi2; +var fj2 = fi2; +var fj2 = fi1; +var fk1 = fj1; +var fk1 = fj2; +var fk2 = fj2; +var fk2 = fj1; +var fl1 = fk1; +var fl1 = fk2; +var fl2 = fk2; +var fl2 = fk1; +var d = f11; +var d = f22; +var d = f32; +var d = f42; +var d = f52; +var d = f62; +var d = f72; +var d = f82; +var d = f92; +var d = fa2; +var d = fb2; +var d = fc2; +var d = fd2; +var d = fe2; +var d = ff2; +var d = fg2; +var d = fh2; +var d = fi2; +var d = fj2; +var d = fk2; +var d = fl2; + +// combinations +var x1 = x1; +var x1 = x2; +var x1 = x3; +var x1 = x4; +var x1 = x5; +var x1 = x6; +var x2 = x1; +var x2 = x2; +var x2 = x3; +var x2 = x4; +var x2 = x5; +var x2 = x6; +var x3 = x1; +var x3 = x2; +var x3 = x3; +var x3 = x4; +var x3 = x5; +var x3 = x6; +var x4 = x1; +var x4 = x2; +var x4 = x3; +var x4 = x4; +var x4 = x5; +var x4 = x6; +var x5 = x1; +var x5 = x2; +var x5 = x3; +var x5 = x4; +var x5 = x5; +var x5 = x6; +var x6 = x1; +var x6 = x2; +var x6 = x3; +var x6 = x4; +var x6 = x5; +var x6 = x6; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/resolved-explained.snapshot new file mode 100644 index 0000000000000..1c43d0fa6427c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/cycle-cache/resolved-explained.snapshot @@ -0,0 +1,327 @@ +*arrow function 425* = (...) => *arrow function 431* + +*arrow function 431* = (...) => *arrow function 437* + +*arrow function 437* = (...) => *arrow function 443* + +*arrow function 443* = (...) => *arrow function 449* + +*arrow function 449* = (...) => 1 + +*arrow function 468* = (...) => *arrow function 474* + +*arrow function 474* = (...) => *arrow function 480* + +*arrow function 480* = (...) => *arrow function 486* + +*arrow function 486* = (...) => *arrow function 492* + +*arrow function 492* = (...) => 2 + +*arrow function 511* = (...) => *arrow function 517* + +*arrow function 517* = (...) => *arrow function 523* + +*arrow function 523* = (...) => *arrow function 529* + +*arrow function 529* = (...) => *arrow function 535* + +*arrow function 535* = (...) => 2 + +*arrow function 554* = (...) => *arrow function 560* + +*arrow function 560* = (...) => *arrow function 566* + +*arrow function 566* = (...) => *arrow function 572* + +*arrow function 572* = (...) => *arrow function 578* + +*arrow function 578* = (...) => 1 + +a = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* b + ⚠️ circular variable reference + +b = (4 | 5 | 6 | 7 | 8 | 9 | 1 | 2 | 3 | ???*0*) +- *0* c + ⚠️ circular variable reference + +c = (7 | 8 | 9 | 1 | 2 | 3 | 4 | 5 | 6 | ???*0*) +- *0* a + ⚠️ circular variable reference + +d = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f11 = ((...) => *arrow function 431* | (...) => *arrow function 474*) + +f12 = ((...) => *arrow function 517* | (...) => *arrow function 560*) + +f21 = ( + | (...) => *arrow function 431* + | (...) => *arrow function 474* + | (...) => *arrow function 517* + | (...) => *arrow function 560* +) + +f22 = ( + | (...) => *arrow function 517* + | (...) => *arrow function 560* + | (...) => *arrow function 431* + | (...) => *arrow function 474* +) + +f31 = ( + | (...) => *arrow function 431* + | (...) => *arrow function 474* + | (...) => *arrow function 517* + | (...) => *arrow function 560* +) + +f32 = ( + | (...) => *arrow function 517* + | (...) => *arrow function 560* + | (...) => *arrow function 431* + | (...) => *arrow function 474* +) + +f41 = ( + | (...) => *arrow function 431* + | (...) => *arrow function 474* + | (...) => *arrow function 517* + | (...) => *arrow function 560* +) + +f42 = ( + | (...) => *arrow function 517* + | (...) => *arrow function 560* + | (...) => *arrow function 431* + | (...) => *arrow function 474* +) + +f51 = ( + | (...) => *arrow function 431* + | (...) => *arrow function 474* + | (...) => *arrow function 517* + | (...) => *arrow function 560* +) + +f52 = ( + | (...) => *arrow function 517* + | (...) => *arrow function 560* + | (...) => *arrow function 431* + | (...) => *arrow function 474* +) + +f61 = ( + | (...) => *arrow function 431* + | (...) => *arrow function 474* + | (...) => *arrow function 517* + | (...) => *arrow function 560* +) + +f62 = ( + | (...) => *arrow function 517* + | (...) => *arrow function 560* + | (...) => *arrow function 431* + | (...) => *arrow function 474* +) + +f71 = ( + | (...) => *arrow function 431* + | (...) => *arrow function 474* + | (...) => *arrow function 517* + | (...) => *arrow function 560* +) + +f72 = ( + | (...) => *arrow function 517* + | (...) => *arrow function 560* + | (...) => *arrow function 431* + | (...) => *arrow function 474* +) + +f81 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f82 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f91 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f92 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fa1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fa2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fb1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fb2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fc1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fc2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fd1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fd2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fe1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fe2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ff1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ff2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fg1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fg2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fh1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fh2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fi1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fi2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fj1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fj2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fk1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fk2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fl1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +fl2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +x1 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x2 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x3 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x4 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x5 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x6 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +y = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z1 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z2 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z3 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z4 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z5 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z6 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z7 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z8 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference + +z9 = (1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ???*0*) +- *0* a + ⚠️ circular variable reference diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph-effects.snapshot new file mode 100644 index 0000000000000..e7a4e2f5f179c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph-effects.snapshot @@ -0,0 +1,36 @@ +[ + FreeVar { + var: FreeVar( + "f", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 10, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Ident, + ), + ], + span: 166..167#1, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph-explained.snapshot new file mode 100644 index 0000000000000..31f977832b5b0 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph-explained.snapshot @@ -0,0 +1,25 @@ +*anonymous function 25* = (...) => undefined + +a = (...) => undefined + +aa = a + +b = *anonymous function 25* + +bb = b + +c = 123 + +cc = c + +d = "hello" + +dd = d + +e = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +ee = e + +ff = FreeVar(f) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph.snapshot new file mode 100644 index 0000000000000..bbb9433098157 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/graph.snapshot @@ -0,0 +1,110 @@ +[ + ( + "*anonymous function 25*", + Function( + 2, + 25, + Constant( + Undefined, + ), + ), + ), + ( + "a", + Function( + 2, + 1, + Constant( + Undefined, + ), + ), + ), + ( + "aa", + Variable( + ( + "a", + #2, + ), + ), + ), + ( + "b", + Variable( + ( + "*anonymous function 25*", + #0, + ), + ), + ), + ( + "bb", + Variable( + ( + "b", + #2, + ), + ), + ), + ( + "c", + Constant( + Num( + ConstantNumber( + 123.0, + ), + ), + ), + ), + ( + "cc", + Variable( + ( + "c", + #2, + ), + ), + ), + ( + "d", + Constant( + Str( + Word( + "hello", + ), + ), + ), + ), + ( + "dd", + Variable( + ( + "d", + #2, + ), + ), + ), + ( + "e", + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ( + "ee", + Variable( + ( + "e", + #2, + ), + ), + ), + ( + "ff", + FreeVar( + "f", + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/input.js new file mode 100644 index 0000000000000..1af1f9ee62d98 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/input.js @@ -0,0 +1,12 @@ +function a() {} +var b = function () {}; +let c = 123; +const d = "hello"; +class e {} + +const aa = a; +const bb = b; +const cc = c; +const dd = d; +const ee = e; +const ff = f; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/resolved-effects.snapshot new file mode 100644 index 0000000000000..9a07228e4108f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/resolved-effects.snapshot @@ -0,0 +1 @@ +0 -> 1 free var = FreeVar(f) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/resolved-explained.snapshot new file mode 100644 index 0000000000000..155516648cf4b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/declarations/resolved-explained.snapshot @@ -0,0 +1,30 @@ +*anonymous function 25* = (...) => undefined + +a = (...) => undefined + +aa = (...) => undefined + +b = (...) => undefined + +bb = (...) => undefined + +c = 123 + +cc = 123 + +d = "hello" + +dd = "hello" + +e = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +ee = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +ff = ???*0* +- *0* FreeVar(f) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph-effects.snapshot new file mode 100644 index 0000000000000..ddde9ecd2e030 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph-effects.snapshot @@ -0,0 +1,117 @@ +[ + ImportedBinding { + esm_reference_index: 1, + export: Some( + "named", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Params( + 0, + ), + ), + Param( + Pat, + ), + Pat( + Object, + ), + ObjectPat( + Props( + 0, + ), + ), + ObjectPatProp( + Assign, + ), + AssignPatProp( + Value, + ), + Expr( + Ident, + ), + ], + span: 62..67#2, + in_try: false, + }, + ImportedBinding { + esm_reference_index: 1, + export: Some( + "named", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Params( + 0, + ), + ), + Pat( + Object, + ), + ObjectPat( + Props( + 0, + ), + ), + ObjectPatProp( + Assign, + ), + AssignPatProp( + Value, + ), + Expr( + Ident, + ), + ], + span: 117..122#2, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph-explained.snapshot new file mode 100644 index 0000000000000..28e9c70f99826 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph-explained.snapshot @@ -0,0 +1,9 @@ +*arrow function 105* = (...) => value2 + +Fun = (...) => value + +Fun2 = *arrow function 105* + +value = (arguments[0]["value"] | module<./module.js, {}>["named"]) + +value2 = (arguments[0]["value2"] | module<./module.js, {}>["named"]) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph.snapshot new file mode 100644 index 0000000000000..b826e4e58d496 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/graph.snapshot @@ -0,0 +1,117 @@ +[ + ( + "*arrow function 105*", + Function( + 2, + 105, + Variable( + ( + "value2", + #4, + ), + ), + ), + ), + ( + "Fun", + Function( + 2, + 39, + Variable( + ( + "value", + #3, + ), + ), + ), + ), + ( + "Fun2", + Variable( + ( + "*arrow function 105*", + #0, + ), + ), + ), + ( + "value", + Alternatives( + 7, + [ + Member( + 3, + Argument( + 39, + 0, + ), + Constant( + Str( + Atom( + "value", + ), + ), + ), + ), + Member( + 3, + Module( + ModuleValue { + module: "./module.js", + annotations: ImportAnnotations { + map: {}, + }, + }, + ), + Constant( + Str( + Atom( + "named", + ), + ), + ), + ), + ], + ), + ), + ( + "value2", + Alternatives( + 7, + [ + Member( + 3, + Argument( + 105, + 0, + ), + Constant( + Str( + Atom( + "value2", + ), + ), + ), + ), + Member( + 3, + Module( + ModuleValue { + module: "./module.js", + annotations: ImportAnnotations { + map: {}, + }, + }, + ), + Constant( + Str( + Atom( + "named", + ), + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/input.js new file mode 100644 index 0000000000000..2e35963a1c11d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/input.js @@ -0,0 +1,9 @@ +import { named } from "./module.js"; + +function Fun({ value = named }) { + return value; +} + +const Fun2 = ({ value2 = named }) => { + return value2; +}; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/resolved-explained.snapshot new file mode 100644 index 0000000000000..f5f0c0a8ca9f6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/default-args/resolved-explained.snapshot @@ -0,0 +1,17 @@ +*arrow function 105* = (...) => value2 + +Fun = (...) => value + +Fun2 = (...) => value2 + +value = (???*0* | module<./module.js, {}>["named"]) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +value2 = (???*0* | module<./module.js, {}>["named"]) +- *0* ???*1*["value2"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph-effects.snapshot new file mode 100644 index 0000000000000..9d43d7211e5e9 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph-effects.snapshot @@ -0,0 +1,633 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 12..19#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "path", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 12..27#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 41..48#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "path", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 41..56#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "knownWindowsPackages", + #2, + ), + ), + prop: FreeVar( + "platformKey", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Member, + ), + ], + span: 296..329#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "platformKey", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Member, + ), + MemberExpr( + Prop, + ), + MemberProp( + Computed, + ), + ComputedPropName( + Expr, + ), + Expr( + Ident, + ), + ], + span: 317..328#1, + in_try: false, + }, + Call { + func: Variable( + ( + "pkgAndSubpathForCurrentPlatform", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 443..476#0, + in_try: false, + }, + Member { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 515..530#0, + in_try: true, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 515..522#1, + in_try: true, + }, + MemberCall { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + args: [ + Value( + Concat( + 4, + [ + Variable( + ( + "pkg", + #4, + ), + ), + Constant( + Str( + Atom( + "/", + ), + ), + ), + Variable( + ( + "subpath", + #4, + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 515..551#0, + in_try: true, + }, + Call { + func: Variable( + ( + "generateBinPath", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 598..615#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph-explained.snapshot new file mode 100644 index 0000000000000..93242b4bc3cc1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph-explained.snapshot @@ -0,0 +1,35 @@ +binPath = (???*0* | FreeVar(require)["resolve"](`${pkg}/${subpath}`)) +- *0* binPath + ⚠️ pattern without value + +e = ???*0* +- *0* e + ⚠️ pattern without value + +generateBinPath = (...) => binPath + +knownWindowsPackages = { + "win32 arm64 LE": "esbuild-windows-arm64", + "win32 ia32 LE": "esbuild-windows-32", + "win32 x64 LE": "esbuild-windows-64" +} + +path = FreeVar(require)("path") + +path2 = FreeVar(require)("path") + +pkg#3 = (???*0* | knownWindowsPackages[FreeVar(platformKey)]) +- *0* pkg + ⚠️ pattern without value + +pkg#4 = pkgAndSubpathForCurrentPlatform()["pkg"] + +pkgAndSubpathForCurrentPlatform = (...) => {"pkg": pkg, "subpath": subpath} + +subpath#3 = (???*0* | "esbuild.exe") +- *0* subpath + ⚠️ pattern without value + +subpath#4 = pkgAndSubpathForCurrentPlatform()["subpath"] + +x = generateBinPath() diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph.snapshot new file mode 100644 index 0000000000000..6fd479670795e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/graph.snapshot @@ -0,0 +1,343 @@ +[ + ( + "binPath", + Alternatives( + 9, + [ + Unknown { + original_value: Some( + Variable( + ( + "binPath", + #4, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + MemberCall( + 7, + FreeVar( + "require", + ), + Constant( + Str( + Atom( + "resolve", + ), + ), + ), + [ + Concat( + 4, + [ + Variable( + ( + "pkg", + #4, + ), + ), + Constant( + Str( + Atom( + "/", + ), + ), + ), + Variable( + ( + "subpath", + #4, + ), + ), + ], + ), + ], + ), + ], + ), + ), + ( + "e", + Unknown { + original_value: Some( + Variable( + ( + "e", + #6, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + ), + ( + "generateBinPath", + Function( + 2, + 387, + Variable( + ( + "binPath", + #4, + ), + ), + ), + ), + ( + "knownWindowsPackages", + Object { + total_nodes: 7, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "win32 arm64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-windows-arm64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "win32 ia32 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-windows-32", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "win32 x64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-windows-64", + ), + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "path", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "path", + ), + ), + ), + ], + ), + ), + ( + "path2", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "path", + ), + ), + ), + ], + ), + ), + ( + "pkg#3", + Alternatives( + 5, + [ + Unknown { + original_value: Some( + Variable( + ( + "pkg", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Member( + 3, + Variable( + ( + "knownWindowsPackages", + #2, + ), + ), + FreeVar( + "platformKey", + ), + ), + ], + ), + ), + ( + "pkg#4", + Member( + 4, + Call( + 2, + Variable( + ( + "pkgAndSubpathForCurrentPlatform", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "pkg", + ), + ), + ), + ), + ), + ( + "pkgAndSubpathForCurrentPlatform", + Function( + 6, + 217, + Object { + total_nodes: 5, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "pkg", + ), + ), + ), + Variable( + ( + "pkg", + #3, + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "subpath", + ), + ), + ), + Variable( + ( + "subpath", + #3, + ), + ), + ), + ], + mutable: true, + }, + ), + ), + ( + "subpath#3", + Alternatives( + 3, + [ + Unknown { + original_value: Some( + Variable( + ( + "subpath", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Constant( + Str( + Word( + "esbuild.exe", + ), + ), + ), + ], + ), + ), + ( + "subpath#4", + Member( + 4, + Call( + 2, + Variable( + ( + "pkgAndSubpathForCurrentPlatform", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "subpath", + ), + ), + ), + ), + ), + ( + "x", + Call( + 2, + Variable( + ( + "generateBinPath", + #2, + ), + ), + [], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/input.js new file mode 100644 index 0000000000000..40231dac2ffce --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/input.js @@ -0,0 +1,24 @@ +var path = require("path"); +var path2 = require("path"); + +var knownWindowsPackages = { + "win32 arm64 LE": "esbuild-windows-arm64", + "win32 ia32 LE": "esbuild-windows-32", + "win32 x64 LE": "esbuild-windows-64", +}; +function pkgAndSubpathForCurrentPlatform() { + let pkg; + let subpath; + pkg = knownWindowsPackages[platformKey]; + subpath = "esbuild.exe"; + return { pkg, subpath }; +} +function generateBinPath() { + const { pkg, subpath } = pkgAndSubpathForCurrentPlatform(); + let binPath; + try { + binPath = require.resolve(`${pkg}/${subpath}`); + } catch (e) {} + return binPath; +} +let x = generateBinPath(); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/resolved-effects.snapshot new file mode 100644 index 0000000000000..a352ac825a591 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/resolved-effects.snapshot @@ -0,0 +1,36 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 call = require*0*("path") +- *0* require: The require method from CommonJS + +0 -> 3 free var = FreeVar(require) + +0 -> 4 call = require*0*("path") +- *0* require: The require method from CommonJS + +0 -> 6 free var = FreeVar(platformKey) + +0 -> 7 call = (...) => {"pkg": pkg, "subpath": subpath}() + +0 -> 9 free var = FreeVar(require) + +0 -> 10 member call = require*0*["resolve"]( + `${(???*1* | "esbuild-windows-arm64" | "esbuild-windows-32" | "esbuild-windows-64" | ???*2* | ???*4*)}/${(???*5* | "esbuild.exe" | ???*6*)}` +) +- *0* require: The require method from CommonJS +- *1* pkg + ⚠️ pattern without value +- *2* {}[???*3*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *3* FreeVar(platformKey) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* subpath + ⚠️ pattern without value +- *6* unknown mutation + ⚠️ This value might have side effects + +0 -> 11 call = (...) => binPath() diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/resolved-explained.snapshot new file mode 100644 index 0000000000000..5b1b771cfa5f5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild-reduced/resolved-explained.snapshot @@ -0,0 +1,99 @@ +binPath = (???*0* | ???*1*) +- *0* binPath + ⚠️ pattern without value +- *1* require.resolve*2*( + `${(???*3* | "esbuild-windows-arm64" | "esbuild-windows-32" | "esbuild-windows-64" | ???*4* | ???*6*)}/${(???*7* | "esbuild.exe" | ???*8*)}` + ) + ⚠️ require.resolve non constant + ⚠️ This value might have side effects +- *2* require.resolve: The require.resolve method from CommonJS +- *3* pkg + ⚠️ pattern without value +- *4* {}[???*5*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *5* FreeVar(platformKey) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* subpath + ⚠️ pattern without value +- *8* unknown mutation + ⚠️ This value might have side effects + +e = ???*0* +- *0* e + ⚠️ pattern without value + +generateBinPath = (...) => binPath + +knownWindowsPackages = { + "win32 arm64 LE": "esbuild-windows-arm64", + "win32 ia32 LE": "esbuild-windows-32", + "win32 x64 LE": "esbuild-windows-64" +} + +path = path*0* +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +path2 = path*0* +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +pkg#3 = (???*0* | "esbuild-windows-arm64" | "esbuild-windows-32" | "esbuild-windows-64" | ???*1*) +- *0* pkg + ⚠️ pattern without value +- *1* {}[???*2*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *2* FreeVar(platformKey) + ⚠️ unknown global + ⚠️ This value might have side effects + +pkg#4 = (???*0* | "esbuild-windows-arm64" | "esbuild-windows-32" | "esbuild-windows-64" | ???*1* | ???*3*) +- *0* pkg + ⚠️ pattern without value +- *1* {}[???*2*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *2* FreeVar(platformKey) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects + +pkgAndSubpathForCurrentPlatform = (...) => {"pkg": pkg, "subpath": subpath} + +subpath#3 = (???*0* | "esbuild.exe") +- *0* subpath + ⚠️ pattern without value + +subpath#4 = (???*0* | "esbuild.exe" | ???*1*) +- *0* subpath + ⚠️ pattern without value +- *1* unknown mutation + ⚠️ This value might have side effects + +x = (???*0* | ???*1*) +- *0* binPath + ⚠️ pattern without value +- *1* require.resolve*2*( + `${(???*3* | "esbuild-windows-arm64" | "esbuild-windows-32" | "esbuild-windows-64" | ???*4* | ???*6*)}/${(???*7* | "esbuild.exe" | ???*8*)}` + ) + ⚠️ require.resolve non constant + ⚠️ This value might have side effects +- *2* require.resolve: The require.resolve method from CommonJS +- *3* pkg + ⚠️ pattern without value +- *4* {}[???*5*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *5* FreeVar(platformKey) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* subpath + ⚠️ pattern without value +- *8* unknown mutation + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph-effects.snapshot new file mode 100644 index 0000000000000..3c97beeacce15 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph-effects.snapshot @@ -0,0 +1,5957 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 12..19#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "path", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 12..27#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 41..48#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "path", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 41..56#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 67..74#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "os", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 67..80#0, + in_try: false, + }, + Member { + obj: FreeVar( + "process", + ), + prop: Constant( + Str( + Atom( + "platform", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Member, + ), + ], + span: 1005..1021#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "process", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 1005..1012#1, + in_try: false, + }, + Member { + obj: Variable( + ( + "os", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "arch", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 1025..1032#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "os", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "arch", + ), + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Call, + ), + ], + span: 1025..1034#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "os", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "endianness", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 2, + ), + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 1038..1051#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "os", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "endianness", + ), + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 2, + ), + ), + Expr( + Call, + ), + ], + span: 1038..1053#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "knownWindowsPackages", + #2, + ), + ), + prop: Variable( + ( + "platformKey", + #3, + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Member, + ), + ], + span: 1112..1145#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "knownUnixlikePackages", + #2, + ), + ), + prop: Variable( + ( + "platformKey", + #3, + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Member, + ), + ], + span: 1239..1273#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "Error", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Throw, + ), + ThrowStmt( + Arg, + ), + Expr( + New, + ), + NewExpr( + Callee, + ), + Expr( + Ident, + ), + ], + span: 1329..1334#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "ESBUILD_BINARY_PATH", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Ident, + ), + ], + span: 1444..1463#1, + in_try: false, + }, + Conditional { + condition: FreeVar( + "ESBUILD_BINARY_PATH", + ), + kind: If { + then: EffectsBlock { + effects: [ + FreeVar { + var: FreeVar( + "ESBUILD_BINARY_PATH", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Ident, + ), + ], + span: 1478..1497#1, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 1440..1502#0, + in_try: false, + }, + Call { + func: Variable( + ( + "pkgAndSubpathForCurrentPlatform", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 1530..1563#0, + in_try: false, + }, + Member { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 1602..1617#0, + in_try: true, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 1602..1609#1, + in_try: true, + }, + MemberCall { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + args: [ + Value( + Concat( + 4, + [ + Variable( + ( + "pkg", + #7, + ), + ), + Constant( + Str( + Atom( + "/", + ), + ), + ), + Variable( + ( + "subpath", + #7, + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1602..1638#0, + in_try: true, + }, + FreeVar { + var: FreeVar( + "downloadedBinPath", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 1670..1687#1, + in_try: false, + }, + Call { + func: FreeVar( + "downloadedBinPath", + ), + args: [ + Value( + Variable( + ( + "pkg", + #7, + ), + ), + ), + Value( + Variable( + ( + "subpath", + #7, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1670..1701#0, + in_try: false, + }, + Member { + obj: FreeVar( + "fs", + ), + prop: Constant( + Str( + Atom( + "existsSync", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 1712..1725#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "fs", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 1712..1714#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "fs", + ), + prop: Constant( + Str( + Atom( + "existsSync", + ), + ), + ), + args: [ + Value( + Variable( + ( + "binPath", + #7, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + ], + span: 1712..1734#0, + in_try: false, + }, + Conditional { + condition: Not( + 5, + MemberCall( + 4, + FreeVar( + "fs", + ), + Constant( + Str( + Atom( + "existsSync", + ), + ), + ), + [ + Variable( + ( + "binPath", + #7, + ), + ), + ], + ), + ), + kind: If { + then: EffectsBlock { + effects: [ + Member { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 1758..1773#0, + in_try: true, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 1758..1765#1, + in_try: true, + }, + MemberCall { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + args: [ + Value( + Variable( + ( + "pkg", + #7, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 1758..1778#0, + in_try: true, + }, + FreeVar { + var: FreeVar( + "Error", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Throw, + ), + ThrowStmt( + Arg, + ), + Expr( + New, + ), + NewExpr( + Callee, + ), + Expr( + Ident, + ), + ], + span: 1814..1819#1, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 1707..2154#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 2196..2203#1, + in_try: true, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "pnpapi", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 2196..2213#0, + in_try: true, + }, + Conditional { + condition: Variable( + ( + "isYarnPnP", + #7, + ), + ), + kind: If { + then: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "dirname", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2299..2311#0, + in_try: false, + }, + Member { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2312..2327#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 2312..2319#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "esbuild", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + ], + span: 2312..2338#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "dirname", + ), + ), + ), + args: [ + Value( + MemberCall( + 4, + FreeVar( + "require", + ), + Constant( + Str( + Atom( + "resolve", + ), + ), + ), + [ + Constant( + Str( + Word( + "esbuild", + ), + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 2299..2339#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2367..2376#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "basename", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 1, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2422..2435#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "basename", + ), + ), + ), + args: [ + Value( + Variable( + ( + "subpath", + #7, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 1, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Call, + ), + ], + span: 2422..2444#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + args: [ + Value( + Variable( + ( + "esbuildLibDir", + #16, + ), + ), + ), + Value( + Concat( + 8, + [ + Constant( + Str( + Atom( + "pnpapi-", + ), + ), + ), + Variable( + ( + "pkg", + #7, + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + MemberCall( + 4, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "basename", + ), + ), + ), + [ + Variable( + ( + "subpath", + #7, + ), + ), + ], + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 2367..2452#0, + in_try: false, + }, + Member { + obj: FreeVar( + "fs", + ), + prop: Constant( + Str( + Atom( + "existsSync", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2463..2476#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "fs", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 2463..2465#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "fs", + ), + prop: Constant( + Str( + Atom( + "existsSync", + ), + ), + ), + args: [ + Value( + Variable( + ( + "binTargetPath", + #16, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + ], + span: 2463..2491#0, + in_try: false, + }, + Conditional { + condition: Not( + 5, + MemberCall( + 4, + FreeVar( + "fs", + ), + Constant( + Str( + Atom( + "existsSync", + ), + ), + ), + [ + Variable( + ( + "binTargetPath", + #16, + ), + ), + ], + ), + ), + kind: If { + then: EffectsBlock { + effects: [ + Member { + obj: FreeVar( + "fs", + ), + prop: Constant( + Str( + Atom( + "copyFileSync", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2501..2516#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "fs", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 2501..2503#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "fs", + ), + prop: Constant( + Str( + Atom( + "copyFileSync", + ), + ), + ), + args: [ + Value( + Variable( + ( + "binPath", + #7, + ), + ), + ), + Value( + Variable( + ( + "binTargetPath", + #16, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 2501..2540#0, + in_try: false, + }, + Member { + obj: FreeVar( + "fs", + ), + prop: Constant( + Str( + Atom( + "chmodSync", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2548..2560#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "fs", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 2548..2550#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "fs", + ), + prop: Constant( + Str( + Atom( + "chmodSync", + ), + ), + ), + args: [ + Value( + Variable( + ( + "binTargetPath", + #16, + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 493.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 2548..2580#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 2458..2587#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 2256..2617#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "ESBUILD_BINARY_PATH", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Ident, + ), + ], + span: 2687..2706#1, + in_try: false, + }, + Member { + obj: Variable( + ( + "path2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "basename", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2725..2739#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "__filename", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Ident, + ), + ], + span: 2740..2750#1, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "basename", + ), + ), + ), + args: [ + Value( + FreeVar( + "__filename", + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + ], + span: 2725..2751#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "path2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "basename", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 2775..2789#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "__dirname", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Ident, + ), + ], + span: 2790..2799#1, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "basename", + ), + ), + ), + args: [ + Value( + FreeVar( + "__dirname", + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + ], + span: 2775..2800#0, + in_try: false, + }, + Conditional { + condition: Logical( + 18, + And, + [ + Logical( + 4, + Or, + [ + Not( + 2, + FreeVar( + "ESBUILD_BINARY_PATH", + ), + ), + Constant( + False, + ), + ], + ), + Logical( + 13, + Or, + [ + Binary( + 6, + MemberCall( + 4, + Variable( + ( + "path2", + #2, + ), + ), + Constant( + Str( + Atom( + "basename", + ), + ), + ), + [ + FreeVar( + "__filename", + ), + ], + ), + StrictNotEqual, + Constant( + Str( + Word( + "main.js", + ), + ), + ), + ), + Binary( + 6, + MemberCall( + 4, + Variable( + ( + "path2", + #2, + ), + ), + Constant( + Str( + Atom( + "basename", + ), + ), + ), + [ + FreeVar( + "__dirname", + ), + ], + ), + StrictNotEqual, + Constant( + Str( + Word( + "lib", + ), + ), + ), + ), + ], + ), + ], + ), + kind: If { + then: EffectsBlock { + effects: [ + FreeVar { + var: FreeVar( + "Error", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Throw, + ), + ThrowStmt( + Arg, + ), + Expr( + New, + ), + NewExpr( + Callee, + ), + Expr( + Ident, + ), + ], + span: 2832..2837#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "__filename", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Throw, + ), + ThrowStmt( + Arg, + ), + Expr( + New, + ), + NewExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Ident, + ), + ], + span: 3047..3057#1, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 2676..3489#0, + in_try: false, + }, + Conditional { + condition: Constant( + False, + ), + kind: If { + then: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "path2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Array, + ), + ArrayLit( + Elems( + 1, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Array, + ), + ArrayLit( + Elems( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 3526..3536#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "__dirname", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Array, + ), + ArrayLit( + Elems( + 1, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Array, + ), + ArrayLit( + Elems( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Ident, + ), + ], + span: 3537..3546#1, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + args: [ + Value( + FreeVar( + "__dirname", + ), + ), + Value( + Constant( + Str( + Word( + "..", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "bin", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "esbuild", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Array, + ), + ArrayLit( + Elems( + 1, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Array, + ), + ArrayLit( + Elems( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + ], + span: 3526..3571#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 3492..3578#0, + in_try: false, + }, + Call { + func: Variable( + ( + "generateBinPath", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Array, + ), + ArrayLit( + Elems( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + ], + span: 3589..3606#0, + in_try: false, + }, + Call { + func: Variable( + ( + "esbuildCommandAndArgs", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 3638..3661#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "args", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 9, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 3671..3682#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "args", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + args: [ + Value( + Constant( + Str( + RcStr( + "--service=0.14.12", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "--ping", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 9, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 3671..3718#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph-explained.snapshot new file mode 100644 index 0000000000000..5000a2cdf3dc7 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph-explained.snapshot @@ -0,0 +1,87 @@ +*arrow function 2666* = (...) => ( + | [ + "node", + [ + path2["join"](FreeVar(__dirname), "..", "bin", "esbuild") + ] + ] + | [generateBinPath(), []] +) + +args = esbuildCommandAndArgs()[1] + +binPath = ( + | ???*0* + | FreeVar(require)["resolve"](`${pkg}/${subpath}`) + | FreeVar(downloadedBinPath)(pkg, subpath) +) +- *0* binPath + ⚠️ pattern without value + +binTargetPath = path["join"](esbuildLibDir, `pnpapi-${pkg}-${path["basename"](subpath)}`) + +command = esbuildCommandAndArgs()[0] + +e#10 = ???*0* +- *0* e + ⚠️ pattern without value + +e#15 = ???*0* +- *0* e + ⚠️ pattern without value + +esbuildCommandAndArgs = *arrow function 2666* + +esbuildLibDir = path["dirname"](FreeVar(require)["resolve"]("esbuild")) + +generateBinPath = (...) => (FreeVar(ESBUILD_BINARY_PATH) | binTargetPath | binPath) + +isYarnPnP = (false | true) + +knownUnixlikePackages = { + "android arm64 LE": "esbuild-android-arm64", + "darwin arm64 LE": "esbuild-darwin-arm64", + "darwin x64 LE": "esbuild-darwin-64", + "freebsd arm64 LE": "esbuild-freebsd-arm64", + "freebsd x64 LE": "esbuild-freebsd-64", + "linux arm LE": "esbuild-linux-arm", + "linux arm64 LE": "esbuild-linux-arm64", + "linux ia32 LE": "esbuild-linux-32", + "linux mips64el LE": "esbuild-linux-mips64le", + "linux ppc64 LE": "esbuild-linux-ppc64le", + "linux s390x BE": "esbuild-linux-s390x", + "linux x64 LE": "esbuild-linux-64", + "netbsd x64 LE": "esbuild-netbsd-64", + "openbsd x64 LE": "esbuild-openbsd-64", + "sunos x64 LE": "esbuild-sunos-64" +} + +knownWindowsPackages = { + "win32 arm64 LE": "esbuild-windows-arm64", + "win32 ia32 LE": "esbuild-windows-32", + "win32 x64 LE": "esbuild-windows-64" +} + +os = FreeVar(require)("os") + +path = FreeVar(require)("path") + +path2 = FreeVar(require)("path") + +pkg#3 = (???*0* | knownWindowsPackages[platformKey] | knownUnixlikePackages[platformKey]) +- *0* pkg + ⚠️ pattern without value + +pkg#7 = pkgAndSubpathForCurrentPlatform()["pkg"] + +pkgAndSubpathForCurrentPlatform = (...) => {"pkg": pkg, "subpath": subpath} + +platformKey = `${FreeVar(process)["platform"]} ${os["arch"]()} ${os["endianness"]()}` + +subpath#3 = (???*0* | "esbuild.exe" | "bin/esbuild") +- *0* subpath + ⚠️ pattern without value + +subpath#7 = pkgAndSubpathForCurrentPlatform()["subpath"] + +x = args["concat"]("--service=0.14.12", "--ping") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph.snapshot new file mode 100644 index 0000000000000..ae1c98f9602a0 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/graph.snapshot @@ -0,0 +1,1057 @@ +[ + ( + "*arrow function 2666*", + Function( + 16, + 2666, + Alternatives( + 15, + [ + Array { + total_nodes: 10, + items: [ + Constant( + Str( + Word( + "node", + ), + ), + ), + Array { + total_nodes: 8, + items: [ + MemberCall( + 7, + Variable( + ( + "path2", + #2, + ), + ), + Constant( + Str( + Atom( + "join", + ), + ), + ), + [ + FreeVar( + "__dirname", + ), + Constant( + Str( + Word( + "..", + ), + ), + ), + Constant( + Str( + Word( + "bin", + ), + ), + ), + Constant( + Str( + Word( + "esbuild", + ), + ), + ), + ], + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + Array { + total_nodes: 4, + items: [ + Call( + 2, + Variable( + ( + "generateBinPath", + #2, + ), + ), + [], + ), + Array { + total_nodes: 1, + items: [], + mutable: true, + }, + ], + mutable: true, + }, + ], + ), + ), + ), + ( + "args", + Member( + 4, + Call( + 2, + Variable( + ( + "esbuildCommandAndArgs", + #2, + ), + ), + [], + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "binPath", + Alternatives( + 13, + [ + Unknown { + original_value: Some( + Variable( + ( + "binPath", + #7, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + MemberCall( + 7, + FreeVar( + "require", + ), + Constant( + Str( + Atom( + "resolve", + ), + ), + ), + [ + Concat( + 4, + [ + Variable( + ( + "pkg", + #7, + ), + ), + Constant( + Str( + Atom( + "/", + ), + ), + ), + Variable( + ( + "subpath", + #7, + ), + ), + ], + ), + ], + ), + Call( + 4, + FreeVar( + "downloadedBinPath", + ), + [ + Variable( + ( + "pkg", + #7, + ), + ), + Variable( + ( + "subpath", + #7, + ), + ), + ], + ), + ], + ), + ), + ( + "binTargetPath", + MemberCall( + 12, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "join", + ), + ), + ), + [ + Variable( + ( + "esbuildLibDir", + #16, + ), + ), + Concat( + 8, + [ + Constant( + Str( + Atom( + "pnpapi-", + ), + ), + ), + Variable( + ( + "pkg", + #7, + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + MemberCall( + 4, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "basename", + ), + ), + ), + [ + Variable( + ( + "subpath", + #7, + ), + ), + ], + ), + ], + ), + ], + ), + ), + ( + "command", + Member( + 4, + Call( + 2, + Variable( + ( + "esbuildCommandAndArgs", + #2, + ), + ), + [], + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + ), + ( + "e#10", + Unknown { + original_value: Some( + Variable( + ( + "e", + #10, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + ), + ( + "e#15", + Unknown { + original_value: Some( + Variable( + ( + "e", + #15, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + ), + ( + "esbuildCommandAndArgs", + Variable( + ( + "*arrow function 2666*", + #0, + ), + ), + ), + ( + "esbuildLibDir", + MemberCall( + 7, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "dirname", + ), + ), + ), + [ + MemberCall( + 4, + FreeVar( + "require", + ), + Constant( + Str( + Atom( + "resolve", + ), + ), + ), + [ + Constant( + Str( + Word( + "esbuild", + ), + ), + ), + ], + ), + ], + ), + ), + ( + "generateBinPath", + Function( + 5, + 1409, + Alternatives( + 4, + [ + FreeVar( + "ESBUILD_BINARY_PATH", + ), + Variable( + ( + "binTargetPath", + #16, + ), + ), + Variable( + ( + "binPath", + #7, + ), + ), + ], + ), + ), + ), + ( + "isYarnPnP", + Alternatives( + 3, + [ + Constant( + False, + ), + Constant( + True, + ), + ], + ), + ), + ( + "knownUnixlikePackages", + Object { + total_nodes: 31, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "android arm64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-android-arm64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "darwin arm64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-darwin-arm64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "darwin x64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-darwin-64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "freebsd arm64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-freebsd-arm64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "freebsd x64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-freebsd-64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "linux arm LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-linux-arm", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "linux arm64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-linux-arm64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "linux ia32 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-linux-32", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "linux mips64el LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-linux-mips64le", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "linux ppc64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-linux-ppc64le", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "linux s390x BE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-linux-s390x", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "linux x64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-linux-64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "netbsd x64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-netbsd-64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "openbsd x64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-openbsd-64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "sunos x64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-sunos-64", + ), + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "knownWindowsPackages", + Object { + total_nodes: 7, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "win32 arm64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-windows-arm64", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "win32 ia32 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-windows-32", + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "win32 x64 LE", + ), + ), + ), + Constant( + Str( + Word( + "esbuild-windows-64", + ), + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "os", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "os", + ), + ), + ), + ], + ), + ), + ( + "path", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "path", + ), + ), + ), + ], + ), + ), + ( + "path2", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "path", + ), + ), + ), + ], + ), + ), + ( + "pkg#3", + Alternatives( + 8, + [ + Unknown { + original_value: Some( + Variable( + ( + "pkg", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Member( + 3, + Variable( + ( + "knownWindowsPackages", + #2, + ), + ), + Variable( + ( + "platformKey", + #3, + ), + ), + ), + Member( + 3, + Variable( + ( + "knownUnixlikePackages", + #2, + ), + ), + Variable( + ( + "platformKey", + #3, + ), + ), + ), + ], + ), + ), + ( + "pkg#7", + Member( + 4, + Call( + 2, + Variable( + ( + "pkgAndSubpathForCurrentPlatform", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "pkg", + ), + ), + ), + ), + ), + ( + "pkgAndSubpathForCurrentPlatform", + Function( + 6, + 911, + Object { + total_nodes: 5, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "pkg", + ), + ), + ), + Variable( + ( + "pkg", + #3, + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "subpath", + ), + ), + ), + Variable( + ( + "subpath", + #3, + ), + ), + ), + ], + mutable: true, + }, + ), + ), + ( + "platformKey", + Concat( + 12, + [ + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + Constant( + Str( + Atom( + " ", + ), + ), + ), + MemberCall( + 3, + Variable( + ( + "os", + #2, + ), + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + [], + ), + Constant( + Str( + Atom( + " ", + ), + ), + ), + MemberCall( + 3, + Variable( + ( + "os", + #2, + ), + ), + Constant( + Str( + Atom( + "endianness", + ), + ), + ), + [], + ), + ], + ), + ), + ( + "subpath#3", + Alternatives( + 4, + [ + Unknown { + original_value: Some( + Variable( + ( + "subpath", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Constant( + Str( + Word( + "esbuild.exe", + ), + ), + ), + Constant( + Str( + Word( + "bin/esbuild", + ), + ), + ), + ], + ), + ), + ( + "subpath#7", + Member( + 4, + Call( + 2, + Variable( + ( + "pkgAndSubpathForCurrentPlatform", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "subpath", + ), + ), + ), + ), + ), + ( + "x", + MemberCall( + 5, + Variable( + ( + "args", + #2, + ), + ), + Constant( + Str( + Atom( + "concat", + ), + ), + ), + [ + Constant( + Str( + RcStr( + "--service=0.14.12", + ), + ), + ), + Constant( + Str( + Word( + "--ping", + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/input.js new file mode 100644 index 0000000000000..bdd1e511e61ba --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/input.js @@ -0,0 +1,100 @@ +var path = require("path"); +var path2 = require("path"); +var os = require("os"); + +var knownWindowsPackages = { + "win32 arm64 LE": "esbuild-windows-arm64", + "win32 ia32 LE": "esbuild-windows-32", + "win32 x64 LE": "esbuild-windows-64", +}; +var knownUnixlikePackages = { + "android arm64 LE": "esbuild-android-arm64", + "darwin arm64 LE": "esbuild-darwin-arm64", + "darwin x64 LE": "esbuild-darwin-64", + "freebsd arm64 LE": "esbuild-freebsd-arm64", + "freebsd x64 LE": "esbuild-freebsd-64", + "linux arm LE": "esbuild-linux-arm", + "linux arm64 LE": "esbuild-linux-arm64", + "linux ia32 LE": "esbuild-linux-32", + "linux mips64el LE": "esbuild-linux-mips64le", + "linux ppc64 LE": "esbuild-linux-ppc64le", + "linux s390x BE": "esbuild-linux-s390x", + "linux x64 LE": "esbuild-linux-64", + "netbsd x64 LE": "esbuild-netbsd-64", + "openbsd x64 LE": "esbuild-openbsd-64", + "sunos x64 LE": "esbuild-sunos-64", +}; +function pkgAndSubpathForCurrentPlatform() { + let pkg; + let subpath; + let platformKey = `${process.platform} ${os.arch()} ${os.endianness()}`; + if (platformKey in knownWindowsPackages) { + pkg = knownWindowsPackages[platformKey]; + subpath = "esbuild.exe"; + } else if (platformKey in knownUnixlikePackages) { + pkg = knownUnixlikePackages[platformKey]; + subpath = "bin/esbuild"; + } else { + throw new Error(`Unsupported platform: ${platformKey}`); + } + return { pkg, subpath }; +} +function generateBinPath() { + if (ESBUILD_BINARY_PATH) { + return ESBUILD_BINARY_PATH; + } + const { pkg, subpath } = pkgAndSubpathForCurrentPlatform(); + let binPath; + try { + binPath = require.resolve(`${pkg}/${subpath}`); + } catch (e) { + binPath = downloadedBinPath(pkg, subpath); + if (!fs.existsSync(binPath)) { + try { + require.resolve(pkg); + } catch { + throw new Error(`The package "${pkg}" could not be found, and is needed by esbuild. + +If you are installing esbuild with npm, make sure that you don't specify the +"--no-optional" flag. The "optionalDependencies" package.json feature is used +by esbuild to install the correct binary executable for your current platform.`); + } + throw e; + } + } + let isYarnPnP = false; + try { + require("pnpapi"); + isYarnPnP = true; + } catch (e) {} + if (isYarnPnP) { + const esbuildLibDir = path.dirname(require.resolve("esbuild")); + const binTargetPath = path.join( + esbuildLibDir, + `pnpapi-${pkg}-${path.basename(subpath)}` + ); + if (!fs.existsSync(binTargetPath)) { + fs.copyFileSync(binPath, binTargetPath); + fs.chmodSync(binTargetPath, 493); + } + return binTargetPath; + } + return binPath; +} +var esbuildCommandAndArgs = () => { + if ( + (!ESBUILD_BINARY_PATH || false) && + (path2.basename(__filename) !== "main.js" || + path2.basename(__dirname) !== "lib") + ) { + throw new Error(`The esbuild JavaScript API cannot be bundled. Please mark the "esbuild" package as external so it's not included in the bundle. + +More information: The file containing the code for esbuild's JavaScript API (${__filename}) does not appear to be inside the esbuild package on the file system, which usually means that the esbuild package was bundled into another file. This is problematic because the API needs to run a binary executable inside the esbuild package which is located using a relative path from the API code to the executable. If the esbuild package is bundled, the relative path will be incorrect and the executable won't be found.`); + } + if (false) { + return ["node", [path2.join(__dirname, "..", "bin", "esbuild")]]; + } + return [generateBinPath(), []]; +}; +let [command, args] = esbuildCommandAndArgs(); +let x = args.concat(`--service=${"0.14.12"}`, "--ping"); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/resolved-effects.snapshot new file mode 100644 index 0000000000000..e6876bcfb98e6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/resolved-effects.snapshot @@ -0,0 +1,347 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 call = require*0*("path") +- *0* require: The require method from CommonJS + +0 -> 3 free var = FreeVar(require) + +0 -> 4 call = require*0*("path") +- *0* require: The require method from CommonJS + +0 -> 5 free var = FreeVar(require) + +0 -> 6 call = require*0*("os") +- *0* require: The require method from CommonJS + +0 -> 8 free var = FreeVar(process) + +0 -> 10 member call = os*0*["arch"]() +- *0* os: The Node.js os module: https://nodejs.org/api/os.html + +0 -> 12 member call = os*0*["endianness"]() +- *0* os: The Node.js os module: https://nodejs.org/api/os.html + +0 -> 15 free var = FreeVar(Error) + +0 -> 16 free var = FreeVar(ESBUILD_BINARY_PATH) + +0 -> 17 conditional = ???*0* +- *0* FreeVar(ESBUILD_BINARY_PATH) + ⚠️ unknown global + ⚠️ This value might have side effects + +17 -> 18 free var = FreeVar(ESBUILD_BINARY_PATH) + +0 -> 19 call = (...) => {"pkg": pkg, "subpath": subpath}() + +0 -> 21 free var = FreeVar(require) + +0 -> 22 member call = require*0*["resolve"]( + `${(???*1* | ???*2* | ???*3* | "esbuild-linux-64")}/${(???*4* | "esbuild.exe" | "bin/esbuild" | ???*5*)}` +) +- *0* require: The require method from CommonJS +- *1* pkg + ⚠️ pattern without value +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* subpath + ⚠️ pattern without value +- *5* unknown mutation + ⚠️ This value might have side effects + +0 -> 23 free var = FreeVar(downloadedBinPath) + +0 -> 24 call = ???*0*((???*1* | ???*2* | ???*3* | "esbuild-linux-64"), (???*4* | "esbuild.exe" | "bin/esbuild" | ???*5*)) +- *0* FreeVar(downloadedBinPath) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* pkg + ⚠️ pattern without value +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* subpath + ⚠️ pattern without value +- *5* unknown mutation + ⚠️ This value might have side effects + +0 -> 26 free var = FreeVar(fs) + +0 -> 27 member call = ???*0*["existsSync"]((???*1* | ???*2* | ???*9*)) +- *0* FreeVar(fs) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* binPath + ⚠️ pattern without value +- *2* require.resolve*3*( + `${(???*4* | ???*5* | ???*6* | "esbuild-linux-64")}/${(???*7* | "esbuild.exe" | "bin/esbuild" | ???*8*)}` + ) + ⚠️ require.resolve non constant + ⚠️ This value might have side effects +- *3* require.resolve: The require.resolve method from CommonJS +- *4* pkg + ⚠️ pattern without value +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* subpath + ⚠️ pattern without value +- *8* unknown mutation + ⚠️ This value might have side effects +- *9* ???*10*(pkg, subpath) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *10* FreeVar(downloadedBinPath) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 28 conditional = !(???*0*) +- *0* ???*1*["existsSync"](binPath) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(fs) + ⚠️ unknown global + ⚠️ This value might have side effects + +28 -> 30 free var = FreeVar(require) + +28 -> 31 member call = require*0*["resolve"]((???*1* | ???*2* | ???*3* | "esbuild-linux-64")) +- *0* require: The require method from CommonJS +- *1* pkg + ⚠️ pattern without value +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects + +28 -> 32 free var = FreeVar(Error) + +0 -> 33 free var = FreeVar(require) + +0 -> 34 call = require*0*("pnpapi") +- *0* require: The require method from CommonJS + +0 -> 35 conditional = (false | true) + +35 -> 38 free var = FreeVar(require) + +35 -> 39 member call = require*0*["resolve"]("esbuild") +- *0* require: The require method from CommonJS + +35 -> 40 member call = path*0*["dirname"]("\"esbuild\"/resolved/lib/index.js") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +35 -> 43 member call = path*0*["basename"]((???*1* | "esbuild.exe" | "bin/esbuild" | ???*2*)) +- *0* path: The Node.js path module: https://nodejs.org/api/path.html +- *1* subpath + ⚠️ pattern without value +- *2* unknown mutation + ⚠️ This value might have side effects + +35 -> 44 member call = path*0*["join"]( + "\"esbuild\"/resolved/lib", + `pnpapi-${(???*1* | ???*2* | ???*3* | "esbuild-linux-64")}-${???*4*}` +) +- *0* path: The Node.js path module: https://nodejs.org/api/path.html +- *1* pkg + ⚠️ pattern without value +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* ???*5*((???*7* | "esbuild.exe" | "bin/esbuild" | ???*8*)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *5* path*6*["basename"] + ⚠️ unsupported property on Node.js path module + ⚠️ This value might have side effects +- *6* path: The Node.js path module: https://nodejs.org/api/path.html +- *7* subpath + ⚠️ pattern without value +- *8* unknown mutation + ⚠️ This value might have side effects + +35 -> 46 free var = FreeVar(fs) + +35 -> 47 member call = ???*0*["existsSync"]( + `"esbuild"/resolved/lib${("/" | "")}pnpapi-${(???*1* | ???*2* | ???*3* | "esbuild-linux-64")}-${???*4*}` +) +- *0* FreeVar(fs) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* pkg + ⚠️ pattern without value +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* ???*5*((???*7* | "esbuild.exe" | "bin/esbuild" | ???*8*)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *5* path*6*["basename"] + ⚠️ unsupported property on Node.js path module + ⚠️ This value might have side effects +- *6* path: The Node.js path module: https://nodejs.org/api/path.html +- *7* subpath + ⚠️ pattern without value +- *8* unknown mutation + ⚠️ This value might have side effects + +35 -> 48 conditional = !(???*0*) +- *0* ???*1*["existsSync"](binTargetPath) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(fs) + ⚠️ unknown global + ⚠️ This value might have side effects + +48 -> 50 free var = FreeVar(fs) + +48 -> 51 member call = ???*0*["copyFileSync"]( + (???*1* | ???*2* | ???*9*), + `"esbuild"/resolved/lib${("/" | "")}pnpapi-${(???*11* | ???*12* | ???*13* | "esbuild-linux-64")}-${???*14*}` +) +- *0* FreeVar(fs) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* binPath + ⚠️ pattern without value +- *2* require.resolve*3*( + `${(???*4* | ???*5* | ???*6* | "esbuild-linux-64")}/${(???*7* | "esbuild.exe" | "bin/esbuild" | ???*8*)}` + ) + ⚠️ require.resolve non constant + ⚠️ This value might have side effects +- *3* require.resolve: The require.resolve method from CommonJS +- *4* pkg + ⚠️ pattern without value +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* subpath + ⚠️ pattern without value +- *8* unknown mutation + ⚠️ This value might have side effects +- *9* ???*10*(pkg, subpath) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *10* FreeVar(downloadedBinPath) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* pkg + ⚠️ pattern without value +- *12* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* unknown mutation + ⚠️ This value might have side effects +- *14* ???*15*( + (???*17* | "esbuild.exe" | "bin/esbuild" | ???*18*) + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *15* path*16*["basename"] + ⚠️ unsupported property on Node.js path module + ⚠️ This value might have side effects +- *16* path: The Node.js path module: https://nodejs.org/api/path.html +- *17* subpath + ⚠️ pattern without value +- *18* unknown mutation + ⚠️ This value might have side effects + +48 -> 53 free var = FreeVar(fs) + +48 -> 54 member call = ???*0*["chmodSync"]( + `"esbuild"/resolved/lib${("/" | "")}pnpapi-${(???*1* | ???*2* | ???*3* | "esbuild-linux-64")}-${???*4*}`, + 493 +) +- *0* FreeVar(fs) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* pkg + ⚠️ pattern without value +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* ???*5*((???*7* | "esbuild.exe" | "bin/esbuild" | ???*8*)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *5* path*6*["basename"] + ⚠️ unsupported property on Node.js path module + ⚠️ This value might have side effects +- *6* path: The Node.js path module: https://nodejs.org/api/path.html +- *7* subpath + ⚠️ pattern without value +- *8* unknown mutation + ⚠️ This value might have side effects + +0 -> 55 free var = FreeVar(ESBUILD_BINARY_PATH) + +0 -> 57 free var = FreeVar(__filename) + +0 -> 58 member call = path*0*["basename"]("__filename") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +0 -> 60 free var = FreeVar(__dirname) + +0 -> 61 member call = path*0*["basename"]("__dirname") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +0 -> 62 conditional = (!(???*0*) | false | (???*1* !== "main.js") | (???*4* !== "lib")) +- *0* FreeVar(ESBUILD_BINARY_PATH) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*("__filename") + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* path*3*["basename"] + ⚠️ unsupported property on Node.js path module + ⚠️ This value might have side effects +- *3* path: The Node.js path module: https://nodejs.org/api/path.html +- *4* ???*5*("__dirname") + ⚠️ unknown callee + ⚠️ This value might have side effects +- *5* path*6*["basename"] + ⚠️ unsupported property on Node.js path module + ⚠️ This value might have side effects +- *6* path: The Node.js path module: https://nodejs.org/api/path.html + +62 -> 63 free var = FreeVar(Error) + +62 -> 64 free var = FreeVar(__filename) + +0 -> 65 conditional = false + +65 -> 67 free var = FreeVar(__dirname) + +65 -> 68 member call = path*0*["join"]("__dirname", "..", "bin", "esbuild") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +0 -> 69 call = (...) => (FreeVar(ESBUILD_BINARY_PATH) | binTargetPath | binPath)() + +0 -> 70 call = (...) => ( + | [ + "node", + [ + path2["join"](FreeVar(__dirname), "..", "bin", "esbuild") + ] + ] + | [generateBinPath(), []] +)() + +0 -> 72 member call = ???*0*["concat"]("--service=0.14.12", "--ping") +- *0* max number of linking steps reached + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/resolved-explained.snapshot new file mode 100644 index 0000000000000..c165cfdd35f2a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/esbuild/resolved-explained.snapshot @@ -0,0 +1,157 @@ +*arrow function 2666* = (...) => ( + | [ + "node", + [ + path2["join"](FreeVar(__dirname), "..", "bin", "esbuild") + ] + ] + | [generateBinPath(), []] +) + +args = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +binPath = (???*0* | ???*1* | ???*8*) +- *0* binPath + ⚠️ pattern without value +- *1* require.resolve*2*( + `${(???*3* | ???*4* | ???*5* | "esbuild-linux-64")}/${(???*6* | "esbuild.exe" | "bin/esbuild" | ???*7*)}` + ) + ⚠️ require.resolve non constant + ⚠️ This value might have side effects +- *2* require.resolve: The require.resolve method from CommonJS +- *3* pkg + ⚠️ pattern without value +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* subpath + ⚠️ pattern without value +- *7* unknown mutation + ⚠️ This value might have side effects +- *8* ???*9*(pkg, subpath) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *9* FreeVar(downloadedBinPath) + ⚠️ unknown global + ⚠️ This value might have side effects + +binTargetPath = `"esbuild"/resolved/lib${("/" | "")}pnpapi-${(???*0* | ???*1* | ???*2* | "esbuild-linux-64")}-${???*3*}` +- *0* pkg + ⚠️ pattern without value +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* ???*4*((???*6* | "esbuild.exe" | "bin/esbuild" | ???*7*)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *4* path*5*["basename"] + ⚠️ unsupported property on Node.js path module + ⚠️ This value might have side effects +- *5* path: The Node.js path module: https://nodejs.org/api/path.html +- *6* subpath + ⚠️ pattern without value +- *7* unknown mutation + ⚠️ This value might have side effects + +command = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#10 = ???*0* +- *0* e + ⚠️ pattern without value + +e#15 = ???*0* +- *0* e + ⚠️ pattern without value + +esbuildCommandAndArgs = (...) => ( + | [ + "node", + [ + path2["join"](FreeVar(__dirname), "..", "bin", "esbuild") + ] + ] + | [generateBinPath(), []] +) + +esbuildLibDir = "\"esbuild\"/resolved/lib" + +generateBinPath = (...) => (FreeVar(ESBUILD_BINARY_PATH) | binTargetPath | binPath) + +isYarnPnP = (false | true) + +knownUnixlikePackages = { + "android arm64 LE": "esbuild-android-arm64", + "darwin arm64 LE": "esbuild-darwin-arm64", + "darwin x64 LE": "esbuild-darwin-64", + "freebsd arm64 LE": "esbuild-freebsd-arm64", + "freebsd x64 LE": "esbuild-freebsd-64", + "linux arm LE": "esbuild-linux-arm", + "linux arm64 LE": "esbuild-linux-arm64", + "linux ia32 LE": "esbuild-linux-32", + "linux mips64el LE": "esbuild-linux-mips64le", + "linux ppc64 LE": "esbuild-linux-ppc64le", + "linux s390x BE": "esbuild-linux-s390x", + "linux x64 LE": "esbuild-linux-64", + "netbsd x64 LE": "esbuild-netbsd-64", + "openbsd x64 LE": "esbuild-openbsd-64", + "sunos x64 LE": "esbuild-sunos-64" +} + +knownWindowsPackages = { + "win32 arm64 LE": "esbuild-windows-arm64", + "win32 ia32 LE": "esbuild-windows-32", + "win32 x64 LE": "esbuild-windows-64" +} + +os = os*0* +- *0* os: The Node.js os module: https://nodejs.org/api/os.html + +path = path*0* +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +path2 = path*0* +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +pkg#3 = (???*0* | ???*1* | ???*2* | "esbuild-linux-64") +- *0* pkg + ⚠️ pattern without value +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects + +pkg#7 = (???*0* | ???*1* | ???*2* | "esbuild-linux-64") +- *0* pkg + ⚠️ pattern without value +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects + +pkgAndSubpathForCurrentPlatform = (...) => {"pkg": pkg, "subpath": subpath} + +platformKey = "linux x64 LE" + +subpath#3 = (???*0* | "esbuild.exe" | "bin/esbuild") +- *0* subpath + ⚠️ pattern without value + +subpath#7 = (???*0* | "esbuild.exe" | "bin/esbuild" | ???*1*) +- *0* subpath + ⚠️ pattern without value +- *1* unknown mutation + ⚠️ This value might have side effects + +x = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph-effects.snapshot new file mode 100644 index 0000000000000..c62e42a42732e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph-effects.snapshot @@ -0,0 +1,59 @@ +[ + Call { + func: Variable( + ( + "c", + #2, + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "1", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "2", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 72..83#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph-explained.snapshot new file mode 100644 index 0000000000000..a4368f244c306 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph-explained.snapshot @@ -0,0 +1,13 @@ +a = arguments[0] + +b = arguments[1] + +c = (...) => [`${a}${x}`, a] + +d = c("1", "2") + +e = d[0] + +f = d[1] + +x = b diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph.snapshot new file mode 100644 index 0000000000000..281f66a09bbc4 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/graph.snapshot @@ -0,0 +1,127 @@ +[ + ( + "a", + Argument( + 1, + 0, + ), + ), + ( + "b", + Argument( + 1, + 1, + ), + ), + ( + "c", + Function( + 6, + 1, + Array { + total_nodes: 5, + items: [ + Concat( + 3, + [ + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "x", + #3, + ), + ), + ], + ), + Variable( + ( + "a", + #3, + ), + ), + ], + mutable: true, + }, + ), + ), + ( + "d", + Call( + 4, + Variable( + ( + "c", + #2, + ), + ), + [ + Constant( + Str( + Word( + "1", + ), + ), + ), + Constant( + Str( + Word( + "2", + ), + ), + ), + ], + ), + ), + ( + "e", + Member( + 3, + Variable( + ( + "d", + #2, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + ), + ( + "f", + Member( + 3, + Variable( + ( + "d", + #2, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "x", + Variable( + ( + "b", + #3, + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/input.js new file mode 100644 index 0000000000000..4db3b7fcd3172 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/input.js @@ -0,0 +1,8 @@ +function c(a, b) { + var x = b; + return [`${a}${x}`, a]; +} + +const d = c("1", "2"); + +const [e, f] = d; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/resolved-effects.snapshot new file mode 100644 index 0000000000000..e0fdda9108171 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/resolved-effects.snapshot @@ -0,0 +1 @@ +0 -> 1 call = (...) => [`${a}${x}`, a]("1", "2") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/resolved-explained.snapshot new file mode 100644 index 0000000000000..32205659e99a7 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array-2/resolved-explained.snapshot @@ -0,0 +1,23 @@ +a = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +c = (...) => [`${a}${x}`, a] + +d = ["12", "1"] + +e = ("12" | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +f = ("1" | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +x = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph-effects.snapshot new file mode 100644 index 0000000000000..ac8747e442c7a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph-effects.snapshot @@ -0,0 +1,59 @@ +[ + Call { + func: Variable( + ( + "c", + #2, + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "1", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "2", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 59..70#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph-explained.snapshot new file mode 100644 index 0000000000000..0410a38ff3879 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph-explained.snapshot @@ -0,0 +1,11 @@ +a = arguments[0] + +b = arguments[1] + +c = (...) => [`${a}${b}`, a] + +d = c("1", "2") + +e = d[0] + +f = d[1] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph.snapshot new file mode 100644 index 0000000000000..7fe80c360ca7a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/graph.snapshot @@ -0,0 +1,118 @@ +[ + ( + "a", + Argument( + 1, + 0, + ), + ), + ( + "b", + Argument( + 1, + 1, + ), + ), + ( + "c", + Function( + 6, + 1, + Array { + total_nodes: 5, + items: [ + Concat( + 3, + [ + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + ], + ), + Variable( + ( + "a", + #3, + ), + ), + ], + mutable: true, + }, + ), + ), + ( + "d", + Call( + 4, + Variable( + ( + "c", + #2, + ), + ), + [ + Constant( + Str( + Word( + "1", + ), + ), + ), + Constant( + Str( + Word( + "2", + ), + ), + ), + ], + ), + ), + ( + "e", + Member( + 3, + Variable( + ( + "d", + #2, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + ), + ( + "f", + Member( + 3, + Variable( + ( + "d", + #2, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/input.js new file mode 100644 index 0000000000000..cb187eeb5028b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/input.js @@ -0,0 +1,7 @@ +function c(a, b) { + return [`${a}${b}`, a]; +} + +const d = c("1", "2"); + +const [e, f] = d; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/resolved-effects.snapshot new file mode 100644 index 0000000000000..cefd31428c09c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/resolved-effects.snapshot @@ -0,0 +1 @@ +0 -> 1 call = (...) => [`${a}${b}`, a]("1", "2") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/resolved-explained.snapshot new file mode 100644 index 0000000000000..0a53353075555 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/fn-array/resolved-explained.snapshot @@ -0,0 +1,19 @@ +a = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +c = (...) => [`${a}${b}`, a] + +d = ["12", "1"] + +e = ("12" | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +f = ("1" | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph-effects.snapshot new file mode 100644 index 0000000000000..1ac7da4601469 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph-effects.snapshot @@ -0,0 +1,153 @@ +[ + Member { + obj: FreeVar( + "Buffer", + ), + prop: Constant( + Str( + Atom( + "from", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 13..24#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "Buffer", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 13..19#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "Buffer", + ), + prop: Constant( + Str( + Atom( + "from", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "Hello World", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 13..39#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph-explained.snapshot new file mode 100644 index 0000000000000..202db9c3b5476 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph-explained.snapshot @@ -0,0 +1 @@ +buf = FreeVar(Buffer)["from"]("Hello World") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph.snapshot new file mode 100644 index 0000000000000..9b174317c822d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/graph.snapshot @@ -0,0 +1,27 @@ +[ + ( + "buf", + MemberCall( + 4, + FreeVar( + "Buffer", + ), + Constant( + Str( + Atom( + "from", + ), + ), + ), + [ + Constant( + Str( + Word( + "Hello World", + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/input.js new file mode 100644 index 0000000000000..61362a7206bbc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/input.js @@ -0,0 +1 @@ +const buf = Buffer.from("Hello World"); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/resolved-effects.snapshot new file mode 100644 index 0000000000000..e0c7a64a82785 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/resolved-effects.snapshot @@ -0,0 +1,6 @@ +0 -> 2 free var = FreeVar(Buffer) + +0 -> 3 member call = ???*0*["from"]("Hello World") +- *0* FreeVar(Buffer) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/resolved-explained.snapshot new file mode 100644 index 0000000000000..e430c26f038a5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/free-vars/resolved-explained.snapshot @@ -0,0 +1,7 @@ +buf = ???*0* +- *0* ???*1*["from"]("Hello World") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Buffer) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph-effects.snapshot new file mode 100644 index 0000000000000..4f5f69a1660b4 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph-effects.snapshot @@ -0,0 +1,240 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Ident, + ), + ], + span: 9..16#1, + in_try: false, + }, + Conditional { + condition: Constant( + True, + ), + kind: If { + then: EffectsBlock { + effects: [ + Call { + func: Variable( + ( + "f", + #5, + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "test", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 153..162#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 137..167#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph-explained.snapshot new file mode 100644 index 0000000000000..4e86cab15535c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph-explained.snapshot @@ -0,0 +1,13 @@ +a = FreeVar(require) + +b = a + +c = b + +d = a + +e = d + +f = a + +g = f diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph.snapshot new file mode 100644 index 0000000000000..1da067fdba6f2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/graph.snapshot @@ -0,0 +1,62 @@ +[ + ( + "a", + FreeVar( + "require", + ), + ), + ( + "b", + Variable( + ( + "a", + #2, + ), + ), + ), + ( + "c", + Variable( + ( + "b", + #3, + ), + ), + ), + ( + "d", + Variable( + ( + "a", + #2, + ), + ), + ), + ( + "e", + Variable( + ( + "d", + #4, + ), + ), + ), + ( + "f", + Variable( + ( + "a", + #2, + ), + ), + ), + ( + "g", + Variable( + ( + "f", + #5, + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/input.js new file mode 100644 index 0000000000000..67967a40df511 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/input.js @@ -0,0 +1,18 @@ +let a = require; + +(function (b) { + let c = b; +})(a); + +// prettier-ignore +!function (d) { + let e = d; +}(a); + +((f) => { + let g = f; + + if (true) { + f("test"); + } +})(a); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/resolved-effects.snapshot new file mode 100644 index 0000000000000..b9b82b69628bc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/resolved-effects.snapshot @@ -0,0 +1,6 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 conditional = true + +2 -> 3 call = require*0*("test") +- *0* require: The require method from CommonJS diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/resolved-explained.snapshot new file mode 100644 index 0000000000000..7c259a1c55ae2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/iife/resolved-explained.snapshot @@ -0,0 +1,20 @@ +a = require*0* +- *0* require: The require method from CommonJS + +b = require*0* +- *0* require: The require method from CommonJS + +c = require*0* +- *0* require: The require method from CommonJS + +d = require*0* +- *0* require: The require method from CommonJS + +e = require*0* +- *0* require: The require method from CommonJS + +f = require*0* +- *0* require: The require method from CommonJS + +g = require*0* +- *0* require: The require method from CommonJS diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph-effects.snapshot new file mode 100644 index 0000000000000..eb17c8f9bdc77 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph-effects.snapshot @@ -0,0 +1,114 @@ +[ + ImportedBinding { + esm_reference_index: 1, + export: Some( + "default", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 5, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Ident, + ), + ], + span: 158..159#2, + in_try: false, + }, + ImportedBinding { + esm_reference_index: 3, + export: Some( + "a", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 6, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Ident, + ), + ], + span: 170..171#2, + in_try: false, + }, + ImportedBinding { + esm_reference_index: 6, + export: None, + ast_path: [ + Program( + Module, + ), + Module( + Body( + 7, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Ident, + ), + ], + span: 182..183#2, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph-explained.snapshot new file mode 100644 index 0000000000000..1fe0d1c124c72 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph-explained.snapshot @@ -0,0 +1,5 @@ +aa = module["a"] + +xx = module["default"] + +yy = module diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph.snapshot new file mode 100644 index 0000000000000..27007a9baee56 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/graph.snapshot @@ -0,0 +1,55 @@ +[ + ( + "aa", + Member( + 3, + Module( + ModuleValue { + module: "x2", + annotations: ImportAnnotations { + map: {}, + }, + }, + ), + Constant( + Str( + Atom( + "a", + ), + ), + ), + ), + ), + ( + "xx", + Member( + 3, + Module( + ModuleValue { + module: "x1", + annotations: ImportAnnotations { + map: {}, + }, + }, + ), + Constant( + Str( + Atom( + "default", + ), + ), + ), + ), + ), + ( + "yy", + Module( + ModuleValue { + module: "x3", + annotations: ImportAnnotations { + map: {}, + }, + }, + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/input.js new file mode 100644 index 0000000000000..cb6beda6281dc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/input.js @@ -0,0 +1,10 @@ +import x from "x1"; +import { a, b } from "x2"; +import * as y from "x3"; +export { a, b } from "x4"; +// export x from "x5"; +export * as y from "x6"; + +let xx = x; +let aa = a; +let yy = y; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/resolved-explained.snapshot new file mode 100644 index 0000000000000..1fe0d1c124c72 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/imports/resolved-explained.snapshot @@ -0,0 +1,5 @@ +aa = module["a"] + +xx = module["default"] + +yy = module diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph-effects.snapshot new file mode 100644 index 0000000000000..c162d07f57ffd --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph-effects.snapshot @@ -0,0 +1,278 @@ +[ + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Ident, + ), + ], + span: 132..138#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Ident, + ), + ], + span: 164..170#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 9, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Ident, + ), + ], + span: 208..214#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 10, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Ident, + ), + ], + span: 256..262#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 11, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Ident, + ), + ], + span: 284..290#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 12, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Ident, + ), + ], + span: 323..329#1, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph-explained.snapshot new file mode 100644 index 0000000000000..8a56ef7b5b36d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph-explained.snapshot @@ -0,0 +1,25 @@ +a = (x && y) + +b = (x || y) + +c = (x ?? y) + +chain1 = (1 && 2 && 3 && FreeVar(global)) + +chain2 = ((1 && 2 && FreeVar(global)) || 3 || 4) + +d = !(x) + +e = !(!(x)) + +resolve1 = (1 && 2 && FreeVar(global) && 3 && 4) + +resolve2 = (1 && 2 && 0 && FreeVar(global) && 4) + +resolve3 = (FreeVar(global) || true) + +resolve4 = (true || FreeVar(global)) + +x = true + +y = false diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph.snapshot new file mode 100644 index 0000000000000..79b0bb0f2f373 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/graph.snapshot @@ -0,0 +1,293 @@ +[ + ( + "a", + Logical( + 3, + And, + [ + Variable( + ( + "x", + #2, + ), + ), + Variable( + ( + "y", + #2, + ), + ), + ], + ), + ), + ( + "b", + Logical( + 3, + Or, + [ + Variable( + ( + "x", + #2, + ), + ), + Variable( + ( + "y", + #2, + ), + ), + ], + ), + ), + ( + "c", + Logical( + 3, + NullishCoalescing, + [ + Variable( + ( + "x", + #2, + ), + ), + Variable( + ( + "y", + #2, + ), + ), + ], + ), + ), + ( + "chain1", + Logical( + 5, + And, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + FreeVar( + "global", + ), + ], + ), + ), + ( + "chain2", + Logical( + 7, + Or, + [ + Logical( + 4, + And, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + FreeVar( + "global", + ), + ], + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + ( + "d", + Not( + 2, + Variable( + ( + "x", + #2, + ), + ), + ), + ), + ( + "e", + Not( + 3, + Not( + 2, + Variable( + ( + "x", + #2, + ), + ), + ), + ), + ), + ( + "resolve1", + Logical( + 6, + And, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + FreeVar( + "global", + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + ( + "resolve2", + Logical( + 6, + And, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + FreeVar( + "global", + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + ( + "resolve3", + Logical( + 3, + Or, + [ + FreeVar( + "global", + ), + Constant( + True, + ), + ], + ), + ), + ( + "resolve4", + Logical( + 3, + Or, + [ + Constant( + True, + ), + FreeVar( + "global", + ), + ], + ), + ), + ( + "x", + Constant( + True, + ), + ), + ( + "y", + Constant( + False, + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/input.js new file mode 100644 index 0000000000000..770fb991566b1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/input.js @@ -0,0 +1,14 @@ +let x = true; +let y = false; +let a = x && y; +let b = x || y; +let c = x ?? y; +let d = !x; +let e = !!x; + +let chain1 = 1 && 2 && 3 && global; +let chain2 = (1 && 2 && global) || 3 || 4; +let resolve1 = 1 && 2 && global && 3 && 4; +let resolve2 = 1 && 2 && 0 && global && 4; +let resolve3 = global || true; +let resolve4 = true || global; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/resolved-effects.snapshot new file mode 100644 index 0000000000000..62e46549a24fb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/resolved-effects.snapshot @@ -0,0 +1,11 @@ +0 -> 1 free var = FreeVar(global) + +0 -> 2 free var = FreeVar(global) + +0 -> 3 free var = FreeVar(global) + +0 -> 4 free var = FreeVar(global) + +0 -> 5 free var = FreeVar(global) + +0 -> 6 free var = FreeVar(global) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/resolved-explained.snapshot new file mode 100644 index 0000000000000..0e381ce8400af --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/logical/resolved-explained.snapshot @@ -0,0 +1,37 @@ +a = false + +b = true + +c = true + +chain1 = ???*0* +- *0* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +chain2 = (???*0* | 3) +- *0* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +d = false + +e = true + +resolve1 = (???*0* | 4) +- *0* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +resolve2 = 0 + +resolve3 = (???*0* | true) +- *0* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +resolve4 = true + +x = true + +y = false diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph-effects.snapshot new file mode 100644 index 0000000000000..8ae0097413573 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph-effects.snapshot @@ -0,0 +1,5118 @@ +[ + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 138..149#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 173..206#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "length", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Member, + ), + ], + span: 380..388#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Variable( + ( + "i", + #3, + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 484..488#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Member( + 3, + Variable( + ( + "x", + #3, + ), + ), + Variable( + ( + "i", + #3, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 466..504#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 532..540#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 514..557#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 585..593#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 606105819.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 567..609#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 637..645#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 619..663#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 8, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 691..699#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 8, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 673..715#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 9, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 743..751#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1200080426.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 9, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 725..768#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 10, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 796..804#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 10, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 778..822#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 850..858#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 832..874#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 12, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 902..910#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1770035416.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 12, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 884..926#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 13, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 954..962#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 13, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 936..980#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 14, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1008..1017#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 14, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 990..1030#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 15, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1058..1067#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 15, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1040..1085#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 16, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1113..1122#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1804603682.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 16, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1095..1138#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 17, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1166..1175#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 17, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1148..1191#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 18, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1219..1228#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 18, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1201..1246#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "x", + #3, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 19, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1274..1283#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5ff", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #3, + ), + ), + ), + Value( + Variable( + ( + "c", + #3, + ), + ), + ), + Value( + Variable( + ( + "d", + #3, + ), + ), + ), + Value( + Variable( + ( + "a", + #3, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1236535329.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 19, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1256..1300#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "safeAdd", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 1459..1466#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "bitRotateLeft", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 1467..1480#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "safeAdd", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 1481..1488#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "safeAdd", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 1489..1496#1, + in_try: false, + }, + Call { + func: FreeVar( + "safeAdd", + ), + args: [ + Value( + Variable( + ( + "a", + #5, + ), + ), + ), + Value( + Variable( + ( + "q", + #5, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + ], + span: 1489..1502#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "safeAdd", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 1, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 1504..1511#1, + in_try: false, + }, + Call { + func: FreeVar( + "safeAdd", + ), + args: [ + Value( + Variable( + ( + "x", + #5, + ), + ), + ), + Value( + Variable( + ( + "t", + #5, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 1, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + ], + span: 1504..1517#0, + in_try: false, + }, + Call { + func: FreeVar( + "safeAdd", + ), + args: [ + Value( + Call( + 4, + FreeVar( + "safeAdd", + ), + [ + Variable( + ( + "a", + #5, + ), + ), + Variable( + ( + "q", + #5, + ), + ), + ], + ), + ), + Value( + Call( + 4, + FreeVar( + "safeAdd", + ), + [ + Variable( + ( + "x", + #5, + ), + ), + Variable( + ( + "t", + #5, + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + ], + span: 1481..1518#0, + in_try: false, + }, + Call { + func: FreeVar( + "bitRotateLeft", + ), + args: [ + Value( + Call( + 10, + FreeVar( + "safeAdd", + ), + [ + Call( + 4, + FreeVar( + "safeAdd", + ), + [ + Variable( + ( + "a", + #5, + ), + ), + Variable( + ( + "q", + #5, + ), + ), + ], + ), + Call( + 4, + FreeVar( + "safeAdd", + ), + [ + Variable( + ( + "x", + #5, + ), + ), + Variable( + ( + "t", + #5, + ), + ), + ], + ), + ], + ), + ), + Value( + Variable( + ( + "s", + #5, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + ], + span: 1467..1522#0, + in_try: false, + }, + Call { + func: FreeVar( + "safeAdd", + ), + args: [ + Value( + Call( + 13, + FreeVar( + "bitRotateLeft", + ), + [ + Call( + 10, + FreeVar( + "safeAdd", + ), + [ + Call( + 4, + FreeVar( + "safeAdd", + ), + [ + Variable( + ( + "a", + #5, + ), + ), + Variable( + ( + "q", + #5, + ), + ), + ], + ), + Call( + 4, + FreeVar( + "safeAdd", + ), + [ + Variable( + ( + "x", + #5, + ), + ), + Variable( + ( + "t", + #5, + ), + ), + ], + ), + ], + ), + Variable( + ( + "s", + #5, + ), + ), + ], + ), + ), + Value( + Variable( + ( + "b", + #5, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 1459..1526#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5cmn", + #2, + ), + ), + args: [ + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + Value( + Variable( + ( + "a", + #6, + ), + ), + ), + Value( + Variable( + ( + "b", + #6, + ), + ), + ), + Value( + Variable( + ( + "x", + #6, + ), + ), + ), + Value( + Variable( + ( + "s", + #6, + ), + ), + ), + Value( + Variable( + ( + "t", + #6, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 1577..1618#0, + in_try: false, + }, + Member { + obj: FreeVar( + "module", + ), + prop: Constant( + Str( + Atom( + "exports", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 1622..1636#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "module", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 1622..1628#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "md5", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Ident, + ), + ], + span: 1639..1642#1, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph-explained.snapshot new file mode 100644 index 0000000000000..52890e6a9df3c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph-explained.snapshot @@ -0,0 +1,121 @@ +a#3 = ( + | 1732584193 + | md5ff(a, b, c, d, x[i], 7, ???*0*) + | md5ff(a, b, c, d, x[(i + 4)], 7, ???*1*) + | md5ff(a, b, c, d, x[(i + 8)], 7, 1770035416) + | md5ff(a, b, c, d, x[(i + 12)], 7, 1804603682) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +a#5 = arguments[1] + +a#6 = arguments[0] + +b#3 = ( + | ???*0* + | md5ff(b, c, d, a, x[(i + 3)], 22, ???*1*) + | md5ff(b, c, d, a, x[(i + 7)], 22, ???*2*) + | md5ff(b, c, d, a, x[(i + 11)], 22, ???*3*) + | md5ff(b, c, d, a, x[(i + 15)], 22, 1236535329) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +b#5 = arguments[2] + +b#6 = arguments[1] + +c#3 = ( + | ???*0* + | md5ff(c, d, a, b, x[(i + 2)], 17, 606105819) + | md5ff(c, d, a, b, x[(i + 6)], 17, ???*1*) + | md5ff(c, d, a, b, x[(i + 10)], 17, ???*2*) + | md5ff(c, d, a, b, x[(i + 14)], 17, ???*3*) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +c#6 = arguments[2] + +d#3 = ( + | 271733878 + | md5ff(d, a, b, c, x[(i + 1)], 12, ???*0*) + | md5ff(d, a, b, c, x[(i + 5)], 12, 1200080426) + | md5ff(d, a, b, c, x[(i + 9)], 12, ???*1*) + | md5ff(d, a, b, c, x[(i + 13)], 12, ???*2*) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +d#6 = arguments[3] + +i = (???*0* | 0 | (i + 16)) +- *0* i + ⚠️ pattern without value + +len = arguments[1] + +md5cmn = (...) => FreeVar(safeAdd)( + FreeVar(bitRotateLeft)( + FreeVar(safeAdd)(FreeVar(safeAdd)(a, q), FreeVar(safeAdd)(x, t)), + s + ), + b +) + +md5ff = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +olda = (???*0* | a) +- *0* olda + ⚠️ pattern without value + +oldb = (???*0* | b) +- *0* oldb + ⚠️ pattern without value + +oldc = (???*0* | c) +- *0* oldc + ⚠️ pattern without value + +oldd = (???*0* | d) +- *0* oldd + ⚠️ pattern without value + +q = arguments[0] + +s#5 = arguments[4] + +s#6 = arguments[5] + +t#5 = arguments[5] + +t#6 = arguments[6] + +wordsToMd5 = (...) => [a, b, c, d] + +x#3 = arguments[0] + +x#5 = arguments[3] + +x#6 = arguments[4] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph.snapshot new file mode 100644 index 0000000000000..015f6f46aff83 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/graph.snapshot @@ -0,0 +1,1667 @@ +[ + ( + "a#3", + Alternatives( + 52, + [ + Constant( + Num( + ConstantNumber( + 1732584193.0, + ), + ), + ), + Call( + 11, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Member( + 3, + Variable( + ( + "x", + #3, + ), + ), + Variable( + ( + "i", + #3, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1770035416.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1804603682.0, + ), + ), + ), + ], + ), + ], + ), + ), + ( + "a#5", + Argument( + 1414, + 1, + ), + ), + ( + "a#6", + Argument( + 1530, + 0, + ), + ), + ( + "b#3", + Alternatives( + 54, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1236535329.0, + ), + ), + ), + ], + ), + ], + ), + ), + ( + "b#5", + Argument( + 1414, + 2, + ), + ), + ( + "b#6", + Argument( + 1530, + 1, + ), + ), + ( + "c#3", + Alternatives( + 54, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 606105819.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + ], + ), + ), + ( + "c#6", + Argument( + 1530, + 2, + ), + ), + ( + "d#3", + Alternatives( + 54, + [ + Constant( + Num( + ConstantNumber( + 271733878.0, + ), + ), + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1200080426.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "md5ff", + #2, + ), + ), + [ + Variable( + ( + "d", + #3, + ), + ), + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Member( + 5, + Variable( + ( + "x", + #3, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + ], + ), + ), + ( + "d#6", + Argument( + 1530, + 3, + ), + ), + ( + "i", + Alternatives( + 6, + [ + Unknown { + original_value: Some( + Variable( + ( + "i", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #3, + ), + ), + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + ], + ), + ], + ), + ), + ( + "len", + Argument( + 83, + 1, + ), + ), + ( + "md5cmn", + Function( + 17, + 1414, + Call( + 16, + FreeVar( + "safeAdd", + ), + [ + Call( + 13, + FreeVar( + "bitRotateLeft", + ), + [ + Call( + 10, + FreeVar( + "safeAdd", + ), + [ + Call( + 4, + FreeVar( + "safeAdd", + ), + [ + Variable( + ( + "a", + #5, + ), + ), + Variable( + ( + "q", + #5, + ), + ), + ], + ), + Call( + 4, + FreeVar( + "safeAdd", + ), + [ + Variable( + ( + "x", + #5, + ), + ), + Variable( + ( + "t", + #5, + ), + ), + ], + ), + ], + ), + Variable( + ( + "s", + #5, + ), + ), + ], + ), + Variable( + ( + "b", + #5, + ), + ), + ], + ), + ), + ), + ( + "md5ff", + Function( + 9, + 1530, + Call( + 8, + Variable( + ( + "md5cmn", + #2, + ), + ), + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "a", + #6, + ), + ), + Variable( + ( + "b", + #6, + ), + ), + Variable( + ( + "x", + #6, + ), + ), + Variable( + ( + "s", + #6, + ), + ), + Variable( + ( + "t", + #6, + ), + ), + ], + ), + ), + ), + ( + "olda", + Alternatives( + 3, + [ + Unknown { + original_value: Some( + Variable( + ( + "olda", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Variable( + ( + "a", + #3, + ), + ), + ], + ), + ), + ( + "oldb", + Alternatives( + 3, + [ + Unknown { + original_value: Some( + Variable( + ( + "oldb", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Variable( + ( + "b", + #3, + ), + ), + ], + ), + ), + ( + "oldc", + Alternatives( + 3, + [ + Unknown { + original_value: Some( + Variable( + ( + "oldc", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Variable( + ( + "c", + #3, + ), + ), + ], + ), + ), + ( + "oldd", + Alternatives( + 3, + [ + Unknown { + original_value: Some( + Variable( + ( + "oldd", + #3, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Variable( + ( + "d", + #3, + ), + ), + ], + ), + ), + ( + "q", + Argument( + 1414, + 0, + ), + ), + ( + "s#5", + Argument( + 1414, + 4, + ), + ), + ( + "s#6", + Argument( + 1530, + 5, + ), + ), + ( + "t#5", + Argument( + 1414, + 5, + ), + ), + ( + "t#6", + Argument( + 1530, + 6, + ), + ), + ( + "wordsToMd5", + Function( + 6, + 83, + Array { + total_nodes: 5, + items: [ + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #3, + ), + ), + Variable( + ( + "c", + #3, + ), + ), + Variable( + ( + "d", + #3, + ), + ), + ], + mutable: true, + }, + ), + ), + ( + "x#3", + Argument( + 83, + 0, + ), + ), + ( + "x#5", + Argument( + 1414, + 3, + ), + ), + ( + "x#6", + Argument( + 1530, + 4, + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/input.js new file mode 100644 index 0000000000000..b85f8bb03a88b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/input.js @@ -0,0 +1,55 @@ +/* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ +function wordsToMd5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var i; + var olda; + var oldb; + var oldc; + var oldd; + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + + var d = 271733878; + + for (i = 0; i < x.length; i += 16) { + olda = a; + oldb = b; + oldc = c; + oldd = d; + + a = md5ff(a, b, c, d, x[i], 7, -680876936); + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); + } + return [a, b, c, d]; +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5cmn(q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); +} +function md5ff(a, b, c, d, x, s, t) { + return md5cmn((b & c) | (~b & d), a, b, x, s, t); +} +module.exports = md5; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/resolved-effects.snapshot new file mode 100644 index 0000000000000..80d10ff7c1f7b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/resolved-effects.snapshot @@ -0,0 +1,375 @@ +0 -> 5 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 7, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[i] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 7 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 12, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 1)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 9 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 17, 606105819) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 2)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 11 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 22, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 3)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 13 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 7, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 4)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 15 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 12, 1200080426) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 5)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 17 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 17, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 6)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 19 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 22, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 7)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 21 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 7, 1770035416) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 8)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 23 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 12, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 9)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 25 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 17, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 10)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 27 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 22, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 11)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 29 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 7, 1804603682) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 12)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 31 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 12, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 13)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 33 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 17, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 14)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 35 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 22, 1236535329) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 15)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 36 free var = FreeVar(safeAdd) + +0 -> 37 free var = FreeVar(bitRotateLeft) + +0 -> 38 free var = FreeVar(safeAdd) + +0 -> 39 free var = FreeVar(safeAdd) + +0 -> 40 call = ???*0*(???*1*, ???*2*) +- *0* FreeVar(safeAdd) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 41 free var = FreeVar(safeAdd) + +0 -> 42 call = ???*0*(???*1*, ???*2*) +- *0* FreeVar(safeAdd) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* arguments[5] + ⚠️ function calls are not analysed yet + +0 -> 43 call = ???*0*(???*1*, ???*3*) +- *0* FreeVar(safeAdd) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*(a, q) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(safeAdd) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* ???*4*(x, t) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *4* FreeVar(safeAdd) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 44 call = ???*0*(???*1*, ???*3*) +- *0* FreeVar(bitRotateLeft) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*(FreeVar(safeAdd)(a, q), FreeVar(safeAdd)(x, t)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(safeAdd) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 45 call = ???*0*(???*1*, ???*3*) +- *0* FreeVar(safeAdd) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*( + FreeVar(safeAdd)(FreeVar(safeAdd)(a, q), FreeVar(safeAdd)(x, t)), + s + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(bitRotateLeft) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 46 call = (...) => FreeVar(safeAdd)( + FreeVar(bitRotateLeft)( + FreeVar(safeAdd)(FreeVar(safeAdd)(a, q), FreeVar(safeAdd)(x, t)), + s + ), + b +)(???*0*, ???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[4] + ⚠️ function calls are not analysed yet +- *4* arguments[5] + ⚠️ function calls are not analysed yet +- *5* arguments[6] + ⚠️ function calls are not analysed yet + +0 -> 48 free var = FreeVar(module) + +0 -> 49 free var = FreeVar(md5) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/resolved-explained.snapshot new file mode 100644 index 0000000000000..54438dc0bf513 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5-reduced/resolved-explained.snapshot @@ -0,0 +1,115 @@ +a#3 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#5 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +a#6 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#3 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#5 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +b#6 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +c#3 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#6 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +d#3 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#6 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +i = (???*0* | 0 | ((???*1* | 0 | ???*2*) + 16)) +- *0* i + ⚠️ pattern without value +- *1* i + ⚠️ pattern without value +- *2* (???*3* + 16) + ⚠️ nested operation +- *3* i + ⚠️ circular variable reference + +len = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +md5cmn = (...) => FreeVar(safeAdd)( + FreeVar(bitRotateLeft)( + FreeVar(safeAdd)(FreeVar(safeAdd)(a, q), FreeVar(safeAdd)(x, t)), + s + ), + b +) + +md5ff = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +olda = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +oldb = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +oldc = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +oldd = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +q = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +s#5 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +s#6 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +t#5 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +t#6 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +wordsToMd5 = (...) => [a, b, c, d] + +x#3 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +x#5 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +x#6 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/graph-explained.snapshot new file mode 100644 index 0000000000000..e22dbe23dc59f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/graph-explained.snapshot @@ -0,0 +1,384 @@ +a#14 = arguments[1] + +a#15 = arguments[0] + +a#16 = arguments[0] + +a#17 = arguments[0] + +a#18 = arguments[0] + +a#7 = ( + | 1732584193 + | md5ff(a, b, c, d, x[i], 7, ???*0*) + | md5ff(a, b, c, d, x[(i + 4)], 7, ???*1*) + | md5ff(a, b, c, d, x[(i + 8)], 7, 1770035416) + | md5ff(a, b, c, d, x[(i + 12)], 7, 1804603682) + | md5gg(a, b, c, d, x[(i + 1)], 5, ???*2*) + | md5gg(a, b, c, d, x[(i + 5)], 5, ???*3*) + | md5gg(a, b, c, d, x[(i + 9)], 5, 568446438) + | md5gg(a, b, c, d, x[(i + 13)], 5, ???*4*) + | md5hh(a, b, c, d, x[(i + 5)], 4, ???*5*) + | md5hh(a, b, c, d, x[(i + 1)], 4, ???*6*) + | md5hh(a, b, c, d, x[(i + 13)], 4, 681279174) + | md5hh(a, b, c, d, x[(i + 9)], 4, ???*7*) + | md5ii(a, b, c, d, x[i], 6, ???*8*) + | md5ii(a, b, c, d, x[(i + 12)], 6, 1700485571) + | md5ii(a, b, c, d, x[(i + 8)], 6, 1873313359) + | md5ii(a, b, c, d, x[(i + 4)], 6, ???*9*) + | safeAdd(a, olda) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects + +b#14 = arguments[2] + +b#15 = arguments[1] + +b#16 = arguments[1] + +b#17 = arguments[1] + +b#18 = arguments[1] + +b#7 = ( + | ???*0* + | md5ff(b, c, d, a, x[(i + 3)], 22, ???*1*) + | md5ff(b, c, d, a, x[(i + 7)], 22, ???*2*) + | md5ff(b, c, d, a, x[(i + 11)], 22, ???*3*) + | md5ff(b, c, d, a, x[(i + 15)], 22, 1236535329) + | md5gg(b, c, d, a, x[i], 20, ???*4*) + | md5gg(b, c, d, a, x[(i + 4)], 20, ???*5*) + | md5gg(b, c, d, a, x[(i + 8)], 20, 1163531501) + | md5gg(b, c, d, a, x[(i + 12)], 20, ???*6*) + | md5hh(b, c, d, a, x[(i + 14)], 23, ???*7*) + | md5hh(b, c, d, a, x[(i + 10)], 23, ???*8*) + | md5hh(b, c, d, a, x[(i + 6)], 23, 76029189) + | md5hh(b, c, d, a, x[(i + 2)], 23, ???*9*) + | md5ii(b, c, d, a, x[(i + 5)], 21, ???*10*) + | md5ii(b, c, d, a, x[(i + 1)], 21, ???*11*) + | md5ii(b, c, d, a, x[(i + 13)], 21, 1309151649) + | md5ii(b, c, d, a, x[(i + 9)], 21, ???*12*) + | safeAdd(b, oldb) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects + +bitRotateLeft = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +bytes = (arguments[0] | ???*0*) +- *0* unknown new expression + ⚠️ This value might have side effects + +bytesToWords = (...) => output + +c#15 = arguments[2] + +c#16 = arguments[2] + +c#17 = arguments[2] + +c#18 = arguments[2] + +c#7 = ( + | ???*0* + | md5ff(c, d, a, b, x[(i + 2)], 17, 606105819) + | md5ff(c, d, a, b, x[(i + 6)], 17, ???*1*) + | md5ff(c, d, a, b, x[(i + 10)], 17, ???*2*) + | md5ff(c, d, a, b, x[(i + 14)], 17, ???*3*) + | md5gg(c, d, a, b, x[(i + 11)], 14, 643717713) + | md5gg(c, d, a, b, x[(i + 15)], 14, ???*4*) + | md5gg(c, d, a, b, x[(i + 3)], 14, ???*5*) + | md5gg(c, d, a, b, x[(i + 7)], 14, 1735328473) + | md5hh(c, d, a, b, x[(i + 11)], 16, 1839030562) + | md5hh(c, d, a, b, x[(i + 7)], 16, ???*6*) + | md5hh(c, d, a, b, x[(i + 3)], 16, ???*7*) + | md5hh(c, d, a, b, x[(i + 15)], 16, 530742520) + | md5ii(c, d, a, b, x[(i + 14)], 15, ???*8*) + | md5ii(c, d, a, b, x[(i + 10)], 15, ???*9*) + | md5ii(c, d, a, b, x[(i + 6)], 15, ???*10*) + | md5ii(c, d, a, b, x[(i + 2)], 15, 718787259) + | safeAdd(c, oldc) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects + +cnt = arguments[1] + +d#15 = arguments[3] + +d#16 = arguments[3] + +d#17 = arguments[3] + +d#18 = arguments[3] + +d#7 = ( + | 271733878 + | md5ff(d, a, b, c, x[(i + 1)], 12, ???*0*) + | md5ff(d, a, b, c, x[(i + 5)], 12, 1200080426) + | md5ff(d, a, b, c, x[(i + 9)], 12, ???*1*) + | md5ff(d, a, b, c, x[(i + 13)], 12, ???*2*) + | md5gg(d, a, b, c, x[(i + 6)], 9, ???*3*) + | md5gg(d, a, b, c, x[(i + 10)], 9, 38016083) + | md5gg(d, a, b, c, x[(i + 14)], 9, ???*4*) + | md5gg(d, a, b, c, x[(i + 2)], 9, ???*5*) + | md5hh(d, a, b, c, x[(i + 8)], 11, ???*6*) + | md5hh(d, a, b, c, x[(i + 4)], 11, 1272893353) + | md5hh(d, a, b, c, x[i], 11, ???*7*) + | md5hh(d, a, b, c, x[(i + 12)], 11, ???*8*) + | md5ii(d, a, b, c, x[(i + 7)], 10, 1126891415) + | md5ii(d, a, b, c, x[(i + 3)], 10, ???*9*) + | md5ii(d, a, b, c, x[(i + 15)], 10, ???*10*) + | md5ii(d, a, b, c, x[(i + 11)], 10, ???*11*) + | safeAdd(d, oldd) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects + +hex = ( + | ???*0* + | FreeVar(parseInt)( + (hexTab["charAt"](???*1*) + hexTab["charAt"](???*2*)), + 16 + ) +) +- *0* hex + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +hexTab = "0123456789abcdef" + +i#3 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +i#5 = (???*0* | 0 | (i + 8)) +- *0* i + ⚠️ pattern without value + +i#7 = (???*0* | 0 | (i + 16)) +- *0* i + ⚠️ pattern without value + +i#9 = (???*0* | 0 | (i + 1) | (i + 8)) +- *0* i + ⚠️ pattern without value + +input#5 = arguments[0] + +input#9 = arguments[0] + +len = arguments[1] + +length32 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +length8 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +lsw = (???*0* + ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +md5 = (...) => md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +md5ToHexEncodedArray = (...) => output + +md5cmn = (...) => safeAdd( + bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), + b +) + +md5ff = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +md5gg = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +md5hh = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +md5ii = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +msg = FreeVar(unescape)(FreeVar(encodeURIComponent)(bytes)) + +msw = (???*0* + ???*1* + ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +num = arguments[0] + +olda = (???*0* | a) +- *0* olda + ⚠️ pattern without value + +oldb = (???*0* | b) +- *0* oldb + ⚠️ pattern without value + +oldc = (???*0* | c) +- *0* oldc + ⚠️ pattern without value + +oldd = (???*0* | d) +- *0* oldd + ⚠️ pattern without value + +output#5 = [] + +output#9 = [] + +q = arguments[0] + +s#14 = arguments[4] + +s#15 = arguments[5] + +s#16 = arguments[5] + +s#17 = arguments[5] + +s#18 = arguments[5] + +safeAdd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +t#14 = arguments[5] + +t#15 = arguments[6] + +t#16 = arguments[6] + +t#17 = arguments[6] + +t#18 = arguments[6] + +wordsToMd5 = (...) => [a, b, c, d] + +x#12 = arguments[0] + +x#14 = arguments[3] + +x#15 = arguments[4] + +x#16 = arguments[4] + +x#17 = arguments[4] + +x#18 = arguments[4] + +x#5 = (???*0* | ???*1*) +- *0* x + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +x#7 = arguments[0] + +y = arguments[1] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/input.js new file mode 100644 index 0000000000000..464e16f71c2f9 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/input.js @@ -0,0 +1,216 @@ +/* + * Browser-compatible JavaScript MD5 + * + * Modification of JavaScript MD5 + * https://github.com/blueimp/JavaScript-MD5 + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * https://opensource.org/licenses/MIT + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +"use strict"; + +function md5(bytes) { + if (typeof bytes == "string") { + var msg = unescape(encodeURIComponent(bytes)); // UTF8 escape + bytes = new Array(msg.length); + for (var i = 0; i < msg.length; i++) bytes[i] = msg.charCodeAt(i); + } + + return md5ToHexEncodedArray( + wordsToMd5(bytesToWords(bytes), bytes.length * 8) + ); +} + +/* + * Convert an array of little-endian words to an array of bytes + */ +function md5ToHexEncodedArray(input) { + var i; + var x; + var output = []; + var length32 = input.length * 32; + var hexTab = "0123456789abcdef"; + var hex; + + for (i = 0; i < length32; i += 8) { + x = (input[i >> 5] >>> i % 32) & 0xff; + + hex = parseInt( + hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f), + 16 + ); + + output.push(hex); + } + return output; +} + +/* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ +function wordsToMd5(x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << len % 32; + x[(((len + 64) >>> 9) << 4) + 14] = len; + + var i; + var olda; + var oldb; + var oldc; + var oldd; + var a = 1732584193; + var b = -271733879; + var c = -1732584194; + + var d = 271733878; + + for (i = 0; i < x.length; i += 16) { + olda = a; + oldb = b; + oldc = c; + oldd = d; + + a = md5ff(a, b, c, d, x[i], 7, -680876936); + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586); + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819); + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330); + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897); + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426); + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341); + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983); + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416); + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417); + c = md5ff(c, d, a, b, x[i + 10], 17, -42063); + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162); + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682); + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101); + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290); + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329); + + a = md5gg(a, b, c, d, x[i + 1], 5, -165796510); + d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632); + c = md5gg(c, d, a, b, x[i + 11], 14, 643717713); + b = md5gg(b, c, d, a, x[i], 20, -373897302); + a = md5gg(a, b, c, d, x[i + 5], 5, -701558691); + d = md5gg(d, a, b, c, x[i + 10], 9, 38016083); + c = md5gg(c, d, a, b, x[i + 15], 14, -660478335); + b = md5gg(b, c, d, a, x[i + 4], 20, -405537848); + a = md5gg(a, b, c, d, x[i + 9], 5, 568446438); + d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690); + c = md5gg(c, d, a, b, x[i + 3], 14, -187363961); + b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501); + a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467); + d = md5gg(d, a, b, c, x[i + 2], 9, -51403784); + c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473); + b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734); + + a = md5hh(a, b, c, d, x[i + 5], 4, -378558); + d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463); + c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562); + b = md5hh(b, c, d, a, x[i + 14], 23, -35309556); + a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060); + d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353); + c = md5hh(c, d, a, b, x[i + 7], 16, -155497632); + b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640); + a = md5hh(a, b, c, d, x[i + 13], 4, 681279174); + d = md5hh(d, a, b, c, x[i], 11, -358537222); + c = md5hh(c, d, a, b, x[i + 3], 16, -722521979); + b = md5hh(b, c, d, a, x[i + 6], 23, 76029189); + a = md5hh(a, b, c, d, x[i + 9], 4, -640364487); + d = md5hh(d, a, b, c, x[i + 12], 11, -421815835); + c = md5hh(c, d, a, b, x[i + 15], 16, 530742520); + b = md5hh(b, c, d, a, x[i + 2], 23, -995338651); + + a = md5ii(a, b, c, d, x[i], 6, -198630844); + d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415); + c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905); + b = md5ii(b, c, d, a, x[i + 5], 21, -57434055); + a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571); + d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606); + c = md5ii(c, d, a, b, x[i + 10], 15, -1051523); + b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799); + a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359); + d = md5ii(d, a, b, c, x[i + 15], 10, -30611744); + c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380); + b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649); + a = md5ii(a, b, c, d, x[i + 4], 6, -145523070); + d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379); + c = md5ii(c, d, a, b, x[i + 2], 15, 718787259); + b = md5ii(b, c, d, a, x[i + 9], 21, -343485551); + + a = safeAdd(a, olda); + b = safeAdd(b, oldb); + c = safeAdd(c, oldc); + d = safeAdd(d, oldd); + } + return [a, b, c, d]; +} + +/* + * Convert an array bytes to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ +function bytesToWords(input) { + var i; + var output = []; + output[(input.length >> 2) - 1] = undefined; + for (i = 0; i < output.length; i += 1) { + output[i] = 0; + } + var length8 = input.length * 8; + for (i = 0; i < length8; i += 8) { + output[i >> 5] |= (input[i / 8] & 0xff) << i % 32; + } + + return output; +} + +/* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ +function safeAdd(x, y) { + var lsw = (x & 0xffff) + (y & 0xffff); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xffff); +} + +/* + * Bitwise rotate a 32-bit number to the left. + */ +function bitRotateLeft(num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)); +} + +/* + * These functions implement the four basic operations the algorithm uses. + */ +function md5cmn(q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b); +} +function md5ff(a, b, c, d, x, s, t) { + return md5cmn((b & c) | (~b & d), a, b, x, s, t); +} +function md5gg(a, b, c, d, x, s, t) { + return md5cmn((b & d) | (c & ~d), a, b, x, s, t); +} +function md5hh(a, b, c, d, x, s, t) { + return md5cmn(b ^ c ^ d, a, b, x, s, t); +} +function md5ii(a, b, c, d, x, s, t) { + return md5cmn(c ^ (b | ~d), a, b, x, s, t); +} + +module.exports = md5; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/large b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/large new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/resolved-effects.snapshot new file mode 100644 index 0000000000000..89fded395799a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/resolved-effects.snapshot @@ -0,0 +1,1353 @@ +0 -> 1 conditional = (???*0* == "string") +- *0* typeof((???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects + +1 -> 2 free var = FreeVar(unescape) + +1 -> 3 free var = FreeVar(encodeURIComponent) + +1 -> 4 call = ???*0*((???*1* | ???*2*)) +- *0* FreeVar(encodeURIComponent) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects + +1 -> 5 call = ???*0*(???*1*) +- *0* FreeVar(unescape) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*(bytes) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(encodeURIComponent) + ⚠️ unknown global + ⚠️ This value might have side effects + +1 -> 6 free var = FreeVar(Array) + +1 -> 11 member call = ???*0*["charCodeAt"]((0 | ???*2*)) +- *0* ???*1*(FreeVar(encodeURIComponent)(bytes)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* FreeVar(unescape) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +0 -> 12 call = (...) => output((???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +0 -> 14 call = (...) => [a, b, c, d]([], ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 15 call = (...) => output(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 18 free var = FreeVar(parseInt) + +0 -> 20 member call = "0123456789abcdef"["charAt"](???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 22 member call = "0123456789abcdef"["charAt"](???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 23 call = ???*0*((???*1* + ???*3*), 16) +- *0* FreeVar(parseInt) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* "0123456789abcdef"["charAt"](???*2*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* "0123456789abcdef"["charAt"](???*4*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects + +0 -> 25 member call = []["push"]((???*0* | ???*1*)) +- *0* hex + ⚠️ pattern without value +- *1* ???*2*( + (hexTab["charAt"](???*3*) + hexTab["charAt"](???*4*)), + 16 + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(parseInt) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +0 -> 30 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 7, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[i] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 32 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 12, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 1)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 34 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 17, 606105819) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 2)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 36 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 22, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 3)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 38 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 7, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 4)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 40 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 12, 1200080426) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 5)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 42 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 17, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 6)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 44 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 22, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 7)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 46 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 7, 1770035416) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 8)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 48 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 12, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 9)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 50 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 17, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 10)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 52 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 22, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 11)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 54 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 7, 1804603682) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 12)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 56 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 12, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 13)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 58 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 17, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 14)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 60 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 22, 1236535329) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 15)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 62 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 5, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 1)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 64 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 9, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 6)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 66 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 14, 643717713) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 11)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 68 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 20, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[i] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 70 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 5, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 5)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 72 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 9, 38016083) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 10)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 74 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 14, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 15)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 76 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 20, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 4)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 78 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 5, 568446438) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 9)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 80 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 9, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 14)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 82 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 14, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 3)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 84 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 20, 1163531501) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 8)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 86 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 5, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 13)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 88 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 9, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 2)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 90 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 14, 1735328473) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 7)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 92 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 20, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 12)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 94 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 4, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 5)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 96 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 11, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 8)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 98 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 16, 1839030562) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 11)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 100 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 23, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 14)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 102 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 4, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 1)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 104 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 11, 1272893353) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 4)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 106 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 16, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 7)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 108 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 23, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 10)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 110 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 4, 681279174) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 13)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 112 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 11, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[i] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 114 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 16, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 3)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 116 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 23, 76029189) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 6)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 118 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 4, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 9)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 120 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 11, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 12)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 122 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 16, 530742520) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 15)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 124 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 23, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 2)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 126 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 6, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[i] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 128 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 10, 1126891415) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 7)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 130 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 15, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 14)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 132 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 21, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 5)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 134 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 6, 1700485571) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 12)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 136 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 10, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 3)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 138 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 15, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 10)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 140 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 21, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 1)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 142 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 6, 1873313359) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 8)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 144 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 10, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 15)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 146 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 15, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 6)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 148 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 21, 1309151649) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 13)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 150 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 6, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 4)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 152 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 10, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 11)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 154 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 15, 718787259) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 2)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 156 call = (...) => md5cmn(???*0*, a, b, x, s, t)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, 21, ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(i + 9)] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 157 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 158 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 159 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 160 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 163 free var = FreeVar(undefined) + +0 -> 169 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 170 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* arguments[5] + ⚠️ function calls are not analysed yet + +0 -> 171 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 172 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 173 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 174 call = (...) => safeAdd( + bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), + b +)(???*0*, ???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[4] + ⚠️ function calls are not analysed yet +- *4* arguments[5] + ⚠️ function calls are not analysed yet +- *5* arguments[6] + ⚠️ function calls are not analysed yet + +0 -> 175 call = (...) => safeAdd( + bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), + b +)(???*0*, ???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[4] + ⚠️ function calls are not analysed yet +- *4* arguments[5] + ⚠️ function calls are not analysed yet +- *5* arguments[6] + ⚠️ function calls are not analysed yet + +0 -> 176 call = (...) => safeAdd( + bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), + b +)(???*0*, ???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[4] + ⚠️ function calls are not analysed yet +- *4* arguments[5] + ⚠️ function calls are not analysed yet +- *5* arguments[6] + ⚠️ function calls are not analysed yet + +0 -> 177 call = (...) => safeAdd( + bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), + b +)(???*0*, ???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[4] + ⚠️ function calls are not analysed yet +- *4* arguments[5] + ⚠️ function calls are not analysed yet +- *5* arguments[6] + ⚠️ function calls are not analysed yet + +0 -> 179 free var = FreeVar(module) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/resolved-explained.snapshot new file mode 100644 index 0000000000000..360f8bd754235 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5/resolved-explained.snapshot @@ -0,0 +1,343 @@ +a#14 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +a#15 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#16 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#17 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#18 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#7 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#14 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +b#15 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#16 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#17 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#18 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#7 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +bitRotateLeft = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +bytes = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +bytesToWords = (...) => output + +c#15 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#16 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#17 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#18 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#7 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +cnt = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +d#15 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#16 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#17 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#18 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#7 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +hex = (???*0* | ???*1*) +- *0* hex + ⚠️ pattern without value +- *1* ???*2*( + (hexTab["charAt"](???*3*) + hexTab["charAt"](???*4*)), + 16 + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(parseInt) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +hexTab = "0123456789abcdef" + +i#3 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +i#5 = (???*0* | 0 | ((???*1* | 0 | ???*2*) + 8)) +- *0* i + ⚠️ pattern without value +- *1* i + ⚠️ pattern without value +- *2* (???*3* + 8) + ⚠️ nested operation +- *3* i + ⚠️ circular variable reference + +i#7 = (???*0* | 0 | ((???*1* | 0 | ???*2*) + 16)) +- *0* i + ⚠️ pattern without value +- *1* i + ⚠️ pattern without value +- *2* (???*3* + 16) + ⚠️ nested operation +- *3* i + ⚠️ circular variable reference + +i#9 = (???*0* | 0 | ((???*1* | 0 | ???*2*) + 1) | ((???*4* | 0 | ???*5*) + 8)) +- *0* i + ⚠️ pattern without value +- *1* i + ⚠️ pattern without value +- *2* (???*3* + 1) + ⚠️ nested operation +- *3* i + ⚠️ circular variable reference +- *4* i + ⚠️ pattern without value +- *5* (???*6* + 1) + ⚠️ nested operation +- *6* i + ⚠️ circular variable reference + +input#5 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +input#9 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +len = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +length32 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +length8 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +lsw = (???*0* + ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +md5 = (...) => md5ToHexEncodedArray(wordsToMd5(bytesToWords(bytes), ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +md5ToHexEncodedArray = (...) => output + +md5cmn = (...) => safeAdd( + bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), + b +) + +md5ff = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +md5gg = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +md5hh = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +md5ii = (...) => md5cmn(???*0*, a, b, x, s, t) +- *0* unsupported expression + ⚠️ This value might have side effects + +msg = ???*0* +- *0* ???*1*(FreeVar(encodeURIComponent)(bytes)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* FreeVar(unescape) + ⚠️ unknown global + ⚠️ This value might have side effects + +msw = (???*0* + ???*1* + ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +num = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +olda = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +oldb = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +oldc = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +oldd = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +output#5 = [] + +output#9 = [] + +q = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +s#14 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +s#15 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +s#16 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +s#17 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +s#18 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +safeAdd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +t#14 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +t#15 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +t#16 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +t#17 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +t#18 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +wordsToMd5 = (...) => [a, b, c, d] + +x#12 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +x#14 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +x#15 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +x#16 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +x#17 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +x#18 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +x#5 = (???*0* | ???*1*) +- *0* x + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +x#7 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +y = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph-effects.snapshot new file mode 100644 index 0000000000000..5c726ba52876b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph-effects.snapshot @@ -0,0 +1,30373 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 30..37#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "crypt", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 30..46#0, + in_try: false, + }, + Member { + obj: Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "charenc", + ), + ), + ), + ], + ), + prop: Constant( + Str( + Atom( + "utf8", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 1, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 59..82#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 1, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 59..66#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "charenc", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 1, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Call, + ), + ], + span: 59..77#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 2, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 99..106#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "is-buffer", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 2, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 99..119#0, + in_try: false, + }, + Member { + obj: Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "charenc", + ), + ), + ), + ], + ), + prop: Constant( + Str( + Atom( + "bin", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 3, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 131..153#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 3, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 131..138#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "charenc", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 3, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Call, + ), + ], + span: 131..149#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "message", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "constructor", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 252..271#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "String", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Ident, + ), + ], + span: 275..281#1, + in_try: false, + }, + Conditional { + condition: Binary( + 5, + Member( + 3, + Variable( + ( + "message", + #4, + ), + ), + Constant( + Str( + Atom( + "constructor", + ), + ), + ), + ), + Equal, + FreeVar( + "String", + ), + ), + kind: IfElse { + then: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "options", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "encoding", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 306..322#0, + in_try: false, + }, + Conditional { + condition: Logical( + 7, + And, + [ + Variable( + ( + "options", + #4, + ), + ), + Binary( + 5, + Member( + 3, + Variable( + ( + "options", + #4, + ), + ), + Constant( + Str( + Atom( + "encoding", + ), + ), + ), + ), + StrictEqual, + Constant( + Str( + Word( + "binary", + ), + ), + ), + ), + ], + ), + kind: IfElse { + then: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "bin", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "stringToBytes", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 357..374#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "bin", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "stringToBytes", + ), + ), + ), + args: [ + Value( + Variable( + ( + "message", + #4, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 357..383#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "utf8", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "stringToBytes", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 408..426#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "utf8", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "stringToBytes", + ), + ), + ), + args: [ + Value( + Variable( + ( + "message", + #4, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 408..435#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 291..436#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [ + Call { + func: Variable( + ( + "isBuffer", + #3, + ), + ), + args: [ + Value( + Variable( + ( + "message", + #4, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Call, + ), + ], + span: 452..469#0, + in_try: false, + }, + Conditional { + condition: Call( + 3, + Variable( + ( + "isBuffer", + #3, + ), + ), + [ + Variable( + ( + "message", + #4, + ), + ), + ], + ), + kind: IfElse { + then: EffectsBlock { + effects: [ + Member { + obj: Member( + 5, + Member( + 3, + FreeVar( + "Array", + ), + Constant( + Str( + Atom( + "prototype", + ), + ), + ), + ), + Constant( + Str( + Atom( + "slice", + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "call", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 489..515#0, + in_try: false, + }, + Member { + obj: Member( + 3, + FreeVar( + "Array", + ), + Constant( + Str( + Atom( + "prototype", + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "slice", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + ], + span: 489..510#0, + in_try: false, + }, + Member { + obj: FreeVar( + "Array", + ), + prop: Constant( + Str( + Atom( + "prototype", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + ], + span: 489..504#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "Array", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 489..494#1, + in_try: false, + }, + MemberCall { + obj: Member( + 5, + Member( + 3, + FreeVar( + "Array", + ), + Constant( + Str( + Atom( + "prototype", + ), + ), + ), + ), + Constant( + Str( + Atom( + "slice", + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "call", + ), + ), + ), + args: [ + Value( + Variable( + ( + "message", + #4, + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 489..527#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [ + Member { + obj: FreeVar( + "Array", + ), + prop: Constant( + Str( + Atom( + "isArray", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 545..558#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "Array", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 545..550#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "Array", + ), + prop: Constant( + Str( + Atom( + "isArray", + ), + ), + ), + args: [ + Value( + Variable( + ( + "message", + #4, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Call, + ), + ], + span: 545..567#0, + in_try: false, + }, + Conditional { + condition: Not( + 5, + MemberCall( + 4, + FreeVar( + "Array", + ), + Constant( + Str( + Atom( + "isArray", + ), + ), + ), + [ + Variable( + ( + "message", + #4, + ), + ), + ], + ), + ), + kind: If { + then: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "message", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "toString", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 579..595#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "message", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "toString", + ), + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 579..597#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 540..598#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 448..598#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 248..598#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "crypt", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "bytesToWords", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 655..673#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "crypt", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "bytesToWords", + ), + ), + ), + args: [ + Value( + Variable( + ( + "message", + #4, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 655..682#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "message", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "length", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 1, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 696..710#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "length", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + For, + ), + ForStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Member, + ), + ], + span: 860..868#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Variable( + ( + "i", + #4, + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 885..889#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Variable( + ( + "i", + #4, + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 905..909#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Variable( + ( + "i", + #4, + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 919..923#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Variable( + ( + "i", + #4, + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 962..966#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Variable( + ( + "i", + #4, + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 977..981#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 1037..1047#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 1073..1104#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_ff", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 1152..1159#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_gg", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 1, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 1174..1181#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_hh", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 2, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 1196..1203#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_ii", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 3, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 1218..1225#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "length", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Member, + ), + ], + span: 1254..1262#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1377..1385#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1362..1401#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1430..1438#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1415..1455#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1484..1492#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 606105819.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1469..1508#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1537..1545#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1522..1563#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1592..1600#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1577..1616#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1645..1653#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1200080426.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1630..1670#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1699..1707#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1684..1725#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 8, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1754..1762#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 8, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1739..1778#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 9, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1807..1815#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1770035416.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 9, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1792..1831#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 10, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1860..1868#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 10, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1845..1886#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1915..1924#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 11, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1900..1937#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 12, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 1966..1975#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 12, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 1951..1993#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 13, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2022..2031#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1804603682.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 13, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2007..2047#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 14, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2076..2085#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 14, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2061..2101#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 15, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2130..2139#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 15, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2115..2157#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 16, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2186..2195#0, + in_try: false, + }, + Call { + func: Variable( + ( + "FF", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1236535329.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 16, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2171..2212#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 17, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2242..2250#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 17, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2227..2266#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 18, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2295..2303#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 18, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2280..2320#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 19, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2349..2358#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 643717713.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 19, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2334..2374#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 20, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2403..2411#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 20.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 20, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2388..2428#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 21, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2457..2465#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 21, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2442..2481#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 22, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2510..2519#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 38016083.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 22, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2495..2533#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 23, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2562..2571#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 23, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2547..2588#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 24, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2617..2625#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 20.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 24, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2602..2642#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 25, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2671..2679#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 568446438.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 25, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2656..2694#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 26, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2723..2732#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 26, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2708..2749#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 27, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2778..2786#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 27, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2763..2803#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 28, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2832..2840#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 20.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1163531501.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 28, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2817..2857#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 29, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2886..2895#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 29, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2871..2912#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 30, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2941..2949#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 30, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2926..2964#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 31, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 2993..3001#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1735328473.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 31, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 2978..3018#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 32, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3047..3056#0, + in_try: false, + }, + Call { + func: Variable( + ( + "GG", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 20.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 32, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3032..3074#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 33, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3104..3112#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 33, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3089..3125#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 34, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3154..3162#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 34, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3139..3180#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 35, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3209..3218#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1839030562.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 35, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3194..3235#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 36, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3264..3273#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 23.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 36, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3249..3289#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 37, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3318..3326#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 37, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3303..3343#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 38, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3372..3380#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1272893353.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 38, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3357..3397#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 39, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3426..3434#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 39, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3411..3451#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 40, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3480..3489#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 23.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 40, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3465..3507#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 41, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3536..3545#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 681279174.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 41, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3521..3560#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 42, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3589..3597#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 42, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3574..3614#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 43, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3643..3651#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 43, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3628..3668#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 44, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3697..3705#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 23.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 76029189.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 44, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3682..3720#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 45, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3749..3757#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 45, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3734..3773#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 46, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3802..3811#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 46, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3787..3828#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 47, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3857..3866#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 530742520.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 47, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3842..3882#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 48, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3911..3919#0, + in_try: false, + }, + Call { + func: Variable( + ( + "HH", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 23.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 48, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3896..3936#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 49, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 3966..3974#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 49, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 3951..3990#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 50, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4019..4027#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1126891415.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 50, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4004..4044#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 51, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4073..4082#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 51, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4058..4100#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 52, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4129..4137#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 21.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 52, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4114..4153#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 53, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4182..4191#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1700485571.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 53, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4167..4207#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 54, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4236..4244#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 54, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4221..4262#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 55, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4291..4300#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 55, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4276..4315#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 56, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4344..4352#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 21.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 56, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4329..4370#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 57, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4399..4407#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1873313359.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 57, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4384..4423#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 58, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4452..4461#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 58, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4437..4477#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 59, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4506..4514#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 59, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4491..4532#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 60, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4561..4570#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 21.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 1309151649.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 60, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4546..4587#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 61, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4616..4624#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 61, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4601..4640#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 62, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4669..4678#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 62, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4654..4696#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 63, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4725..4733#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 718787259.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 63, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4710..4749#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "m", + #4, + ), + ), + prop: Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 64, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Member, + ), + ], + span: 4778..4786#0, + in_try: false, + }, + Call { + func: Variable( + ( + "II", + #4, + ), + ), + args: [ + Value( + Variable( + ( + "b", + #4, + ), + ), + ), + Value( + Variable( + ( + "c", + #4, + ), + ), + ), + Value( + Variable( + ( + "d", + #4, + ), + ), + ), + Value( + Variable( + ( + "a", + #4, + ), + ), + ), + Value( + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 21.0, + ), + ), + ), + ), + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + For, + ), + ForStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 64, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 4763..4803#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "crypt", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "endian", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 4940..4952#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "crypt", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "endian", + ), + ), + ), + args: [ + Value( + Array { + total_nodes: 5, + items: [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + ], + mutable: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 4, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 4940..4966#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_ff", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 5003..5010#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_gg", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 5153..5160#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_hh", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 5303..5310#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_ii", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 5444..5451#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_blocksize", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 5620..5634#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "md5", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "_digestsize", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 5643..5658#0, + in_try: false, + }, + Member { + obj: FreeVar( + "module", + ), + prop: Constant( + Str( + Atom( + "exports", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 5668..5682#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "module", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 5668..5674#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "undefined", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Ident, + ), + ], + span: 5735..5744#1, + in_try: false, + }, + Conditional { + condition: Logical( + 7, + Or, + [ + Binary( + 3, + Variable( + ( + "message", + #11, + ), + ), + StrictEqual, + FreeVar( + "undefined", + ), + ), + Binary( + 3, + Variable( + ( + "message", + #11, + ), + ), + StrictEqual, + Constant( + Null, + ), + ), + ], + ), + kind: If { + then: EffectsBlock { + effects: [ + FreeVar { + var: FreeVar( + "Error", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + Stmt( + Throw, + ), + ThrowStmt( + Arg, + ), + Expr( + New, + ), + NewExpr( + Callee, + ), + Expr( + Ident, + ), + ], + span: 5782..5787#1, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 5719..5819#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "crypt", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "wordsToBytes", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 5843..5861#0, + in_try: false, + }, + Call { + func: Variable( + ( + "md5", + #3, + ), + ), + args: [ + Value( + Variable( + ( + "message", + #11, + ), + ), + ), + Value( + Variable( + ( + "options", + #11, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Call, + ), + ], + span: 5862..5883#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "crypt", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "wordsToBytes", + ), + ), + ), + args: [ + Value( + Call( + 4, + Variable( + ( + "md5", + #3, + ), + ), + [ + Variable( + ( + "message", + #11, + ), + ), + Variable( + ( + "options", + #11, + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 5843..5884#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "options", + #11, + ), + ), + prop: Constant( + Str( + Atom( + "asBytes", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Member, + ), + ], + span: 5908..5923#0, + in_try: false, + }, + Conditional { + condition: Logical( + 5, + And, + [ + Variable( + ( + "options", + #11, + ), + ), + Member( + 3, + Variable( + ( + "options", + #11, + ), + ), + Constant( + Str( + Atom( + "asBytes", + ), + ), + ), + ), + ], + ), + kind: Ternary { + then: EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "options", + #11, + ), + ), + prop: Constant( + Str( + Atom( + "asString", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Right, + ), + Expr( + Member, + ), + ], + span: 5963..5979#0, + in_try: false, + }, + Conditional { + condition: Logical( + 5, + And, + [ + Variable( + ( + "options", + #11, + ), + ), + Member( + 3, + Variable( + ( + "options", + #11, + ), + ), + Constant( + Str( + Atom( + "asString", + ), + ), + ), + ), + ], + ), + kind: Ternary { + then: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "bin", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "bytesToString", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 5988..6005#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "bin", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "bytesToString", + ), + ), + ), + args: [ + Value( + Variable( + ( + "digestbytes", + #11, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + Expr( + Call, + ), + ], + span: 5988..6018#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [ + Member { + obj: Variable( + ( + "crypt", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "bytesToHex", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 6027..6043#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "crypt", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "bytesToHex", + ), + ), + ), + args: [ + Value( + Variable( + ( + "digestbytes", + #11, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Call, + ), + ], + span: 6027..6056#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + ], + span: 5952..6056#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Fn, + ), + FnExpr( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + ], + span: 5897..6056#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph-explained.snapshot new file mode 100644 index 0000000000000..8e9c32742ee21 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph-explained.snapshot @@ -0,0 +1,329 @@ +*anonymous function 181* = (...) => crypt["endian"]([a, b, c, d]) + +*anonymous function 5013* = (...) => (???*0* + b) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 5163* = (...) => (???*0* + b) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 5313* = (...) => (???*0* + b) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 5454* = (...) => (???*0* + b) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 5685* = (...) => ((options && options["asBytes"]) ? digestbytes : ((options && options["asString"]) ? bin["bytesToString"](digestbytes) : crypt["bytesToHex"](digestbytes))) + +FF = md5["_ff"] + +GG = md5["_gg"] + +HH = md5["_hh"] + +II = md5["_ii"] + +a#10 = arguments[0] + +a#4 = ( + | 1732584193 + | FF(a, b, c, d, m[(i + 0)], 7, ???*0*) + | FF(a, b, c, d, m[(i + 4)], 7, ???*1*) + | FF(a, b, c, d, m[(i + 8)], 7, 1770035416) + | FF(a, b, c, d, m[(i + 12)], 7, 1804603682) + | GG(a, b, c, d, m[(i + 1)], 5, ???*2*) + | GG(a, b, c, d, m[(i + 5)], 5, ???*3*) + | GG(a, b, c, d, m[(i + 9)], 5, 568446438) + | GG(a, b, c, d, m[(i + 13)], 5, ???*4*) + | HH(a, b, c, d, m[(i + 5)], 4, ???*5*) + | HH(a, b, c, d, m[(i + 1)], 4, ???*6*) + | HH(a, b, c, d, m[(i + 13)], 4, 681279174) + | HH(a, b, c, d, m[(i + 9)], 4, ???*7*) + | II(a, b, c, d, m[(i + 0)], 6, ???*8*) + | II(a, b, c, d, m[(i + 12)], 6, 1700485571) + | II(a, b, c, d, m[(i + 8)], 6, 1873313359) + | II(a, b, c, d, m[(i + 4)], 6, ???*9*) + | ???*10* +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects + +a#7 = arguments[0] + +a#8 = arguments[0] + +a#9 = arguments[0] + +aa = a + +b#10 = arguments[1] + +b#4 = ( + | ???*0* + | FF(b, c, d, a, m[(i + 3)], 22, ???*1*) + | FF(b, c, d, a, m[(i + 7)], 22, ???*2*) + | FF(b, c, d, a, m[(i + 11)], 22, ???*3*) + | FF(b, c, d, a, m[(i + 15)], 22, 1236535329) + | GG(b, c, d, a, m[(i + 0)], 20, ???*4*) + | GG(b, c, d, a, m[(i + 4)], 20, ???*5*) + | GG(b, c, d, a, m[(i + 8)], 20, 1163531501) + | GG(b, c, d, a, m[(i + 12)], 20, ???*6*) + | HH(b, c, d, a, m[(i + 14)], 23, ???*7*) + | HH(b, c, d, a, m[(i + 10)], 23, ???*8*) + | HH(b, c, d, a, m[(i + 6)], 23, 76029189) + | HH(b, c, d, a, m[(i + 2)], 23, ???*9*) + | II(b, c, d, a, m[(i + 5)], 21, ???*10*) + | II(b, c, d, a, m[(i + 1)], 21, ???*11*) + | II(b, c, d, a, m[(i + 13)], 21, 1309151649) + | II(b, c, d, a, m[(i + 9)], 21, ???*12*) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects + +b#7 = arguments[1] + +b#8 = arguments[1] + +b#9 = arguments[1] + +bb = b + +bin = FreeVar(require)("charenc")["bin"] + +c#10 = arguments[2] + +c#4 = ( + | ???*0* + | FF(c, d, a, b, m[(i + 2)], 17, 606105819) + | FF(c, d, a, b, m[(i + 6)], 17, ???*1*) + | FF(c, d, a, b, m[(i + 10)], 17, ???*2*) + | FF(c, d, a, b, m[(i + 14)], 17, ???*3*) + | GG(c, d, a, b, m[(i + 11)], 14, 643717713) + | GG(c, d, a, b, m[(i + 15)], 14, ???*4*) + | GG(c, d, a, b, m[(i + 3)], 14, ???*5*) + | GG(c, d, a, b, m[(i + 7)], 14, 1735328473) + | HH(c, d, a, b, m[(i + 11)], 16, 1839030562) + | HH(c, d, a, b, m[(i + 7)], 16, ???*6*) + | HH(c, d, a, b, m[(i + 3)], 16, ???*7*) + | HH(c, d, a, b, m[(i + 15)], 16, 530742520) + | II(c, d, a, b, m[(i + 14)], 15, ???*8*) + | II(c, d, a, b, m[(i + 10)], 15, ???*9*) + | II(c, d, a, b, m[(i + 6)], 15, ???*10*) + | II(c, d, a, b, m[(i + 2)], 15, 718787259) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects + +c#7 = arguments[2] + +c#8 = arguments[2] + +c#9 = arguments[2] + +cc = c + +crypt = FreeVar(require)("crypt") + +d#10 = arguments[3] + +d#4 = ( + | 271733878 + | FF(d, a, b, c, m[(i + 1)], 12, ???*0*) + | FF(d, a, b, c, m[(i + 5)], 12, 1200080426) + | FF(d, a, b, c, m[(i + 9)], 12, ???*1*) + | FF(d, a, b, c, m[(i + 13)], 12, ???*2*) + | GG(d, a, b, c, m[(i + 6)], 9, ???*3*) + | GG(d, a, b, c, m[(i + 10)], 9, 38016083) + | GG(d, a, b, c, m[(i + 14)], 9, ???*4*) + | GG(d, a, b, c, m[(i + 2)], 9, ???*5*) + | HH(d, a, b, c, m[(i + 8)], 11, ???*6*) + | HH(d, a, b, c, m[(i + 4)], 11, 1272893353) + | HH(d, a, b, c, m[(i + 0)], 11, ???*7*) + | HH(d, a, b, c, m[(i + 12)], 11, ???*8*) + | II(d, a, b, c, m[(i + 7)], 10, 1126891415) + | II(d, a, b, c, m[(i + 3)], 10, ???*9*) + | II(d, a, b, c, m[(i + 15)], 10, ???*10*) + | II(d, a, b, c, m[(i + 11)], 10, ???*11*) + | ???*12* +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects + +d#7 = arguments[3] + +d#8 = arguments[3] + +d#9 = arguments[3] + +dd = d + +digestbytes = crypt["wordsToBytes"](md5(message, options)) + +i = (0 | ???*0* | (i + 16)) +- *0* updated with update expression + ⚠️ This value might have side effects + +isBuffer = FreeVar(require)("is-buffer") + +l = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +m = crypt["bytesToWords"](message) + +md5 = *anonymous function 181* + +message#11 = arguments[0] + +message#4 = ( + | arguments[0] + | bin["stringToBytes"](message) + | utf8["stringToBytes"](message) + | FreeVar(Array)["prototype"]["slice"]["call"](message, 0) + | message["toString"]() +) + +n#10 = (a + ???*0* + ???*1* + t) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +n#7 = (a + ???*0* + ???*1* + t) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +n#8 = (a + ???*0* + ???*1* + t) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +n#9 = (a + ???*0* + ???*1* + t) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +options#11 = arguments[1] + +options#4 = arguments[1] + +s#10 = arguments[5] + +s#7 = arguments[5] + +s#8 = arguments[5] + +s#9 = arguments[5] + +t#10 = arguments[6] + +t#7 = arguments[6] + +t#8 = arguments[6] + +t#9 = arguments[6] + +utf8 = FreeVar(require)("charenc")["utf8"] + +x#10 = arguments[4] + +x#7 = arguments[4] + +x#8 = arguments[4] + +x#9 = arguments[4] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph.snapshot new file mode 100644 index 0000000000000..d09cede4aaaeb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/graph.snapshot @@ -0,0 +1,5906 @@ +[ + ( + "*anonymous function 181*", + Function( + 9, + 181, + MemberCall( + 8, + Variable( + ( + "crypt", + #3, + ), + ), + Constant( + Str( + Atom( + "endian", + ), + ), + ), + [ + Array { + total_nodes: 5, + items: [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + ], + mutable: true, + }, + ], + ), + ), + ), + ( + "*anonymous function 5013*", + Function( + 4, + 5013, + Add( + 3, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "b", + #7, + ), + ), + ], + ), + ), + ), + ( + "*anonymous function 5163*", + Function( + 4, + 5163, + Add( + 3, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "b", + #8, + ), + ), + ], + ), + ), + ), + ( + "*anonymous function 5313*", + Function( + 4, + 5313, + Add( + 3, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "b", + #9, + ), + ), + ], + ), + ), + ), + ( + "*anonymous function 5454*", + Function( + 4, + 5454, + Add( + 3, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "b", + #10, + ), + ), + ], + ), + ), + ), + ( + "*anonymous function 5685*", + Function( + 22, + 5685, + Tenary( + 21, + Logical( + 5, + And, + [ + Variable( + ( + "options", + #11, + ), + ), + Member( + 3, + Variable( + ( + "options", + #11, + ), + ), + Constant( + Str( + Atom( + "asBytes", + ), + ), + ), + ), + ], + ), + Variable( + ( + "digestbytes", + #11, + ), + ), + Tenary( + 14, + Logical( + 5, + And, + [ + Variable( + ( + "options", + #11, + ), + ), + Member( + 3, + Variable( + ( + "options", + #11, + ), + ), + Constant( + Str( + Atom( + "asString", + ), + ), + ), + ), + ], + ), + MemberCall( + 4, + Variable( + ( + "bin", + #3, + ), + ), + Constant( + Str( + Atom( + "bytesToString", + ), + ), + ), + [ + Variable( + ( + "digestbytes", + #11, + ), + ), + ], + ), + MemberCall( + 4, + Variable( + ( + "crypt", + #3, + ), + ), + Constant( + Str( + Atom( + "bytesToHex", + ), + ), + ), + [ + Variable( + ( + "digestbytes", + #11, + ), + ), + ], + ), + ), + ), + ), + ), + ( + "FF", + Member( + 3, + Variable( + ( + "md5", + #3, + ), + ), + Constant( + Str( + Atom( + "_ff", + ), + ), + ), + ), + ), + ( + "GG", + Member( + 3, + Variable( + ( + "md5", + #3, + ), + ), + Constant( + Str( + Atom( + "_gg", + ), + ), + ), + ), + ), + ( + "HH", + Member( + 3, + Variable( + ( + "md5", + #3, + ), + ), + Constant( + Str( + Atom( + "_hh", + ), + ), + ), + ), + ), + ( + "II", + Member( + 3, + Variable( + ( + "md5", + #3, + ), + ), + Constant( + Str( + Atom( + "_ii", + ), + ), + ), + ), + ), + ( + "a#10", + Argument( + 5454, + 0, + ), + ), + ( + "a#4", + Alternatives( + 211, + [ + Constant( + Num( + ConstantNumber( + 1732584193.0, + ), + ), + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1770035416.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1804603682.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 568446438.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 681279174.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1700485571.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1873313359.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + ), + ( + "a#7", + Argument( + 5013, + 0, + ), + ), + ( + "a#8", + Argument( + 5163, + 0, + ), + ), + ( + "a#9", + Argument( + 5313, + 0, + ), + ), + ( + "aa", + Variable( + ( + "a", + #4, + ), + ), + ), + ( + "b#10", + Argument( + 5454, + 1, + ), + ), + ( + "b#4", + Alternatives( + 210, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1236535329.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 20.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 20.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 20.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1163531501.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 20.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 23.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 23.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 23.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 76029189.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 23.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 21.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 21.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 21.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1309151649.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 21.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + ], + ), + ), + ( + "b#7", + Argument( + 5013, + 1, + ), + ), + ( + "b#8", + Argument( + 5163, + 1, + ), + ), + ( + "b#9", + Argument( + 5313, + 1, + ), + ), + ( + "bb", + Variable( + ( + "b", + #4, + ), + ), + ), + ( + "bin", + Member( + 5, + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "charenc", + ), + ), + ), + ], + ), + Constant( + Str( + Atom( + "bin", + ), + ), + ), + ), + ), + ( + "c#10", + Argument( + 5454, + 2, + ), + ), + ( + "c#4", + Alternatives( + 210, + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 606105819.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 17.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 643717713.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1735328473.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1839030562.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 530742520.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "c", + #4, + ), + ), + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 718787259.0, + ), + ), + ), + ], + ), + ], + ), + ), + ( + "c#7", + Argument( + 5013, + 2, + ), + ), + ( + "c#8", + Argument( + 5163, + 2, + ), + ), + ( + "c#9", + Argument( + 5313, + 2, + ), + ), + ( + "cc", + Variable( + ( + "c", + #4, + ), + ), + ), + ( + "crypt", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "crypt", + ), + ), + ), + ], + ), + ), + ( + "d#10", + Argument( + 5454, + 3, + ), + ), + ( + "d#4", + Alternatives( + 211, + [ + Constant( + Num( + ConstantNumber( + 271733878.0, + ), + ), + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1200080426.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "FF", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 13.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 38016083.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 14.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "GG", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1272893353.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "HH", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 12.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1126891415.0, + ), + ), + ), + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 15.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Call( + 13, + Variable( + ( + "II", + #4, + ), + ), + [ + Variable( + ( + "d", + #4, + ), + ), + Variable( + ( + "a", + #4, + ), + ), + Variable( + ( + "b", + #4, + ), + ), + Variable( + ( + "c", + #4, + ), + ), + Member( + 5, + Variable( + ( + "m", + #4, + ), + ), + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ], + ), + ), + Constant( + Num( + ConstantNumber( + 10.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + ), + ( + "d#7", + Argument( + 5013, + 3, + ), + ), + ( + "d#8", + Argument( + 5163, + 3, + ), + ), + ( + "d#9", + Argument( + 5313, + 3, + ), + ), + ( + "dd", + Variable( + ( + "d", + #4, + ), + ), + ), + ( + "digestbytes", + MemberCall( + 7, + Variable( + ( + "crypt", + #3, + ), + ), + Constant( + Str( + Atom( + "wordsToBytes", + ), + ), + ), + [ + Call( + 4, + Variable( + ( + "md5", + #3, + ), + ), + [ + Variable( + ( + "message", + #11, + ), + ), + Variable( + ( + "options", + #11, + ), + ), + ], + ), + ], + ), + ), + ( + "i", + Alternatives( + 6, + [ + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "updated with update expression", + has_side_effects: true, + }, + Add( + 3, + [ + Variable( + ( + "i", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 16.0, + ), + ), + ), + ], + ), + ], + ), + ), + ( + "isBuffer", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "is-buffer", + ), + ), + ), + ], + ), + ), + ( + "l", + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ( + "m", + MemberCall( + 4, + Variable( + ( + "crypt", + #3, + ), + ), + Constant( + Str( + Atom( + "bytesToWords", + ), + ), + ), + [ + Variable( + ( + "message", + #4, + ), + ), + ], + ), + ), + ( + "md5", + Variable( + ( + "*anonymous function 181*", + #0, + ), + ), + ), + ( + "message#11", + Argument( + 5685, + 0, + ), + ), + ( + "message#4", + Alternatives( + 22, + [ + Argument( + 181, + 0, + ), + MemberCall( + 4, + Variable( + ( + "bin", + #3, + ), + ), + Constant( + Str( + Atom( + "stringToBytes", + ), + ), + ), + [ + Variable( + ( + "message", + #4, + ), + ), + ], + ), + MemberCall( + 4, + Variable( + ( + "utf8", + #3, + ), + ), + Constant( + Str( + Atom( + "stringToBytes", + ), + ), + ), + [ + Variable( + ( + "message", + #4, + ), + ), + ], + ), + MemberCall( + 9, + Member( + 5, + Member( + 3, + FreeVar( + "Array", + ), + Constant( + Str( + Atom( + "prototype", + ), + ), + ), + ), + Constant( + Str( + Atom( + "slice", + ), + ), + ), + ), + Constant( + Str( + Atom( + "call", + ), + ), + ), + [ + Variable( + ( + "message", + #4, + ), + ), + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ], + ), + MemberCall( + 3, + Variable( + ( + "message", + #4, + ), + ), + Constant( + Str( + Atom( + "toString", + ), + ), + ), + [], + ), + ], + ), + ), + ( + "n#10", + Add( + 5, + [ + Variable( + ( + "a", + #10, + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "t", + #10, + ), + ), + ], + ), + ), + ( + "n#7", + Add( + 5, + [ + Variable( + ( + "a", + #7, + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "t", + #7, + ), + ), + ], + ), + ), + ( + "n#8", + Add( + 5, + [ + Variable( + ( + "a", + #8, + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "t", + #8, + ), + ), + ], + ), + ), + ( + "n#9", + Add( + 5, + [ + Variable( + ( + "a", + #9, + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + Variable( + ( + "t", + #9, + ), + ), + ], + ), + ), + ( + "options#11", + Argument( + 5685, + 1, + ), + ), + ( + "options#4", + Argument( + 181, + 1, + ), + ), + ( + "s#10", + Argument( + 5454, + 5, + ), + ), + ( + "s#7", + Argument( + 5013, + 5, + ), + ), + ( + "s#8", + Argument( + 5163, + 5, + ), + ), + ( + "s#9", + Argument( + 5313, + 5, + ), + ), + ( + "t#10", + Argument( + 5454, + 6, + ), + ), + ( + "t#7", + Argument( + 5013, + 6, + ), + ), + ( + "t#8", + Argument( + 5163, + 6, + ), + ), + ( + "t#9", + Argument( + 5313, + 6, + ), + ), + ( + "utf8", + Member( + 5, + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "charenc", + ), + ), + ), + ], + ), + Constant( + Str( + Atom( + "utf8", + ), + ), + ), + ), + ), + ( + "x#10", + Argument( + 5454, + 4, + ), + ), + ( + "x#7", + Argument( + 5013, + 4, + ), + ), + ( + "x#8", + Argument( + 5163, + 4, + ), + ), + ( + "x#9", + Argument( + 5313, + 4, + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/input.js new file mode 100644 index 0000000000000..c659c9c16c82e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/input.js @@ -0,0 +1,158 @@ +(function () { + var crypt = require("crypt"), + utf8 = require("charenc").utf8, + isBuffer = require("is-buffer"), + bin = require("charenc").bin, + // The core + md5 = function (message, options) { + // Convert to byte array + if (message.constructor == String) + if (options && options.encoding === "binary") + message = bin.stringToBytes(message); + else message = utf8.stringToBytes(message); + else if (isBuffer(message)) + message = Array.prototype.slice.call(message, 0); + else if (!Array.isArray(message)) message = message.toString(); + // else, assume byte array already + + var m = crypt.bytesToWords(message), + l = message.length * 8, + a = 1732584193, + b = -271733879, + c = -1732584194, + d = 271733878; + + // Swap endian + for (var i = 0; i < m.length; i++) { + m[i] = + (((m[i] << 8) | (m[i] >>> 24)) & 0x00ff00ff) | + (((m[i] << 24) | (m[i] >>> 8)) & 0xff00ff00); + } + + // Padding + m[l >>> 5] |= 0x80 << l % 32; + m[(((l + 64) >>> 9) << 4) + 14] = l; + + // Method shortcuts + var FF = md5._ff, + GG = md5._gg, + HH = md5._hh, + II = md5._ii; + + for (var i = 0; i < m.length; i += 16) { + var aa = a, + bb = b, + cc = c, + dd = d; + + a = FF(a, b, c, d, m[i + 0], 7, -680876936); + d = FF(d, a, b, c, m[i + 1], 12, -389564586); + c = FF(c, d, a, b, m[i + 2], 17, 606105819); + b = FF(b, c, d, a, m[i + 3], 22, -1044525330); + a = FF(a, b, c, d, m[i + 4], 7, -176418897); + d = FF(d, a, b, c, m[i + 5], 12, 1200080426); + c = FF(c, d, a, b, m[i + 6], 17, -1473231341); + b = FF(b, c, d, a, m[i + 7], 22, -45705983); + a = FF(a, b, c, d, m[i + 8], 7, 1770035416); + d = FF(d, a, b, c, m[i + 9], 12, -1958414417); + c = FF(c, d, a, b, m[i + 10], 17, -42063); + b = FF(b, c, d, a, m[i + 11], 22, -1990404162); + a = FF(a, b, c, d, m[i + 12], 7, 1804603682); + d = FF(d, a, b, c, m[i + 13], 12, -40341101); + c = FF(c, d, a, b, m[i + 14], 17, -1502002290); + b = FF(b, c, d, a, m[i + 15], 22, 1236535329); + + a = GG(a, b, c, d, m[i + 1], 5, -165796510); + d = GG(d, a, b, c, m[i + 6], 9, -1069501632); + c = GG(c, d, a, b, m[i + 11], 14, 643717713); + b = GG(b, c, d, a, m[i + 0], 20, -373897302); + a = GG(a, b, c, d, m[i + 5], 5, -701558691); + d = GG(d, a, b, c, m[i + 10], 9, 38016083); + c = GG(c, d, a, b, m[i + 15], 14, -660478335); + b = GG(b, c, d, a, m[i + 4], 20, -405537848); + a = GG(a, b, c, d, m[i + 9], 5, 568446438); + d = GG(d, a, b, c, m[i + 14], 9, -1019803690); + c = GG(c, d, a, b, m[i + 3], 14, -187363961); + b = GG(b, c, d, a, m[i + 8], 20, 1163531501); + a = GG(a, b, c, d, m[i + 13], 5, -1444681467); + d = GG(d, a, b, c, m[i + 2], 9, -51403784); + c = GG(c, d, a, b, m[i + 7], 14, 1735328473); + b = GG(b, c, d, a, m[i + 12], 20, -1926607734); + + a = HH(a, b, c, d, m[i + 5], 4, -378558); + d = HH(d, a, b, c, m[i + 8], 11, -2022574463); + c = HH(c, d, a, b, m[i + 11], 16, 1839030562); + b = HH(b, c, d, a, m[i + 14], 23, -35309556); + a = HH(a, b, c, d, m[i + 1], 4, -1530992060); + d = HH(d, a, b, c, m[i + 4], 11, 1272893353); + c = HH(c, d, a, b, m[i + 7], 16, -155497632); + b = HH(b, c, d, a, m[i + 10], 23, -1094730640); + a = HH(a, b, c, d, m[i + 13], 4, 681279174); + d = HH(d, a, b, c, m[i + 0], 11, -358537222); + c = HH(c, d, a, b, m[i + 3], 16, -722521979); + b = HH(b, c, d, a, m[i + 6], 23, 76029189); + a = HH(a, b, c, d, m[i + 9], 4, -640364487); + d = HH(d, a, b, c, m[i + 12], 11, -421815835); + c = HH(c, d, a, b, m[i + 15], 16, 530742520); + b = HH(b, c, d, a, m[i + 2], 23, -995338651); + + a = II(a, b, c, d, m[i + 0], 6, -198630844); + d = II(d, a, b, c, m[i + 7], 10, 1126891415); + c = II(c, d, a, b, m[i + 14], 15, -1416354905); + b = II(b, c, d, a, m[i + 5], 21, -57434055); + a = II(a, b, c, d, m[i + 12], 6, 1700485571); + d = II(d, a, b, c, m[i + 3], 10, -1894986606); + c = II(c, d, a, b, m[i + 10], 15, -1051523); + b = II(b, c, d, a, m[i + 1], 21, -2054922799); + a = II(a, b, c, d, m[i + 8], 6, 1873313359); + d = II(d, a, b, c, m[i + 15], 10, -30611744); + c = II(c, d, a, b, m[i + 6], 15, -1560198380); + b = II(b, c, d, a, m[i + 13], 21, 1309151649); + a = II(a, b, c, d, m[i + 4], 6, -145523070); + d = II(d, a, b, c, m[i + 11], 10, -1120210379); + c = II(c, d, a, b, m[i + 2], 15, 718787259); + b = II(b, c, d, a, m[i + 9], 21, -343485551); + + a = (a + aa) >>> 0; + b = (b + bb) >>> 0; + c = (c + cc) >>> 0; + d = (d + dd) >>> 0; + } + + return crypt.endian([a, b, c, d]); + }; + + // Auxiliary functions + md5._ff = function (a, b, c, d, x, s, t) { + var n = a + ((b & c) | (~b & d)) + (x >>> 0) + t; + return ((n << s) | (n >>> (32 - s))) + b; + }; + md5._gg = function (a, b, c, d, x, s, t) { + var n = a + ((b & d) | (c & ~d)) + (x >>> 0) + t; + return ((n << s) | (n >>> (32 - s))) + b; + }; + md5._hh = function (a, b, c, d, x, s, t) { + var n = a + (b ^ c ^ d) + (x >>> 0) + t; + return ((n << s) | (n >>> (32 - s))) + b; + }; + md5._ii = function (a, b, c, d, x, s, t) { + var n = a + (c ^ (b | ~d)) + (x >>> 0) + t; + return ((n << s) | (n >>> (32 - s))) + b; + }; + + // Package private blocksize + md5._blocksize = 16; + md5._digestsize = 16; + + module.exports = function (message, options) { + if (message === undefined || message === null) + throw new Error("Illegal argument " + message); + + var digestbytes = crypt.wordsToBytes(md5(message, options)); + return options && options.asBytes + ? digestbytes + : options && options.asString + ? bin.bytesToString(digestbytes) + : crypt.bytesToHex(digestbytes); + }; +})(); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/resolved-effects.snapshot new file mode 100644 index 0000000000000..741d5b1621a31 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/resolved-effects.snapshot @@ -0,0 +1,3149 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 call = require*0*("crypt") +- *0* require: The require method from CommonJS + +0 -> 4 free var = FreeVar(require) + +0 -> 5 call = require*0*("charenc") +- *0* require: The require method from CommonJS + +0 -> 6 free var = FreeVar(require) + +0 -> 7 call = require*0*("is-buffer") +- *0* require: The require method from CommonJS + +0 -> 9 free var = FreeVar(require) + +0 -> 10 call = require*0*("charenc") +- *0* require: The require method from CommonJS + +0 -> 12 free var = FreeVar(String) + +0 -> 13 conditional = ((???*0* | ???*2*) == ???*7*) +- *0* ???*1*["constructor"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["constructor"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* ???*5*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* FreeVar(String) + ⚠️ unknown global + ⚠️ This value might have side effects + +13 -> 15 conditional = (???*0* | (???*1* === "binary")) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["encoding"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +15 -> 17 member call = module["bin"]["stringToBytes"]( + ( + | ???*0* + | module["bin"]["stringToBytes"](???*1*) + | module["utf8"]["stringToBytes"](???*2*) + | ???*3* + | ???*7*() + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* message + ⚠️ circular variable reference +- *2* message + ⚠️ circular variable reference +- *3* ???*4*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* ???*5*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* ???*8*["toString"] + ⚠️ unknown object +- *8* message + ⚠️ circular variable reference + +15 -> 19 member call = module["utf8"]["stringToBytes"]( + ( + | ???*0* + | module["bin"]["stringToBytes"](???*1*) + | module["utf8"]["stringToBytes"](???*2*) + | ???*3* + | ???*7*() + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* message + ⚠️ circular variable reference +- *2* message + ⚠️ circular variable reference +- *3* ???*4*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* ???*5*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* ???*8*["toString"] + ⚠️ unknown object +- *8* message + ⚠️ circular variable reference + +13 -> 20 call = module( + ( + | ???*0* + | module["bin"]["stringToBytes"](???*1*) + | module["utf8"]["stringToBytes"](???*2*) + | ???*3* + | ???*7*() + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* message + ⚠️ circular variable reference +- *2* message + ⚠️ circular variable reference +- *3* ???*4*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* ???*5*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* ???*8*["toString"] + ⚠️ unknown object +- *8* message + ⚠️ circular variable reference + +13 -> 21 conditional = module((???*0* | ???*1* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* module["bin"]["stringToBytes"](???*2*) + ⚠️ nested operation +- *2* message + ⚠️ circular variable reference +- *3* ???*4*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* ???*5*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +21 -> 25 free var = FreeVar(Array) + +21 -> 26 member call = ???*0*["call"]( + ( + | ???*3* + | module["bin"]["stringToBytes"](???*4*) + | module["utf8"]["stringToBytes"](???*5*) + | ???*6* + | ???*10*() + ), + 0 +) +- *0* ???*1*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* message + ⚠️ circular variable reference +- *5* message + ⚠️ circular variable reference +- *6* ???*7*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *7* ???*8*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???*9*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* ???*11*["toString"] + ⚠️ unknown object +- *11* message + ⚠️ circular variable reference + +21 -> 28 free var = FreeVar(Array) + +21 -> 29 member call = ???*0*["isArray"]( + ( + | ???*1* + | module["bin"]["stringToBytes"](???*2*) + | module["utf8"]["stringToBytes"](???*3*) + | ???*4* + | ???*8*() + ) +) +- *0* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* message + ⚠️ circular variable reference +- *3* message + ⚠️ circular variable reference +- *4* ???*5*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* ???*6*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* ???*9*["toString"] + ⚠️ unknown object +- *9* message + ⚠️ circular variable reference + +21 -> 30 conditional = !(???*0*) +- *0* ???*1*["isArray"](message) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +30 -> 32 member call = ( + | ???*0* + | module["bin"]["stringToBytes"](???*1*) + | module["utf8"]["stringToBytes"](???*2*) + | ???*3* + | ???*7*() +)["toString"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* message + ⚠️ circular variable reference +- *2* message + ⚠️ circular variable reference +- *3* ???*4*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* ???*5*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* ???*8*["toString"] + ⚠️ unknown object +- *8* message + ⚠️ circular variable reference + +0 -> 34 member call = module["bytesToWords"]( + ( + | ???*0* + | module["bin"]["stringToBytes"](???*1*) + | module["utf8"]["stringToBytes"](???*2*) + | ???*3* + | ???*7*() + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* message + ⚠️ circular variable reference +- *2* message + ⚠️ circular variable reference +- *3* ???*4*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* ???*5*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* ???*8*["toString"] + ⚠️ unknown object +- *8* message + ⚠️ circular variable reference + +0 -> 50 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 0)], + 7, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 52 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 1)], + 12, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 54 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 2)], + 17, + 606105819 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 56 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 3)], + 22, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 58 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 4)], + 7, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 60 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 5)], + 12, + 1200080426 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 62 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 6)], + 17, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 64 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 7)], + 22, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 66 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 8)], + 7, + 1770035416 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 68 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 9)], + 12, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 70 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 10)], + 17, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 72 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 11)], + 22, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 74 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 12)], + 7, + 1804603682 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 76 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 13)], + 12, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 78 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 14)], + 17, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 80 call = (...) => crypt["endian"]([a, b, c, d])["_ff"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 15)], + 22, + 1236535329 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 82 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 1)], + 5, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 84 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 6)], + 9, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 86 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 11)], + 14, + 643717713 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 88 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 0)], + 20, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 90 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 5)], + 5, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 92 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 10)], + 9, + 38016083 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 94 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 15)], + 14, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 96 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 4)], + 20, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 98 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 9)], + 5, + 568446438 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 100 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 14)], + 9, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 102 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 3)], + 14, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 104 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 8)], + 20, + 1163531501 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 106 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 13)], + 5, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 108 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 2)], + 9, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 110 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 7)], + 14, + 1735328473 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 112 call = (...) => crypt["endian"]([a, b, c, d])["_gg"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 12)], + 20, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 114 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 5)], + 4, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 116 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 8)], + 11, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 118 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 11)], + 16, + 1839030562 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 120 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 14)], + 23, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 122 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 1)], + 4, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 124 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 4)], + 11, + 1272893353 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 126 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 7)], + 16, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 128 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 10)], + 23, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 130 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 13)], + 4, + 681279174 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 132 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 0)], + 11, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 134 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 3)], + 16, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 136 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 6)], + 23, + 76029189 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 138 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 9)], + 4, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 140 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 12)], + 11, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 142 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 15)], + 16, + 530742520 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 144 call = (...) => crypt["endian"]([a, b, c, d])["_hh"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 2)], + 23, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 146 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 0)], + 6, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 148 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 7)], + 10, + 1126891415 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 150 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 14)], + 15, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 152 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 5)], + 21, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 154 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 12)], + 6, + 1700485571 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 156 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 3)], + 10, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 158 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 10)], + 15, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 160 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 1)], + 21, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 162 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 8)], + 6, + 1873313359 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 164 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 15)], + 10, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 166 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 6)], + 15, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 168 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 13)], + 21, + 1309151649 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 170 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 4)], + 6, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 172 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 11)], + 10, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 174 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 2)], + 15, + 718787259 +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference + +0 -> 176 call = (...) => crypt["endian"]([a, b, c, d])["_ii"]( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + module["bytesToWords"]((???*4* | ???*5* | ???*7*))[((0 | ???*11* | ???*12*) + 9)], + 21, + ???*14* +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* module["bin"]["stringToBytes"](???*6*) + ⚠️ nested operation +- *6* message + ⚠️ circular variable reference +- *7* ???*8*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* (???*13* + 16) + ⚠️ nested operation +- *13* i + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects + +0 -> 178 member call = module["endian"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 186 free var = FreeVar(module) + +0 -> 187 free var = FreeVar(undefined) + +0 -> 188 conditional = ((???*0* === ???*1*) | (???*2* === null)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +188 -> 189 free var = FreeVar(Error) + +0 -> 191 call = (...) => crypt["endian"]([a, b, c, d])(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 192 member call = module["wordsToBytes"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 194 conditional = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["asBytes"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +194 -> 196 conditional = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["asString"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +196 -> 198 member call = module["bin"]["bytesToString"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +196 -> 200 member call = module["bytesToHex"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/resolved-explained.snapshot new file mode 100644 index 0000000000000..9b3bd5bcf6609 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/md5_2/resolved-explained.snapshot @@ -0,0 +1,349 @@ +*anonymous function 181* = (...) => crypt["endian"]([a, b, c, d]) + +*anonymous function 5013* = (...) => (???*0* + b) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 5163* = (...) => (???*0* + b) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 5313* = (...) => (???*0* + b) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 5454* = (...) => (???*0* + b) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 5685* = (...) => ((options && options["asBytes"]) ? digestbytes : ((options && options["asString"]) ? bin["bytesToString"](digestbytes) : crypt["bytesToHex"](digestbytes))) + +FF = (...) => crypt["endian"]([a, b, c, d])["_ff"] + +GG = (...) => crypt["endian"]([a, b, c, d])["_gg"] + +HH = (...) => crypt["endian"]([a, b, c, d])["_hh"] + +II = (...) => crypt["endian"]([a, b, c, d])["_ii"] + +a#10 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#4 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#7 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#8 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#9 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +aa = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#10 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#4 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#7 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#8 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#9 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +bb = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +bin = module["bin"] + +c#10 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#4 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#7 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#8 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#9 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +cc = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +crypt = module + +d#10 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#4 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#7 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#8 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#9 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +dd = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +digestbytes = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +i = (0 | ???*0* | ((0 | ???*1* | ???*2*) + 16)) +- *0* updated with update expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects +- *2* (???*3* + 16) + ⚠️ nested operation +- *3* i + ⚠️ circular variable reference + +isBuffer = module + +l = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +m = module["bytesToWords"]((???*0* | ???*1* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* module["bin"]["stringToBytes"](???*2*) + ⚠️ nested operation +- *2* message + ⚠️ circular variable reference +- *3* ???*4*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* ???*5*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +md5 = (...) => crypt["endian"]([a, b, c, d]) + +message#11 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +message#4 = ( + | ???*0* + | module["bin"]["stringToBytes"]((???*1* | ???*2* | ???*4*)) + | module["utf8"]["stringToBytes"]((???*8* | ???*9* | ???*11*)) + | ???*15* + | ???*19*() + | ???*21*() +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* module["bin"]["stringToBytes"](???*3*) + ⚠️ nested operation +- *3* message + ⚠️ circular variable reference +- *4* ???*5*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* ???*6*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* module["bin"]["stringToBytes"](???*10*) + ⚠️ nested operation +- *10* message + ⚠️ circular variable reference +- *11* ???*12*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *12* ???*13*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* ???*14*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *15* ???*16*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *16* ???*17*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* ???*18*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *19* ???*20*["toString"] + ⚠️ unknown object +- *20* arguments[0] + ⚠️ function calls are not analysed yet +- *21* ???*22*["toString"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* ???*23*["call"](message, 0) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *23* ???*24*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* ???*25*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *25* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +n#10 = (???*0* + ???*1* + ???*2* + ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[6] + ⚠️ function calls are not analysed yet + +n#7 = (???*0* + ???*1* + ???*2* + ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[6] + ⚠️ function calls are not analysed yet + +n#8 = (???*0* + ???*1* + ???*2* + ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[6] + ⚠️ function calls are not analysed yet + +n#9 = (???*0* + ???*1* + ???*2* + ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[6] + ⚠️ function calls are not analysed yet + +options#11 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +options#4 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +s#10 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +s#7 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +s#8 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +s#9 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +t#10 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +t#7 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +t#8 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +t#9 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +utf8 = module["utf8"] + +x#10 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +x#7 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +x#8 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +x#9 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph-effects.snapshot new file mode 100644 index 0000000000000..0e29da6f94e19 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph-effects.snapshot @@ -0,0 +1,1076 @@ +[ + Member { + obj: Variable( + ( + "array", + #2, + ), + ), + prop: Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 35..43#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "array", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 70..82#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "array", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + args: [ + Value( + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ), + Value( + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + mutable: true, + }, + ), + Value( + Concat( + 3, + [ + Constant( + Str( + Atom( + "hello ", + ), + ), + ), + Variable( + ( + "item", + #2, + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 70..119#0, + in_try: false, + }, + Member { + obj: Member( + 7, + Array { + total_nodes: 5, + items: [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 139..160#0, + in_try: false, + }, + Member { + obj: Array { + total_nodes: 5, + items: [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + prop: Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + ], + span: 139..153#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "unknown", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Array, + ), + ArrayLit( + Elems( + 3, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Ident, + ), + ], + span: 171..178#1, + in_try: false, + }, + MemberCall { + obj: Member( + 7, + Array { + total_nodes: 5, + items: [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + args: [ + Value( + Array { + total_nodes: 5, + items: [ + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + FreeVar( + "unknown", + ), + ], + mutable: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 139..180#0, + in_try: false, + }, + Member { + obj: Member( + 7, + Array { + total_nodes: 5, + items: [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 200..221#0, + in_try: false, + }, + Member { + obj: Array { + total_nodes: 5, + items: [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + prop: Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + ], + span: 200..214#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "unknown", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 3, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Ident, + ), + ], + span: 231..238#1, + in_try: false, + }, + MemberCall { + obj: Member( + 7, + Array { + total_nodes: 5, + items: [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + args: [ + Value( + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ), + Value( + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ), + Value( + FreeVar( + "unknown", + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 200..239#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "arrays", + #2, + ), + ), + prop: Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 304..313#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "array", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 348..360#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "array", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "concat", + ), + ), + ), + args: [ + Value( + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + mutable: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 348..371#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph-explained.snapshot new file mode 100644 index 0000000000000..bc4cd4ab1aae2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph-explained.snapshot @@ -0,0 +1,15 @@ +array = [1, 2, 3] + +arrays = ([1, 2, 3] | [4, 5, 6]) + +concatenated_array = array["concat"](4, 5, 6, [7, 8, 9], `hello ${item}`) + +concatenated_array_options = array["concat"]([7, 8, 9]) + +item = array[1] + +item_options = arrays[1] + +pick_array1 = [[1, 2, 3]][0]["concat"]([4, 5, 6, FreeVar(unknown)]) + +pick_array2 = [[1, 2, 3]][0]["concat"](4, 5, 6, FreeVar(unknown)) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph.snapshot new file mode 100644 index 0000000000000..f43ce4e63ae8f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/graph.snapshot @@ -0,0 +1,437 @@ +[ + ( + "array", + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "arrays", + Alternatives( + 9, + [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + ], + mutable: true, + }, + ], + ), + ), + ( + "concatenated_array", + MemberCall( + 13, + Variable( + ( + "array", + #2, + ), + ), + Constant( + Str( + Atom( + "concat", + ), + ), + ), + [ + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + mutable: true, + }, + Concat( + 3, + [ + Constant( + Str( + Atom( + "hello ", + ), + ), + ), + Variable( + ( + "item", + #2, + ), + ), + ], + ), + ], + ), + ), + ( + "concatenated_array_options", + MemberCall( + 7, + Variable( + ( + "array", + #2, + ), + ), + Constant( + Str( + Atom( + "concat", + ), + ), + ), + [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 7.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 8.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 9.0, + ), + ), + ), + ], + mutable: true, + }, + ], + ), + ), + ( + "item", + Member( + 3, + Variable( + ( + "array", + #2, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "item_options", + Member( + 3, + Variable( + ( + "arrays", + #2, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ), + ( + "pick_array1", + MemberCall( + 14, + Member( + 7, + Array { + total_nodes: 5, + items: [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + Constant( + Str( + Atom( + "concat", + ), + ), + ), + [ + Array { + total_nodes: 5, + items: [ + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + FreeVar( + "unknown", + ), + ], + mutable: true, + }, + ], + ), + ), + ( + "pick_array2", + MemberCall( + 13, + Member( + 7, + Array { + total_nodes: 5, + items: [ + Array { + total_nodes: 4, + items: [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + Constant( + Str( + Atom( + "concat", + ), + ), + ), + [ + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + Constant( + Num( + ConstantNumber( + 6.0, + ), + ), + ), + FreeVar( + "unknown", + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/input.js new file mode 100644 index 0000000000000..7462058fe7eac --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/input.js @@ -0,0 +1,9 @@ +let array = [1, 2, 3]; +let item = array[1]; +let concatenated_array = array.concat(4, 5, 6, [7, 8, 9], `hello ${item}`); +let pick_array1 = [[1, 2, 3]][0].concat([4, 5, 6, unknown]); +let pick_array2 = [[1, 2, 3]][0].concat(4, 5, 6, unknown); +let arrays = [1, 2, 3]; +arrays = [4, 5, 6]; +let item_options = arrays[1]; +let concatenated_array_options = array.concat([7, 8, 9]); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/resolved-effects.snapshot new file mode 100644 index 0000000000000..f6279a6a0150e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/resolved-effects.snapshot @@ -0,0 +1,23 @@ +0 -> 3 member call = [1, 2, 3]["concat"](4, 5, 6, [7, 8, 9], `hello ${(2 | ???*0*)}`) +- *0* unknown mutation + ⚠️ This value might have side effects + +0 -> 6 free var = FreeVar(unknown) + +0 -> 7 member call = ([1, 2, 3] | ???*0*)["concat"]([4, 5, 6, ???*1*]) +- *0* unknown mutation + ⚠️ This value might have side effects +- *1* FreeVar(unknown) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 10 free var = FreeVar(unknown) + +0 -> 11 member call = ([1, 2, 3] | ???*0*)["concat"](4, 5, 6, ???*1*) +- *0* unknown mutation + ⚠️ This value might have side effects +- *1* FreeVar(unknown) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 14 member call = [1, 2, 3]["concat"]([7, 8, 9]) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/resolved-explained.snapshot new file mode 100644 index 0000000000000..19f7d92a7ad36 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-call/resolved-explained.snapshot @@ -0,0 +1,48 @@ +array = [1, 2, 3] + +arrays = ([1, 2, 3] | [4, 5, 6]) + +concatenated_array = [1, 2, 3, 4, 5, 6, 7, 8, 9, `hello ${(2 | ???*0*)}`] +- *0* unknown mutation + ⚠️ This value might have side effects + +concatenated_array_options = [1, 2, 3, 7, 8, 9] + +item = (2 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +item_options = (2 | ???*0* | 5) +- *0* unknown mutation + ⚠️ This value might have side effects + +pick_array1 = ([1, 2, 3, 4, 5, 6, ???*0*] | ???*1*) +- *0* FreeVar(unknown) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["concat"]([4, 5, 6, ???*3*]) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* FreeVar(unknown) + ⚠️ unknown global + ⚠️ This value might have side effects + +pick_array2 = (???*0* | ???*3*) +- *0* ???*1*(4, 5, 6, ???*2*) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* [1, 2, 3]["concat"] + ⚠️ non-num constant property on array +- *2* FreeVar(unknown) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* ???*4*["concat"](4, 5, 6, ???*5*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* FreeVar(unknown) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/graph-effects.snapshot new file mode 100644 index 0000000000000..ef118dd8e99ee --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/graph-effects.snapshot @@ -0,0 +1,67 @@ +[ + Member { + obj: FreeVar( + "A", + ), + prop: Constant( + Str( + Atom( + "B", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Member, + ), + ], + span: 1..4#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "A", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 1..2#1, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/graph-explained.snapshot new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/graph.snapshot new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/graph.snapshot @@ -0,0 +1 @@ +[] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/input.js new file mode 100644 index 0000000000000..41079d7b9d01b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/input.js @@ -0,0 +1 @@ +A.B; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/resolved-effects.snapshot new file mode 100644 index 0000000000000..62afbaa393eea --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/resolved-effects.snapshot @@ -0,0 +1 @@ +0 -> 2 free var = FreeVar(A) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/member-prop/resolved-explained.snapshot new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph-effects.snapshot new file mode 100644 index 0000000000000..a0927ce8afd81 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph-effects.snapshot @@ -0,0 +1,293 @@ +[ + Member { + obj: FreeVar( + "global", + ), + prop: Constant( + Str( + Atom( + "MONGOOSE_DRIVER_PATH", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + ], + span: 16..43#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 16..22#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 123..130#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Concat( + 3, + [ + Variable( + ( + "driver", + #2, + ), + ), + Constant( + Str( + Word( + "/connection", + ), + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 123..154#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 199..206#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Concat( + 3, + [ + Variable( + ( + "driver", + #2, + ), + ), + Constant( + Str( + Word( + "/collection", + ), + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 199..230#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph-explained.snapshot new file mode 100644 index 0000000000000..68fb3ada93fa9 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph-explained.snapshot @@ -0,0 +1,5 @@ +Collection = FreeVar(require)(`${driver}/collection`) + +Connection = FreeVar(require)(`${driver}/connection`) + +driver = (FreeVar(global)["MONGOOSE_DRIVER_PATH"] || "./drivers/node-mongodb-native") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph.snapshot new file mode 100644 index 0000000000000..90d147723176e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/graph.snapshot @@ -0,0 +1,89 @@ +[ + ( + "Collection", + Call( + 5, + FreeVar( + "require", + ), + [ + Concat( + 3, + [ + Variable( + ( + "driver", + #2, + ), + ), + Constant( + Str( + Word( + "/collection", + ), + ), + ), + ], + ), + ], + ), + ), + ( + "Connection", + Call( + 5, + FreeVar( + "require", + ), + [ + Concat( + 3, + [ + Variable( + ( + "driver", + #2, + ), + ), + Constant( + Str( + Word( + "/connection", + ), + ), + ), + ], + ), + ], + ), + ), + ( + "driver", + Logical( + 5, + Or, + [ + Member( + 3, + FreeVar( + "global", + ), + Constant( + Str( + Atom( + "MONGOOSE_DRIVER_PATH", + ), + ), + ), + ), + Constant( + Str( + Word( + "./drivers/node-mongodb-native", + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/input.js new file mode 100644 index 0000000000000..900c9f0739526 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/input.js @@ -0,0 +1,13 @@ +const driver = global.MONGOOSE_DRIVER_PATH || "./drivers/node-mongodb-native"; + +/*! + * Connection + */ + +const Connection = require(driver + "/connection"); + +/*! + * Collection + */ + +const Collection = require(driver + "/collection"); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/resolved-effects.snapshot new file mode 100644 index 0000000000000..90c86a64ba3fc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/resolved-effects.snapshot @@ -0,0 +1,27 @@ +0 -> 2 free var = FreeVar(global) + +0 -> 3 free var = FreeVar(require) + +0 -> 4 call = require*0*( + `${(???*1* | "./drivers/node-mongodb-native")}/connection` +) +- *0* require: The require method from CommonJS +- *1* ???*2*["MONGOOSE_DRIVER_PATH"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 5 free var = FreeVar(require) + +0 -> 6 call = require*0*( + `${(???*1* | "./drivers/node-mongodb-native")}/collection` +) +- *0* require: The require method from CommonJS +- *1* ???*2*["MONGOOSE_DRIVER_PATH"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/resolved-explained.snapshot new file mode 100644 index 0000000000000..b3850d090653b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/mongoose-reduced/resolved-explained.snapshot @@ -0,0 +1,35 @@ +Collection = ???*0* +- *0* require*1*( + `${(???*2* | "./drivers/node-mongodb-native")}/collection` + ) + ⚠️ only constant argument is supported + ⚠️ This value might have side effects +- *1* require: The require method from CommonJS +- *2* ???*3*["MONGOOSE_DRIVER_PATH"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +Connection = ???*0* +- *0* require*1*( + `${(???*2* | "./drivers/node-mongodb-native")}/connection` + ) + ⚠️ only constant argument is supported + ⚠️ This value might have side effects +- *1* require: The require method from CommonJS +- *2* ???*3*["MONGOOSE_DRIVER_PATH"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +driver = (???*0* | "./drivers/node-mongodb-native") +- *0* ???*1*["MONGOOSE_DRIVER_PATH"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph-effects.snapshot new file mode 100644 index 0000000000000..c4ed549499ebd --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph-effects.snapshot @@ -0,0 +1,488 @@ +[ + Call { + func: Variable( + ( + "x", + #2, + ), + ), + args: [ + Value( + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Call, + ), + ], + span: 77..81#0, + in_try: false, + }, + Call { + func: Call( + 3, + Variable( + ( + "x", + #2, + ), + ), + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + args: [ + Value( + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 77..84#0, + in_try: false, + }, + Conditional { + condition: Binary( + 3, + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + StrictEqual, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + kind: IfElse { + then: EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [ + Call { + func: Variable( + ( + "r", + #2, + ), + ), + args: [ + Value( + Add( + 3, + [ + Variable( + ( + "a", + #6, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + ], + span: 159..167#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + ], + span: 105..176#0, + in_try: false, + }, + Call { + func: Variable( + ( + "r", + #2, + ), + ), + args: [ + Value( + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 190..194#0, + in_try: false, + }, + Call { + func: Variable( + ( + "inner", + #9, + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "b", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 271..281#0, + in_try: false, + }, + Call { + func: Variable( + ( + "outer", + #2, + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "a", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 295..305#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph-explained.snapshot new file mode 100644 index 0000000000000..4b8e577ee38ec --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph-explained.snapshot @@ -0,0 +1,25 @@ +a#3 = arguments[0] + +a#6 = arguments[0] + +a#9 = arguments[0] + +b#10 = arguments[0] + +b#5 = arguments[0] + +inner = (...) => (a + b) + +outer = (...) => inner("b") + +r = (...) => (undefined | a | (r((a + 1)) + 1)) + +v1 = x(1)(2) + +v2 = r(2) + +v3 = outer("a") + +x = (...) => y + +y = (...) => (a + b) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph.snapshot new file mode 100644 index 0000000000000..635a40a118bdc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/graph.snapshot @@ -0,0 +1,260 @@ +[ + ( + "a#3", + Argument( + 1, + 0, + ), + ), + ( + "a#6", + Argument( + 87, + 0, + ), + ), + ( + "a#9", + Argument( + 197, + 0, + ), + ), + ( + "b#10", + Argument( + 219, + 0, + ), + ), + ( + "b#5", + Argument( + 26, + 0, + ), + ), + ( + "inner", + Function( + 4, + 219, + Add( + 3, + [ + Variable( + ( + "a", + #9, + ), + ), + Variable( + ( + "b", + #10, + ), + ), + ], + ), + ), + ), + ( + "outer", + Function( + 4, + 197, + Call( + 3, + Variable( + ( + "inner", + #9, + ), + ), + [ + Constant( + Str( + Word( + "b", + ), + ), + ), + ], + ), + ), + ), + ( + "r", + Function( + 11, + 87, + Alternatives( + 10, + [ + Constant( + Undefined, + ), + Variable( + ( + "a", + #6, + ), + ), + Add( + 7, + [ + Call( + 5, + Variable( + ( + "r", + #2, + ), + ), + [ + Add( + 3, + [ + Variable( + ( + "a", + #6, + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ], + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + ], + ), + ), + ), + ( + "v1", + Call( + 5, + Call( + 3, + Variable( + ( + "x", + #2, + ), + ), + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ], + ), + [ + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + ( + "v2", + Call( + 3, + Variable( + ( + "r", + #2, + ), + ), + [ + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ], + ), + ), + ( + "v3", + Call( + 3, + Variable( + ( + "outer", + #2, + ), + ), + [ + Constant( + Str( + Word( + "a", + ), + ), + ), + ], + ), + ), + ( + "x", + Function( + 2, + 1, + Variable( + ( + "y", + #4, + ), + ), + ), + ), + ( + "y", + Function( + 4, + 26, + Add( + 3, + [ + Variable( + ( + "a", + #3, + ), + ), + Variable( + ( + "b", + #5, + ), + ), + ], + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/input.js new file mode 100644 index 0000000000000..1d8cf975027c2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/input.js @@ -0,0 +1,24 @@ +function x(a) { + return function y(b) { + return a + b; + } +} +const v1 = x(1)(2); + +function r(a) { + if(a % 2 === 0) { + return a; + } else { + return r(a + 1) + 1; + } +} +const v2 = r(2); + +function outer(a) { + function inner(b) { + return a + b; + } + + return inner("b") +} +const v3 = outer("a"); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/resolved-effects.snapshot new file mode 100644 index 0000000000000..130958ca5ae1f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/resolved-effects.snapshot @@ -0,0 +1,17 @@ +0 -> 1 call = (...) => y(1) + +0 -> 2 call = (...) => (a + b)(2) + +0 -> 3 conditional = (???*0* === 0) +- *0* unsupported expression + ⚠️ This value might have side effects + +3 -> 4 call = (...) => (undefined | a | (r((a + 1)) + 1))((???*0* + 1)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5 call = (...) => (undefined | a | (r((a + 1)) + 1))(2) + +0 -> 6 call = (...) => (a + b)("b") + +0 -> 7 call = (...) => inner("b")("a") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/resolved-explained.snapshot new file mode 100644 index 0000000000000..f9b00360809eb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested-args/resolved-explained.snapshot @@ -0,0 +1,40 @@ +a#3 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#6 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#9 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#10 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#5 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +inner = (...) => (a + b) + +outer = (...) => inner("b") + +r = (...) => (undefined | a | (r((a + 1)) + 1)) + +v1 = (???*0* + 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +v2 = (undefined | 2 | (???*0* + 1)) +- *0* (...) => (undefined | a | (r((a + 1)) + 1))((2 + 1)) + ⚠️ recursive function call + ⚠️ This value might have side effects + +v3 = `ab` + +x = (...) => y + +y = (...) => (a + b) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph-effects.snapshot new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph-effects.snapshot @@ -0,0 +1 @@ +[] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph-explained.snapshot new file mode 100644 index 0000000000000..fd238a1511f39 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph-explained.snapshot @@ -0,0 +1,53 @@ +*anonymous function 66* = (...) => undefined + +*arrow function 118* = (...) => undefined + +*arrow function 229* = (...) => undefined + +a = (...) => undefined + +b = *anonymous function 66* + +c = *arrow function 118* + +d = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +e = (...) => undefined + +f = e + +x#3 = 1 + +x#4 = 1 + +x#5 = 1 + +x#6 = 1 + +x#7 = 1 + +x#9 = 1 + +y#3 = x + +y#4 = x + +y#5 = x + +y#6 = x + +y#7 = x + +y#9 = x + +z#3 = a + +z#6 = d + +z#7 = d + +z#9 = e + +z2 = f diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph.snapshot new file mode 100644 index 0000000000000..b8e0c65871230 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/graph.snapshot @@ -0,0 +1,246 @@ +[ + ( + "*anonymous function 66*", + Function( + 2, + 66, + Constant( + Undefined, + ), + ), + ), + ( + "*arrow function 118*", + Function( + 2, + 118, + Constant( + Undefined, + ), + ), + ), + ( + "*arrow function 229*", + Function( + 2, + 229, + Constant( + Undefined, + ), + ), + ), + ( + "a", + Function( + 2, + 1, + Constant( + Undefined, + ), + ), + ), + ( + "b", + Variable( + ( + "*anonymous function 66*", + #0, + ), + ), + ), + ( + "c", + Variable( + ( + "*arrow function 118*", + #0, + ), + ), + ), + ( + "d", + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ( + "e", + Function( + 2, + 298, + Constant( + Undefined, + ), + ), + ), + ( + "f", + Variable( + ( + "e", + #8, + ), + ), + ), + ( + "x#3", + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ( + "x#4", + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ( + "x#5", + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ( + "x#6", + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ( + "x#7", + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ( + "x#9", + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ( + "y#3", + Variable( + ( + "x", + #3, + ), + ), + ), + ( + "y#4", + Variable( + ( + "x", + #4, + ), + ), + ), + ( + "y#5", + Variable( + ( + "x", + #5, + ), + ), + ), + ( + "y#6", + Variable( + ( + "x", + #6, + ), + ), + ), + ( + "y#7", + Variable( + ( + "x", + #7, + ), + ), + ), + ( + "y#9", + Variable( + ( + "x", + #9, + ), + ), + ), + ( + "z#3", + Variable( + ( + "a", + #2, + ), + ), + ), + ( + "z#6", + Variable( + ( + "d", + #2, + ), + ), + ), + ( + "z#7", + Variable( + ( + "d", + #2, + ), + ), + ), + ( + "z#9", + Variable( + ( + "e", + #8, + ), + ), + ), + ( + "z2", + Variable( + ( + "f", + #2, + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/input.js new file mode 100644 index 0000000000000..d737c7dff9680 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/input.js @@ -0,0 +1,35 @@ +function a() { + let x = 1; + let y = x; + let z = a; +} + +let b = function () { + let x = 1; + let y = x; +}; + +let c = () => { + let x = 1; + let y = x; +}; + +class d { + m() { + let x = 1; + let y = x; + let z = d; + } + n = () => { + let x = 1; + let y = x; + let z = d; + }; +} + +var f = function e() { + let x = 1; + let y = x; + let z = e; + let z2 = f; +}; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/resolved-explained.snapshot new file mode 100644 index 0000000000000..fc96e60169a63 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/nested/resolved-explained.snapshot @@ -0,0 +1,57 @@ +*anonymous function 66* = (...) => undefined + +*arrow function 118* = (...) => undefined + +*arrow function 229* = (...) => undefined + +a = (...) => undefined + +b = (...) => undefined + +c = (...) => undefined + +d = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +e = (...) => undefined + +f = (...) => undefined + +x#3 = 1 + +x#4 = 1 + +x#5 = 1 + +x#6 = 1 + +x#7 = 1 + +x#9 = 1 + +y#3 = 1 + +y#4 = 1 + +y#5 = 1 + +y#6 = 1 + +y#7 = 1 + +y#9 = 1 + +z#3 = (...) => undefined + +z#6 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +z#7 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +z#9 = (...) => undefined + +z2 = (...) => undefined diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph-effects.snapshot new file mode 100644 index 0000000000000..fa92b29c492dc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph-effects.snapshot @@ -0,0 +1,1044 @@ +[ + Member { + obj: Variable( + ( + "object", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "a", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 75..83#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object", + #2, + ), + ), + prop: Constant( + Str( + Word( + "a", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 96..107#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "b", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 120..128#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object", + #2, + ), + ), + prop: Constant( + Str( + Word( + "b", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 141..152#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "c", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 165..173#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object", + #2, + ), + ), + prop: Constant( + Str( + Word( + "c", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 186..197#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "d", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 210..218#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object", + #2, + ), + ), + prop: Constant( + Str( + Word( + "d", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 231..242#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object_spread", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "a", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 10, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 308..323#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object_spread", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "b", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 11, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 336..351#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object_spread", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "c", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 12, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 364..379#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object_spread", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "d", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 13, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 392..407#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 16, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 1, + ), + ), + PropOrSpread( + Spread, + ), + SpreadElement( + Expr, + ), + Expr( + Ident, + ), + ], + span: 548..554#1, + in_try: false, + }, + Member { + obj: Variable( + ( + "unknown_spread", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "a", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 17, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 576..592#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "unknown_spread", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "b", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 18, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 605..621#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "unknown_spread", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "c", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 19, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 634..650#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 20, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 1, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Key, + ), + PropName( + Computed, + ), + ComputedPropName( + Expr, + ), + Expr( + Ident, + ), + ], + span: 678..684#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 20, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 3, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Key, + ), + PropName( + Computed, + ), + ComputedPropName( + Expr, + ), + Expr( + Ident, + ), + ], + span: 697..703#1, + in_try: false, + }, + Member { + obj: Variable( + ( + "object2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "a", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 21, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 728..737#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "b", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 22, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 750..759#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "c", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 23, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 772..781#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "d", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 24, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 794..803#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "object2", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "e", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 25, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Member, + ), + ], + span: 816..825#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph-explained.snapshot new file mode 100644 index 0000000000000..700cd66dab33f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph-explained.snapshot @@ -0,0 +1,63 @@ +a = object["a"] + +a1 = object["a"] + +a2 = object["a"] + +a3 = object_spread["a"] + +a4 = object["a"] + +a5 = unknown_spread["a"] + +a6 = object2["a"] + +b = object["b"] + +b1 = object["b"] + +b2 = object["b"] + +b3 = object_spread["b"] + +b4 = object["b"] + +b5 = unknown_spread["b"] + +b6 = object2["b"] + +c = object["c"] + +c1 = object["c"] + +c2 = object["c"] + +c3 = object_spread["c"] + +c4 = object["c"] + +c5 = unknown_spread["c"] + +c6 = object2["c"] + +d = object["d"] + +d1 = object["d"] + +d2 = object["d"] + +d3 = object_spread["d"] + +d4 = object["d"] + +d6 = object2["d"] + +e6 = object2["e"] + +object = {"a": 1, "b": 2, "c": 3} + +object2 = {"a": 1, FreeVar(global): 2, "c": 3, FreeVar(global): 4, "e": 5} + +object_spread = {"a": 11, ...object, "b": 22} + +unknown_spread = {"a": 1, ...FreeVar(global), "b": 2} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph.snapshot new file mode 100644 index 0000000000000..959ad94971ae1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/graph.snapshot @@ -0,0 +1,767 @@ +[ + ( + "a", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "a", + ), + ), + ), + ), + ), + ( + "a1", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "a", + ), + ), + ), + ), + ), + ( + "a2", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Word( + "a", + ), + ), + ), + ), + ), + ( + "a3", + Member( + 3, + Variable( + ( + "object_spread", + #2, + ), + ), + Constant( + Str( + Atom( + "a", + ), + ), + ), + ), + ), + ( + "a4", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "a", + ), + ), + ), + ), + ), + ( + "a5", + Member( + 3, + Variable( + ( + "unknown_spread", + #2, + ), + ), + Constant( + Str( + Atom( + "a", + ), + ), + ), + ), + ), + ( + "a6", + Member( + 3, + Variable( + ( + "object2", + #2, + ), + ), + Constant( + Str( + Atom( + "a", + ), + ), + ), + ), + ), + ( + "b", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "b", + ), + ), + ), + ), + ), + ( + "b1", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "b", + ), + ), + ), + ), + ), + ( + "b2", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Word( + "b", + ), + ), + ), + ), + ), + ( + "b3", + Member( + 3, + Variable( + ( + "object_spread", + #2, + ), + ), + Constant( + Str( + Atom( + "b", + ), + ), + ), + ), + ), + ( + "b4", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "b", + ), + ), + ), + ), + ), + ( + "b5", + Member( + 3, + Variable( + ( + "unknown_spread", + #2, + ), + ), + Constant( + Str( + Atom( + "b", + ), + ), + ), + ), + ), + ( + "b6", + Member( + 3, + Variable( + ( + "object2", + #2, + ), + ), + Constant( + Str( + Atom( + "b", + ), + ), + ), + ), + ), + ( + "c", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "c", + ), + ), + ), + ), + ), + ( + "c1", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "c", + ), + ), + ), + ), + ), + ( + "c2", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Word( + "c", + ), + ), + ), + ), + ), + ( + "c3", + Member( + 3, + Variable( + ( + "object_spread", + #2, + ), + ), + Constant( + Str( + Atom( + "c", + ), + ), + ), + ), + ), + ( + "c4", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Word( + "c", + ), + ), + ), + ), + ), + ( + "c5", + Member( + 3, + Variable( + ( + "unknown_spread", + #2, + ), + ), + Constant( + Str( + Atom( + "c", + ), + ), + ), + ), + ), + ( + "c6", + Member( + 3, + Variable( + ( + "object2", + #2, + ), + ), + Constant( + Str( + Atom( + "c", + ), + ), + ), + ), + ), + ( + "d", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "d", + ), + ), + ), + ), + ), + ( + "d1", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "d", + ), + ), + ), + ), + ), + ( + "d2", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Word( + "d", + ), + ), + ), + ), + ), + ( + "d3", + Member( + 3, + Variable( + ( + "object_spread", + #2, + ), + ), + Constant( + Str( + Atom( + "d", + ), + ), + ), + ), + ), + ( + "d4", + Member( + 3, + Variable( + ( + "object", + #2, + ), + ), + Constant( + Str( + Atom( + "d", + ), + ), + ), + ), + ), + ( + "d6", + Member( + 3, + Variable( + ( + "object2", + #2, + ), + ), + Constant( + Str( + Atom( + "d", + ), + ), + ), + ), + ), + ( + "e6", + Member( + 3, + Variable( + ( + "object2", + #2, + ), + ), + Constant( + Str( + Atom( + "e", + ), + ), + ), + ), + ), + ( + "object", + Object { + total_nodes: 7, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "a", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "b", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Word( + "c", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "object2", + Object { + total_nodes: 11, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "a", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + KeyValue( + FreeVar( + "global", + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "c", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ), + KeyValue( + FreeVar( + "global", + ), + Constant( + Num( + ConstantNumber( + 4.0, + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "e", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 5.0, + ), + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "object_spread", + Object { + total_nodes: 6, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "a", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 11.0, + ), + ), + ), + ), + Spread( + Variable( + ( + "object", + #2, + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "b", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 22.0, + ), + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "unknown_spread", + Object { + total_nodes: 6, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "a", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + Spread( + FreeVar( + "global", + ), + ), + KeyValue( + Constant( + Str( + Atom( + "b", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ], + mutable: true, + }, + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/input.js new file mode 100644 index 0000000000000..c9f26fc1fbbed --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/input.js @@ -0,0 +1,35 @@ +// prettier-ignore +const object = { a: 1, 'b': 2, ['c']: 3 }; + +const a1 = object.a; +const a2 = object["a"]; +const b1 = object.b; +const b2 = object["b"]; +const c1 = object.c; +const c2 = object["c"]; +const d1 = object.d; +const d2 = object["d"]; + +const object_spread = { a: 11, ...object, b: 22 }; + +const a3 = object_spread.a; +const b3 = object_spread.b; +const c3 = object_spread.c; +const d3 = object_spread.d; + +// prettier-ignore +const { a: a4, 'b': b4, ['c']: c4, d: d4 } = object; +const { a, b, c, d } = object; + +const unknown_spread = { a: 1, ...global, b: 2 }; + +const a5 = unknown_spread.a; +const b5 = unknown_spread.b; +const c5 = unknown_spread.c; + +const object2 = { a: 1, [global]: 2, c: 3, [global]: 4, e: 5 }; +const a6 = object2.a; +const b6 = object2.b; +const c6 = object2.c; +const d6 = object2.d; +const e6 = object2.e; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/resolved-effects.snapshot new file mode 100644 index 0000000000000..3ff470ad60d4f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/resolved-effects.snapshot @@ -0,0 +1,5 @@ +0 -> 13 free var = FreeVar(global) + +0 -> 17 free var = FreeVar(global) + +0 -> 18 free var = FreeVar(global) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/resolved-explained.snapshot new file mode 100644 index 0000000000000..eb4e659a62777 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/object/resolved-explained.snapshot @@ -0,0 +1,157 @@ +a = (1 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +a1 = (1 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +a2 = (1 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +a3 = (1 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +a4 = (1 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +a5 = ???*0* +- *0* {"a": 1, ...???*1*, "b": 2}["a"] + ⚠️ spread object + ⚠️ This value might have side effects +- *1* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +a6 = (1 | 2 | 4 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b = (2 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b1 = (2 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b2 = (2 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b3 = (22 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b4 = (2 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b5 = (2 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b6 = (2 | 4 | ???*0* | ???*1*) +- *0* {}["b"] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects + +c = (3 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +c1 = (3 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +c2 = (3 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +c3 = (3 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +c4 = (3 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +c5 = ???*0* +- *0* {"a": 1, ...???*1*, "b": 2}["c"] + ⚠️ spread object + ⚠️ This value might have side effects +- *1* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +c6 = (3 | 4 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +d = (???*0* | ???*1*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects + +d1 = (???*0* | ???*1*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects + +d2 = (???*0* | ???*1*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects + +d3 = (???*0* | ???*1*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects + +d4 = (???*0* | ???*1*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects + +d6 = (2 | 4 | ???*0* | ???*1*) +- *0* {}["d"] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects + +e6 = (5 | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +object = {"a": 1, "b": 2, "c": 3} + +object2 = {"a": 1, ???*0*: 2, "c": 3, ???*1*: 4, "e": 5} +- *0* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects + +object_spread = {"a": 11, "a": 1, "b": 2, "c": 3, "b": 22} + +unknown_spread = {"a": 1, ...???*0*, "b": 2} +- *0* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph-effects.snapshot new file mode 100644 index 0000000000000..11d6bb8686f76 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph-effects.snapshot @@ -0,0 +1,1368 @@ +[ + Member { + obj: FreeVar( + "performance", + ), + prop: Constant( + Str( + Atom( + "now", + ), + ), + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 212..227#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "performance", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 212..223#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "performance", + ), + prop: Constant( + Str( + Atom( + "now", + ), + ), + ), + args: [], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 212..229#0, + in_try: false, + }, + Member { + obj: Member( + 3, + Variable( + ( + "ComponentMod", + #3, + ), + ), + Constant( + Str( + Atom( + "__next_app__", + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "loadChunk", + ), + ), + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 257..292#0, + in_try: true, + }, + Member { + obj: Variable( + ( + "ComponentMod", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "__next_app__", + ), + ), + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Member, + ), + ], + span: 257..282#0, + in_try: true, + }, + MemberCall { + obj: Member( + 3, + Variable( + ( + "ComponentMod", + #3, + ), + ), + Constant( + Str( + Atom( + "__next_app__", + ), + ), + ), + ), + prop: Constant( + Str( + Atom( + "loadChunk", + ), + ), + ), + args: [ + Spread, + ], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 257..301#0, + in_try: true, + }, + Member { + obj: FreeVar( + "performance", + ), + prop: Constant( + Str( + Atom( + "now", + ), + ), + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Finalizer, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 356..371#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "performance", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Finalizer, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 356..367#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "performance", + ), + prop: Constant( + Str( + Atom( + "now", + ), + ), + ), + args: [], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 1, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Finalizer, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + ], + span: 356..373#0, + in_try: false, + }, + Conditional { + condition: Binary( + 3, + Variable( + ( + "clientComponentLoadTimes", + #2, + ), + ), + StrictEqual, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + kind: Ternary { + then: EffectsBlock { + effects: [ + FreeVar { + var: FreeVar( + "undefined", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + Expr( + Ident, + ), + ], + span: 535..544#1, + in_try: false, + }, + ], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + ], + span: 496..600#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "options", + #7, + ), + ), + prop: Constant( + Str( + Atom( + "reset", + ), + ), + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + ModuleDecl, + ), + ModuleDecl( + ExportDecl, + ), + ExportDecl( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Member, + ), + ], + span: 608..621#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph-explained.snapshot new file mode 100644 index 0000000000000..e5b4d24788113 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph-explained.snapshot @@ -0,0 +1,27 @@ +*arrow function 173* = (...) => (undefined | ???*0*) +- *0* spread in function calls is not supported + ⚠️ This value might have side effects + +ComponentMod = arguments[0] + +args = ???*0* +- *0* args + ⚠️ pattern without value + +clientComponentLoadTimes = (0 | (clientComponentLoadTimes + ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +getClientComponentLoaderMetrics = (...) => metrics + +metrics = ((clientComponentLoadTimes === 0) ? FreeVar(undefined) : { + "clientComponentLoadTimes": clientComponentLoadTimes +}) + +options = ???*0* +- *0* options + ⚠️ pattern without value + +startTime = FreeVar(performance)["now"]() + +wrapClientComponentLoader = (...) => {"loadChunk": *arrow function 173*} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph.snapshot new file mode 100644 index 0000000000000..d8e11a41df38f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/graph.snapshot @@ -0,0 +1,195 @@ +[ + ( + "*arrow function 173*", + Function( + 4, + 173, + Alternatives( + 3, + [ + Constant( + Undefined, + ), + Unknown { + original_value: None, + reason: "spread in function calls is not supported", + has_side_effects: true, + }, + ], + ), + ), + ), + ( + "ComponentMod", + Argument( + 95, + 0, + ), + ), + ( + "args", + Unknown { + original_value: Some( + Variable( + ( + "args", + #4, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + ), + ( + "clientComponentLoadTimes", + Alternatives( + 5, + [ + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + Add( + 3, + [ + Variable( + ( + "clientComponentLoadTimes", + #2, + ), + ), + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + ], + ), + ), + ( + "getClientComponentLoaderMetrics", + Function( + 2, + 415, + Variable( + ( + "metrics", + #7, + ), + ), + ), + ), + ( + "metrics", + Tenary( + 8, + Binary( + 3, + Variable( + ( + "clientComponentLoadTimes", + #2, + ), + ), + StrictEqual, + Constant( + Num( + ConstantNumber( + 0.0, + ), + ), + ), + ), + FreeVar( + "undefined", + ), + Object { + total_nodes: 3, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "clientComponentLoadTimes", + ), + ), + ), + Variable( + ( + "clientComponentLoadTimes", + #2, + ), + ), + ), + ], + mutable: true, + }, + ), + ), + ( + "options", + Unknown { + original_value: Some( + Variable( + ( + "options", + #7, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + ), + ( + "startTime", + MemberCall( + 3, + FreeVar( + "performance", + ), + Constant( + Str( + Atom( + "now", + ), + ), + ), + [], + ), + ), + ( + "wrapClientComponentLoader", + Function( + 4, + 95, + Object { + total_nodes: 3, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "loadChunk", + ), + ), + ), + Variable( + ( + "*arrow function 173*", + #0, + ), + ), + ), + ], + mutable: true, + }, + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/input.js new file mode 100644 index 0000000000000..8f17ce62114fd --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/input.js @@ -0,0 +1,33 @@ +// Combined load times for loading client components +let clientComponentLoadTimes = 0 + +export function wrapClientComponentLoader(ComponentMod) { + return { + + loadChunk: (...args) => { + const startTime = performance.now() + try { + return ComponentMod.__next_app__.loadChunk(...args) + } finally { + clientComponentLoadTimes += performance.now() - startTime + } + }, + } +} + +export function getClientComponentLoaderMetrics( + options = {} +) { + const metrics = + clientComponentLoadTimes === 0 + ? undefined + : { + clientComponentLoadTimes, + } + + if (options.reset) { + clientComponentLoadTimes = 0 + } + + return metrics +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/resolved-effects.snapshot new file mode 100644 index 0000000000000..9f17676ad99df --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/resolved-effects.snapshot @@ -0,0 +1,31 @@ +0 -> 2 free var = FreeVar(performance) + +0 -> 3 member call = ???*0*["now"]() +- *0* FreeVar(performance) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 6 member call = ???*0*["loadChunk"](???*2*) +- *0* ???*1*["__next_app__"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* spread + ⚠️ This value might have side effects + +0 -> 8 free var = FreeVar(performance) + +0 -> 9 member call = ???*0*["now"]() +- *0* FreeVar(performance) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 10 conditional = ((0 | ???*0*) === 0) +- *0* (???*1* + ???*2*) + ⚠️ nested operation +- *1* clientComponentLoadTimes + ⚠️ circular variable reference +- *2* unsupported expression + ⚠️ This value might have side effects + +10 -> 11 free var = FreeVar(undefined) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/resolved-explained.snapshot new file mode 100644 index 0000000000000..dce12a7b461e0 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/op-assign/resolved-explained.snapshot @@ -0,0 +1,56 @@ +*arrow function 173* = (...) => (undefined | ???*0*) +- *0* spread in function calls is not supported + ⚠️ This value might have side effects + +ComponentMod = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +args = ???*0* +- *0* args + ⚠️ pattern without value + +clientComponentLoadTimes = (0 | ((0 | ???*0*) + ???*3*)) +- *0* (???*1* + ???*2*) + ⚠️ nested operation +- *1* clientComponentLoadTimes + ⚠️ circular variable reference +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +getClientComponentLoaderMetrics = (...) => metrics + +metrics = (???*0* ? ???*4* : {"clientComponentLoadTimes": (0 | ???*5*)}) +- *0* ((0 | ???*1*) === 0) + ⚠️ nested operation +- *1* (???*2* + ???*3*) + ⚠️ nested operation +- *2* clientComponentLoadTimes + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* (???*6* + ???*7*) + ⚠️ nested operation +- *6* clientComponentLoadTimes + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects + +options = ???*0* +- *0* options + ⚠️ pattern without value + +startTime = ???*0*() +- *0* ???*1*["now"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(performance) + ⚠️ unknown global + ⚠️ This value might have side effects + +wrapClientComponentLoader = (...) => {"loadChunk": *arrow function 173*} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph-effects.snapshot new file mode 100644 index 0000000000000..ce033c2cd1532 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph-effects.snapshot @@ -0,0 +1,335 @@ +[ + FreeVar { + var: FreeVar( + "Object", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Ident, + ), + ], + span: 11..17#1, + in_try: false, + }, + Member { + obj: FreeVar( + "Object", + ), + prop: Constant( + Str( + Atom( + "keys", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 30..41#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "Object", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 30..36#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "Object", + ), + prop: Constant( + Str( + Atom( + "keys", + ), + ), + ), + args: [ + Value( + Variable( + ( + "O", + #2, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 30..44#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "O", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "keys", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 56..62#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "Object", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Ident, + ), + ], + span: 63..69#1, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "O", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "keys", + ), + ), + ), + args: [ + Value( + FreeVar( + "Object", + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 56..70#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph-explained.snapshot new file mode 100644 index 0000000000000..c6c71bf9e32af --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph-explained.snapshot @@ -0,0 +1,5 @@ +O = FreeVar(Object) + +a = FreeVar(Object)["keys"](O) + +b = O["keys"](FreeVar(Object)) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph.snapshot new file mode 100644 index 0000000000000..5d27860403f47 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/graph.snapshot @@ -0,0 +1,56 @@ +[ + ( + "O", + FreeVar( + "Object", + ), + ), + ( + "a", + MemberCall( + 4, + FreeVar( + "Object", + ), + Constant( + Str( + Atom( + "keys", + ), + ), + ), + [ + Variable( + ( + "O", + #2, + ), + ), + ], + ), + ), + ( + "b", + MemberCall( + 4, + Variable( + ( + "O", + #2, + ), + ), + Constant( + Str( + Atom( + "keys", + ), + ), + ), + [ + FreeVar( + "Object", + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/input.js new file mode 100644 index 0000000000000..8e00ea1f10c2a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/input.js @@ -0,0 +1,4 @@ +const O = Object; + +const a = Object.keys(O); +const b = O.keys(Object); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/resolved-effects.snapshot new file mode 100644 index 0000000000000..af635daa39306 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/resolved-effects.snapshot @@ -0,0 +1,21 @@ +0 -> 1 free var = FreeVar(Object) + +0 -> 3 free var = FreeVar(Object) + +0 -> 4 member call = ???*0*["keys"](???*1*) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 6 free var = FreeVar(Object) + +0 -> 7 member call = ???*0*["keys"](???*1*) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/resolved-explained.snapshot new file mode 100644 index 0000000000000..edf361db166e7 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/other-free-vars/resolved-explained.snapshot @@ -0,0 +1,20 @@ +O = ???*0* +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +a = ???*0* +- *0* ???*1*["keys"](O) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +b = ???*0* +- *0* ???*1*["keys"](FreeVar(Object)) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph-effects.snapshot new file mode 100644 index 0000000000000..6470003e71890 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph-effects.snapshot @@ -0,0 +1,337 @@ +[ + FreeVar { + var: FreeVar( + "EdgeRuntime", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Unary, + ), + UnaryExpr( + Arg, + ), + Expr( + Ident, + ), + ], + span: 102..113#1, + in_try: false, + }, + Conditional { + condition: Binary( + 4, + TypeOf( + 2, + FreeVar( + "EdgeRuntime", + ), + ), + StrictEqual, + Constant( + Str( + Word( + "undefined", + ), + ), + ), + ), + kind: Ternary { + then: EffectsBlock { + effects: [ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 132..139#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "ioredis", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + Expr( + Call, + ), + ], + span: 132..150#0, + in_try: false, + }, + ], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [ + ImportedBinding { + esm_reference_index: 2, + export: Some( + "Redis", + ), + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + Expr( + Ident, + ), + ], + span: 153..165#2, + in_try: false, + }, + ], + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Module, + ), + Module( + Body( + 2, + ), + ), + ModuleItem( + Stmt, + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + ], + span: 95..165#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph-explained.snapshot new file mode 100644 index 0000000000000..c3f1f66c0b69c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph-explained.snapshot @@ -0,0 +1 @@ +Redis = ((typeof(FreeVar(EdgeRuntime)) === "undefined") ? FreeVar(require)("ioredis") : module<@upstash/redis, {}>["Redis"]) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph.snapshot new file mode 100644 index 0000000000000..76ea157bf743c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/graph.snapshot @@ -0,0 +1,58 @@ +[ + ( + "Redis", + Tenary( + 11, + Binary( + 4, + TypeOf( + 2, + FreeVar( + "EdgeRuntime", + ), + ), + StrictEqual, + Constant( + Str( + Word( + "undefined", + ), + ), + ), + ), + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "ioredis", + ), + ), + ), + ], + ), + Member( + 3, + Module( + ModuleValue { + module: "@upstash/redis", + annotations: ImportAnnotations { + map: {}, + }, + }, + ), + Constant( + Str( + Atom( + "Redis", + ), + ), + ), + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/input.js new file mode 100644 index 0000000000000..0c309d74de580 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/input.js @@ -0,0 +1,6 @@ +import 'server-only' + +import { Redis as UpstashRedis } from '@upstash/redis' + +const Redis = + typeof EdgeRuntime === 'undefined' ? require('ioredis') : UpstashRedis diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/resolved-effects.snapshot new file mode 100644 index 0000000000000..fa64c6cb60276 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/resolved-effects.snapshot @@ -0,0 +1,13 @@ +0 -> 1 free var = FreeVar(EdgeRuntime) + +0 -> 2 conditional = (???*0* === "undefined") +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(EdgeRuntime) + ⚠️ unknown global + ⚠️ This value might have side effects + +2 -> 3 free var = FreeVar(require) + +2 -> 4 call = require*0*("ioredis") +- *0* require: The require method from CommonJS diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/resolved-explained.snapshot new file mode 100644 index 0000000000000..446c7c1dc2820 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2236/resolved-explained.snapshot @@ -0,0 +1,8 @@ +Redis = (???*0* ? module : module<@upstash/redis, {}>["Redis"]) +- *0* (???*1* === "undefined") + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(EdgeRuntime) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph-effects.snapshot new file mode 100644 index 0000000000000..2ca98813b4d51 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph-effects.snapshot @@ -0,0 +1,543 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 33..40#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "./libvips", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 33..53#0, + in_try: false, + }, + Call { + func: Variable( + ( + "runtimePlatformArch", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 79..100#0, + in_try: false, + }, + Member { + obj: FreeVar( + "console", + ), + prop: Constant( + Str( + Atom( + "log", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 102..113#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "console", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 102..109#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "console", + ), + prop: Constant( + Str( + Atom( + "log", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "runtimePlatform:", + ), + ), + ), + ), + Value( + Variable( + ( + "runtimePlatform", + #2, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 102..150#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + ForOf, + ), + ForOfStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 429..436#1, + in_try: true, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Variable( + ( + "path", + #3, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + ForOf, + ), + ForOfStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 429..442#0, + in_try: true, + }, + Member { + obj: Variable( + ( + "errors", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "push", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + ForOf, + ), + ForOfStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 508..519#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "errors", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "push", + ), + ), + ), + args: [ + Value( + Variable( + ( + "err", + #6, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + ForOf, + ), + ForOfStmt( + Body, + ), + Stmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 508..524#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph-explained.snapshot new file mode 100644 index 0000000000000..b7ca82b9398ad --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph-explained.snapshot @@ -0,0 +1,22 @@ +err = ???*0* +- *0* err + ⚠️ pattern without value + +errors = [] + +path = Iterated(paths) + +paths = [ + `../src/build/Release/sharp-${runtimePlatform}.node`, + "../src/build/Release/sharp-wasm32.node", + `@img/sharp-${runtimePlatform}/sharp.node`, + "@img/sharp-wasm32/sharp.node" +] + +runtimePlatform = runtimePlatformArch() + +runtimePlatformArch = FreeVar(require)("./libvips")["runtimePlatformArch"] + +sharp = (???*0* | FreeVar(require)(path)) +- *0* sharp + ⚠️ pattern without value diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph.snapshot new file mode 100644 index 0000000000000..b28eb48f3bae1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/graph.snapshot @@ -0,0 +1,185 @@ +[ + ( + "err", + Unknown { + original_value: Some( + Variable( + ( + "err", + #6, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + ), + ( + "errors", + Array { + total_nodes: 1, + items: [], + mutable: true, + }, + ), + ( + "path", + Iterated( + 2, + Variable( + ( + "paths", + #2, + ), + ), + ), + ), + ( + "paths", + Array { + total_nodes: 11, + items: [ + Concat( + 4, + [ + Constant( + Str( + Atom( + "../src/build/Release/sharp-", + ), + ), + ), + Variable( + ( + "runtimePlatform", + #2, + ), + ), + Constant( + Str( + Atom( + ".node", + ), + ), + ), + ], + ), + Constant( + Str( + Word( + "../src/build/Release/sharp-wasm32.node", + ), + ), + ), + Concat( + 4, + [ + Constant( + Str( + Atom( + "@img/sharp-", + ), + ), + ), + Variable( + ( + "runtimePlatform", + #2, + ), + ), + Constant( + Str( + Atom( + "/sharp.node", + ), + ), + ), + ], + ), + Constant( + Str( + Word( + "@img/sharp-wasm32/sharp.node", + ), + ), + ), + ], + mutable: true, + }, + ), + ( + "runtimePlatform", + Call( + 2, + Variable( + ( + "runtimePlatformArch", + #2, + ), + ), + [], + ), + ), + ( + "runtimePlatformArch", + Member( + 5, + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "./libvips", + ), + ), + ), + ], + ), + Constant( + Str( + Atom( + "runtimePlatformArch", + ), + ), + ), + ), + ), + ( + "sharp", + Alternatives( + 5, + [ + Unknown { + original_value: Some( + Variable( + ( + "sharp", + #2, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Call( + 3, + FreeVar( + "require", + ), + [ + Variable( + ( + "path", + #3, + ), + ), + ], + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/input.js new file mode 100644 index 0000000000000..a289de161716e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/input.js @@ -0,0 +1,21 @@ +const { runtimePlatformArch } = require('./libvips'); +const runtimePlatform = runtimePlatformArch(); +console.log('runtimePlatform:', runtimePlatform); +const paths = [ + `../src/build/Release/sharp-${runtimePlatform}.node`, + '../src/build/Release/sharp-wasm32.node', + `@img/sharp-${runtimePlatform}/sharp.node`, + '@img/sharp-wasm32/sharp.node' +]; + +let sharp; +const errors = []; +for (const path of paths) { + try { + sharp = require(path); + break; + } catch (err) { + /* istanbul ignore next */ + errors.push(err); + } +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/resolved-effects.snapshot new file mode 100644 index 0000000000000..56249e323237e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/resolved-effects.snapshot @@ -0,0 +1,33 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 call = require*0*("./libvips") +- *0* require: The require method from CommonJS + +0 -> 3 call = module<./libvips, {}>["runtimePlatformArch"]() + +0 -> 5 free var = FreeVar(console) + +0 -> 6 member call = ???*0*["log"]("runtimePlatform:", module<./libvips, {}>["runtimePlatformArch"]()) +- *0* FreeVar(console) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 7 free var = FreeVar(require) + +0 -> 8 call = require*0*( + ( + | `../src/build/Release/sharp-${???*1*}.node` + | "../src/build/Release/sharp-wasm32.node" + | `@img/sharp-${???*2*}/sharp.node` + | "@img/sharp-wasm32/sharp.node" + ) +) +- *0* require: The require method from CommonJS +- *1* module<./libvips, {}>["runtimePlatformArch"]() + ⚠️ nested operation +- *2* module<./libvips, {}>["runtimePlatformArch"]() + ⚠️ nested operation + +0 -> 10 member call = []["push"](???*0*) +- *0* err + ⚠️ pattern without value diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/resolved-explained.snapshot new file mode 100644 index 0000000000000..7c2fa11a18886 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2521/resolved-explained.snapshot @@ -0,0 +1,50 @@ +err = ???*0* +- *0* err + ⚠️ pattern without value + +errors = [] + +path = ( + | `../src/build/Release/sharp-${???*0*}.node` + | "../src/build/Release/sharp-wasm32.node" + | `@img/sharp-${???*1*}/sharp.node` + | "@img/sharp-wasm32/sharp.node" +) +- *0* module<./libvips, {}>["runtimePlatformArch"]() + ⚠️ nested operation +- *1* module<./libvips, {}>["runtimePlatformArch"]() + ⚠️ nested operation + +paths = [ + `../src/build/Release/sharp-${???*0*}.node`, + "../src/build/Release/sharp-wasm32.node", + `@img/sharp-${???*1*}/sharp.node`, + "@img/sharp-wasm32/sharp.node" +] +- *0* module<./libvips, {}>["runtimePlatformArch"]() + ⚠️ nested operation +- *1* module<./libvips, {}>["runtimePlatformArch"]() + ⚠️ nested operation + +runtimePlatform = module<./libvips, {}>["runtimePlatformArch"]() + +runtimePlatformArch = module<./libvips, {}>["runtimePlatformArch"] + +sharp = (???*0* | ???*1*) +- *0* sharp + ⚠️ pattern without value +- *1* require*2*( + ( + | `../src/build/Release/sharp-${???*3*}.node` + | "../src/build/Release/sharp-wasm32.node" + | `@img/sharp-${???*4*}/sharp.node` + | "@img/sharp-wasm32/sharp.node" + ) + ) + ⚠️ only constant argument is supported + ⚠️ This value might have side effects +- *2* require: The require method from CommonJS +- *3* module<./libvips, {}>["runtimePlatformArch"]() + ⚠️ nested operation +- *4* module<./libvips, {}>["runtimePlatformArch"]() + ⚠️ nested operation diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph-effects.snapshot new file mode 100644 index 0000000000000..aab7e41e1f201 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph-effects.snapshot @@ -0,0 +1,826 @@ +[ + Member { + obj: FreeVar( + "Math", + ), + prop: Constant( + Str( + Atom( + "random", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 50..61#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "Math", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 50..54#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "Math", + ), + prop: Constant( + Str( + Atom( + "random", + ), + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + If, + ), + IfStmt( + Test, + ), + Expr( + Bin, + ), + BinExpr( + Left, + ), + Expr( + Call, + ), + ], + span: 50..63#0, + in_try: false, + }, + Member { + obj: FreeVar( + "JSON", + ), + prop: Constant( + Str( + Atom( + "stringify", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 273..287#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "JSON", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 273..277#1, + in_try: false, + }, + Conditional { + condition: Binary( + 3, + Variable( + ( + "variable", + #3, + ), + ), + StrictEqual, + Constant( + Str( + Word( + "true", + ), + ), + ), + ), + kind: Ternary { + then: EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 1, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Cond, + ), + CondExpr( + Cons, + ), + ], + }, + else: EffectsBlock { + effects: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 1, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Cond, + ), + CondExpr( + Alt, + ), + ], + }, + }, + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 1, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Cond, + ), + CondExpr( + Test, + ), + ], + span: 354..392#0, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "JSON", + ), + prop: Constant( + Str( + Atom( + "stringify", + ), + ), + ), + args: [ + Value( + Object { + total_nodes: 12, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "condition", + ), + ), + ), + Binary( + 3, + Variable( + ( + "variable", + #3, + ), + ), + StrictEqual, + Constant( + Str( + Word( + "true", + ), + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "buggedConditionalCheck", + ), + ), + ), + Tenary( + 6, + Binary( + 3, + Variable( + ( + "variable", + #3, + ), + ), + StrictEqual, + Constant( + Str( + Word( + "true", + ), + ), + ), + ), + Constant( + Str( + Word( + "true", + ), + ), + ), + Constant( + Str( + Word( + "false", + ), + ), + ), + ), + ), + ], + mutable: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 273..398#0, + in_try: false, + }, + Call { + func: Variable( + ( + "BuggyArguments", + #2, + ), + ), + args: [ + Value( + Object { + total_nodes: 3, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "variable", + ), + ), + ), + Constant( + Str( + Word( + "false", + ), + ), + ), + ), + ], + mutable: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 416..453#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph-explained.snapshot new file mode 100644 index 0000000000000..a7331f9e2bf2f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph-explained.snapshot @@ -0,0 +1,12 @@ +*arrow function 24* = (...) => FreeVar(JSON)["stringify"]( + { + "condition": (variable === "true"), + "buggedConditionalCheck": ((variable === "true") ? "true" : "false") + } +) + +BuggyArguments = *arrow function 24* + +res = BuggyArguments({"variable": "false"}) + +variable = (arguments[0]["variable"] | "true") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph.snapshot new file mode 100644 index 0000000000000..cf1b3d0637805 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/graph.snapshot @@ -0,0 +1,173 @@ +[ + ( + "*arrow function 24*", + Function( + 16, + 24, + MemberCall( + 15, + FreeVar( + "JSON", + ), + Constant( + Str( + Atom( + "stringify", + ), + ), + ), + [ + Object { + total_nodes: 12, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "condition", + ), + ), + ), + Binary( + 3, + Variable( + ( + "variable", + #3, + ), + ), + StrictEqual, + Constant( + Str( + Word( + "true", + ), + ), + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "buggedConditionalCheck", + ), + ), + ), + Tenary( + 6, + Binary( + 3, + Variable( + ( + "variable", + #3, + ), + ), + StrictEqual, + Constant( + Str( + Word( + "true", + ), + ), + ), + ), + Constant( + Str( + Word( + "true", + ), + ), + ), + Constant( + Str( + Word( + "false", + ), + ), + ), + ), + ), + ], + mutable: true, + }, + ], + ), + ), + ), + ( + "BuggyArguments", + Variable( + ( + "*arrow function 24*", + #0, + ), + ), + ), + ( + "res", + Call( + 5, + Variable( + ( + "BuggyArguments", + #2, + ), + ), + [ + Object { + total_nodes: 3, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "variable", + ), + ), + ), + Constant( + Str( + Word( + "false", + ), + ), + ), + ), + ], + mutable: true, + }, + ], + ), + ), + ( + "variable", + Alternatives( + 5, + [ + Member( + 3, + Argument( + 24, + 0, + ), + Constant( + Str( + Atom( + "variable", + ), + ), + ), + ), + Constant( + Str( + Word( + "true", + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/input.js new file mode 100644 index 0000000000000..2b4875cf80a1b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/input.js @@ -0,0 +1,15 @@ +const BuggyArguments = ({ variable }) => { + if (Math.random() > 1) { + // this will never execute because Math.random() > 1 will never be true but + // for turbopack this should appear as a condition that could execute sometimes + + variable = "true"; + } + + return JSON.stringify({ + condition: variable === "true", + buggedConditionalCheck: variable === "true" ? "true" : "false", + }); +}; + +const res = BuggyArguments({ variable: "false" }); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/resolved-effects.snapshot new file mode 100644 index 0000000000000..5e45590c28702 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/resolved-effects.snapshot @@ -0,0 +1,41 @@ +0 -> 2 free var = FreeVar(Math) + +0 -> 3 member call = ???*0*["random"]() +- *0* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 5 free var = FreeVar(JSON) + +0 -> 6 conditional = ((???*0* | "true") === "true") +- *0* ???*1*["variable"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 7 member call = ???*0*["stringify"]( + { + "condition": ((???*1* | "true") === "true"), + "buggedConditionalCheck": (???*3* ? "true" : "false") + } +) +- *0* FreeVar(JSON) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["variable"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ((???*4* | "true") === "true") + ⚠️ nested operation +- *4* ???*5*["variable"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 8 call = (...) => FreeVar(JSON)["stringify"]( + { + "condition": (variable === "true"), + "buggedConditionalCheck": ((variable === "true") ? "true" : "false") + } +)({"variable": "false"}) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/resolved-explained.snapshot new file mode 100644 index 0000000000000..f0846f144b3f5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/pack-2682/resolved-explained.snapshot @@ -0,0 +1,32 @@ +*arrow function 24* = (...) => FreeVar(JSON)["stringify"]( + { + "condition": (variable === "true"), + "buggedConditionalCheck": ((variable === "true") ? "true" : "false") + } +) + +BuggyArguments = (...) => FreeVar(JSON)["stringify"]( + { + "condition": (variable === "true"), + "buggedConditionalCheck": ((variable === "true") ? "true" : "false") + } +) + +res = ???*0* +- *0* ???*1*["stringify"]( + { + "condition": (variable === "true"), + "buggedConditionalCheck": ((variable === "true") ? "true" : "false") + } + ) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(JSON) + ⚠️ unknown global + ⚠️ This value might have side effects + +variable = (???*0* | "true") +- *0* ???*1*["variable"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph-effects.snapshot new file mode 100644 index 0000000000000..204f857ccceb3 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph-effects.snapshot @@ -0,0 +1,849 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 11..18#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "foo", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 11..25#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 79..86#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "path", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 79..94#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 115..124#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "foo", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "bar", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 115..138#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 158..167#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "foo/", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "bar", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 158..182#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 202..211#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "foo", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "/bar", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 202..226#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 246..255#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "foo/", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "/bar", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 246..271#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 291..300#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "global", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 4, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Ident, + ), + ], + span: 328..334#1, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "path", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "join", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "foo", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "bar", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "..", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "baz", + ), + ), + ), + ), + Value( + FreeVar( + "global", + ), + ), + Value( + Constant( + Str( + Word( + "..", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "foo", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 291..348#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph-explained.snapshot new file mode 100644 index 0000000000000..ae603758cc4cf --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph-explained.snapshot @@ -0,0 +1,13 @@ +a = FreeVar(require)("foo") + +path = FreeVar(require)("path") + +z1_joined = path["join"]("foo", "bar") + +z2_joined = path["join"]("foo/", "bar") + +z3_joined = path["join"]("foo", "/bar") + +z4_joined = path["join"]("foo/", "/bar") + +z5_joined = path["join"]("foo", "bar", "..", "baz", FreeVar(global), "..", "foo") diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph.snapshot new file mode 100644 index 0000000000000..09f3b375d6923 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/graph.snapshot @@ -0,0 +1,244 @@ +[ + ( + "a", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "foo", + ), + ), + ), + ], + ), + ), + ( + "path", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "path", + ), + ), + ), + ], + ), + ), + ( + "z1_joined", + MemberCall( + 5, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "join", + ), + ), + ), + [ + Constant( + Str( + Word( + "foo", + ), + ), + ), + Constant( + Str( + Word( + "bar", + ), + ), + ), + ], + ), + ), + ( + "z2_joined", + MemberCall( + 5, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "join", + ), + ), + ), + [ + Constant( + Str( + Word( + "foo/", + ), + ), + ), + Constant( + Str( + Word( + "bar", + ), + ), + ), + ], + ), + ), + ( + "z3_joined", + MemberCall( + 5, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "join", + ), + ), + ), + [ + Constant( + Str( + Word( + "foo", + ), + ), + ), + Constant( + Str( + Word( + "/bar", + ), + ), + ), + ], + ), + ), + ( + "z4_joined", + MemberCall( + 5, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "join", + ), + ), + ), + [ + Constant( + Str( + Word( + "foo/", + ), + ), + ), + Constant( + Str( + Word( + "/bar", + ), + ), + ), + ], + ), + ), + ( + "z5_joined", + MemberCall( + 10, + Variable( + ( + "path", + #2, + ), + ), + Constant( + Str( + Atom( + "join", + ), + ), + ), + [ + Constant( + Str( + Word( + "foo", + ), + ), + ), + Constant( + Str( + Word( + "bar", + ), + ), + ), + Constant( + Str( + Word( + "..", + ), + ), + ), + Constant( + Str( + Word( + "baz", + ), + ), + ), + FreeVar( + "global", + ), + Constant( + Str( + Word( + "..", + ), + ), + ), + Constant( + Str( + Word( + "foo", + ), + ), + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/input.js new file mode 100644 index 0000000000000..cbf08e11be128 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/input.js @@ -0,0 +1,11 @@ +const a = require("foo"); + +// const b = require.resolve('foo'); + +const path = require("path"); + +const z1_joined = path.join("foo", "bar"); +const z2_joined = path.join("foo/", "bar"); +const z3_joined = path.join("foo", "/bar"); +const z4_joined = path.join("foo/", "/bar"); +const z5_joined = path.join("foo", "bar", "..", "baz", global, "..", "foo"); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/resolved-effects.snapshot new file mode 100644 index 0000000000000..e3a9286282c57 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/resolved-effects.snapshot @@ -0,0 +1,29 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 call = require*0*("foo") +- *0* require: The require method from CommonJS + +0 -> 3 free var = FreeVar(require) + +0 -> 4 call = require*0*("path") +- *0* require: The require method from CommonJS + +0 -> 6 member call = path*0*["join"]("foo", "bar") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +0 -> 8 member call = path*0*["join"]("foo/", "bar") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +0 -> 10 member call = path*0*["join"]("foo", "/bar") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +0 -> 12 member call = path*0*["join"]("foo/", "/bar") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +0 -> 14 free var = FreeVar(global) + +0 -> 15 member call = path*0*["join"]("foo", "bar", "..", "baz", ???*1*, "..", "foo") +- *0* path: The Node.js path module: https://nodejs.org/api/path.html +- *1* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/resolved-explained.snapshot new file mode 100644 index 0000000000000..576738e3f279e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/path-join/resolved-explained.snapshot @@ -0,0 +1,17 @@ +a = module + +path = path*0* +- *0* path: The Node.js path module: https://nodejs.org/api/path.html + +z1_joined = "foo/bar" + +z2_joined = "foo/bar" + +z3_joined = "foo/bar" + +z4_joined = "foo/bar" + +z5_joined = `foo/baz${("/" | "")}${???*0*}${("/" | "")}../foo` +- *0* FreeVar(global) + ⚠️ unknown global + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/graph-explained.snapshot new file mode 100644 index 0000000000000..42890cde6c8ba --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/graph-explained.snapshot @@ -0,0 +1,3493 @@ +*anonymous function 10064* = (...) => "OR" + +*anonymous function 10192* = (...) => "NOT" + +*anonymous function 10796* = (...) => {"type": "identifier", "name": name} + +*anonymous function 11187* = (...) => (head + tail["join"]("")) + +*anonymous function 11339* = (...) => {"type": "parameter_name", "name": text()} + +*anonymous function 11668* = (...) => text() + +*anonymous function 11725* = (...) => seq + +*anonymous function 11890* = (...) => "\b" + +*anonymous function 12016* = (...) => "\f" + +*anonymous function 12142* = (...) => "\n" + +*anonymous function 12268* = (...) => "\r" + +*anonymous function 12394* = (...) => "\t" + +*anonymous function 12449* = (...) => text() + +*anonymous function 12577* = (...) => FreeVar(String)["fromCharCode"](FreeVar(parseInt)(digits, 16)) + +*anonymous function 1271* = (...) => "any character" + +*anonymous function 12829* = (...) => v + +*anonymous function 12892* = (...) => {"property": property, "alias": alias} + +*anonymous function 12977* = (...) => expression + +*anonymous function 13048* = (...) => {"type": "array_subquery_expression", "expression": expression} + +*anonymous function 13181* = (...) => {"type": "exists_subquery_expression", "expression": expression} + +*anonymous function 13315* = (...) => {"type": "scalar_subquery_expression", "expression": expression} + +*anonymous function 1343* = (...) => "end of input" + +*anonymous function 13449* = (...) => {"property": property, "computed": false} + +*anonymous function 13543* = (...) => {"property": property, "computed": true} + +*anonymous function 13636* = (...) => tail["reduce"](*arrow function 13694*, head) + +*anonymous function 13891* = (...) => {"type": "scalar_unary_expression", "operator": operator, "argument": argument} + +*anonymous function 1416* = (...) => expectation["description"] + +*anonymous function 14188* = (...) => { + "type": "scalar_conditional_expression", + "test": test, + "consequent": consequent, + "alternate": alternate +} + +*anonymous function 14448* = (...) => buildBinaryExpression(head, tail) + +*anonymous function 15047* = (...) => {"type": "scalar_in_expression", "value": value, "list": list} + +*anonymous function 15185* = (...) => {"type": "scalar_between_expression", "value": value, "begin": begin, "end": end} + +*anonymous function 15997* = (...) => {"key": key, "value": value} + +*anonymous function 16072* = (...) => {"type": "collection_expression", "expression": expression} + +*anonymous function 16201* = (...) => tail["reduce"](*arrow function 16259*, head) + +*anonymous function 16460* = (...) => {"type": "collection_subquery_expression", "expression": expression} + +*anonymous function 16598* = (...) => {"type": "top_specification", "value": value} + +*anonymous function 16713* = (...) => {"type": "number_constant", "value": FreeVar(Number)(text())} + +*anonymous function 16837* = (...) => (head ? ???*0* : []) +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 16925* = (...) => subquery + +*anonymous function 1822* = (...) => `\x0${hex(ch)}` + +*anonymous function 1920* = (...) => `\x${hex(ch)}` + +*anonymous function 2287* = (...) => `\x0${hex(ch)}` + +*anonymous function 2385* = (...) => `\x${hex(ch)}` + +*anonymous function 3852* = (...) => {"type": "sql", "body": body} + +*anonymous function 3949* = (...) => v + +*anonymous function 4000* = (...) => v + +*anonymous function 4064* = (...) => v + +*anonymous function 4134* = (...) => v + +*anonymous function 4211* = (...) => { + "type": "select_query", + "top": top, + "select": select, + "from": from, + "where": where, + "orderBy": orderBy +} + +*anonymous function 4474* = (...) => {"type": "select_specification", "*": true} + +*anonymous function 4589* = (...) => {"type": "select_specification", "properties": properties} + +*anonymous function 4716* = (...) => {"type": "select_specification", "value": value} + +*anonymous function 4902* = (...) => v + +*anonymous function 4960* = (...) => {"type": "object_property_list", "properties": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 5104* = (...) => v + +*anonymous function 5164* = (...) => {"type": "from_specification", "source": source, "joins": joins} + +*anonymous function 5303* = (...) => {"type": "from_source", "expression": expression, "alias": alias, "iteration": true} + +*anonymous function 5468* = (...) => v + +*anonymous function 5532* = (...) => {"type": "from_source", "expression": expression, "alias": alias} + +*anonymous function 5672* = (...) => {"type": "filter_condition", "condition": condition} + +*anonymous function 5793* = (...) => {"type": "sort_specification", "expressions": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 5936* = (...) => {"type": "sort_expression", "expression": expression, "order": order} + +*anonymous function 625* = (...) => `Expected ${describeExpected(expected)} but ${describeFound(found)} found.` + +*anonymous function 6287* = (...) => {"type": "scalar_function_expression", "name": name, "arguments": args, "udf": true} + +*anonymous function 6458* = (...) => {"type": "scalar_function_expression", "name": name, "arguments": args} + +*anonymous function 6748* = (...) => {"type": "scalar_object_expression", "properties": (head ? ???*0* : [])} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 702* = (...) => `"${literalEscape(expectation["text"])}"` + +*anonymous function 7046* = (...) => {"type": "scalar_array_expression", "elements": elements} + +*anonymous function 7257* = (...) => {"type": "undefined_constant"} + +*anonymous function 7337* = (...) => {"type": "null_constant"} + +*anonymous function 7412* = (...) => {"type": "boolean_constant", "value": false} + +*anonymous function 7527* = (...) => {"type": "boolean_constant", "value": true} + +*anonymous function 7869* = (...) => { + "type": "number_constant", + "value": (hex ? FreeVar(parseInt)(text(), 16) : FreeVar(parseFloat)(text())) +} + +*anonymous function 804* = (...) => `[${(expectation["inverted"] ? "^" : "")}${escapedParts}]` + +*anonymous function 8139* = (...) => {"type": "string_constant", "value": chars["join"]("")} + +*anonymous function 8336* = (...) => {"type": "array_constant", "elements": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 8472* = (...) => {"type": "object_constant", "properties": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 9682* = (...) => "ASC" + +*anonymous function 9811* = (...) => "DESC" + +*anonymous function 9939* = (...) => "AND" + +*arrow function 13694* = (...) => {"type": "scalar_member_expression", "object": object, "property": property, "computed": computed} + +*arrow function 16259* = (...) => { + "type": "collection_member_expression", + "object": object, + "property": property, + "computed": computed +} + +*arrow function 169161* = (...) => {"type": "scalar_binary_expression", "left": left, "operator": operator, "right": right} + +DESCRIBE_EXPECTATION_FNS = { + "literal": *anonymous function 702*, + "class": *anonymous function 804*, + "any": *anonymous function 1271*, + "end": *anonymous function 1343*, + "other": *anonymous function 1416* +} + +alias#42 = arguments[0] + +alias#44 = arguments[1] + +alias#78 = arguments[1] + +alternate = arguments[2] + +args#48 = arguments[1] + +args#49 = arguments[1] + +argument = arguments[1] + +begin = arguments[1] + +body = arguments[0] + +buildBinaryExpression = (...) => tail["reduce"](*arrow function 169161*, head) + +ch#14 = arguments[0] + +ch#16 = arguments[0] + +ch#17 = arguments[0] + +ch#19 = arguments[0] + +ch#20 = arguments[0] + +chars = arguments[0] + +child = arguments[0] + +classEscape = (...) => ...[...](..., ...)["replace"](/\]/g, "\\]")["replace"](/\^/g, "\\^")["replace"](/-/g, "\\-")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 2287*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*) + +computed#86 = arguments[1]["computed"] + +computed#95 = arguments[1]["computed"] + +condition = arguments[0] + +consequent = arguments[1] + +ctor = (...) => undefined + +describeExpectation = (...) => DESCRIBE_EXPECTATION_FNS[expectation["type"]](expectation) + +describeExpected = (...) => ( + | undefined + | descriptions[0] + | `${descriptions[0]} or ${descriptions[1]}` + | `${descriptions["slice"](0, ???*0*)["join"](", ")}, or ${descriptions[???*1*]}` +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +describeFound = (...) => (found ? `"${literalEscape(found)}"` : "end of input") + +description#105 = arguments[0] + +description#111 = arguments[0] + +descriptions = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +details = ( + | peg$posDetailsCache[pos] + | peg$posDetailsCache[p] + | {"line": details["line"], "column": details["column"]} +) + +digits = arguments[0] + +elements = arguments[0] + +end = arguments[2] + +endPos = arguments[1] + +endPosDetails = peg$computePosDetails(endPos) + +error = (...) => undefined + +escapedParts = ( + | "" + | ( + + escapedParts + + (???*0* ? `${classEscape(expectation["parts"][i][0])}-${classEscape(expectation["parts"][i][1])}` : classEscape(expectation["parts"][i])) + ) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +expectation#11 = arguments[0] + +expectation#12 = arguments[0] + +expectation#13 = arguments[0] + +expectation#21 = arguments[0] + +expectation#8 = arguments[0] + +expectation#9 = arguments[0] + +expected#120 = arguments[0] + +expected#124 = arguments[0] + +expected#22 = arguments[0] + +expected#28 = (...) => undefined + +expected#5 = arguments[1] + +expected#7 = arguments[0] + +expression#42 = arguments[1] + +expression#43 = arguments[0] + +expression#44 = arguments[0] + +expression#47 = arguments[0] + +expression#79 = arguments[0] + +expression#80 = arguments[0] + +expression#81 = arguments[0] + +expression#82 = arguments[0] + +expression#93 = arguments[0] + +expression#96 = arguments[0] + +found#124 = arguments[1] + +found#27 = arguments[0] + +found#5 = arguments[2] + +found#7 = arguments[1] + +from#32 = arguments[2] + +from#33 = arguments[2] + +from#34 = arguments[2] + +head#1801 = arguments[0] + +head#38 = arguments[0] + +head#39 = arguments[0] + +head#46 = arguments[0] + +head#50 = arguments[0] + +head#58 = arguments[0] + +head#59 = arguments[0] + +head#66 = arguments[0] + +head#83 = arguments[0] + +head#84 = arguments[0] + +head#85 = arguments[0] + +head#89 = arguments[0] + +head#94 = arguments[0] + +head#99 = arguments[0] + +hex#56 = arguments[0] + +hex#7 = (...) => ch["charCodeAt"](0)["toString"](16)["toUpperCase"]() + +i#22 = (???*0* | 0 | ???*1* | 1) +- *0* i + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +i#9 = (???*0* | 0 | ???*1*) +- *0* i + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +ignoreCase#107 = arguments[1] + +ignoreCase#108 = arguments[2] + +input = arguments[0] + +inverted = arguments[1] + +j = (???*0* | 1 | ???*1*) +- *0* j + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +joins = arguments[1] + +key = arguments[0] + +left = arguments[0] + +list = arguments[1] + +literalEscape = (...) => s["replace"](/\\/g, "\\\\")["replace"](/"/g, "\\\"")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 1822*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 1920*) + +location#105 = ( + | arguments[1] + | ((location !== ???*0*) ? location : peg$computeLocation(peg$savedPos, peg$currPos)) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +location#106 = ( + | arguments[1] + | ((location !== ???*0*) ? location : peg$computeLocation(peg$savedPos, peg$currPos)) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +location#123 = arguments[1] + +location#124 = arguments[2] + +location#28 = (...) => peg$computeLocation(peg$savedPos, peg$currPos) + +location#5 = arguments[3] + +message#106 = arguments[0] + +message#123 = arguments[0] + +message#5 = arguments[0] + +name#48 = arguments[0] + +name#49 = arguments[0] + +name#65 = arguments[0] + +object#86 = arguments[0] + +object#95 = arguments[0] + +operator#1802 = arguments[1][1] + +operator#87 = arguments[0] + +options = (arguments[1] | ((options !== ???*0*) ? options : {})) +- *0* unsupported expression + ⚠️ This value might have side effects + +order = arguments[1] + +orderBy = arguments[4] + +p = (???*0* | ???*1* | ???*2*) +- *0* p + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +parent = arguments[1] + +parts = arguments[0] + +peg$FAILED = {} + +peg$SyntaxError = (...) => undefined + +peg$anyExpectation = (...) => {"type": "any"} + +peg$buildSimpleError = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +peg$buildStructuredError = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +peg$c0 = *anonymous function 3852* + +peg$c1 = *anonymous function 3949* + +peg$c10 = *anonymous function 4716* + +peg$c100 = peg$literalExpectation("NOT", true) + +peg$c101 = *anonymous function 10192* + +peg$c102 = "between" + +peg$c103 = peg$literalExpectation("BETWEEN", true) + +peg$c104 = "exists" + +peg$c105 = peg$literalExpectation("EXISTS", true) + +peg$c106 = "array" + +peg$c107 = peg$literalExpectation("ARRAY", true) + +peg$c108 = "null" + +peg$c109 = peg$literalExpectation("null", false) + +peg$c11 = "," + +peg$c110 = "true" + +peg$c111 = peg$literalExpectation("true", false) + +peg$c112 = "false" + +peg$c113 = peg$literalExpectation("false", false) + +peg$c114 = "udf" + +peg$c115 = peg$literalExpectation("udf", false) + +peg$c116 = *anonymous function 10796* + +peg$c117 = /^[a-zA-Z_]/ + +peg$c118 = peg$classExpectation([["a", "z"], ["A", "Z"], "_"], false, false) + +peg$c119 = /^[a-zA-Z0-9_]/ + +peg$c12 = peg$literalExpectation(",", false) + +peg$c120 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_"], false, false) + +peg$c121 = *anonymous function 11187* + +peg$c122 = "@" + +peg$c123 = peg$literalExpectation("@", false) + +peg$c124 = *anonymous function 11339* + +peg$c125 = "+" + +peg$c126 = peg$literalExpectation("+", false) + +peg$c127 = "~" + +peg$c128 = peg$literalExpectation("~", false) + +peg$c129 = "\\" + +peg$c13 = *anonymous function 4902* + +peg$c130 = peg$literalExpectation("\\", false) + +peg$c131 = *anonymous function 11668* + +peg$c132 = *anonymous function 11725* + +peg$c133 = peg$anyExpectation() + +peg$c134 = "b" + +peg$c135 = peg$literalExpectation("b", false) + +peg$c136 = *anonymous function 11890* + +peg$c137 = "f" + +peg$c138 = peg$literalExpectation("f", false) + +peg$c139 = *anonymous function 12016* + +peg$c14 = *anonymous function 4960* + +peg$c140 = "n" + +peg$c141 = peg$literalExpectation("n", false) + +peg$c142 = *anonymous function 12142* + +peg$c143 = "r" + +peg$c144 = peg$literalExpectation("r", false) + +peg$c145 = *anonymous function 12268* + +peg$c146 = "t" + +peg$c147 = peg$literalExpectation("t", false) + +peg$c148 = *anonymous function 12394* + +peg$c149 = *anonymous function 12449* + +peg$c15 = *anonymous function 5104* + +peg$c150 = "u" + +peg$c151 = peg$literalExpectation("u", false) + +peg$c152 = *anonymous function 12577* + +peg$c153 = /^[0-9a-f]/i + +peg$c154 = peg$classExpectation([["0", "9"], ["a", "f"]], false, true) + +peg$c155 = *anonymous function 12829* + +peg$c156 = *anonymous function 12892* + +peg$c157 = *anonymous function 12977* + +peg$c158 = *anonymous function 13048* + +peg$c159 = *anonymous function 13181* + +peg$c16 = *anonymous function 5164* + +peg$c160 = *anonymous function 13315* + +peg$c161 = *anonymous function 13449* + +peg$c162 = *anonymous function 13543* + +peg$c163 = *anonymous function 13636* + +peg$c164 = *anonymous function 13891* + +peg$c165 = "?" + +peg$c166 = peg$literalExpectation("?", false) + +peg$c167 = ":" + +peg$c168 = peg$literalExpectation(":", false) + +peg$c169 = *anonymous function 14188* + +peg$c17 = *anonymous function 5303* + +peg$c170 = "??" + +peg$c171 = peg$literalExpectation("??", false) + +peg$c172 = *anonymous function 14448* + +peg$c173 = "=" + +peg$c174 = peg$literalExpectation("=", false) + +peg$c175 = "!=" + +peg$c176 = peg$literalExpectation("!=", false) + +peg$c177 = "<>" + +peg$c178 = peg$literalExpectation("<>", false) + +peg$c179 = "<=" + +peg$c18 = *anonymous function 5468* + +peg$c180 = peg$literalExpectation("<=", false) + +peg$c181 = ">=" + +peg$c182 = peg$literalExpectation(">=", false) + +peg$c183 = "<" + +peg$c184 = peg$literalExpectation("<", false) + +peg$c185 = ">" + +peg$c186 = peg$literalExpectation(">", false) + +peg$c187 = *anonymous function 15047* + +peg$c188 = *anonymous function 15185* + +peg$c189 = "|" + +peg$c19 = *anonymous function 5532* + +peg$c190 = peg$literalExpectation("|", false) + +peg$c191 = "^" + +peg$c192 = peg$literalExpectation("^", false) + +peg$c193 = "&" + +peg$c194 = peg$literalExpectation("&", false) + +peg$c195 = "<<" + +peg$c196 = peg$literalExpectation("<<", false) + +peg$c197 = ">>>" + +peg$c198 = peg$literalExpectation(">>>", false) + +peg$c199 = ">>" + +peg$c2 = *anonymous function 4000* + +peg$c20 = *anonymous function 5672* + +peg$c200 = peg$literalExpectation(">>", false) + +peg$c201 = "||" + +peg$c202 = peg$literalExpectation("||", false) + +peg$c203 = "/" + +peg$c204 = peg$literalExpectation("/", false) + +peg$c205 = "%" + +peg$c206 = peg$literalExpectation("%", false) + +peg$c207 = *anonymous function 15997* + +peg$c208 = *anonymous function 16072* + +peg$c209 = *anonymous function 16201* + +peg$c21 = *anonymous function 5793* + +peg$c210 = *anonymous function 16460* + +peg$c211 = *anonymous function 16598* + +peg$c212 = *anonymous function 16713* + +peg$c213 = *anonymous function 16837* + +peg$c214 = *anonymous function 16925* + +peg$c22 = *anonymous function 5936* + +peg$c23 = "." + +peg$c24 = peg$literalExpectation(".", false) + +peg$c25 = "(" + +peg$c26 = peg$literalExpectation("(", false) + +peg$c27 = ")" + +peg$c28 = peg$literalExpectation(")", false) + +peg$c29 = *anonymous function 6287* + +peg$c3 = *anonymous function 4064* + +peg$c30 = *anonymous function 6458* + +peg$c31 = "{" + +peg$c32 = peg$literalExpectation("{", false) + +peg$c33 = "}" + +peg$c34 = peg$literalExpectation("}", false) + +peg$c35 = *anonymous function 6748* + +peg$c36 = "[" + +peg$c37 = peg$literalExpectation("[", false) + +peg$c38 = "]" + +peg$c39 = peg$literalExpectation("]", false) + +peg$c4 = *anonymous function 4134* + +peg$c40 = *anonymous function 7046* + +peg$c41 = "undefined" + +peg$c42 = peg$literalExpectation("undefined", false) + +peg$c43 = *anonymous function 7257* + +peg$c44 = *anonymous function 7337* + +peg$c45 = *anonymous function 7412* + +peg$c46 = *anonymous function 7527* + +peg$c47 = "-" + +peg$c48 = peg$literalExpectation("-", false) + +peg$c49 = "0x" + +peg$c5 = *anonymous function 4211* + +peg$c50 = peg$literalExpectation("0x", false) + +peg$c51 = /^[0-9]/ + +peg$c52 = peg$classExpectation([["0", "9"]], false, false) + +peg$c53 = *anonymous function 7869* + +peg$c54 = "\"" + +peg$c55 = peg$literalExpectation("\"", false) + +peg$c56 = *anonymous function 8139* + +peg$c57 = "'" + +peg$c58 = peg$literalExpectation("'", false) + +peg$c59 = *anonymous function 8336* + +peg$c6 = "*" + +peg$c60 = *anonymous function 8472* + +peg$c61 = /^[ \t\n\r]/ + +peg$c62 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false) + +peg$c63 = "--" + +peg$c64 = peg$literalExpectation("--", false) + +peg$c65 = /^[\n\r]/ + +peg$c66 = peg$classExpectation(["\n", "\r"], false, false) + +peg$c67 = "select" + +peg$c68 = peg$literalExpectation("SELECT", true) + +peg$c69 = "top" + +peg$c7 = peg$literalExpectation("*", false) + +peg$c70 = peg$literalExpectation("TOP", true) + +peg$c71 = "from" + +peg$c72 = peg$literalExpectation("FROM", true) + +peg$c73 = "where" + +peg$c74 = peg$literalExpectation("WHERE", true) + +peg$c75 = "order" + +peg$c76 = peg$literalExpectation("ORDER", true) + +peg$c77 = "by" + +peg$c78 = peg$literalExpectation("BY", true) + +peg$c79 = "as" + +peg$c8 = *anonymous function 4474* + +peg$c80 = peg$literalExpectation("AS", true) + +peg$c81 = "join" + +peg$c82 = peg$literalExpectation("JOIN", true) + +peg$c83 = "in" + +peg$c84 = peg$literalExpectation("IN", true) + +peg$c85 = "value" + +peg$c86 = peg$literalExpectation("VALUE", true) + +peg$c87 = "asc" + +peg$c88 = peg$literalExpectation("ASC", true) + +peg$c89 = *anonymous function 9682* + +peg$c9 = *anonymous function 4589* + +peg$c90 = "desc" + +peg$c91 = peg$literalExpectation("DESC", true) + +peg$c92 = *anonymous function 9811* + +peg$c93 = "and" + +peg$c94 = peg$literalExpectation("AND", true) + +peg$c95 = *anonymous function 9939* + +peg$c96 = "or" + +peg$c97 = peg$literalExpectation("OR", true) + +peg$c98 = *anonymous function 10064* + +peg$c99 = "not" + +peg$classExpectation = (...) => {"type": "class", "parts": parts, "inverted": inverted, "ignoreCase": ignoreCase} + +peg$computeLocation = (...) => { + "start": {"offset": startPos, "line": startPosDetails["line"], "column": startPosDetails["column"]}, + "end": {"offset": endPos, "line": endPosDetails["line"], "column": endPosDetails["column"]} +} + +peg$computePosDetails = (...) => (undefined | details) + +peg$currPos = ( + | 0 + | s0 + | s3 + | s7 + | s9 + | s11 + | s0 + | ???*0* + | s0 + | s3 + | s0 + | s3 + | s0 + | s0 + | s3 + | s2 + | s3 + | s0 + | s2 + | s0 + | s0 + | s5 + | s0 + | s0 + | (peg$currPos + 9) + | (peg$currPos + 2) + | s4 + | s0 + | s0 + | s5 + | s0 + | s5 + | s0 + | s4 + | s3 + | s0 + | (peg$currPos + 6) + | s2 + | s0 + | (peg$currPos + 3) + | s2 + | s0 + | (peg$currPos + 4) + | s2 + | s0 + | (peg$currPos + 5) + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | (peg$currPos + 7) + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s2 + | s0 + | s1 + | s0 + | s0 + | s0 + | s1 + | s0 + | s1 + | s0 + | s1 + | s0 + | s3 + | s0 + | s3 + | s2 + | s0 + | s0 + | s0 + | s0 + | s3 + | s0 + | s0 + | s0 + | s3 + | s0 + | s3 + | s0 + | s3 + | s0 + | s3 + | s0 + | s0 + | s0 + | s3 + | s0 + | s3 + | s0 + | s3 + | s0 + | s3 + | s0 + | s3 + | s0 + | s3 + | s0 + | s0 + | s0 + | s3 + | s0 + | s3 + | s0 + | s0 +) +- *0* updated with update expression + ⚠️ This value might have side effects + +peg$endExpectation = (...) => {"type": "end"} + +peg$fail = (...) => (undefined | FreeVar(undefined)) + +peg$literalExpectation = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase} + +peg$maxFailExpected = [] + +peg$maxFailPos = (0 | peg$currPos) + +peg$otherExpectation = (...) => {"type": "other", "description": description} + +peg$parse = (...) => (undefined | peg$result) + +peg$parse_ = (...) => s0 + +peg$parseand = (...) => s0 + +peg$parsearray = (...) => s0 + +peg$parsearray_constant = (...) => s0 + +peg$parsearray_subquery_expression = (...) => s0 + +peg$parseas = (...) => s0 + +peg$parseasc = (...) => s0 + +peg$parsebetween = (...) => s0 + +peg$parseboolean_constant = (...) => s0 + +peg$parseby = (...) => s0 + +peg$parsecharactor_escape_sequence = (...) => s0 + +peg$parsecollection_expression = (...) => s0 + +peg$parsecollection_member_expression = (...) => s0 + +peg$parsecollection_primary_expression = (...) => s0 + +peg$parsecollection_subquery_expression = (...) => s0 + +peg$parsecomment = (...) => s0 + +peg$parseconstant = (...) => s0 + +peg$parsedesc = (...) => s0 + +peg$parsedouble_string_character = (...) => s0 + +peg$parseescape_character = (...) => s0 + +peg$parseescape_sequence = (...) => s0 + +peg$parseexists = (...) => s0 + +peg$parseexists_subquery_expression = (...) => s0 + +peg$parsefalse = (...) => s0 + +peg$parsefilter_condition = (...) => s0 + +peg$parsefrom = (...) => s0 + +peg$parsefrom_source = (...) => s0 + +peg$parsefrom_specification = (...) => s0 + +peg$parsehex_digit = (...) => s0 + +peg$parseidentifier = (...) => s0 + +peg$parseidentifier_name = (...) => s0 + +peg$parseidentifier_start = (...) => s0 + +peg$parsein = (...) => s0 + +peg$parsejoin = (...) => s0 + +peg$parsenon_escape_character = (...) => s0 + +peg$parsenot = (...) => s0 + +peg$parsenull = (...) => s0 + +peg$parsenull_constant = (...) => s0 + +peg$parsenumber_constant = (...) => s0 + +peg$parseobject_constant = (...) => s0 + +peg$parseobject_constant_property = (...) => s0 + +peg$parseobject_property = (...) => s0 + +peg$parseobject_property_list = (...) => s0 + +peg$parseor = (...) => s0 + +peg$parseorder = (...) => s0 + +peg$parseparameter_name = (...) => s0 + +peg$parsereserved = (...) => s0 + +peg$parsescalar_array_expression = (...) => s0 + +peg$parsescalar_between_expression = (...) => s0 + +peg$parsescalar_binary_additive_expression = (...) => s0 + +peg$parsescalar_binary_and_expression = (...) => s0 + +peg$parsescalar_binary_bitwise_and_expression = (...) => s0 + +peg$parsescalar_binary_bitwise_or_expression = (...) => s0 + +peg$parsescalar_binary_bitwise_xor_expression = (...) => s0 + +peg$parsescalar_binary_equality_expression = (...) => s0 + +peg$parsescalar_binary_multiplicative_expression = (...) => s0 + +peg$parsescalar_binary_or_expression = (...) => s0 + +peg$parsescalar_binary_relational_expression = (...) => s0 + +peg$parsescalar_binary_shift_expression = (...) => s0 + +peg$parsescalar_conditional_expression = (...) => s0 + +peg$parsescalar_expression_list = (...) => s0 + +peg$parsescalar_function_expression = (...) => s0 + +peg$parsescalar_in_expression = (...) => s0 + +peg$parsescalar_member_expression = (...) => s0 + +peg$parsescalar_object_element_property = (...) => s0 + +peg$parsescalar_object_expression = (...) => s0 + +peg$parsescalar_primary_expression = (...) => s0 + +peg$parsescalar_subquery_expression = (...) => s0 + +peg$parsescalar_unary_expression = (...) => s0 + +peg$parseselect = (...) => s0 + +peg$parseselect_query = (...) => s0 + +peg$parseselect_specification = (...) => s0 + +peg$parsesingle_escape_character = (...) => s0 + +peg$parsesingle_string_character = (...) => s0 + +peg$parsesort_expression = (...) => s0 + +peg$parsesort_specification = (...) => s0 + +peg$parsesource_character = (...) => s0 + +peg$parsesql = (...) => s0 + +peg$parsestring_constant = (...) => s0 + +peg$parsesubquery = (...) => s0 + +peg$parsesubquery_expression = (...) => s0 + +peg$parsetop = (...) => s0 + +peg$parsetop_specification = (...) => s0 + +peg$parsetrue = (...) => s0 + +peg$parseudf = (...) => s0 + +peg$parseunary_operator = (...) => s0 + +peg$parseundefined_constant = (...) => s0 + +peg$parseunicode_escape_sequence = (...) => s0 + +peg$parseunsigned_integer = (...) => s0 + +peg$parsevalue = (...) => s0 + +peg$parsewhere = (...) => s0 + +peg$parsewhitespace = (...) => s0 + +peg$posDetailsCache = [{"line": 1, "column": 1}] + +peg$result = (???*0* | peg$startRuleFunction()) +- *0* peg$result + ⚠️ pattern without value + +peg$savedPos = ( + | 0 + | s0 + | s3 + | s7 + | s9 + | s11 + | s0 + | s0 + | s3 + | s0 + | s3 + | s0 + | s0 + | s2 + | s0 + | s3 + | s0 + | s2 + | s0 + | s0 + | s5 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s5 + | s0 + | s5 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s2 + | s0 + | s0 + | s0 + | s0 + | s0 + | s3 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s0 + | s3 + | s0 + | s0 + | s0 + | s0 + | s3 + | s0 + | s0 +) + +peg$silentFails = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +peg$startRuleFunction = (peg$parsesql | peg$startRuleFunctions[options["startRule"]]) + +peg$startRuleFunctions = {"sql": peg$parsesql} + +peg$subclass = (...) => undefined + +pos = arguments[0] + +properties = arguments[0] + +property#77 = arguments[0] + +property#78 = arguments[0] + +property#83 = arguments[1] + +property#84 = arguments[1] + +property#86 = arguments[1]["property"] + +property#95 = arguments[1]["property"] + +right = arguments[1][3] + +s#15 = arguments[0] + +s#18 = arguments[0] + +s0#1019 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1026 = (???*0* | peg$parsesingle_escape_character() | peg$c150 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1031 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1049 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1053 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1070 = ( + | ???*0* + | peg$parseidentifier() + | peg$parseparameter_name() + | peg$parseconstant() + | peg$parsescalar_array_expression() + | peg$parsescalar_object_expression() + | peg$parsesubquery_expression() + | peg$currPos + | s1 + | peg$FAILED +) +- *0* s0 + ⚠️ pattern without value + +s0#1093 = ( + | ???*0* + | peg$parsearray_subquery_expression() + | peg$parseexists_subquery_expression() + | peg$parsescalar_subquery_expression() +) +- *0* s0 + ⚠️ pattern without value + +s0#1096 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1103 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1110 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#1112 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1186 = ( + | ???*0* + | peg$parsescalar_function_expression() + | peg$parsescalar_member_expression() + | peg$currPos + | s1 + | peg$FAILED +) +- *0* s0 + ⚠️ pattern without value + +s0#1195 = (???*0* | peg$currPos | s1 | peg$FAILED | peg$parsescalar_binary_or_expression()) +- *0* s0 + ⚠️ pattern without value + +s0#1221 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#125 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1251 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1273 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1317 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#132 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1369 = (???*0* | peg$currPos | s1 | peg$FAILED | peg$parsescalar_between_expression()) +- *0* s0 + ⚠️ pattern without value + +s0#1395 = (???*0* | peg$currPos | s1 | peg$FAILED | peg$parsescalar_binary_bitwise_or_expression()) +- *0* s0 + ⚠️ pattern without value + +s0#1415 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1443 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1471 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1499 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1543 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1587 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1631 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1646 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1661 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#1663 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1739 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#1741 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#1744 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#1755 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#1784 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#187 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#201 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#229 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#251 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#279 = ( + | ???*0* + | peg$parsecollection_member_expression() + | peg$parsecollection_primary_expression() + | peg$parsecollection_subquery_expression() +) +- *0* s0 + ⚠️ pattern without value + +s0#282 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#284 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#312 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#323 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#376 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#419 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#436 = ( + | ???*0* + | peg$parseundefined_constant() + | peg$parsenull_constant() + | peg$parseboolean_constant() + | peg$parsenumber_constant() + | peg$parsestring_constant() + | peg$parsearray_constant() + | peg$parseobject_constant() +) +- *0* s0 + ⚠️ pattern without value + +s0#443 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#448 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#450 = (???*0* | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s0#454 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#497 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#525 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#567 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#609 = (???*0* | []) +- *0* s0 + ⚠️ pattern without value + +s0#613 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#617 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#644 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#654 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#664 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#674 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#684 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#694 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#704 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#714 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#724 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#734 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#744 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#754 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#764 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#774 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#784 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#794 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#804 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#814 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#824 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#834 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#844 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#854 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#864 = ( + | ???*0* + | peg$parseselect() + | peg$parsetop() + | peg$parsefrom() + | peg$parsewhere() + | peg$parseorder() + | peg$parseby() + | peg$parseas() + | peg$parsejoin() + | peg$parsein() + | peg$parsevalue() + | peg$parseasc() + | peg$parsedesc() + | peg$parseand() + | peg$parseor() + | peg$parsenot() + | peg$parsebetween() + | peg$parseexists() + | peg$parsearray() + | peg$parsenull() + | peg$parsetrue() + | peg$parsefalse() + | peg$parseudf() +) +- *0* s0 + ⚠️ pattern without value + +s0#886 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#893 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#897 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#909 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#917 = (???*0* | peg$c125 | peg$FAILED | peg$c47 | peg$c127 | peg$parsenot()) +- *0* s0 + ⚠️ pattern without value + +s0#930 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#952 = (???*0* | peg$currPos | s1 | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#974 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED) +- *0* s0 + ⚠️ pattern without value + +s0#978 = (???*0* | peg$parsecharactor_escape_sequence() | peg$parseunicode_escape_sequence()) +- *0* s0 + ⚠️ pattern without value + +s0#980 = (???*0* | peg$parsesingle_escape_character() | peg$parsenon_escape_character()) +- *0* s0 + ⚠️ pattern without value + +s0#982 = (???*0* | peg$c57 | peg$FAILED | peg$c54 | peg$c129 | peg$currPos | s1) +- *0* s0 + ⚠️ pattern without value + +s1#1019 = (???*0* | peg$currPos | ???*1* | peg$FAILED | peg$c149()) +- *0* s1 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s1#1031 = (???*0* | peg$c150 | peg$FAILED | peg$c152(s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1053 = (???*0* | peg$parsescalar_conditional_expression() | peg$c156(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1070 = (???*0* | peg$c25 | peg$FAILED | peg$c157(s3)) +- *0* s1 + ⚠️ pattern without value + +s1#1096 = (???*0* | peg$parsearray() | peg$c158(s3)) +- *0* s1 + ⚠️ pattern without value + +s1#1103 = (???*0* | peg$parseexists() | peg$c159(s3)) +- *0* s1 + ⚠️ pattern without value + +s1#1110 = (???*0* | peg$parsesubquery() | peg$c160(s1)) +- *0* s1 + ⚠️ pattern without value + +s1#1112 = (???*0* | peg$parsescalar_primary_expression() | peg$c163(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1186 = (???*0* | peg$parseunary_operator() | peg$c164(s1, s3)) +- *0* s1 + ⚠️ pattern without value + +s1#1195 = (???*0* | peg$parsescalar_binary_or_expression() | peg$c169(s1, s5, s9)) +- *0* s1 + ⚠️ pattern without value + +s1#1221 = (???*0* | peg$parsescalar_binary_and_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#125 = (???*0* | peg$parse_() | peg$c0(s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1251 = (???*0* | peg$parsescalar_binary_equality_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1273 = (???*0* | peg$parsescalar_binary_relational_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1317 = (???*0* | peg$parsescalar_in_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#132 = (???*0* | peg$parseselect() | peg$c5(s3, s5, s7, s9, s11)) +- *0* s1 + ⚠️ pattern without value + +s1#1369 = (???*0* | peg$parsescalar_between_expression() | peg$c187(s1, s7)) +- *0* s1 + ⚠️ pattern without value + +s1#1395 = (???*0* | peg$parsescalar_binary_bitwise_or_expression() | peg$c188(s1, s5, s9)) +- *0* s1 + ⚠️ pattern without value + +s1#1415 = (???*0* | peg$parsescalar_binary_bitwise_xor_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1443 = (???*0* | peg$parsescalar_binary_bitwise_and_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1471 = (???*0* | peg$parsescalar_binary_shift_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1499 = (???*0* | peg$parsescalar_binary_additive_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1543 = (???*0* | peg$parsescalar_binary_multiplicative_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1587 = (???*0* | peg$parsescalar_unary_expression() | peg$c172(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1631 = (???*0* | peg$parseidentifier() | peg$parsestring_constant() | peg$c207(s1, s5)) +- *0* s1 + ⚠️ pattern without value + +s1#1646 = (???*0* | peg$parseidentifier() | peg$parsestring_constant() | peg$c207(s1, s5)) +- *0* s1 + ⚠️ pattern without value + +s1#1661 = (???*0* | peg$parseidentifier() | peg$c208(s1)) +- *0* s1 + ⚠️ pattern without value + +s1#1663 = (???*0* | peg$parsecollection_primary_expression() | peg$c209(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1739 = (???*0* | peg$parsesubquery() | peg$c210(s1)) +- *0* s1 + ⚠️ pattern without value + +s1#1741 = (???*0* | peg$parseunsigned_integer() | peg$parseparameter_name() | peg$c211(s1)) +- *0* s1 + ⚠️ pattern without value + +s1#1744 = (???*0* | [] | peg$FAILED | peg$c212()) +- *0* s1 + ⚠️ pattern without value + +s1#1755 = (???*0* | peg$parsescalar_conditional_expression() | null | peg$c213(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#1784 = (???*0* | peg$c25 | peg$FAILED | peg$c214(s3)) +- *0* s1 + ⚠️ pattern without value + +s1#187 = ( + | ???*0* + | peg$c6 + | peg$FAILED + | peg$c8() + | peg$parseobject_property_list() + | peg$c9(s1) + | peg$parsevalue() + | peg$c10(s3) +) +- *0* s1 + ⚠️ pattern without value + +s1#201 = (???*0* | peg$parseobject_property() | peg$c14(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#229 = (???*0* | peg$parsefrom_source() | peg$c16(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#251 = ( + | ???*0* + | peg$parseidentifier() + | peg$c17(s1, s5) + | peg$parsecollection_expression() + | peg$c19(s1, s2) +) +- *0* s1 + ⚠️ pattern without value + +s1#282 = (???*0* | peg$parsescalar_conditional_expression() | peg$c20(s1)) +- *0* s1 + ⚠️ pattern without value + +s1#284 = (???*0* | peg$parsesort_expression() | peg$c21(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#312 = (???*0* | peg$parsescalar_conditional_expression() | peg$c22(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#323 = (???*0* | peg$parseudf() | peg$c29(s5, s9) | peg$parseidentifier() | peg$c30(s1, s5)) +- *0* s1 + ⚠️ pattern without value + +s1#376 = (???*0* | peg$c31 | peg$FAILED | peg$c35(s3, s4)) +- *0* s1 + ⚠️ pattern without value + +s1#419 = (???*0* | peg$c36 | peg$FAILED | peg$c40(s3)) +- *0* s1 + ⚠️ pattern without value + +s1#443 = (???*0* | peg$c41 | peg$FAILED | peg$c43()) +- *0* s1 + ⚠️ pattern without value + +s1#448 = (???*0* | peg$parsenull() | peg$c44()) +- *0* s1 + ⚠️ pattern without value + +s1#450 = (???*0* | peg$parsefalse() | peg$c45() | peg$parsetrue() | peg$c46()) +- *0* s1 + ⚠️ pattern without value + +s1#454 = (???*0* | peg$c47 | peg$FAILED | null | peg$c53(s2)) +- *0* s1 + ⚠️ pattern without value + +s1#497 = (???*0* | peg$c54 | peg$FAILED | peg$c56(s2) | peg$c57) +- *0* s1 + ⚠️ pattern without value + +s1#525 = (???*0* | peg$c36 | peg$FAILED | peg$c59(s3, s4)) +- *0* s1 + ⚠️ pattern without value + +s1#567 = (???*0* | peg$c31 | peg$FAILED | peg$c60(s3, s4)) +- *0* s1 + ⚠️ pattern without value + +s1#609 = (???*0* | peg$parsewhitespace() | peg$parsecomment()) +- *0* s1 + ⚠️ pattern without value + +s1#617 = (???*0* | peg$c63 | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#644 = (???*0* | input["substr"](peg$currPos, 6) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#654 = (???*0* | input["substr"](peg$currPos, 3) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#664 = (???*0* | input["substr"](peg$currPos, 4) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#674 = (???*0* | input["substr"](peg$currPos, 5) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#684 = (???*0* | input["substr"](peg$currPos, 5) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#694 = (???*0* | input["substr"](peg$currPos, 2) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#704 = (???*0* | input["substr"](peg$currPos, 2) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#714 = (???*0* | input["substr"](peg$currPos, 4) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#724 = (???*0* | input["substr"](peg$currPos, 2) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#734 = (???*0* | input["substr"](peg$currPos, 5) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#744 = (???*0* | input["substr"](peg$currPos, 3) | peg$FAILED | peg$c89()) +- *0* s1 + ⚠️ pattern without value + +s1#754 = (???*0* | input["substr"](peg$currPos, 4) | peg$FAILED | peg$c92()) +- *0* s1 + ⚠️ pattern without value + +s1#764 = (???*0* | input["substr"](peg$currPos, 3) | peg$FAILED | peg$c95()) +- *0* s1 + ⚠️ pattern without value + +s1#774 = (???*0* | input["substr"](peg$currPos, 2) | peg$FAILED | peg$c98()) +- *0* s1 + ⚠️ pattern without value + +s1#784 = (???*0* | input["substr"](peg$currPos, 3) | peg$FAILED | peg$c101()) +- *0* s1 + ⚠️ pattern without value + +s1#794 = (???*0* | input["substr"](peg$currPos, 7) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#804 = (???*0* | input["substr"](peg$currPos, 6) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#814 = (???*0* | input["substr"](peg$currPos, 5) | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#824 = (???*0* | peg$c108 | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#834 = (???*0* | peg$c110 | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#844 = (???*0* | peg$c112 | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#854 = (???*0* | peg$c114 | peg$FAILED | [s1, s2]) +- *0* s1 + ⚠️ pattern without value + +s1#886 = (???*0* | peg$currPos | ???*1* | peg$FAILED | peg$c116(s2)) +- *0* s1 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s1#897 = (???*0* | peg$parseidentifier_start() | peg$c121(s1, s2)) +- *0* s1 + ⚠️ pattern without value + +s1#909 = (???*0* | peg$c122 | peg$FAILED | peg$c124()) +- *0* s1 + ⚠️ pattern without value + +s1#930 = (???*0* | peg$currPos | ???*1* | peg$FAILED | peg$c131() | peg$c129 | peg$c132(s2)) +- *0* s1 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s1#952 = (???*0* | peg$currPos | ???*1* | peg$FAILED | peg$c131() | peg$c129 | peg$c132(s2)) +- *0* s1 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s1#982 = ( + | ???*0* + | peg$c134 + | peg$FAILED + | peg$c136() + | peg$c137 + | peg$c139() + | peg$c140 + | peg$c142() + | peg$c143 + | peg$c145() + | peg$c146 + | peg$c148() +) +- *0* s1 + ⚠️ pattern without value + +s10#132 = ( + | ???*0* + | peg$parsefrom_specification() + | peg$parsewhere() + | peg$c3(s3, s5, s7, s12) + | peg$parse_() +) +- *0* s10 + ⚠️ pattern without value + +s10#323 = (???*0* | peg$parse_()) +- *0* s10 + ⚠️ pattern without value + +s11#132 = (???*0* | peg$parse_() | peg$currPos | s12 | peg$FAILED | null) +- *0* s11 + ⚠️ pattern without value + +s11#323 = (???*0* | peg$c27 | peg$FAILED) +- *0* s11 + ⚠️ pattern without value + +s12 = (???*0* | peg$parsefilter_condition() | peg$parseorder() | peg$c4(s3, s5, s7, s9, s16)) +- *0* s12 + ⚠️ pattern without value + +s13 = (???*0* | peg$parse_()) +- *0* s13 + ⚠️ pattern without value + +s14 = (???*0* | peg$parseby()) +- *0* s14 + ⚠️ pattern without value + +s15 = (???*0* | peg$parse_()) +- *0* s15 + ⚠️ pattern without value + +s16 = (???*0* | peg$parsesort_specification()) +- *0* s16 + ⚠️ pattern without value + +s2#1019 = (???*0* | peg$parseescape_character() | peg$parsesource_character()) +- *0* s2 + ⚠️ pattern without value + +s2#1031 = (???*0* | peg$currPos | input["substring"](s2, peg$currPos) | s3) +- *0* s2 + ⚠️ pattern without value + +s2#1053 = (???*0* | peg$currPos | s3 | peg$FAILED | null) +- *0* s2 + ⚠️ pattern without value + +s2#1070 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1096 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1103 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1112 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1186 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1195 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1221 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#125 = (???*0* | peg$parseselect_query()) +- *0* s2 + ⚠️ pattern without value + +s2#1251 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1273 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1317 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#132 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1369 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1395 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1415 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1443 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1471 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1499 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1543 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1587 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1631 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1646 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#1663 = (???*0* | [] | peg$FAILED) +- *0* s2 + ⚠️ pattern without value + +s2#1744 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED) +- *0* s2 + ⚠️ pattern without value + +s2#1755 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1784 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#187 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#201 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#229 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#251 = (???*0* | peg$parse_() | peg$currPos | s3 | peg$FAILED | null) +- *0* s2 + ⚠️ pattern without value + +s2#284 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#312 = (???*0* | peg$currPos | s3 | peg$FAILED | null) +- *0* s2 + ⚠️ pattern without value + +s2#323 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#376 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#419 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#454 = (???*0* | peg$c49 | peg$FAILED | null) +- *0* s2 + ⚠️ pattern without value + +s2#497 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#525 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#567 = (???*0* | peg$parse_()) +- *0* s2 + ⚠️ pattern without value + +s2#617 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#644 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#654 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#664 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#674 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#684 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#694 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#704 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#714 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#724 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#734 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#744 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#754 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#764 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#774 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#784 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#794 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#804 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#814 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#824 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#834 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#844 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#854 = (???*0* | peg$currPos | ???*1* | peg$FAILED) +- *0* s2 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s2#886 = (???*0* | peg$parsereserved() | peg$parseidentifier_name()) +- *0* s2 + ⚠️ pattern without value + +s2#897 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#909 = (???*0* | peg$parseidentifier_name()) +- *0* s2 + ⚠️ pattern without value + +s2#930 = ( + | ???*0* + | peg$c54 + | peg$FAILED + | peg$c129 + | peg$parsesource_character() + | peg$parseescape_sequence() +) +- *0* s2 + ⚠️ pattern without value + +s2#952 = ( + | ???*0* + | peg$c57 + | peg$FAILED + | peg$c129 + | peg$parsesource_character() + | peg$parseescape_sequence() +) +- *0* s2 + ⚠️ pattern without value + +s3#1031 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1053 = (???*0* | peg$currPos | s4 | peg$FAILED | null | peg$c155(s1, s5)) +- *0* s3 + ⚠️ pattern without value + +s3#1070 = (???*0* | peg$parsescalar_conditional_expression()) +- *0* s3 + ⚠️ pattern without value + +s3#1096 = (???*0* | peg$parsesubquery()) +- *0* s3 + ⚠️ pattern without value + +s3#1103 = (???*0* | peg$parsesubquery()) +- *0* s3 + ⚠️ pattern without value + +s3#1112 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1186 = (???*0* | peg$parsescalar_unary_expression()) +- *0* s3 + ⚠️ pattern without value + +s3#1195 = (???*0* | peg$c165 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1221 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#125 = (???*0* | peg$parse_()) +- *0* s3 + ⚠️ pattern without value + +s3#1251 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1273 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1317 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#132 = (???*0* | peg$currPos | s4 | peg$FAILED | null) +- *0* s3 + ⚠️ pattern without value + +s3#1369 = (???*0* | peg$parsein()) +- *0* s3 + ⚠️ pattern without value + +s3#1395 = (???*0* | peg$parsebetween()) +- *0* s3 + ⚠️ pattern without value + +s3#1415 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1443 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1471 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1499 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1543 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1587 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1631 = (???*0* | peg$c167 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1646 = (???*0* | peg$c167 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1663 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1755 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#1784 = (???*0* | peg$parseselect_query()) +- *0* s3 + ⚠️ pattern without value + +s3#187 = (???*0* | peg$parsescalar_conditional_expression()) +- *0* s3 + ⚠️ pattern without value + +s3#201 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#229 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#251 = (???*0* | peg$parsein() | peg$currPos | s4 | peg$FAILED | null | peg$c18(s1, s5)) +- *0* s3 + ⚠️ pattern without value + +s3#284 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#312 = (???*0* | peg$parse_() | peg$c18(s1, s4)) +- *0* s3 + ⚠️ pattern without value + +s3#323 = (???*0* | peg$c23 | peg$FAILED | peg$c25) +- *0* s3 + ⚠️ pattern without value + +s3#376 = (???*0* | peg$parsescalar_object_element_property() | null) +- *0* s3 + ⚠️ pattern without value + +s3#419 = (???*0* | peg$parsescalar_expression_list()) +- *0* s3 + ⚠️ pattern without value + +s3#454 = (???*0* | [] | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#497 = ( + | ???*0* + | peg$parsedouble_string_character() + | peg$c54 + | peg$FAILED + | peg$parsesingle_string_character() + | peg$c57 +) +- *0* s3 + ⚠️ pattern without value + +s3#525 = (???*0* | peg$parseconstant()) +- *0* s3 + ⚠️ pattern without value + +s3#567 = (???*0* | peg$parseobject_constant_property()) +- *0* s3 + ⚠️ pattern without value + +s3#617 = (???*0* | peg$currPos | s4 | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s3#644 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#654 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#664 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#674 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#684 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#694 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#704 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#714 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#724 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#734 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#744 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#754 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#764 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#774 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#784 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#794 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#804 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#814 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#824 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#834 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#844 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#854 = (???*0* | peg$parseidentifier_start()) +- *0* s3 + ⚠️ pattern without value + +s3#897 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED) +- *0* s3 + ⚠️ pattern without value + +s4#1031 = (???*0* | peg$parsehex_digit() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1053 = (???*0* | peg$parse_() | [s4, s5]) +- *0* s4 + ⚠️ pattern without value + +s4#1070 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#1112 = (???*0* | peg$parse_() | peg$c161(s1, s7) | peg$c162(s1, s7)) +- *0* s4 + ⚠️ pattern without value + +s4#1195 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#1221 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1251 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1273 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1317 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#132 = (???*0* | peg$parsetop() | peg$c1(s6) | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#1369 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#1395 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#1415 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1443 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1471 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1499 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1543 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1587 = (???*0* | peg$parse_() | [s4, s5, s6, s7]) +- *0* s4 + ⚠️ pattern without value + +s4#1631 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#1646 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#1663 = (???*0* | peg$parse_() | peg$c161(s1, s7) | peg$c162(s1, s7)) +- *0* s4 + ⚠️ pattern without value + +s4#1755 = (???*0* | peg$parse_() | peg$c13(s1, s7)) +- *0* s4 + ⚠️ pattern without value + +s4#1784 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#201 = (???*0* | peg$parse_() | peg$c13(s1, s7)) +- *0* s4 + ⚠️ pattern without value + +s4#229 = (???*0* | peg$parse_() | peg$c15(s1, s7)) +- *0* s4 + ⚠️ pattern without value + +s4#251 = (???*0* | peg$parse_() | [s4, s5]) +- *0* s4 + ⚠️ pattern without value + +s4#284 = (???*0* | peg$parse_() | peg$c13(s1, s7)) +- *0* s4 + ⚠️ pattern without value + +s4#312 = (???*0* | peg$parseasc() | peg$parsedesc()) +- *0* s4 + ⚠️ pattern without value + +s4#323 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#376 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#419 = (???*0* | peg$parse_()) +- *0* s4 + ⚠️ pattern without value + +s4#454 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED | peg$currPos | s5 | null) +- *0* s4 + ⚠️ pattern without value + +s4#525 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#567 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#617 = (???*0* | peg$currPos | ???*1* | peg$FAILED | [s4, s5]) +- *0* s4 + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +s5#1031 = (???*0* | peg$parsehex_digit()) +- *0* s5 + ⚠️ pattern without value + +s5#1053 = (???*0* | peg$parseas() | peg$parseidentifier()) +- *0* s5 + ⚠️ pattern without value + +s5#1070 = (???*0* | peg$c27 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#1112 = (???*0* | peg$c23 | peg$FAILED | peg$c36) +- *0* s5 + ⚠️ pattern without value + +s5#1195 = (???*0* | peg$parsescalar_conditional_expression()) +- *0* s5 + ⚠️ pattern without value + +s5#1221 = (???*0* | peg$parseor() | peg$c170 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#1251 = (???*0* | peg$parseand()) +- *0* s5 + ⚠️ pattern without value + +s5#1273 = (???*0* | peg$c173 | peg$FAILED | peg$c175 | peg$c177) +- *0* s5 + ⚠️ pattern without value + +s5#1317 = (???*0* | peg$c179 | peg$FAILED | peg$c181 | peg$c183 | peg$c185) +- *0* s5 + ⚠️ pattern without value + +s5#132 = (???*0* | peg$parse_() | peg$parseselect_specification()) +- *0* s5 + ⚠️ pattern without value + +s5#1369 = (???*0* | peg$c25 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#1395 = (???*0* | peg$parsescalar_binary_bitwise_or_expression()) +- *0* s5 + ⚠️ pattern without value + +s5#1415 = (???*0* | peg$c189 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#1443 = (???*0* | peg$c191 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#1471 = (???*0* | peg$c193 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#1499 = (???*0* | peg$c195 | peg$FAILED | peg$c197 | peg$c199) +- *0* s5 + ⚠️ pattern without value + +s5#1543 = (???*0* | peg$c125 | peg$FAILED | peg$c47 | peg$c201) +- *0* s5 + ⚠️ pattern without value + +s5#1587 = (???*0* | peg$c6 | peg$FAILED | peg$c203 | peg$c205) +- *0* s5 + ⚠️ pattern without value + +s5#1631 = (???*0* | peg$parsescalar_conditional_expression()) +- *0* s5 + ⚠️ pattern without value + +s5#1646 = (???*0* | peg$parseconstant()) +- *0* s5 + ⚠️ pattern without value + +s5#1663 = (???*0* | peg$c23 | peg$FAILED | peg$c36) +- *0* s5 + ⚠️ pattern without value + +s5#1755 = (???*0* | peg$c11 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#1784 = (???*0* | peg$c27 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#201 = (???*0* | peg$c11 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#229 = (???*0* | peg$parsejoin()) +- *0* s5 + ⚠️ pattern without value + +s5#251 = (???*0* | peg$parsecollection_expression() | peg$parseas() | peg$parseidentifier()) +- *0* s5 + ⚠️ pattern without value + +s5#284 = (???*0* | peg$c11 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#323 = (???*0* | peg$parseidentifier() | peg$parsescalar_expression_list()) +- *0* s5 + ⚠️ pattern without value + +s5#376 = (???*0* | peg$currPos | s6 | peg$FAILED | peg$parse_()) +- *0* s5 + ⚠️ pattern without value + +s5#419 = (???*0* | peg$c38 | peg$FAILED) +- *0* s5 + ⚠️ pattern without value + +s5#454 = (???*0* | peg$c23 | peg$FAILED | [s5, s6]) +- *0* s5 + ⚠️ pattern without value + +s5#525 = (???*0* | peg$currPos | s6 | peg$FAILED | peg$parse_()) +- *0* s5 + ⚠️ pattern without value + +s5#567 = (???*0* | peg$currPos | s6 | peg$FAILED | peg$parse_()) +- *0* s5 + ⚠️ pattern without value + +s5#617 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED | peg$parsesource_character()) +- *0* s5 + ⚠️ pattern without value + +s6#1031 = (???*0* | peg$parsehex_digit()) +- *0* s6 + ⚠️ pattern without value + +s6#1112 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1195 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1221 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1251 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1273 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1317 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#132 = (???*0* | peg$parsetop_specification() | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1369 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1395 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1415 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1443 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1471 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1499 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1543 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1587 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1663 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#1755 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#201 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#229 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#284 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#323 = (???*0* | peg$parse_()) +- *0* s6 + ⚠️ pattern without value + +s6#376 = (???*0* | peg$parse_() | peg$c13(s3, s9) | peg$c33 | peg$FAILED) +- *0* s6 + ⚠️ pattern without value + +s6#454 = (???*0* | [] | peg$FAILED) +- *0* s6 + ⚠️ pattern without value + +s6#525 = (???*0* | peg$parse_() | peg$c13(s3, s9) | peg$c38 | peg$FAILED) +- *0* s6 + ⚠️ pattern without value + +s6#567 = (???*0* | peg$parse_() | peg$c13(s3, s9) | peg$c33 | peg$FAILED) +- *0* s6 + ⚠️ pattern without value + +s7#1031 = (???*0* | peg$parsehex_digit()) +- *0* s7 + ⚠️ pattern without value + +s7#1112 = ( + | ???*0* + | peg$parseidentifier() + | peg$parsestring_constant() + | peg$parseunsigned_integer() + | peg$parseparameter_name() +) +- *0* s7 + ⚠️ pattern without value + +s7#1195 = (???*0* | peg$c167 | peg$FAILED) +- *0* s7 + ⚠️ pattern without value + +s7#1221 = (???*0* | peg$parsescalar_binary_and_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1251 = (???*0* | peg$parsescalar_binary_equality_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1273 = (???*0* | peg$parsescalar_binary_relational_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1317 = (???*0* | peg$parsescalar_in_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#132 = (???*0* | peg$currPos | s8 | peg$FAILED | null) +- *0* s7 + ⚠️ pattern without value + +s7#1369 = (???*0* | peg$parsescalar_expression_list()) +- *0* s7 + ⚠️ pattern without value + +s7#1395 = (???*0* | peg$parseand()) +- *0* s7 + ⚠️ pattern without value + +s7#1415 = (???*0* | peg$parsescalar_binary_bitwise_xor_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1443 = (???*0* | peg$parsescalar_binary_bitwise_and_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1471 = (???*0* | peg$parsescalar_binary_shift_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1499 = (???*0* | peg$parsescalar_binary_additive_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1543 = (???*0* | peg$parsescalar_binary_multiplicative_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1587 = (???*0* | peg$parsescalar_unary_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#1663 = ( + | ???*0* + | peg$parseidentifier() + | peg$parsestring_constant() + | peg$parseunsigned_integer() + | peg$parseparameter_name() +) +- *0* s7 + ⚠️ pattern without value + +s7#1755 = (???*0* | peg$parsescalar_conditional_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#201 = (???*0* | peg$parseobject_property()) +- *0* s7 + ⚠️ pattern without value + +s7#229 = (???*0* | peg$parsefrom_source()) +- *0* s7 + ⚠️ pattern without value + +s7#284 = (???*0* | peg$parsesort_expression()) +- *0* s7 + ⚠️ pattern without value + +s7#323 = (???*0* | peg$c25 | peg$FAILED | peg$c27) +- *0* s7 + ⚠️ pattern without value + +s7#376 = (???*0* | peg$c11 | peg$FAILED) +- *0* s7 + ⚠️ pattern without value + +s7#454 = (???*0* | input["charAt"](peg$currPos) | peg$FAILED) +- *0* s7 + ⚠️ pattern without value + +s7#525 = (???*0* | peg$c11 | peg$FAILED) +- *0* s7 + ⚠️ pattern without value + +s7#567 = (???*0* | peg$c11 | peg$FAILED) +- *0* s7 + ⚠️ pattern without value + +s8#1112 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#1195 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#132 = (???*0* | peg$parsefrom() | peg$c2(s3, s5, s10) | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#1369 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#1395 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#1663 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#323 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#376 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#525 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s8#567 = (???*0* | peg$parse_()) +- *0* s8 + ⚠️ pattern without value + +s9#1112 = (???*0* | peg$c38 | peg$FAILED) +- *0* s9 + ⚠️ pattern without value + +s9#1195 = (???*0* | peg$parsescalar_conditional_expression()) +- *0* s9 + ⚠️ pattern without value + +s9#132 = (???*0* | peg$parse_() | peg$currPos | s10 | peg$FAILED | null) +- *0* s9 + ⚠️ pattern without value + +s9#1369 = (???*0* | peg$c27 | peg$FAILED) +- *0* s9 + ⚠️ pattern without value + +s9#1395 = (???*0* | peg$parsescalar_binary_bitwise_or_expression()) +- *0* s9 + ⚠️ pattern without value + +s9#1663 = (???*0* | peg$c38 | peg$FAILED) +- *0* s9 + ⚠️ pattern without value + +s9#323 = (???*0* | peg$parsescalar_expression_list()) +- *0* s9 + ⚠️ pattern without value + +s9#376 = (???*0* | peg$parsescalar_object_element_property()) +- *0* s9 + ⚠️ pattern without value + +s9#525 = (???*0* | peg$parseconstant()) +- *0* s9 + ⚠️ pattern without value + +s9#567 = (???*0* | peg$parseobject_constant_property()) +- *0* s9 + ⚠️ pattern without value + +select#31 = arguments[1] + +select#32 = arguments[1] + +select#33 = arguments[1] + +select#34 = arguments[1] + +seq = arguments[0] + +source#40 = arguments[0] + +source#41 = arguments[0] + +startPos = arguments[0] + +startPosDetails = peg$computePosDetails(startPos) + +subquery = arguments[0] + +tail#1801 = arguments[1] + +tail#39 = arguments[1] + +tail#46 = arguments[1] + +tail#50 = arguments[1] + +tail#58 = arguments[1] + +tail#59 = arguments[1] + +tail#66 = arguments[1] + +tail#85 = arguments[1] + +tail#89 = arguments[1] + +tail#94 = arguments[1] + +tail#99 = arguments[1] + +test = arguments[0] + +text#107 = arguments[0] + +text#28 = (...) => input["substring"](peg$savedPos, peg$currPos) + +top#31 = arguments[0] + +top#32 = arguments[0] + +top#33 = arguments[0] + +top#34 = arguments[0] + +v#30 = arguments[0] + +v#31 = arguments[2] + +v#32 = arguments[3] + +v#33 = arguments[4] + +v#38 = arguments[1] + +v#40 = arguments[1] + +v#43 = arguments[1] + +v#77 = arguments[1] + +value#37 = arguments[0] + +value#90 = arguments[0] + +value#91 = arguments[0] + +value#92 = arguments[1] + +value#97 = arguments[0] + +where#33 = arguments[3] + +where#34 = arguments[3] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/input.js new file mode 100644 index 0000000000000..1520858e58020 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/input.js @@ -0,0 +1,6734 @@ +/* + * Generated by PEG.js 0.10.0. + * + * http://pegjs.org/ + */ + +"use strict"; + +function peg$subclass(child, parent) { + function ctor() { + this.constructor = child; + } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); +} + +function peg$SyntaxError(message, expected, found, location) { + this.message = message; + this.expected = expected; + this.found = found; + this.location = location; + this.name = "SyntaxError"; + + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, peg$SyntaxError); + } +} + +peg$subclass(peg$SyntaxError, Error); + +peg$SyntaxError.buildMessage = function (expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function (expectation) { + return '"' + literalEscape(expectation.text) + '"'; + }, + + class: function (expectation) { + var escapedParts = "", + i; + + for (i = 0; i < expectation.parts.length; i++) { + escapedParts += + expectation.parts[i] instanceof Array + ? classEscape(expectation.parts[i][0]) + + "-" + + classEscape(expectation.parts[i][1]) + : classEscape(expectation.parts[i]); + } + + return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; + }, + + any: function (expectation) { + return "any character"; + }, + + end: function (expectation) { + return "end of input"; + }, + + other: function (expectation) { + return expectation.description; + }, + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/"/g, '\\"') + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function (ch) { + return "\\x0" + hex(ch); + }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) { + return "\\x" + hex(ch); + }); + } + + function classEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/\]/g, "\\]") + .replace(/\^/g, "\\^") + .replace(/-/g, "\\-") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function (ch) { + return "\\x0" + hex(ch); + }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) { + return "\\x" + hex(ch); + }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = new Array(expected.length), + i, + j; + + for (i = 0; i < expected.length; i++) { + descriptions[i] = describeExpectation(expected[i]); + } + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return ( + descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1] + ); + } + } + + function describeFound(found) { + return found ? '"' + literalEscape(found) + '"' : "end of input"; + } + + return ( + "Expected " + + describeExpected(expected) + + " but " + + describeFound(found) + + " found." + ); +}; + +function peg$parse(input, options) { + options = options !== void 0 ? options : {}; + + var peg$FAILED = {}, + peg$startRuleFunctions = { sql: peg$parsesql }, + peg$startRuleFunction = peg$parsesql, + peg$c0 = function (body) { + return { + type: "sql", + body, + }; + }, + peg$c1 = function (v) { + return v; + }, + peg$c2 = function (top, select, v) { + return v; + }, + peg$c3 = function (top, select, from, v) { + return v; + }, + peg$c4 = function (top, select, from, where, v) { + return v; + }, + peg$c5 = function (top, select, from, where, orderBy) { + return { + type: "select_query", + top, + select, + from, + where, + orderBy, + }; + }, + peg$c6 = "*", + peg$c7 = peg$literalExpectation("*", false), + peg$c8 = function () { + return { + type: "select_specification", + "*": true, + }; + }, + peg$c9 = function (properties) { + return { + type: "select_specification", + properties, + }; + }, + peg$c10 = function (value) { + return { + type: "select_specification", + value, + }; + }, + peg$c11 = ",", + peg$c12 = peg$literalExpectation(",", false), + peg$c13 = function (head, v) { + return v; + }, + peg$c14 = function (head, tail) { + return { + type: "object_property_list", + properties: [head, ...tail], + }; + }, + peg$c15 = function (source, v) { + return v; + }, + peg$c16 = function (source, joins) { + return { + type: "from_specification", + source, + joins, + }; + }, + peg$c17 = function (alias, expression) { + return { + type: "from_source", + expression, + alias, + iteration: true, + }; + }, + peg$c18 = function (expression, v) { + return v; + }, + peg$c19 = function (expression, alias) { + return { + type: "from_source", + expression, + alias, + }; + }, + peg$c20 = function (condition) { + return { + type: "filter_condition", + condition, + }; + }, + peg$c21 = function (head, tail) { + return { + type: "sort_specification", + expressions: [head, ...tail], + }; + }, + peg$c22 = function (expression, order) { + return { + type: "sort_expression", + expression, + order, + }; + }, + peg$c23 = ".", + peg$c24 = peg$literalExpectation(".", false), + peg$c25 = "(", + peg$c26 = peg$literalExpectation("(", false), + peg$c27 = ")", + peg$c28 = peg$literalExpectation(")", false), + peg$c29 = function (name, args) { + return { + type: "scalar_function_expression", + name, + arguments: args, + udf: true, + }; + }, + peg$c30 = function (name, args) { + return { + type: "scalar_function_expression", + name, + arguments: args, + }; + }, + peg$c31 = "{", + peg$c32 = peg$literalExpectation("{", false), + peg$c33 = "}", + peg$c34 = peg$literalExpectation("}", false), + peg$c35 = function (head, tail) { + return { + type: "scalar_object_expression", + properties: head ? [head, ...tail] : [], + }; + }, + peg$c36 = "[", + peg$c37 = peg$literalExpectation("[", false), + peg$c38 = "]", + peg$c39 = peg$literalExpectation("]", false), + peg$c40 = function (elements) { + return { + type: "scalar_array_expression", + elements, + }; + }, + peg$c41 = "undefined", + peg$c42 = peg$literalExpectation("undefined", false), + peg$c43 = function () { + return { type: "undefined_constant" }; + }, + peg$c44 = function () { + return { type: "null_constant" }; + }, + peg$c45 = function () { + return { + type: "boolean_constant", + value: false, + }; + }, + peg$c46 = function () { + return { + type: "boolean_constant", + value: true, + }; + }, + peg$c47 = "-", + peg$c48 = peg$literalExpectation("-", false), + peg$c49 = "0x", + peg$c50 = peg$literalExpectation("0x", false), + peg$c51 = /^[0-9]/, + peg$c52 = peg$classExpectation([["0", "9"]], false, false), + peg$c53 = function (hex) { + return { + type: "number_constant", + // FIXME: support hex with float? + value: hex ? parseInt(text(), 16) : parseFloat(text()), + }; + }, + peg$c54 = '"', + peg$c55 = peg$literalExpectation('"', false), + peg$c56 = function (chars) { + return { + type: "string_constant", + value: chars.join(""), + }; + }, + peg$c57 = "'", + peg$c58 = peg$literalExpectation("'", false), + peg$c59 = function (head, tail) { + return { + type: "array_constant", + elements: [head, ...tail], + }; + }, + peg$c60 = function (head, tail) { + return { + type: "object_constant", + properties: [head, ...tail], + }; + }, + peg$c61 = /^[ \t\n\r]/, + peg$c62 = peg$classExpectation([" ", "\t", "\n", "\r"], false, false), + peg$c63 = "--", + peg$c64 = peg$literalExpectation("--", false), + peg$c65 = /^[\n\r]/, + peg$c66 = peg$classExpectation(["\n", "\r"], false, false), + peg$c67 = "select", + peg$c68 = peg$literalExpectation("SELECT", true), + peg$c69 = "top", + peg$c70 = peg$literalExpectation("TOP", true), + peg$c71 = "from", + peg$c72 = peg$literalExpectation("FROM", true), + peg$c73 = "where", + peg$c74 = peg$literalExpectation("WHERE", true), + peg$c75 = "order", + peg$c76 = peg$literalExpectation("ORDER", true), + peg$c77 = "by", + peg$c78 = peg$literalExpectation("BY", true), + peg$c79 = "as", + peg$c80 = peg$literalExpectation("AS", true), + peg$c81 = "join", + peg$c82 = peg$literalExpectation("JOIN", true), + peg$c83 = "in", + peg$c84 = peg$literalExpectation("IN", true), + peg$c85 = "value", + peg$c86 = peg$literalExpectation("VALUE", true), + peg$c87 = "asc", + peg$c88 = peg$literalExpectation("ASC", true), + peg$c89 = function () { + return "ASC"; + }, + peg$c90 = "desc", + peg$c91 = peg$literalExpectation("DESC", true), + peg$c92 = function () { + return "DESC"; + }, + peg$c93 = "and", + peg$c94 = peg$literalExpectation("AND", true), + peg$c95 = function () { + return "AND"; + }, + peg$c96 = "or", + peg$c97 = peg$literalExpectation("OR", true), + peg$c98 = function () { + return "OR"; + }, + peg$c99 = "not", + peg$c100 = peg$literalExpectation("NOT", true), + peg$c101 = function () { + return "NOT"; + }, + peg$c102 = "between", + peg$c103 = peg$literalExpectation("BETWEEN", true), + peg$c104 = "exists", + peg$c105 = peg$literalExpectation("EXISTS", true), + peg$c106 = "array", + peg$c107 = peg$literalExpectation("ARRAY", true), + peg$c108 = "null", + peg$c109 = peg$literalExpectation("null", false), + peg$c110 = "true", + peg$c111 = peg$literalExpectation("true", false), + peg$c112 = "false", + peg$c113 = peg$literalExpectation("false", false), + peg$c114 = "udf", + peg$c115 = peg$literalExpectation("udf", false), + peg$c116 = function (name) { + return { + type: "identifier", + name, + }; + }, + peg$c117 = /^[a-zA-Z_]/, + peg$c118 = peg$classExpectation( + [["a", "z"], ["A", "Z"], "_"], + false, + false + ), + peg$c119 = /^[a-zA-Z0-9_]/, + peg$c120 = peg$classExpectation( + [["a", "z"], ["A", "Z"], ["0", "9"], "_"], + false, + false + ), + peg$c121 = function (head, tail) { + return head + tail.join(""); + }, + peg$c122 = "@", + peg$c123 = peg$literalExpectation("@", false), + peg$c124 = function () { + return { + type: "parameter_name", + name: text(), + }; + }, + peg$c125 = "+", + peg$c126 = peg$literalExpectation("+", false), + peg$c127 = "~", + peg$c128 = peg$literalExpectation("~", false), + peg$c129 = "\\", + peg$c130 = peg$literalExpectation("\\", false), + peg$c131 = function () { + return text(); + }, + peg$c132 = function (seq) { + return seq; + }, + peg$c133 = peg$anyExpectation(), + peg$c134 = "b", + peg$c135 = peg$literalExpectation("b", false), + peg$c136 = function () { + return "\b"; + }, + peg$c137 = "f", + peg$c138 = peg$literalExpectation("f", false), + peg$c139 = function () { + return "\f"; + }, + peg$c140 = "n", + peg$c141 = peg$literalExpectation("n", false), + peg$c142 = function () { + return "\n"; + }, + peg$c143 = "r", + peg$c144 = peg$literalExpectation("r", false), + peg$c145 = function () { + return "\r"; + }, + peg$c146 = "t", + peg$c147 = peg$literalExpectation("t", false), + peg$c148 = function () { + return "\t"; + }, + peg$c149 = function () { + return text(); + }, + peg$c150 = "u", + peg$c151 = peg$literalExpectation("u", false), + peg$c152 = function (digits) { + return String.fromCharCode(parseInt(digits, 16)); + }, + peg$c153 = /^[0-9a-f]/i, + peg$c154 = peg$classExpectation( + [ + ["0", "9"], + ["a", "f"], + ], + false, + true + ), + peg$c155 = function (property, v) { + return v; + }, + peg$c156 = function (property, alias) { + return { property, alias }; + }, + peg$c157 = function (expression) { + return expression; + }, + peg$c158 = function (expression) { + return { + type: "array_subquery_expression", + expression, + }; + }, + peg$c159 = function (expression) { + return { + type: "exists_subquery_expression", + expression, + }; + }, + peg$c160 = function (expression) { + return { + type: "scalar_subquery_expression", + expression, + }; + }, + peg$c161 = function (head, property) { + return { property, computed: false }; + }, + peg$c162 = function (head, property) { + return { property, computed: true }; + }, + peg$c163 = function (head, tail) { + return tail.reduce( + (object, { property, computed }) => ({ + type: "scalar_member_expression", + object, + property, + computed, + }), + head + ); + }, + peg$c164 = function (operator, argument) { + return { + type: "scalar_unary_expression", + operator, + argument, + }; + }, + peg$c165 = "?", + peg$c166 = peg$literalExpectation("?", false), + peg$c167 = ":", + peg$c168 = peg$literalExpectation(":", false), + peg$c169 = function (test, consequent, alternate) { + return { + type: "scalar_conditional_expression", + test, + consequent, + alternate, + }; + }, + peg$c170 = "??", + peg$c171 = peg$literalExpectation("??", false), + peg$c172 = function (head, tail) { + return buildBinaryExpression(head, tail); + }, + peg$c173 = "=", + peg$c174 = peg$literalExpectation("=", false), + peg$c175 = "!=", + peg$c176 = peg$literalExpectation("!=", false), + peg$c177 = "<>", + peg$c178 = peg$literalExpectation("<>", false), + peg$c179 = "<=", + peg$c180 = peg$literalExpectation("<=", false), + peg$c181 = ">=", + peg$c182 = peg$literalExpectation(">=", false), + peg$c183 = "<", + peg$c184 = peg$literalExpectation("<", false), + peg$c185 = ">", + peg$c186 = peg$literalExpectation(">", false), + peg$c187 = function (value, list) { + return { + type: "scalar_in_expression", + value, + list, + }; + }, + peg$c188 = function (value, begin, end) { + return { + type: "scalar_between_expression", + value, + begin, + end, + }; + }, + peg$c189 = "|", + peg$c190 = peg$literalExpectation("|", false), + peg$c191 = "^", + peg$c192 = peg$literalExpectation("^", false), + peg$c193 = "&", + peg$c194 = peg$literalExpectation("&", false), + peg$c195 = "<<", + peg$c196 = peg$literalExpectation("<<", false), + peg$c197 = ">>>", + peg$c198 = peg$literalExpectation(">>>", false), + peg$c199 = ">>", + peg$c200 = peg$literalExpectation(">>", false), + peg$c201 = "||", + peg$c202 = peg$literalExpectation("||", false), + peg$c203 = "/", + peg$c204 = peg$literalExpectation("/", false), + peg$c205 = "%", + peg$c206 = peg$literalExpectation("%", false), + peg$c207 = function (key, value) { + return { key, value }; + }, + peg$c208 = function (expression) { + return { + type: "collection_expression", + expression, + }; + }, + peg$c209 = function (head, tail) { + return tail.reduce( + (object, { property, computed }) => ({ + type: "collection_member_expression", + object, + property, + computed, + }), + head + ); + }, + peg$c210 = function (expression) { + return { + type: "collection_subquery_expression", + expression, + }; + }, + peg$c211 = function (value) { + return { + type: "top_specification", + value, + }; + }, + peg$c212 = function () { + return { + type: "number_constant", + value: Number(text()), + }; + }, + peg$c213 = function (head, tail) { + return head ? [head, ...tail] : []; + }, + peg$c214 = function (subquery) { + return subquery; + }, + peg$currPos = 0, + peg$savedPos = 0, + peg$posDetailsCache = [{ line: 1, column: 1 }], + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$silentFails = 0, + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error( + "Can't start parsing from rule \"" + options.startRule + '".' + ); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$savedPos, peg$currPos); + } + + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); + } + + function expected(description, location) { + location = + location !== void 0 + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildStructuredError( + [peg$otherExpectation(description)], + input.substring(peg$savedPos, peg$currPos), + location + ); + } + + function error(message, location) { + location = + location !== void 0 + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildSimpleError(message, location); + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { + type: "class", + parts: parts, + inverted: inverted, + ignoreCase: ignoreCase, + }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$otherExpectation(description) { + return { type: "other", description: description }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos], + p; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column, + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + return details; + } + } + + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos), + endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column, + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column, + }, + }; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { + return; + } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildSimpleError(message, location) { + return new peg$SyntaxError(message, null, null, location); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError( + peg$SyntaxError.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parsesql() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + s2 = peg$parseselect_query(); + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c0(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseselect_query() { + var s0, + s1, + s2, + s3, + s4, + s5, + s6, + s7, + s8, + s9, + s10, + s11, + s12, + s13, + s14, + s15, + s16; + + s0 = peg$currPos; + s1 = peg$parseselect(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parsetop(); + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parsetop_specification(); + if (s6 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c1(s6); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseselect_specification(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$currPos; + s8 = peg$parsefrom(); + if (s8 !== peg$FAILED) { + s9 = peg$parse_(); + if (s9 !== peg$FAILED) { + s10 = peg$parsefrom_specification(); + if (s10 !== peg$FAILED) { + peg$savedPos = s7; + s8 = peg$c2(s3, s5, s10); + s7 = s8; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$currPos; + s10 = peg$parsewhere(); + if (s10 !== peg$FAILED) { + s11 = peg$parse_(); + if (s11 !== peg$FAILED) { + s12 = peg$parsefilter_condition(); + if (s12 !== peg$FAILED) { + peg$savedPos = s9; + s10 = peg$c3(s3, s5, s7, s12); + s9 = s10; + } else { + peg$currPos = s9; + s9 = peg$FAILED; + } + } else { + peg$currPos = s9; + s9 = peg$FAILED; + } + } else { + peg$currPos = s9; + s9 = peg$FAILED; + } + if (s9 === peg$FAILED) { + s9 = null; + } + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + s11 = peg$currPos; + s12 = peg$parseorder(); + if (s12 !== peg$FAILED) { + s13 = peg$parse_(); + if (s13 !== peg$FAILED) { + s14 = peg$parseby(); + if (s14 !== peg$FAILED) { + s15 = peg$parse_(); + if (s15 !== peg$FAILED) { + s16 = peg$parsesort_specification(); + if (s16 !== peg$FAILED) { + peg$savedPos = s11; + s12 = peg$c4(s3, s5, s7, s9, s16); + s11 = s12; + } else { + peg$currPos = s11; + s11 = peg$FAILED; + } + } else { + peg$currPos = s11; + s11 = peg$FAILED; + } + } else { + peg$currPos = s11; + s11 = peg$FAILED; + } + } else { + peg$currPos = s11; + s11 = peg$FAILED; + } + } else { + peg$currPos = s11; + s11 = peg$FAILED; + } + if (s11 === peg$FAILED) { + s11 = null; + } + if (s11 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c5(s3, s5, s7, s9, s11); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseselect_specification() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 42) { + s1 = peg$c6; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c7); + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c8(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseobject_property_list(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c9(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsevalue(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsescalar_conditional_expression(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c10(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + + return s0; + } + + function peg$parseobject_property_list() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parseobject_property(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c11; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseobject_property(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c13(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c11; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseobject_property(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c13(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c14(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefrom_specification() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsefrom_source(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parsejoin(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsefrom_source(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c15(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parsejoin(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsefrom_source(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c15(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c16(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefrom_source() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parseidentifier(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsein(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parsecollection_expression(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c17(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsecollection_expression(); + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseas(); + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseidentifier(); + if (s5 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c18(s1, s5); + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c19(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + return s0; + } + + function peg$parsecollection_expression() { + var s0; + + s0 = peg$parsecollection_member_expression(); + if (s0 === peg$FAILED) { + s0 = peg$parsecollection_primary_expression(); + if (s0 === peg$FAILED) { + s0 = peg$parsecollection_subquery_expression(); + } + } + + return s0; + } + + function peg$parsefilter_condition() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parsescalar_conditional_expression(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c20(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsesort_specification() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsesort_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c11; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsesort_expression(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c13(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c11; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsesort_expression(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c13(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c21(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsesort_expression() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + s1 = peg$parsescalar_conditional_expression(); + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + s4 = peg$parseasc(); + if (s4 === peg$FAILED) { + s4 = peg$parsedesc(); + } + if (s4 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c18(s1, s4); + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c22(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_function_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11; + + s0 = peg$currPos; + s1 = peg$parseudf(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c23; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c24); + } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseidentifier(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 40) { + s7 = peg$c25; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c26); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parsescalar_expression_list(); + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s11 = peg$c27; + peg$currPos++; + } else { + s11 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c28); + } + } + if (s11 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c29(s5, s9); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseidentifier(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 40) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c26); + } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parsescalar_expression_list(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s7 = peg$c27; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c28); + } + } + if (s7 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c30(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + return s0; + } + + function peg$parsescalar_object_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 123) { + s1 = peg$c31; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c32); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsescalar_object_element_property(); + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = []; + s5 = peg$currPos; + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s7 = peg$c11; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parsescalar_object_element_property(); + if (s9 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c13(s3, s9); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$currPos; + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s7 = peg$c11; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parsescalar_object_element_property(); + if (s9 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c13(s3, s9); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 125) { + s6 = peg$c33; + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c34); + } + } + if (s6 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c35(s3, s4); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_array_expression() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c36; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c37); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsescalar_expression_list(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s5 = peg$c38; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c39); + } + } + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c40(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseconstant() { + var s0; + + s0 = peg$parseundefined_constant(); + if (s0 === peg$FAILED) { + s0 = peg$parsenull_constant(); + if (s0 === peg$FAILED) { + s0 = peg$parseboolean_constant(); + if (s0 === peg$FAILED) { + s0 = peg$parsenumber_constant(); + if (s0 === peg$FAILED) { + s0 = peg$parsestring_constant(); + if (s0 === peg$FAILED) { + s0 = peg$parsearray_constant(); + if (s0 === peg$FAILED) { + s0 = peg$parseobject_constant(); + } + } + } + } + } + } + + return s0; + } + + function peg$parseundefined_constant() { + var s0, s1; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 9) === peg$c41) { + s1 = peg$c41; + peg$currPos += 9; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c42); + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c43(); + } + s0 = s1; + + return s0; + } + + function peg$parsenull_constant() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parsenull(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c44(); + } + s0 = s1; + + return s0; + } + + function peg$parseboolean_constant() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parsefalse(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c45(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsetrue(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c46(); + } + s0 = s1; + } + + return s0; + } + + function peg$parsenumber_constant() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s1 = peg$c47; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c48); + } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c49) { + s2 = peg$c49; + peg$currPos += 2; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c50); + } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s3 = []; + if (peg$c51.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c52); + } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c51.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c52); + } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c23; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c24); + } + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c51.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c52); + } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c51.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c52); + } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c53(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsestring_constant() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c54; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c55); + } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parsedouble_string_character(); + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parsedouble_string_character(); + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c54; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c55); + } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c56(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c57; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c58); + } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parsesingle_string_character(); + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parsesingle_string_character(); + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c57; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c58); + } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c56(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + return s0; + } + + function peg$parsearray_constant() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c36; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c37); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseconstant(); + if (s3 !== peg$FAILED) { + s4 = []; + s5 = peg$currPos; + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s7 = peg$c11; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseconstant(); + if (s9 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c13(s3, s9); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$currPos; + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s7 = peg$c11; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseconstant(); + if (s9 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c13(s3, s9); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s6 = peg$c38; + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c39); + } + } + if (s6 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c59(s3, s4); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseobject_constant() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 123) { + s1 = peg$c31; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c32); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseobject_constant_property(); + if (s3 !== peg$FAILED) { + s4 = []; + s5 = peg$currPos; + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s7 = peg$c11; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseobject_constant_property(); + if (s9 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c13(s3, s9); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$currPos; + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s7 = peg$c11; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseobject_constant_property(); + if (s9 !== peg$FAILED) { + peg$savedPos = s5; + s6 = peg$c13(s3, s9); + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 125) { + s6 = peg$c33; + peg$currPos++; + } else { + s6 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c34); + } + } + if (s6 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c60(s3, s4); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parse_() { + var s0, s1; + + s0 = []; + s1 = peg$parsewhitespace(); + if (s1 === peg$FAILED) { + s1 = peg$parsecomment(); + } + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parsewhitespace(); + if (s1 === peg$FAILED) { + s1 = peg$parsecomment(); + } + } + + return s0; + } + + function peg$parsewhitespace() { + var s0; + + if (peg$c61.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c62); + } + } + + return s0; + } + + function peg$parsecomment() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c63) { + s1 = peg$c63; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c64); + } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$currPos; + peg$silentFails++; + if (peg$c65.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c66); + } + } + peg$silentFails--; + if (s5 === peg$FAILED) { + s4 = void 0; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s5 = peg$parsesource_character(); + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$currPos; + peg$silentFails++; + if (peg$c65.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c66); + } + } + peg$silentFails--; + if (s5 === peg$FAILED) { + s4 = void 0; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s5 = peg$parsesource_character(); + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseselect() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6).toLowerCase() === peg$c67) { + s1 = input.substr(peg$currPos, 6); + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c68); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsetop() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3).toLowerCase() === peg$c69) { + s1 = input.substr(peg$currPos, 3); + peg$currPos += 3; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c70); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefrom() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4).toLowerCase() === peg$c71) { + s1 = input.substr(peg$currPos, 4); + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c72); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsewhere() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 5).toLowerCase() === peg$c73) { + s1 = input.substr(peg$currPos, 5); + peg$currPos += 5; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c74); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseorder() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 5).toLowerCase() === peg$c75) { + s1 = input.substr(peg$currPos, 5); + peg$currPos += 5; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c76); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseby() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2).toLowerCase() === peg$c77) { + s1 = input.substr(peg$currPos, 2); + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c78); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseas() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2).toLowerCase() === peg$c79) { + s1 = input.substr(peg$currPos, 2); + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c80); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsejoin() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4).toLowerCase() === peg$c81) { + s1 = input.substr(peg$currPos, 4); + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c82); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsein() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2).toLowerCase() === peg$c83) { + s1 = input.substr(peg$currPos, 2); + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c84); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsevalue() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 5).toLowerCase() === peg$c85) { + s1 = input.substr(peg$currPos, 5); + peg$currPos += 5; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c86); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseasc() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3).toLowerCase() === peg$c87) { + s1 = input.substr(peg$currPos, 3); + peg$currPos += 3; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c88); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c89(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsedesc() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4).toLowerCase() === peg$c90) { + s1 = input.substr(peg$currPos, 4); + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c91); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c92(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseand() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3).toLowerCase() === peg$c93) { + s1 = input.substr(peg$currPos, 3); + peg$currPos += 3; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c94); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c95(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseor() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2).toLowerCase() === peg$c96) { + s1 = input.substr(peg$currPos, 2); + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c97); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c98(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsenot() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3).toLowerCase() === peg$c99) { + s1 = input.substr(peg$currPos, 3); + peg$currPos += 3; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c100); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c101(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsebetween() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 7).toLowerCase() === peg$c102) { + s1 = input.substr(peg$currPos, 7); + peg$currPos += 7; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c103); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseexists() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6).toLowerCase() === peg$c104) { + s1 = input.substr(peg$currPos, 6); + peg$currPos += 6; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c105); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsearray() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 5).toLowerCase() === peg$c106) { + s1 = input.substr(peg$currPos, 5); + peg$currPos += 5; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c107); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsenull() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c108) { + s1 = peg$c108; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c109); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsetrue() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c110) { + s1 = peg$c110; + peg$currPos += 4; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c111); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsefalse() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 5) === peg$c112) { + s1 = peg$c112; + peg$currPos += 5; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c113); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseudf() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c114) { + s1 = peg$c114; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c115); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + peg$silentFails++; + s3 = peg$parseidentifier_start(); + peg$silentFails--; + if (s3 === peg$FAILED) { + s2 = void 0; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsereserved() { + var s0; + + s0 = peg$parseselect(); + if (s0 === peg$FAILED) { + s0 = peg$parsetop(); + if (s0 === peg$FAILED) { + s0 = peg$parsefrom(); + if (s0 === peg$FAILED) { + s0 = peg$parsewhere(); + if (s0 === peg$FAILED) { + s0 = peg$parseorder(); + if (s0 === peg$FAILED) { + s0 = peg$parseby(); + if (s0 === peg$FAILED) { + s0 = peg$parseas(); + if (s0 === peg$FAILED) { + s0 = peg$parsejoin(); + if (s0 === peg$FAILED) { + s0 = peg$parsein(); + if (s0 === peg$FAILED) { + s0 = peg$parsevalue(); + if (s0 === peg$FAILED) { + s0 = peg$parseasc(); + if (s0 === peg$FAILED) { + s0 = peg$parsedesc(); + if (s0 === peg$FAILED) { + s0 = peg$parseand(); + if (s0 === peg$FAILED) { + s0 = peg$parseor(); + if (s0 === peg$FAILED) { + s0 = peg$parsenot(); + if (s0 === peg$FAILED) { + s0 = peg$parsebetween(); + if (s0 === peg$FAILED) { + s0 = peg$parseexists(); + if (s0 === peg$FAILED) { + s0 = peg$parsearray(); + if (s0 === peg$FAILED) { + s0 = peg$parsenull(); + if (s0 === peg$FAILED) { + s0 = peg$parsetrue(); + if (s0 === peg$FAILED) { + s0 = peg$parsefalse(); + if (s0 === peg$FAILED) { + s0 = peg$parseudf(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parseidentifier() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + s2 = peg$parsereserved(); + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseidentifier_name(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c116(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseidentifier_start() { + var s0; + + if (peg$c117.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c118); + } + } + + return s0; + } + + function peg$parseidentifier_name() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parseidentifier_start(); + if (s1 !== peg$FAILED) { + s2 = []; + if (peg$c119.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c120); + } + } + while (s3 !== peg$FAILED) { + s2.push(s3); + if (peg$c119.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c120); + } + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c121(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseparameter_name() { + var s0, s1, s2; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 64) { + s1 = peg$c122; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c123); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseidentifier_name(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c124(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseunary_operator() { + var s0; + + if (input.charCodeAt(peg$currPos) === 43) { + s0 = peg$c125; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c126); + } + } + if (s0 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s0 = peg$c47; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c48); + } + } + if (s0 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 126) { + s0 = peg$c127; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c128); + } + } + if (s0 === peg$FAILED) { + s0 = peg$parsenot(); + } + } + } + + return s0; + } + + function peg$parsedouble_string_character() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + if (input.charCodeAt(peg$currPos) === 34) { + s2 = peg$c54; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c55); + } + } + if (s2 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 92) { + s2 = peg$c129; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c130); + } + } + } + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s2 = peg$parsesource_character(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c131(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s1 = peg$c129; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c130); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseescape_sequence(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c132(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + return s0; + } + + function peg$parsesingle_string_character() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + if (input.charCodeAt(peg$currPos) === 39) { + s2 = peg$c57; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c58); + } + } + if (s2 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 92) { + s2 = peg$c129; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c130); + } + } + } + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s2 = peg$parsesource_character(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c131(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s1 = peg$c129; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c130); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseescape_sequence(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c132(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + return s0; + } + + function peg$parsesource_character() { + var s0; + + if (input.length > peg$currPos) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c133); + } + } + + return s0; + } + + function peg$parseescape_sequence() { + var s0; + + s0 = peg$parsecharactor_escape_sequence(); + if (s0 === peg$FAILED) { + s0 = peg$parseunicode_escape_sequence(); + } + + return s0; + } + + function peg$parsecharactor_escape_sequence() { + var s0; + + s0 = peg$parsesingle_escape_character(); + if (s0 === peg$FAILED) { + s0 = peg$parsenon_escape_character(); + } + + return s0; + } + + function peg$parsesingle_escape_character() { + var s0, s1; + + if (input.charCodeAt(peg$currPos) === 39) { + s0 = peg$c57; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c58); + } + } + if (s0 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s0 = peg$c54; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c55); + } + } + if (s0 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 92) { + s0 = peg$c129; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c130); + } + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 98) { + s1 = peg$c134; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c135); + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c136(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 102) { + s1 = peg$c137; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c138); + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c139(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 110) { + s1 = peg$c140; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c141); + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c142(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 114) { + s1 = peg$c143; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c144); + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c145(); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 116) { + s1 = peg$c146; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c147); + } + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c148(); + } + s0 = s1; + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsenon_escape_character() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = peg$currPos; + peg$silentFails++; + s2 = peg$parseescape_character(); + peg$silentFails--; + if (s2 === peg$FAILED) { + s1 = void 0; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s2 = peg$parsesource_character(); + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c149(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseescape_character() { + var s0; + + s0 = peg$parsesingle_escape_character(); + if (s0 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 117) { + s0 = peg$c150; + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c151); + } + } + } + + return s0; + } + + function peg$parseunicode_escape_sequence() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 117) { + s1 = peg$c150; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c151); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = peg$currPos; + s4 = peg$parsehex_digit(); + if (s4 !== peg$FAILED) { + s5 = peg$parsehex_digit(); + if (s5 !== peg$FAILED) { + s6 = peg$parsehex_digit(); + if (s6 !== peg$FAILED) { + s7 = peg$parsehex_digit(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c152(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsehex_digit() { + var s0; + + if (peg$c153.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c154); + } + } + + return s0; + } + + function peg$parseobject_property() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parsescalar_conditional_expression(); + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseas(); + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseidentifier(); + if (s5 !== peg$FAILED) { + peg$savedPos = s2; + s3 = peg$c155(s1, s5); + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c156(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_primary_expression() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$parseidentifier(); + if (s0 === peg$FAILED) { + s0 = peg$parseparameter_name(); + if (s0 === peg$FAILED) { + s0 = peg$parseconstant(); + if (s0 === peg$FAILED) { + s0 = peg$parsescalar_array_expression(); + if (s0 === peg$FAILED) { + s0 = peg$parsescalar_object_expression(); + if (s0 === peg$FAILED) { + s0 = peg$parsesubquery_expression(); + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c26); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsescalar_conditional_expression(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c27; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c28); + } + } + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c157(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsesubquery_expression() { + var s0; + + s0 = peg$parsearray_subquery_expression(); + if (s0 === peg$FAILED) { + s0 = peg$parseexists_subquery_expression(); + if (s0 === peg$FAILED) { + s0 = peg$parsescalar_subquery_expression(); + } + } + + return s0; + } + + function peg$parsearray_subquery_expression() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsearray(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsesubquery(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c158(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseexists_subquery_expression() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parseexists(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsesubquery(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c159(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_subquery_expression() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parsesubquery(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c160(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsescalar_member_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + s1 = peg$parsescalar_primary_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c23; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c24); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseidentifier(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c161(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c36; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c37); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsestring_constant(); + if (s7 === peg$FAILED) { + s7 = peg$parseunsigned_integer(); + if (s7 === peg$FAILED) { + s7 = peg$parseparameter_name(); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c38; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c39); + } + } + if (s9 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c162(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c23; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c24); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseidentifier(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c161(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c36; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c37); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsestring_constant(); + if (s7 === peg$FAILED) { + s7 = peg$parseunsigned_integer(); + if (s7 === peg$FAILED) { + s7 = peg$parseparameter_name(); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c38; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c39); + } + } + if (s9 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c162(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c163(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_unary_expression() { + var s0, s1, s2, s3; + + s0 = peg$parsescalar_function_expression(); + if (s0 === peg$FAILED) { + s0 = peg$parsescalar_member_expression(); + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseunary_operator(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsescalar_unary_expression(); + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c164(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + + return s0; + } + + function peg$parsescalar_conditional_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_or_expression(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s3 = peg$c165; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c166); + } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parsescalar_conditional_expression(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s7 = peg$c167; + peg$currPos++; + } else { + s7 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c168); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parsescalar_conditional_expression(); + if (s9 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c169(s1, s5, s9); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$parsescalar_binary_or_expression(); + } + + return s0; + } + + function peg$parsescalar_binary_or_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_and_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseor(); + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c170) { + s5 = peg$c170; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c171); + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_and_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseor(); + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c170) { + s5 = peg$c170; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c171); + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_and_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_binary_and_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_equality_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseand(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_equality_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseand(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_equality_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_binary_equality_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_relational_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s5 = peg$c173; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c174); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c175) { + s5 = peg$c175; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c176); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c177) { + s5 = peg$c177; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c178); + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_relational_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s5 = peg$c173; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c174); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c175) { + s5 = peg$c175; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c176); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c177) { + s5 = peg$c177; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c178); + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_relational_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_binary_relational_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_in_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c179) { + s5 = peg$c179; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c180); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c181) { + s5 = peg$c181; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c182); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 60) { + s5 = peg$c183; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c184); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 62) { + s5 = peg$c185; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c186); + } + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_in_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c179) { + s5 = peg$c179; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c180); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c181) { + s5 = peg$c181; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c182); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 60) { + s5 = peg$c183; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c184); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 62) { + s5 = peg$c185; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c186); + } + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_in_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_in_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + s1 = peg$parsescalar_between_expression(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsein(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 40) { + s5 = peg$c25; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c26); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_expression_list(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s9 = peg$c27; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c28); + } + } + if (s9 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c187(s1, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$parsescalar_between_expression(); + } + + return s0; + } + + function peg$parsescalar_between_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_bitwise_or_expression(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsebetween(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parsescalar_binary_bitwise_or_expression(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseand(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parsescalar_binary_bitwise_or_expression(); + if (s9 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c188(s1, s5, s9); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$parsescalar_binary_bitwise_or_expression(); + } + + return s0; + } + + function peg$parsescalar_binary_bitwise_or_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_bitwise_xor_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 124) { + s5 = peg$c189; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c190); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_bitwise_xor_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 124) { + s5 = peg$c189; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c190); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_bitwise_xor_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_binary_bitwise_xor_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_bitwise_and_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 94) { + s5 = peg$c191; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c192); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_bitwise_and_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 94) { + s5 = peg$c191; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c192); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_bitwise_and_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_binary_bitwise_and_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_shift_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 38) { + s5 = peg$c193; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c194); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_shift_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 38) { + s5 = peg$c193; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c194); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_shift_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_binary_shift_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_additive_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c195) { + s5 = peg$c195; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c196); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c197) { + s5 = peg$c197; + peg$currPos += 3; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c198); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c199) { + s5 = peg$c199; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c200); + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_additive_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c195) { + s5 = peg$c195; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c196); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c197) { + s5 = peg$c197; + peg$currPos += 3; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c198); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c199) { + s5 = peg$c199; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c200); + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_additive_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_binary_additive_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_binary_multiplicative_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 43) { + s5 = peg$c125; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c126); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s5 = peg$c47; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c48); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c201) { + s5 = peg$c201; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c202); + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_multiplicative_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 43) { + s5 = peg$c125; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c126); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s5 = peg$c47; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c48); + } + } + if (s5 === peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c201) { + s5 = peg$c201; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c202); + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_binary_multiplicative_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_binary_multiplicative_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_unary_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 42) { + s5 = peg$c6; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c7); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 47) { + s5 = peg$c203; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c204); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 37) { + s5 = peg$c205; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c206); + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_unary_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 42) { + s5 = peg$c6; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c7); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 47) { + s5 = peg$c203; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c204); + } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 37) { + s5 = peg$c205; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c206); + } + } + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_unary_expression(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c172(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsescalar_object_element_property() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parseidentifier(); + if (s1 === peg$FAILED) { + s1 = peg$parsestring_constant(); + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c167; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c168); + } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parsescalar_conditional_expression(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c207(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parseobject_constant_property() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parseidentifier(); + if (s1 === peg$FAILED) { + s1 = peg$parsestring_constant(); + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c167; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c168); + } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseconstant(); + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c207(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsecollection_primary_expression() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parseidentifier(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c208(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsecollection_member_expression() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + s0 = peg$currPos; + s1 = peg$parsecollection_primary_expression(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c23; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c24); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseidentifier(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c161(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c36; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c37); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsestring_constant(); + if (s7 === peg$FAILED) { + s7 = peg$parseunsigned_integer(); + if (s7 === peg$FAILED) { + s7 = peg$parseparameter_name(); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c38; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c39); + } + } + if (s9 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c162(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c23; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c24); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseidentifier(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c161(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c36; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c37); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsestring_constant(); + if (s7 === peg$FAILED) { + s7 = peg$parseunsigned_integer(); + if (s7 === peg$FAILED) { + s7 = peg$parseparameter_name(); + } + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c38; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c39); + } + } + if (s9 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c162(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c209(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsecollection_subquery_expression() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parsesubquery(); + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c210(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsetop_specification() { + var s0, s1; + + s0 = peg$currPos; + s1 = peg$parseunsigned_integer(); + if (s1 === peg$FAILED) { + s1 = peg$parseparameter_name(); + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c211(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseunsigned_integer() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c51.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c52); + } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c51.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c52); + } + } + } + } else { + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c212(); + } + s0 = s1; + + return s0; + } + + function peg$parsescalar_expression_list() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + s0 = peg$currPos; + s1 = peg$parsescalar_conditional_expression(); + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c11; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_conditional_expression(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c13(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c11; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c12); + } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parsescalar_conditional_expression(); + if (s7 !== peg$FAILED) { + peg$savedPos = s3; + s4 = peg$c13(s1, s7); + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c213(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function peg$parsesubquery() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c26); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseselect_query(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c27; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { + peg$fail(peg$c28); + } + } + if (s5 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$c214(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + return s0; + } + + function buildBinaryExpression(head, tail) { + return tail.reduce( + (left, [, operator, , right]) => ({ + type: "scalar_binary_expression", + left, + operator, + right, + }), + head + ); + } + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +module.exports = { + SyntaxError: peg$SyntaxError, + parse: peg$parse, +}; diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/large b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/large new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/resolved-effects.snapshot new file mode 100644 index 0000000000000..1660891e6abdf --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/resolved-effects.snapshot @@ -0,0 +1,8137 @@ +0 -> 11 free var = FreeVar(Error) + +0 -> 12 conditional = (???*0* === "function") +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* ???*2*["captureStackTrace"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +12 -> 14 free var = FreeVar(Error) + +12 -> 15 member call = ???*0*["captureStackTrace"](???*1*, (...) => undefined) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 16 free var = FreeVar(Error) + +0 -> 17 call = (...) => undefined((...) => undefined, ???*0*) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 20 call = (...) => s["replace"](/\\/g, "\\\\")["replace"](/"/g, "\\\"")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 1822*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 1920*)(???*0*) +- *0* ???*1*["text"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 25 free var = FreeVar(Array) + +0 -> 29 call = (...) => ...[...](..., ...)["replace"](/\^/g, "\\^")["replace"](/-/g, "\\-")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 2287*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*)(???*0*) +- *0* ???*1*[0] + ⚠️ unknown object +- *1* ???*2*[i] + ⚠️ unknown object +- *2* ???*3*["parts"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 33 call = (...) => ...[...](..., ...)["replace"](/\^/g, "\\^")["replace"](/-/g, "\\-")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 2287*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*)(???*0*) +- *0* ???*1*[1] + ⚠️ unknown object +- *1* ???*2*[i] + ⚠️ unknown object +- *2* ???*3*["parts"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 36 call = (...) => ...[...](..., ...)["replace"](/\^/g, "\\^")["replace"](/-/g, "\\-")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 2287*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*)(???*0*) +- *0* ???*1*[i] + ⚠️ unknown object +- *1* ???*2*["parts"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 38 conditional = ???*0* +- *0* ???*1*["inverted"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 43 member call = ???*0*["charCodeAt"](0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 44 member call = ???*0*["toString"](16) +- *0* ???*1*["charCodeAt"](0) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 45 member call = ???*0*["toUpperCase"]() +- *0* ???*1*["toString"](16) + ⚠️ unknown callee object +- *1* ???*2*["charCodeAt"](0) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 54 member call = ???*0*["replace"](/\\/g, "\\\\") +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 55 member call = ???*0*["replace"](/"/g, "\\\"") +- *0* ???*1*["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 56 member call = ???*0*["replace"](/\0/g, "\\0") +- *0* ???*1*["replace"](/"/g, "\\\"") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 57 member call = ???*0*["replace"](/\t/g, "\\t") +- *0* ???*1*["replace"](/\0/g, "\\0") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/"/g, "\\\"") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 58 member call = ???*0*["replace"](/\n/g, "\\n") +- *0* ???*1*["replace"](/\t/g, "\\t") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\0/g, "\\0") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/"/g, "\\\"") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 59 member call = ???*0*["replace"](/\r/g, "\\r") +- *0* ???*1*["replace"](/\n/g, "\\n") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\t/g, "\\t") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\0/g, "\\0") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/"/g, "\\\"") + ⚠️ unknown callee object +- *4* ???["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object + +0 -> 60 member call = ???*0*["replace"](/[\x00-\x0F]/g, (...) => `\x0${hex(ch)}`) +- *0* ???*1*["replace"](/\r/g, "\\r") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\n/g, "\\n") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\t/g, "\\t") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/\0/g, "\\0") + ⚠️ unknown callee object +- *4* ???["replace"](/"/g, "\\\"") + ⚠️ unknown callee object + +60 -> 61 call = (...) => ch["charCodeAt"](0)["toString"](16)["toUpperCase"]()(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 62 member call = ???*0*["replace"](/[\x10-\x1F\x7F-\x9F]/g, (...) => `\x${hex(ch)}`) +- *0* ???*1*["replace"](/[\x00-\x0F]/g, *anonymous function 1822*) + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\r/g, "\\r") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\n/g, "\\n") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/\t/g, "\\t") + ⚠️ unknown callee object +- *4* ???["replace"](/\0/g, "\\0") + ⚠️ unknown callee object + +62 -> 63 call = (...) => ch["charCodeAt"](0)["toString"](16)["toUpperCase"]()(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 74 member call = ???*0*["replace"](/\\/g, "\\\\") +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 75 member call = ???*0*["replace"](/\]/g, "\\]") +- *0* ???*1*["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 76 member call = ???*0*["replace"](/\^/g, "\\^") +- *0* ???*1*["replace"](/\]/g, "\\]") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 77 member call = ???*0*["replace"](/-/g, "\\-") +- *0* ???*1*["replace"](/\^/g, "\\^") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\]/g, "\\]") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 78 member call = ???*0*["replace"](/\0/g, "\\0") +- *0* ???*1*["replace"](/-/g, "\\-") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\^/g, "\\^") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\]/g, "\\]") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 79 member call = ???*0*["replace"](/\t/g, "\\t") +- *0* ???*1*["replace"](/\0/g, "\\0") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/-/g, "\\-") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\^/g, "\\^") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/\]/g, "\\]") + ⚠️ unknown callee object +- *4* ???["replace"](/\\/g, "\\\\") + ⚠️ unknown callee object + +0 -> 80 member call = ???*0*["replace"](/\n/g, "\\n") +- *0* ???*1*["replace"](/\t/g, "\\t") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\0/g, "\\0") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/-/g, "\\-") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/\^/g, "\\^") + ⚠️ unknown callee object +- *4* ???["replace"](/\]/g, "\\]") + ⚠️ unknown callee object + +0 -> 81 member call = ???*0*["replace"](/\r/g, "\\r") +- *0* ???*1*["replace"](/\n/g, "\\n") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\t/g, "\\t") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\0/g, "\\0") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/-/g, "\\-") + ⚠️ unknown callee object +- *4* ???["replace"](/\^/g, "\\^") + ⚠️ unknown callee object + +0 -> 82 member call = ???*0*["replace"](/[\x00-\x0F]/g, (...) => `\x0${hex(ch)}`) +- *0* ???*1*["replace"](/\r/g, "\\r") + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\n/g, "\\n") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\t/g, "\\t") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/\0/g, "\\0") + ⚠️ unknown callee object +- *4* ???["replace"](/-/g, "\\-") + ⚠️ unknown callee object + +82 -> 83 call = (...) => ch["charCodeAt"](0)["toString"](16)["toUpperCase"]()(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 84 member call = ???*0*["replace"](/[\x10-\x1F\x7F-\x9F]/g, (...) => `\x${hex(ch)}`) +- *0* ???*1*["replace"](/[\x00-\x0F]/g, *anonymous function 2287*) + ⚠️ unknown callee object +- *1* ???*2*["replace"](/\r/g, "\\r") + ⚠️ unknown callee object +- *2* ???*3*["replace"](/\n/g, "\\n") + ⚠️ unknown callee object +- *3* ???*4*["replace"](/\t/g, "\\t") + ⚠️ unknown callee object +- *4* ???["replace"](/\0/g, "\\0") + ⚠️ unknown callee object + +84 -> 85 call = (...) => ch["charCodeAt"](0)["toString"](16)["toUpperCase"]()(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 88 member call = { + "literal": (...) => `"${literalEscape(expectation["text"])}"`, + "class": (...) => `[${(expectation["inverted"] ? "^" : "")}${escapedParts}]`, + "any": (...) => "any character", + "end": (...) => "end of input", + "other": (...) => expectation["description"] +}[???*0*](???*2*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 89 free var = FreeVar(Array) + +0 -> 94 call = (...) => DESCRIBE_EXPECTATION_FNS[expectation["type"]](expectation)(???*0*) +- *0* ???*1*[i] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 96 member call = ???*0*["sort"]() +- *0* unknown new expression + ⚠️ This value might have side effects + +0 -> 101 conditional = (???*0* !== ???*3*) +- *0* ???*1*[???*2*] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*[i] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects + +0 -> 111 member call = ???*0*["slice"](0, ???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 112 member call = ???*0*["join"](", ") +- *0* ???*1*["slice"](0, ???*2*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 115 conditional = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +115 -> 116 call = (...) => s["replace"](/\\/g, "\\\\")["replace"](/"/g, "\\\"")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 1822*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 1920*)(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 117 call = (...) => ( + | undefined + | descriptions[0] + | `${descriptions[0]} or ${descriptions[1]}` + | `${descriptions["slice"](0, ???*0*)["join"](", ")}, or ${descriptions[???*1*]}` +)(???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 118 call = (...) => (found ? `"${literalEscape(found)}"` : "end of input")(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 119 conditional = ((???*0* | ???*1*) !== ???*6*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? ???*5* : {}) + ⚠️ nested operation +- *2* (???*3* !== ???*4*) + ⚠️ nested operation +- *3* options + ⚠️ circular variable reference +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* options + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects + +0 -> 120 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("*", false) + +0 -> 121 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}(",", false) + +0 -> 122 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}(".", false) + +0 -> 123 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("(", false) + +0 -> 124 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}(")", false) + +0 -> 125 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("{", false) + +0 -> 126 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("}", false) + +0 -> 127 conditional = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 128 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("[", false) + +0 -> 129 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("]", false) + +0 -> 130 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("undefined", false) + +0 -> 131 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("-", false) + +0 -> 132 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("0x", false) + +0 -> 133 call = (...) => {"type": "class", "parts": parts, "inverted": inverted, "ignoreCase": ignoreCase}([["0", "9"]], false, false) + +0 -> 134 conditional = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +134 -> 135 free var = FreeVar(parseInt) + +134 -> 136 call = (...) => input["substring"](peg$savedPos, peg$currPos)() + +134 -> 137 call = ???*0*(???*1*, 16) +- *0* FreeVar(parseInt) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["substring"](peg$savedPos, peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +134 -> 138 free var = FreeVar(parseFloat) + +134 -> 139 call = (...) => input["substring"](peg$savedPos, peg$currPos)() + +134 -> 140 call = ???*0*(???*1*) +- *0* FreeVar(parseFloat) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["substring"](peg$savedPos, peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 141 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("\"", false) + +0 -> 143 member call = ???*0*["join"]("") +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 144 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("'", false) + +0 -> 145 call = (...) => {"type": "class", "parts": parts, "inverted": inverted, "ignoreCase": ignoreCase}([" ", "\t", "\n", "\r"], false, false) + +0 -> 146 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("--", false) + +0 -> 147 call = (...) => {"type": "class", "parts": parts, "inverted": inverted, "ignoreCase": ignoreCase}(["\n", "\r"], false, false) + +0 -> 148 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("SELECT", true) + +0 -> 149 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("TOP", true) + +0 -> 150 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("FROM", true) + +0 -> 151 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("WHERE", true) + +0 -> 152 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("ORDER", true) + +0 -> 153 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("BY", true) + +0 -> 154 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("AS", true) + +0 -> 155 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("JOIN", true) + +0 -> 156 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("IN", true) + +0 -> 157 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("VALUE", true) + +0 -> 158 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("ASC", true) + +0 -> 159 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("DESC", true) + +0 -> 160 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("AND", true) + +0 -> 161 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("OR", true) + +0 -> 162 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("NOT", true) + +0 -> 163 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("BETWEEN", true) + +0 -> 164 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("EXISTS", true) + +0 -> 165 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("ARRAY", true) + +0 -> 166 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("null", false) + +0 -> 167 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("true", false) + +0 -> 168 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("false", false) + +0 -> 169 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("udf", false) + +0 -> 170 call = (...) => {"type": "class", "parts": parts, "inverted": inverted, "ignoreCase": ignoreCase}([["a", "z"], ["A", "Z"], "_"], false, false) + +0 -> 171 call = (...) => {"type": "class", "parts": parts, "inverted": inverted, "ignoreCase": ignoreCase}([["a", "z"], ["A", "Z"], ["0", "9"], "_"], false, false) + +0 -> 173 member call = ???*0*["join"]("") +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 174 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("@", false) + +0 -> 175 call = (...) => input["substring"](peg$savedPos, peg$currPos)() + +0 -> 176 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("+", false) + +0 -> 177 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("~", false) + +0 -> 178 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("\\", false) + +0 -> 179 call = (...) => input["substring"](peg$savedPos, peg$currPos)() + +0 -> 180 call = (...) => {"type": "any"}() + +0 -> 181 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("b", false) + +0 -> 182 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("f", false) + +0 -> 183 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("n", false) + +0 -> 184 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("r", false) + +0 -> 185 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("t", false) + +0 -> 186 call = (...) => input["substring"](peg$savedPos, peg$currPos)() + +0 -> 187 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("u", false) + +0 -> 189 free var = FreeVar(String) + +0 -> 190 free var = FreeVar(parseInt) + +0 -> 191 call = ???*0*(???*1*, 16) +- *0* FreeVar(parseInt) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 192 member call = ???*0*["fromCharCode"](???*1*) +- *0* FreeVar(String) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*(digits, 16) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(parseInt) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 193 call = (...) => {"type": "class", "parts": parts, "inverted": inverted, "ignoreCase": ignoreCase}([["0", "9"], ["a", "f"]], false, true) + +0 -> 195 member call = ???*0*["reduce"]( + (...) => {"type": "scalar_member_expression", "object": object, "property": property, "computed": computed}, + ???*1* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 196 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("?", false) + +0 -> 197 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}(":", false) + +0 -> 198 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("??", false) + +0 -> 199 call = (...) => tail["reduce"](*arrow function 169161*, head)(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 200 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("=", false) + +0 -> 201 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("!=", false) + +0 -> 202 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("<>", false) + +0 -> 203 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("<=", false) + +0 -> 204 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}(">=", false) + +0 -> 205 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("<", false) + +0 -> 206 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}(">", false) + +0 -> 207 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("|", false) + +0 -> 208 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("^", false) + +0 -> 209 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("&", false) + +0 -> 210 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("<<", false) + +0 -> 211 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}(">>>", false) + +0 -> 212 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}(">>", false) + +0 -> 213 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("||", false) + +0 -> 214 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("/", false) + +0 -> 215 call = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase}("%", false) + +0 -> 217 member call = ???*0*["reduce"]( + (...) => { + "type": "collection_member_expression", + "object": object, + "property": property, + "computed": computed + }, + ???*1* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 218 free var = FreeVar(Number) + +0 -> 219 call = (...) => input["substring"](peg$savedPos, peg$currPos)() + +0 -> 220 call = ???*0*(???*1*) +- *0* FreeVar(Number) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["substring"](peg$savedPos, peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 221 conditional = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 223 conditional = !(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +223 -> 224 free var = FreeVar(Error) + +0 -> 229 member call = ???*0*["substring"](???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 230 call = (...) => { + "start": {"offset": startPos, "line": startPosDetails["line"], "column": startPosDetails["column"]}, + "end": {"offset": endPos, "line": endPosDetails["line"], "column": endPosDetails["column"]} +}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 231 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +231 -> 232 call = (...) => { + "start": {"offset": startPos, "line": startPosDetails["line"], "column": startPosDetails["column"]}, + "end": {"offset": endPos, "line": endPosDetails["line"], "column": endPosDetails["column"]} +}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 233 call = (...) => {"type": "other", "description": description}(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 235 member call = ???*0*["substring"](???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 236 call = (...) => ???*0*([{"type": "other", "description": ???*1*}], ???*2*, ???*4*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["substring"](peg$savedPos, peg$currPos) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 237 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +237 -> 238 call = (...) => { + "start": {"offset": startPos, "line": startPosDetails["line"], "column": startPosDetails["column"]}, + "end": {"offset": endPos, "line": endPosDetails["line"], "column": endPosDetails["column"]} +}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 239 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 241 conditional = ({"line": 1, "column": 1} | ???*0* | {"line": ???*2*, "column": ???*4*}) +- *0* [][???*1*] + ⚠️ unknown array prototype methods or values +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["line"] + ⚠️ unknown object +- *3* details + ⚠️ circular variable reference +- *4* ???*5*["column"] + ⚠️ unknown object +- *5* details + ⚠️ circular variable reference + +241 -> 247 member call = ???*0*["charCodeAt"]((???*1* | ???*2* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* p + ⚠️ pattern without value +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* updated with update expression + ⚠️ This value might have side effects + +241 -> 248 conditional = (???*0* === 10) +- *0* ???*1*["charCodeAt"](p) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 253 call = (...) => (undefined | details)(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 254 call = (...) => (undefined | details)(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 260 member call = []["push"](???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 262 member call = (...) => undefined["buildMessage"](???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 263 call = (...) => s0() + +0 -> 264 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +264 -> 265 call = (...) => s0() + +264 -> 266 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +266 -> 267 call = (...) => s0() + +266 -> 268 conditional = ((???*0* | []) !== {}) +- *0* s3 + ⚠️ pattern without value + +268 -> 269 call = (...) => {"type": "sql", "body": body}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 270 call = (...) => s0() + +0 -> 271 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +271 -> 272 call = (...) => s0() + +271 -> 273 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +273 -> 274 call = (...) => s0() + +273 -> 275 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +275 -> 276 call = (...) => s0() + +275 -> 277 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +277 -> 278 call = (...) => s0() + +277 -> 279 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +279 -> 280 call = (...) => v(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +273 -> 281 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +281 -> 282 call = (...) => s0() + +281 -> 283 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +283 -> 284 call = (...) => s0() + +283 -> 285 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +285 -> 286 call = (...) => s0() + +285 -> 287 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +287 -> 288 call = (...) => s0() + +287 -> 289 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +289 -> 290 call = (...) => s0() + +289 -> 291 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +291 -> 292 call = (...) => s0() + +291 -> 293 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +293 -> 294 call = (...) => v(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +287 -> 295 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +295 -> 296 call = (...) => s0() + +295 -> 297 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +297 -> 298 call = (...) => s0() + +297 -> 299 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +299 -> 300 call = (...) => s0() + +299 -> 301 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +301 -> 302 call = (...) => s0() + +301 -> 303 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +303 -> 304 call = (...) => v(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +297 -> 305 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +305 -> 306 call = (...) => s0() + +305 -> 307 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +307 -> 308 call = (...) => s0() + +307 -> 309 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +309 -> 310 call = (...) => s0() + +309 -> 311 conditional = ((???*0* | []) !== {}) +- *0* s13 + ⚠️ pattern without value + +311 -> 312 call = (...) => s0() + +311 -> 313 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +313 -> 314 call = (...) => s0() + +313 -> 315 conditional = ((???*0* | []) !== {}) +- *0* s15 + ⚠️ pattern without value + +315 -> 316 call = (...) => s0() + +315 -> 317 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +317 -> 318 call = (...) => v(???*0*, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +307 -> 319 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +319 -> 320 call = (...) => { + "type": "select_query", + "top": top, + "select": select, + "from": from, + "where": where, + "orderBy": orderBy +}(???*0*, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 322 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 323 conditional = (???*0* === 42) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +323 -> 324 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +324 -> 325 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "*", "ignoreCase": false} +) + +0 -> 326 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +326 -> 327 call = (...) => {"type": "select_specification", "*": true}() + +0 -> 328 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +328 -> 329 call = (...) => s0() + +328 -> 330 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +330 -> 331 call = (...) => {"type": "select_specification", "properties": properties}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +328 -> 332 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +332 -> 333 call = (...) => s0() + +332 -> 334 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +334 -> 335 call = (...) => s0() + +334 -> 336 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +336 -> 337 call = (...) => s0() + +336 -> 338 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +338 -> 339 call = (...) => {"type": "select_specification", "value": value}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 340 call = (...) => s0() + +0 -> 341 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +341 -> 342 call = (...) => s0() + +341 -> 343 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +343 -> 345 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +343 -> 346 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +346 -> 347 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +347 -> 348 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +343 -> 349 conditional = ((???*0* | "," | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +349 -> 350 call = (...) => s0() + +349 -> 351 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +351 -> 352 call = (...) => s0() + +351 -> 353 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +353 -> 354 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +341 -> 356 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +341 -> 357 call = (...) => s0() + +341 -> 358 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +358 -> 360 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +358 -> 361 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +361 -> 362 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +362 -> 363 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +358 -> 364 conditional = ((???*0* | "," | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +364 -> 365 call = (...) => s0() + +364 -> 366 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +366 -> 367 call = (...) => s0() + +366 -> 368 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +368 -> 369 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +341 -> 370 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +370 -> 371 call = (...) => {"type": "object_property_list", "properties": ???*0*}(???*1*, (???*2* | [])) +- *0* spread is not supported + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* s2 + ⚠️ pattern without value + +0 -> 372 call = (...) => s0() + +0 -> 373 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +373 -> 374 call = (...) => s0() + +373 -> 375 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +375 -> 376 call = (...) => s0() + +375 -> 377 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +377 -> 378 call = (...) => s0() + +377 -> 379 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +379 -> 380 call = (...) => s0() + +379 -> 381 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +381 -> 382 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +373 -> 384 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +373 -> 385 call = (...) => s0() + +373 -> 386 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +386 -> 387 call = (...) => s0() + +386 -> 388 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +388 -> 389 call = (...) => s0() + +388 -> 390 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +390 -> 391 call = (...) => s0() + +390 -> 392 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +392 -> 393 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +373 -> 394 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +394 -> 395 call = (...) => {"type": "from_specification", "source": source, "joins": joins}(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 396 call = (...) => s0() + +0 -> 397 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +397 -> 398 call = (...) => s0() + +397 -> 399 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +399 -> 400 call = (...) => s0() + +399 -> 401 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +401 -> 402 call = (...) => s0() + +401 -> 403 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +403 -> 404 call = (...) => s0() + +403 -> 405 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +405 -> 406 call = (...) => {"type": "from_source", "expression": expression, "alias": alias, "iteration": true}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 407 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +407 -> 408 call = (...) => s0() + +407 -> 409 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +409 -> 410 call = (...) => s0() + +409 -> 411 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +411 -> 412 call = (...) => s0() + +409 -> 413 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +413 -> 414 call = (...) => s0() + +413 -> 415 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +415 -> 416 call = (...) => s0() + +415 -> 417 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +417 -> 418 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +409 -> 419 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +419 -> 420 call = (...) => {"type": "from_source", "expression": expression, "alias": alias}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 421 call = (...) => s0() + +0 -> 422 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +422 -> 423 call = (...) => s0() + +422 -> 424 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +424 -> 425 call = (...) => s0() + +0 -> 426 call = (...) => s0() + +0 -> 427 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +427 -> 428 call = (...) => {"type": "filter_condition", "condition": condition}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 429 call = (...) => s0() + +0 -> 430 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +430 -> 431 call = (...) => s0() + +430 -> 432 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +432 -> 434 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +432 -> 435 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +435 -> 436 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +436 -> 437 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +432 -> 438 conditional = ((???*0* | "," | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +438 -> 439 call = (...) => s0() + +438 -> 440 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +440 -> 441 call = (...) => s0() + +440 -> 442 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +442 -> 443 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +430 -> 445 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +430 -> 446 call = (...) => s0() + +430 -> 447 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +447 -> 449 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +447 -> 450 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +450 -> 451 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +451 -> 452 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +447 -> 453 conditional = ((???*0* | "," | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +453 -> 454 call = (...) => s0() + +453 -> 455 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +455 -> 456 call = (...) => s0() + +455 -> 457 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +457 -> 458 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +430 -> 459 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +459 -> 460 call = (...) => {"type": "sort_specification", "expressions": ???*0*}(???*1*, (???*2* | [])) +- *0* spread is not supported + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* s2 + ⚠️ pattern without value + +0 -> 461 call = (...) => s0() + +0 -> 462 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +462 -> 463 call = (...) => s0() + +462 -> 464 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +464 -> 465 call = (...) => s0() + +464 -> 466 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +466 -> 467 call = (...) => s0() + +464 -> 468 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +468 -> 469 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +462 -> 470 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +470 -> 471 call = (...) => {"type": "sort_expression", "expression": expression, "order": order}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 472 call = (...) => s0() + +0 -> 473 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +473 -> 474 call = (...) => s0() + +473 -> 475 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +475 -> 477 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +475 -> 478 conditional = (???*0* === 46) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +478 -> 479 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +479 -> 480 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ".", "ignoreCase": false} +) + +475 -> 481 conditional = ((???*0* | "." | {} | "(") !== {}) +- *0* s3 + ⚠️ pattern without value + +481 -> 482 call = (...) => s0() + +481 -> 483 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +483 -> 484 call = (...) => s0() + +483 -> 485 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +485 -> 486 call = (...) => s0() + +485 -> 487 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +487 -> 489 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +487 -> 490 conditional = (???*0* === 40) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +490 -> 491 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +491 -> 492 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "(", "ignoreCase": false} +) + +487 -> 493 conditional = ((???*0* | "(" | {} | ")") !== {}) +- *0* s7 + ⚠️ pattern without value + +493 -> 494 call = (...) => s0() + +493 -> 495 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +495 -> 496 call = (...) => s0() + +495 -> 497 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +497 -> 498 call = (...) => s0() + +497 -> 499 conditional = ((???*0* | []) !== {}) +- *0* s10 + ⚠️ pattern without value + +499 -> 501 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +499 -> 502 conditional = (???*0* === 41) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +502 -> 503 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +503 -> 504 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ")", "ignoreCase": false} +) + +499 -> 505 conditional = ((???*0* | ")" | {}) !== {}) +- *0* s11 + ⚠️ pattern without value + +505 -> 506 call = (...) => {"type": "scalar_function_expression", "name": name, "arguments": args, "udf": true}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 507 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +507 -> 508 call = (...) => s0() + +507 -> 509 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +509 -> 510 call = (...) => s0() + +509 -> 511 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +511 -> 513 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +511 -> 514 conditional = (???*0* === 40) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +514 -> 515 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +515 -> 516 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "(", "ignoreCase": false} +) + +511 -> 517 conditional = ((???*0* | "." | {} | "(") !== {}) +- *0* s3 + ⚠️ pattern without value + +517 -> 518 call = (...) => s0() + +517 -> 519 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +519 -> 520 call = (...) => s0() + +519 -> 521 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +521 -> 522 call = (...) => s0() + +521 -> 523 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +523 -> 525 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +523 -> 526 conditional = (???*0* === 41) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +526 -> 527 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +527 -> 528 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ")", "ignoreCase": false} +) + +523 -> 529 conditional = ((???*0* | "(" | {} | ")") !== {}) +- *0* s7 + ⚠️ pattern without value + +529 -> 530 call = (...) => {"type": "scalar_function_expression", "name": name, "arguments": args}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 532 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 533 conditional = (???*0* === 123) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +533 -> 534 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +534 -> 535 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "{", "ignoreCase": false} +) + +0 -> 536 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +536 -> 537 call = (...) => s0() + +536 -> 538 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +538 -> 539 call = (...) => s0() + +538 -> 540 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +540 -> 541 call = (...) => s0() + +540 -> 542 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +542 -> 544 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +542 -> 545 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +545 -> 546 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +546 -> 547 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +542 -> 548 conditional = ((???*0* | "," | {}) !== {}) +- *0* s7 + ⚠️ pattern without value + +548 -> 549 call = (...) => s0() + +548 -> 550 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +550 -> 551 call = (...) => s0() + +550 -> 552 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +552 -> 553 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +540 -> 555 member call = (???*0* | [])["push"](???*1*) +- *0* s4 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +540 -> 556 call = (...) => s0() + +540 -> 557 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +557 -> 559 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +557 -> 560 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +560 -> 561 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +561 -> 562 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +557 -> 563 conditional = ((???*0* | "," | {}) !== {}) +- *0* s7 + ⚠️ pattern without value + +563 -> 564 call = (...) => s0() + +563 -> 565 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +565 -> 566 call = (...) => s0() + +565 -> 567 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +567 -> 568 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +540 -> 569 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +569 -> 570 call = (...) => s0() + +569 -> 571 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +571 -> 573 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +571 -> 574 conditional = (???*0* === 125) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +574 -> 575 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +575 -> 576 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "}", "ignoreCase": false} +) + +571 -> 577 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +577 -> 578 call = (...) => {"type": "scalar_object_expression", "properties": (head ? ???*0* : [])}(???*1*, (???*2* | [])) +- *0* spread is not supported + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* s4 + ⚠️ pattern without value + +0 -> 580 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 581 conditional = (???*0* === 91) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +581 -> 582 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +582 -> 583 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "[", "ignoreCase": false} +) + +0 -> 584 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +584 -> 585 call = (...) => s0() + +584 -> 586 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +586 -> 587 call = (...) => s0() + +586 -> 588 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +588 -> 589 call = (...) => s0() + +588 -> 590 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +590 -> 592 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +590 -> 593 conditional = (???*0* === 93) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +593 -> 594 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +594 -> 595 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "]", "ignoreCase": false} +) + +590 -> 596 conditional = ((???*0* | "]" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +596 -> 597 call = (...) => {"type": "scalar_array_expression", "elements": elements}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 598 call = (...) => s0() + +0 -> 599 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +599 -> 600 call = (...) => s0() + +599 -> 601 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +601 -> 602 call = (...) => s0() + +601 -> 603 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +603 -> 604 call = (...) => s0() + +603 -> 605 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +605 -> 606 call = (...) => s0() + +605 -> 607 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +607 -> 608 call = (...) => s0() + +607 -> 609 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +609 -> 610 call = (...) => s0() + +0 -> 612 member call = ???*0*["substr"](???*1*, 9) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 613 conditional = (???*0* === "undefined") +- *0* ???*1*["substr"](peg$currPos, 9) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +613 -> 614 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +614 -> 615 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "undefined", "ignoreCase": false} +) + +0 -> 616 conditional = ((???*0* | "undefined" | {} | {"type": "undefined_constant"}) !== {}) +- *0* s1 + ⚠️ pattern without value + +616 -> 617 call = (...) => {"type": "undefined_constant"}() + +0 -> 618 call = (...) => s0() + +0 -> 619 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +619 -> 620 call = (...) => {"type": "null_constant"}() + +0 -> 621 call = (...) => s0() + +0 -> 622 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +622 -> 623 call = (...) => {"type": "boolean_constant", "value": false}() + +0 -> 624 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +624 -> 625 call = (...) => s0() + +624 -> 626 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +626 -> 627 call = (...) => {"type": "boolean_constant", "value": true}() + +0 -> 629 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 630 conditional = (???*0* === 45) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +630 -> 631 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +631 -> 632 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "-", "ignoreCase": false} +) + +0 -> 633 conditional = ((???*0* | "-" | {} | null | {"type": "number_constant", "value": ???*1*}) !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ((???*2* | "0x" | {} | null) ? ???*3* : ???*5*) + ⚠️ nested operation +- *2* s2 + ⚠️ pattern without value +- *3* ???*4*(text(), 16) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *4* FreeVar(parseInt) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* ???*6*(text()) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *6* FreeVar(parseFloat) + ⚠️ unknown global + ⚠️ This value might have side effects + +633 -> 635 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +633 -> 636 conditional = (???*0* === "0x") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +636 -> 637 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +637 -> 638 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "0x", "ignoreCase": false} +) + +633 -> 639 conditional = ((???*0* | "0x" | {} | null) !== {}) +- *0* s2 + ⚠️ pattern without value + +639 -> 642 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +639 -> 643 member call = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +639 -> 644 conditional = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +644 -> 646 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +644 -> 647 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +647 -> 648 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [["0", "9"]], "inverted": false, "ignoreCase": false} +) + +639 -> 649 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +649 -> 651 member call = (???*0* | [] | {})["push"](???*1*) +- *0* s3 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +649 -> 654 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +649 -> 655 member call = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +649 -> 656 conditional = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +656 -> 658 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +656 -> 659 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +659 -> 660 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [["0", "9"]], "inverted": false, "ignoreCase": false} +) + +639 -> 661 conditional = ((???*0* | [] | {}) !== {}) +- *0* s3 + ⚠️ pattern without value + +661 -> 663 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +661 -> 664 conditional = (???*0* === 46) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +664 -> 665 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +665 -> 666 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ".", "ignoreCase": false} +) + +661 -> 667 conditional = ((???*0* | "." | {} | [???*1*, (???*2* | [] | {})]) !== {}) +- *0* s5 + ⚠️ pattern without value +- *1* s5 + ⚠️ circular variable reference +- *2* s6 + ⚠️ pattern without value + +667 -> 670 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +667 -> 671 member call = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +667 -> 672 conditional = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +672 -> 674 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +672 -> 675 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +675 -> 676 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [["0", "9"]], "inverted": false, "ignoreCase": false} +) + +667 -> 677 conditional = ((???*0* | ???*1* | {}) !== {}) +- *0* s7 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +677 -> 679 member call = (???*0* | [] | {})["push"]((???*1* | ???*2* | {})) +- *0* s6 + ⚠️ pattern without value +- *1* s7 + ⚠️ pattern without value +- *2* ???*3*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +677 -> 682 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +677 -> 683 member call = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +677 -> 684 conditional = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +684 -> 686 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +684 -> 687 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +687 -> 688 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [["0", "9"]], "inverted": false, "ignoreCase": false} +) + +661 -> 689 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +689 -> 690 call = (...) => { + "type": "number_constant", + "value": (hex ? FreeVar(parseInt)(text(), 16) : FreeVar(parseFloat)(text())) +}((???*0* | "0x" | {} | null)) +- *0* s2 + ⚠️ pattern without value + +0 -> 692 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 693 conditional = (???*0* === 34) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +693 -> 694 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +694 -> 695 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\"", "ignoreCase": false} +) + +0 -> 696 conditional = (( + | ???*0* + | "\"" + | {} + | {"type": "string_constant", "value": (???*1* | ???*3*)} + | "'" +) !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["join"]("") + ⚠️ unknown callee object +- *2* s2 + ⚠️ pattern without value +- *3* ???*4*("") + ⚠️ unknown callee +- *4* []["join"] + ⚠️ non-num constant property on array + +696 -> 697 call = (...) => s0() + +696 -> 699 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +696 -> 700 call = (...) => s0() + +696 -> 701 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +701 -> 703 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +701 -> 704 conditional = (???*0* === 34) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +704 -> 705 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +705 -> 706 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\"", "ignoreCase": false} +) + +701 -> 707 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +707 -> 708 call = (...) => {"type": "string_constant", "value": chars["join"]("")}((???*0* | [])) +- *0* s2 + ⚠️ pattern without value + +0 -> 709 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +709 -> 711 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +709 -> 712 conditional = (???*0* === 39) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +712 -> 713 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +713 -> 714 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "'", "ignoreCase": false} +) + +709 -> 715 conditional = (( + | ???*0* + | "\"" + | {} + | {"type": "string_constant", "value": (???*1* | ???*3*)} + | "'" +) !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["join"]("") + ⚠️ unknown callee object +- *2* s2 + ⚠️ pattern without value +- *3* ???*4*("") + ⚠️ unknown callee +- *4* []["join"] + ⚠️ non-num constant property on array + +715 -> 716 call = (...) => s0() + +715 -> 718 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +715 -> 719 call = (...) => s0() + +715 -> 720 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +720 -> 722 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +720 -> 723 conditional = (???*0* === 39) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +723 -> 724 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +724 -> 725 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "'", "ignoreCase": false} +) + +720 -> 726 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +726 -> 727 call = (...) => {"type": "string_constant", "value": chars["join"]("")}((???*0* | [])) +- *0* s2 + ⚠️ pattern without value + +0 -> 729 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 730 conditional = (???*0* === 91) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +730 -> 731 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +731 -> 732 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "[", "ignoreCase": false} +) + +0 -> 733 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +733 -> 734 call = (...) => s0() + +733 -> 735 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +735 -> 736 call = (...) => s0() + +735 -> 737 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +737 -> 738 call = (...) => s0() + +737 -> 739 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +739 -> 741 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +739 -> 742 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +742 -> 743 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +743 -> 744 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +739 -> 745 conditional = ((???*0* | "," | {}) !== {}) +- *0* s7 + ⚠️ pattern without value + +745 -> 746 call = (...) => s0() + +745 -> 747 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +747 -> 748 call = (...) => s0() + +747 -> 749 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +749 -> 750 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +737 -> 752 member call = (???*0* | [])["push"](???*1*) +- *0* s4 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +737 -> 753 call = (...) => s0() + +737 -> 754 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +754 -> 756 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +754 -> 757 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +757 -> 758 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +758 -> 759 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +754 -> 760 conditional = ((???*0* | "," | {}) !== {}) +- *0* s7 + ⚠️ pattern without value + +760 -> 761 call = (...) => s0() + +760 -> 762 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +762 -> 763 call = (...) => s0() + +762 -> 764 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +764 -> 765 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +737 -> 766 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +766 -> 767 call = (...) => s0() + +766 -> 768 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +768 -> 770 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +768 -> 771 conditional = (???*0* === 93) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +771 -> 772 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +772 -> 773 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "]", "ignoreCase": false} +) + +768 -> 774 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +774 -> 775 call = (...) => {"type": "array_constant", "elements": ???*0*}(???*1*, (???*2* | [])) +- *0* spread is not supported + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* s4 + ⚠️ pattern without value + +0 -> 777 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 778 conditional = (???*0* === 123) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +778 -> 779 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +779 -> 780 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "{", "ignoreCase": false} +) + +0 -> 781 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +781 -> 782 call = (...) => s0() + +781 -> 783 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +783 -> 784 call = (...) => s0() + +783 -> 785 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +785 -> 786 call = (...) => s0() + +785 -> 787 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +787 -> 789 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +787 -> 790 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +790 -> 791 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +791 -> 792 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +787 -> 793 conditional = ((???*0* | "," | {}) !== {}) +- *0* s7 + ⚠️ pattern without value + +793 -> 794 call = (...) => s0() + +793 -> 795 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +795 -> 796 call = (...) => s0() + +795 -> 797 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +797 -> 798 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +785 -> 800 member call = (???*0* | [])["push"](???*1*) +- *0* s4 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +785 -> 801 call = (...) => s0() + +785 -> 802 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +802 -> 804 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +802 -> 805 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +805 -> 806 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +806 -> 807 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +802 -> 808 conditional = ((???*0* | "," | {}) !== {}) +- *0* s7 + ⚠️ pattern without value + +808 -> 809 call = (...) => s0() + +808 -> 810 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +810 -> 811 call = (...) => s0() + +810 -> 812 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +812 -> 813 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +785 -> 814 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +814 -> 815 call = (...) => s0() + +814 -> 816 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +816 -> 818 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +816 -> 819 conditional = (???*0* === 125) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +819 -> 820 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +820 -> 821 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "}", "ignoreCase": false} +) + +816 -> 822 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +822 -> 823 call = (...) => {"type": "object_constant", "properties": ???*0*}(???*1*, (???*2* | [])) +- *0* spread is not supported + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* s4 + ⚠️ pattern without value + +0 -> 824 call = (...) => s0() + +0 -> 825 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +825 -> 826 call = (...) => s0() + +0 -> 828 member call = (???*0* | [])["push"](???*1*) +- *0* s0 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 829 call = (...) => s0() + +0 -> 830 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +830 -> 831 call = (...) => s0() + +0 -> 834 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 835 member call = /^[ \t\n\r]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 836 conditional = /^[ \t\n\r]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +836 -> 838 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +836 -> 839 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +839 -> 840 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [" ", "\t", "\n", "\r"], "inverted": false, "ignoreCase": false} +) + +0 -> 842 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 843 conditional = (???*0* === "--") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +843 -> 844 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +844 -> 845 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "--", "ignoreCase": false} +) + +0 -> 846 conditional = ((???*0* | "--" | {} | [???*1*, (???*2* | [])]) !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* s1 + ⚠️ circular variable reference +- *2* s2 + ⚠️ pattern without value + +846 -> 849 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +846 -> 850 member call = /^[\n\r]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +846 -> 851 conditional = /^[\n\r]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +851 -> 853 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +851 -> 854 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +854 -> 855 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": ["\n", "\r"], "inverted": false, "ignoreCase": false} +) + +846 -> 856 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +856 -> 857 call = (...) => s0() + +846 -> 859 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +846 -> 862 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +846 -> 863 member call = /^[\n\r]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +846 -> 864 conditional = /^[\n\r]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +864 -> 866 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +864 -> 867 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +867 -> 868 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": ["\n", "\r"], "inverted": false, "ignoreCase": false} +) + +846 -> 869 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +869 -> 870 call = (...) => s0() + +0 -> 873 member call = ???*0*["substr"](???*1*, 6) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 874 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 6) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 875 conditional = (???*0* === "select") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 6) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +875 -> 877 member call = ???*0*["substr"](???*1*, 6) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +875 -> 878 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +878 -> 879 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "SELECT", "ignoreCase": true} +) + +0 -> 880 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +880 -> 881 call = (...) => s0() + +0 -> 884 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 885 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 886 conditional = (???*0* === "top") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +886 -> 888 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +886 -> 889 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +889 -> 890 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "TOP", "ignoreCase": true} +) + +0 -> 891 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +891 -> 892 call = (...) => s0() + +0 -> 895 member call = ???*0*["substr"](???*1*, 4) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 896 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 897 conditional = (???*0* === "from") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +897 -> 899 member call = ???*0*["substr"](???*1*, 4) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +897 -> 900 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +900 -> 901 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "FROM", "ignoreCase": true} +) + +0 -> 902 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +902 -> 903 call = (...) => s0() + +0 -> 906 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 907 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 908 conditional = (???*0* === "where") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +908 -> 910 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +908 -> 911 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +911 -> 912 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "WHERE", "ignoreCase": true} +) + +0 -> 913 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +913 -> 914 call = (...) => s0() + +0 -> 917 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 918 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 919 conditional = (???*0* === "order") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +919 -> 921 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +919 -> 922 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +922 -> 923 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "ORDER", "ignoreCase": true} +) + +0 -> 924 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +924 -> 925 call = (...) => s0() + +0 -> 928 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 929 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 930 conditional = (???*0* === "by") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +930 -> 932 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +930 -> 933 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +933 -> 934 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "BY", "ignoreCase": true} +) + +0 -> 935 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +935 -> 936 call = (...) => s0() + +0 -> 939 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 940 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 941 conditional = (???*0* === "as") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +941 -> 943 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +941 -> 944 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +944 -> 945 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "AS", "ignoreCase": true} +) + +0 -> 946 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +946 -> 947 call = (...) => s0() + +0 -> 950 member call = ???*0*["substr"](???*1*, 4) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 951 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 952 conditional = (???*0* === "join") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +952 -> 954 member call = ???*0*["substr"](???*1*, 4) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +952 -> 955 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +955 -> 956 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "JOIN", "ignoreCase": true} +) + +0 -> 957 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +957 -> 958 call = (...) => s0() + +0 -> 961 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 962 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 963 conditional = (???*0* === "in") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +963 -> 965 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +963 -> 966 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +966 -> 967 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "IN", "ignoreCase": true} +) + +0 -> 968 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +968 -> 969 call = (...) => s0() + +0 -> 972 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 973 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 974 conditional = (???*0* === "value") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +974 -> 976 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +974 -> 977 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +977 -> 978 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "VALUE", "ignoreCase": true} +) + +0 -> 979 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +979 -> 980 call = (...) => s0() + +0 -> 983 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 984 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 985 conditional = (???*0* === "asc") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +985 -> 987 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +985 -> 988 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +988 -> 989 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "ASC", "ignoreCase": true} +) + +0 -> 990 conditional = ((???*0* | ???*1* | {} | "ASC") !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +990 -> 991 call = (...) => s0() + +990 -> 992 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +992 -> 993 call = (...) => "ASC"() + +0 -> 996 member call = ???*0*["substr"](???*1*, 4) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 997 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 998 conditional = (???*0* === "desc") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +998 -> 1000 member call = ???*0*["substr"](???*1*, 4) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +998 -> 1001 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1001 -> 1002 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "DESC", "ignoreCase": true} +) + +0 -> 1003 conditional = ((???*0* | ???*1* | {} | "DESC") !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1003 -> 1004 call = (...) => s0() + +1003 -> 1005 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1005 -> 1006 call = (...) => "DESC"() + +0 -> 1009 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1010 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1011 conditional = (???*0* === "and") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +1011 -> 1013 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1011 -> 1014 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1014 -> 1015 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "AND", "ignoreCase": true} +) + +0 -> 1016 conditional = ((???*0* | ???*1* | {} | "AND") !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1016 -> 1017 call = (...) => s0() + +1016 -> 1018 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1018 -> 1019 call = (...) => "AND"() + +0 -> 1022 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1023 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1024 conditional = (???*0* === "or") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +1024 -> 1026 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1024 -> 1027 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1027 -> 1028 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "OR", "ignoreCase": true} +) + +0 -> 1029 conditional = ((???*0* | ???*1* | {} | "OR") !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1029 -> 1030 call = (...) => s0() + +1029 -> 1031 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1031 -> 1032 call = (...) => "OR"() + +0 -> 1035 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1036 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1037 conditional = (???*0* === "not") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +1037 -> 1039 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1037 -> 1040 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1040 -> 1041 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "NOT", "ignoreCase": true} +) + +0 -> 1042 conditional = ((???*0* | ???*1* | {} | "NOT") !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1042 -> 1043 call = (...) => s0() + +1042 -> 1044 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1044 -> 1045 call = (...) => "NOT"() + +0 -> 1048 member call = ???*0*["substr"](???*1*, 7) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1049 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 7) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1050 conditional = (???*0* === "between") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 7) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +1050 -> 1052 member call = ???*0*["substr"](???*1*, 7) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1050 -> 1053 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1053 -> 1054 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "BETWEEN", "ignoreCase": true} +) + +0 -> 1055 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1055 -> 1056 call = (...) => s0() + +0 -> 1059 member call = ???*0*["substr"](???*1*, 6) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1060 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 6) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1061 conditional = (???*0* === "exists") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 6) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +1061 -> 1063 member call = ???*0*["substr"](???*1*, 6) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1061 -> 1064 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1064 -> 1065 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "EXISTS", "ignoreCase": true} +) + +0 -> 1066 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1066 -> 1067 call = (...) => s0() + +0 -> 1070 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1071 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1072 conditional = (???*0* === "array") +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toLowerCase"] + ⚠️ unknown object +- *2* ???*3*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +1072 -> 1074 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1072 -> 1075 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1075 -> 1076 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "ARRAY", "ignoreCase": true} +) + +0 -> 1077 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1077 -> 1078 call = (...) => s0() + +0 -> 1080 member call = ???*0*["substr"](???*1*, 4) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1081 conditional = (???*0* === "null") +- *0* ???*1*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1081 -> 1082 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1082 -> 1083 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "null", "ignoreCase": false} +) + +0 -> 1084 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1084 -> 1085 call = (...) => s0() + +0 -> 1087 member call = ???*0*["substr"](???*1*, 4) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1088 conditional = (???*0* === "true") +- *0* ???*1*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1088 -> 1089 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1089 -> 1090 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "true", "ignoreCase": false} +) + +0 -> 1091 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1091 -> 1092 call = (...) => s0() + +0 -> 1094 member call = ???*0*["substr"](???*1*, 5) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1095 conditional = (???*0* === "false") +- *0* ???*1*["substr"](peg$currPos, 5) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1095 -> 1096 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1096 -> 1097 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "false", "ignoreCase": false} +) + +0 -> 1098 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1098 -> 1099 call = (...) => s0() + +0 -> 1101 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1102 conditional = (???*0* === "udf") +- *0* ???*1*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1102 -> 1103 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1103 -> 1104 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "udf", "ignoreCase": false} +) + +0 -> 1105 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1105 -> 1106 call = (...) => s0() + +0 -> 1107 call = (...) => s0() + +0 -> 1108 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1108 -> 1109 call = (...) => s0() + +1108 -> 1110 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1110 -> 1111 call = (...) => s0() + +1110 -> 1112 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1112 -> 1113 call = (...) => s0() + +1112 -> 1114 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1114 -> 1115 call = (...) => s0() + +1114 -> 1116 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1116 -> 1117 call = (...) => s0() + +1116 -> 1118 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1118 -> 1119 call = (...) => s0() + +1118 -> 1120 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1120 -> 1121 call = (...) => s0() + +1120 -> 1122 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1122 -> 1123 call = (...) => s0() + +1122 -> 1124 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1124 -> 1125 call = (...) => s0() + +1124 -> 1126 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1126 -> 1127 call = (...) => s0() + +1126 -> 1128 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1128 -> 1129 call = (...) => s0() + +1128 -> 1130 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1130 -> 1131 call = (...) => s0() + +1130 -> 1132 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1132 -> 1133 call = (...) => s0() + +1132 -> 1134 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1134 -> 1135 call = (...) => s0() + +1134 -> 1136 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1136 -> 1137 call = (...) => s0() + +1136 -> 1138 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1138 -> 1139 call = (...) => s0() + +1138 -> 1140 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1140 -> 1141 call = (...) => s0() + +1140 -> 1142 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1142 -> 1143 call = (...) => s0() + +1142 -> 1144 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1144 -> 1145 call = (...) => s0() + +1144 -> 1146 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1146 -> 1147 call = (...) => s0() + +1146 -> 1148 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1148 -> 1149 call = (...) => s0() + +0 -> 1150 call = (...) => s0() + +0 -> 1151 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1151 -> 1152 call = (...) => s0() + +1151 -> 1153 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1153 -> 1154 call = (...) => {"type": "identifier", "name": name}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1157 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1158 member call = /^[a-zA-Z_]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1159 conditional = /^[a-zA-Z_]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1159 -> 1161 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1159 -> 1162 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1162 -> 1163 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [["a", "z"], ["A", "Z"], "_"], "inverted": false, "ignoreCase": false} +) + +0 -> 1164 call = (...) => s0() + +0 -> 1165 conditional = ((???*0* | ???*1* | {} | ???*3*) !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* (???*4* + (???*5* | ???*7*)) + ⚠️ nested operation +- *4* s1 + ⚠️ circular variable reference +- *5* ???*6*["join"]("") + ⚠️ unknown callee object +- *6* s2 + ⚠️ pattern without value +- *7* ???*8*("") + ⚠️ unknown callee +- *8* []["join"] + ⚠️ non-num constant property on array + +1165 -> 1168 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1165 -> 1169 member call = /^[a-zA-Z0-9_]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1165 -> 1170 conditional = /^[a-zA-Z0-9_]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1170 -> 1172 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1170 -> 1173 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1173 -> 1174 call = (...) => (undefined | FreeVar(undefined))( + { + "type": "class", + "parts": [["a", "z"], ["A", "Z"], ["0", "9"], "_"], + "inverted": false, + "ignoreCase": false + } +) + +1165 -> 1176 member call = (???*0* | [])["push"]((???*1* | ???*2* | {})) +- *0* s2 + ⚠️ pattern without value +- *1* s3 + ⚠️ pattern without value +- *2* ???*3*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +1165 -> 1179 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1165 -> 1180 member call = /^[a-zA-Z0-9_]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1165 -> 1181 conditional = /^[a-zA-Z0-9_]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1181 -> 1183 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1181 -> 1184 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1184 -> 1185 call = (...) => (undefined | FreeVar(undefined))( + { + "type": "class", + "parts": [["a", "z"], ["A", "Z"], ["0", "9"], "_"], + "inverted": false, + "ignoreCase": false + } +) + +1165 -> 1186 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1186 -> 1187 call = (...) => (head + tail["join"](""))( + (???*0* | ???*1* | {} | (???*3* + (???*4* | ???*6*))), + (???*8* | []) +) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* s1 + ⚠️ circular variable reference +- *4* ???*5*["join"]("") + ⚠️ unknown callee object +- *5* s2 + ⚠️ pattern without value +- *6* ???*7*("") + ⚠️ unknown callee +- *7* []["join"] + ⚠️ non-num constant property on array +- *8* s2 + ⚠️ pattern without value + +0 -> 1189 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1190 conditional = (???*0* === 64) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1190 -> 1191 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1191 -> 1192 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "@", "ignoreCase": false} +) + +0 -> 1193 conditional = ((???*0* | "@" | {} | {"type": "parameter_name", "name": ???*1*}) !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substring"](peg$savedPos, peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1193 -> 1194 call = (...) => s0() + +1193 -> 1195 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1195 -> 1196 call = (...) => {"type": "parameter_name", "name": text()}() + +0 -> 1198 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1199 conditional = (???*0* === 43) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1199 -> 1200 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1200 -> 1201 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "+", "ignoreCase": false} +) + +0 -> 1202 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1202 -> 1204 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1202 -> 1205 conditional = (???*0* === 45) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1205 -> 1206 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1206 -> 1207 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "-", "ignoreCase": false} +) + +1202 -> 1208 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1208 -> 1210 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1208 -> 1211 conditional = (???*0* === 126) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1211 -> 1212 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1212 -> 1213 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "~", "ignoreCase": false} +) + +1208 -> 1214 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1214 -> 1215 call = (...) => s0() + +0 -> 1217 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1218 conditional = (???*0* === 34) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1218 -> 1219 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1219 -> 1220 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\"", "ignoreCase": false} +) + +0 -> 1221 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1221 -> 1223 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1221 -> 1224 conditional = (???*0* === 92) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1224 -> 1225 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1225 -> 1226 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\\", "ignoreCase": false} +) + +0 -> 1227 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1227 -> 1228 call = (...) => s0() + +1227 -> 1229 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1229 -> 1230 call = (...) => text()() + +0 -> 1231 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1231 -> 1233 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1231 -> 1234 conditional = (???*0* === 92) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1234 -> 1235 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1235 -> 1236 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\\", "ignoreCase": false} +) + +1231 -> 1237 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1237 -> 1238 call = (...) => s0() + +1237 -> 1239 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1239 -> 1240 call = (...) => seq(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1242 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1243 conditional = (???*0* === 39) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1243 -> 1244 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1244 -> 1245 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "'", "ignoreCase": false} +) + +0 -> 1246 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1246 -> 1248 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1246 -> 1249 conditional = (???*0* === 92) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1249 -> 1250 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1250 -> 1251 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\\", "ignoreCase": false} +) + +0 -> 1252 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1252 -> 1253 call = (...) => s0() + +1252 -> 1254 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1254 -> 1255 call = (...) => text()() + +0 -> 1256 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1256 -> 1258 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1256 -> 1259 conditional = (???*0* === 92) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1259 -> 1260 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1260 -> 1261 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\\", "ignoreCase": false} +) + +1256 -> 1262 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1262 -> 1263 call = (...) => s0() + +1262 -> 1264 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1264 -> 1265 call = (...) => seq(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1268 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1269 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1269 -> 1270 call = (...) => (undefined | FreeVar(undefined))({"type": "any"}) + +0 -> 1271 call = (...) => s0() + +0 -> 1272 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1272 -> 1273 call = (...) => s0() + +0 -> 1274 call = (...) => s0() + +0 -> 1275 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1275 -> 1276 call = (...) => s0() + +0 -> 1278 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1279 conditional = (???*0* === 39) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1279 -> 1280 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1280 -> 1281 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "'", "ignoreCase": false} +) + +0 -> 1282 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1282 -> 1284 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1282 -> 1285 conditional = (???*0* === 34) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1285 -> 1286 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1286 -> 1287 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\"", "ignoreCase": false} +) + +1282 -> 1288 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1288 -> 1290 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1288 -> 1291 conditional = (???*0* === 92) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1291 -> 1292 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1292 -> 1293 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "\\", "ignoreCase": false} +) + +1288 -> 1294 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1294 -> 1296 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1294 -> 1297 conditional = (???*0* === 98) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1297 -> 1298 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1298 -> 1299 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "b", "ignoreCase": false} +) + +1294 -> 1300 conditional = ((???*0* | "b" | {} | "\b" | "f" | "\f" | "n" | "\n" | "r" | "\r" | "t" | "\t") !== {}) +- *0* s1 + ⚠️ pattern without value + +1300 -> 1301 call = (...) => "\b"() + +1294 -> 1302 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1302 -> 1304 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1302 -> 1305 conditional = (???*0* === 102) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1305 -> 1306 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1306 -> 1307 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "f", "ignoreCase": false} +) + +1302 -> 1308 conditional = ((???*0* | "b" | {} | "\b" | "f" | "\f" | "n" | "\n" | "r" | "\r" | "t" | "\t") !== {}) +- *0* s1 + ⚠️ pattern without value + +1308 -> 1309 call = (...) => "\f"() + +1302 -> 1310 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1310 -> 1312 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1310 -> 1313 conditional = (???*0* === 110) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1313 -> 1314 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1314 -> 1315 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "n", "ignoreCase": false} +) + +1310 -> 1316 conditional = ((???*0* | "b" | {} | "\b" | "f" | "\f" | "n" | "\n" | "r" | "\r" | "t" | "\t") !== {}) +- *0* s1 + ⚠️ pattern without value + +1316 -> 1317 call = (...) => "\n"() + +1310 -> 1318 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1318 -> 1320 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1318 -> 1321 conditional = (???*0* === 114) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1321 -> 1322 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1322 -> 1323 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "r", "ignoreCase": false} +) + +1318 -> 1324 conditional = ((???*0* | "b" | {} | "\b" | "f" | "\f" | "n" | "\n" | "r" | "\r" | "t" | "\t") !== {}) +- *0* s1 + ⚠️ pattern without value + +1324 -> 1325 call = (...) => "\r"() + +1318 -> 1326 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1326 -> 1328 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1326 -> 1329 conditional = (???*0* === 116) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1329 -> 1330 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1330 -> 1331 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "t", "ignoreCase": false} +) + +1326 -> 1332 conditional = ((???*0* | "b" | {} | "\b" | "f" | "\f" | "n" | "\n" | "r" | "\r" | "t" | "\t") !== {}) +- *0* s1 + ⚠️ pattern without value + +1332 -> 1333 call = (...) => "\t"() + +0 -> 1334 call = (...) => s0() + +0 -> 1335 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1335 -> 1336 call = (...) => s0() + +1335 -> 1337 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1337 -> 1338 call = (...) => text()() + +0 -> 1339 call = (...) => s0() + +0 -> 1340 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1340 -> 1342 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1340 -> 1343 conditional = (???*0* === 117) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1343 -> 1344 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1344 -> 1345 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "u", "ignoreCase": false} +) + +0 -> 1347 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1348 conditional = (???*0* === 117) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1348 -> 1349 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1349 -> 1350 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "u", "ignoreCase": false} +) + +0 -> 1351 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1351 -> 1352 call = (...) => s0() + +1351 -> 1353 conditional = (( + | ???*0* + | ???*1* + | {} + | [???*3*, (???*4* | ???*5* | {}), (???*7* | ???*8* | {}), (???*10* | ???*11* | {})] +) !== {}) +- *0* s4 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* s4 + ⚠️ circular variable reference +- *4* s5 + ⚠️ pattern without value +- *5* ???*6*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* s6 + ⚠️ pattern without value +- *8* ???*9*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* s7 + ⚠️ pattern without value +- *11* ???*12*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *12* arguments[0] + ⚠️ function calls are not analysed yet + +1353 -> 1354 call = (...) => s0() + +1353 -> 1355 conditional = ((???*0* | ???*1* | {}) !== {}) +- *0* s5 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1355 -> 1356 call = (...) => s0() + +1355 -> 1357 conditional = ((???*0* | ???*1* | {}) !== {}) +- *0* s6 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1357 -> 1358 call = (...) => s0() + +1351 -> 1359 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1359 -> 1361 member call = ???*0*["substring"](???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1351 -> 1362 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1362 -> 1363 call = (...) => FreeVar(String)["fromCharCode"](FreeVar(parseInt)(digits, 16))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1366 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1367 member call = /^[0-9a-f]/i["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1368 conditional = /^[0-9a-f]/i["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1368 -> 1370 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1368 -> 1371 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1371 -> 1372 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [["0", "9"], ["a", "f"]], "inverted": false, "ignoreCase": true} +) + +0 -> 1373 call = (...) => s0() + +0 -> 1374 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1374 -> 1375 call = (...) => s0() + +1374 -> 1376 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1376 -> 1377 call = (...) => s0() + +1374 -> 1378 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1378 -> 1379 call = (...) => s0() + +1378 -> 1380 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1380 -> 1381 call = (...) => s0() + +1380 -> 1382 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1382 -> 1383 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1374 -> 1384 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1384 -> 1385 call = (...) => {"property": property, "alias": alias}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1386 call = (...) => s0() + +0 -> 1387 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1387 -> 1388 call = (...) => s0() + +1387 -> 1389 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1389 -> 1390 call = (...) => s0() + +1389 -> 1391 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1391 -> 1392 call = (...) => s0() + +1391 -> 1393 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1393 -> 1394 call = (...) => s0() + +1393 -> 1395 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1395 -> 1396 call = (...) => s0() + +1395 -> 1397 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1397 -> 1399 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1397 -> 1400 conditional = (???*0* === 40) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1400 -> 1401 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1401 -> 1402 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "(", "ignoreCase": false} +) + +1397 -> 1403 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1403 -> 1404 call = (...) => s0() + +1403 -> 1405 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1405 -> 1406 call = (...) => s0() + +1405 -> 1407 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1407 -> 1408 call = (...) => s0() + +1407 -> 1409 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +1409 -> 1411 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1409 -> 1412 conditional = (???*0* === 41) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1412 -> 1413 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1413 -> 1414 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ")", "ignoreCase": false} +) + +1409 -> 1415 conditional = ((???*0* | ")" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +1415 -> 1416 call = (...) => expression(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1417 call = (...) => s0() + +0 -> 1418 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1418 -> 1419 call = (...) => s0() + +1418 -> 1420 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1420 -> 1421 call = (...) => s0() + +0 -> 1422 call = (...) => s0() + +0 -> 1423 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1423 -> 1424 call = (...) => s0() + +1423 -> 1425 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1425 -> 1426 call = (...) => s0() + +1425 -> 1427 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1427 -> 1428 call = (...) => {"type": "array_subquery_expression", "expression": expression}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1429 call = (...) => s0() + +0 -> 1430 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1430 -> 1431 call = (...) => s0() + +1430 -> 1432 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1432 -> 1433 call = (...) => s0() + +1432 -> 1434 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1434 -> 1435 call = (...) => {"type": "exists_subquery_expression", "expression": expression}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1436 call = (...) => s0() + +0 -> 1437 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1437 -> 1438 call = (...) => {"type": "scalar_subquery_expression", "expression": expression}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1439 call = (...) => s0() + +0 -> 1440 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1440 -> 1441 call = (...) => s0() + +1440 -> 1442 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1442 -> 1444 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1442 -> 1445 conditional = (???*0* === 46) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1445 -> 1446 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1446 -> 1447 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ".", "ignoreCase": false} +) + +1442 -> 1448 conditional = ((???*0* | "." | {} | "[") !== {}) +- *0* s5 + ⚠️ pattern without value + +1448 -> 1449 call = (...) => s0() + +1448 -> 1450 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1450 -> 1451 call = (...) => s0() + +1450 -> 1452 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1452 -> 1453 call = (...) => s0() + +1452 -> 1454 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +1454 -> 1455 call = (...) => {"property": property, "computed": false}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1440 -> 1456 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1456 -> 1457 call = (...) => s0() + +1456 -> 1458 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1458 -> 1460 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1458 -> 1461 conditional = (???*0* === 91) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1461 -> 1462 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1462 -> 1463 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "[", "ignoreCase": false} +) + +1458 -> 1464 conditional = ((???*0* | "." | {} | "[") !== {}) +- *0* s5 + ⚠️ pattern without value + +1464 -> 1465 call = (...) => s0() + +1464 -> 1466 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1466 -> 1467 call = (...) => s0() + +1466 -> 1468 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1468 -> 1469 call = (...) => s0() + +1468 -> 1470 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1470 -> 1471 call = (...) => s0() + +1466 -> 1472 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1472 -> 1473 call = (...) => s0() + +1472 -> 1474 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +1474 -> 1476 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1474 -> 1477 conditional = (???*0* === 93) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1477 -> 1478 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1478 -> 1479 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "]", "ignoreCase": false} +) + +1474 -> 1480 conditional = ((???*0* | "]" | {}) !== {}) +- *0* s9 + ⚠️ pattern without value + +1480 -> 1481 call = (...) => {"property": property, "computed": true}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1440 -> 1483 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1440 -> 1484 call = (...) => s0() + +1440 -> 1485 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1485 -> 1487 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1485 -> 1488 conditional = (???*0* === 46) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1488 -> 1489 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1489 -> 1490 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ".", "ignoreCase": false} +) + +1485 -> 1491 conditional = ((???*0* | "." | {} | "[") !== {}) +- *0* s5 + ⚠️ pattern without value + +1491 -> 1492 call = (...) => s0() + +1491 -> 1493 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1493 -> 1494 call = (...) => s0() + +1493 -> 1495 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1495 -> 1496 call = (...) => s0() + +1495 -> 1497 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +1497 -> 1498 call = (...) => {"property": property, "computed": false}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1440 -> 1499 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1499 -> 1500 call = (...) => s0() + +1499 -> 1501 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1501 -> 1503 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1501 -> 1504 conditional = (???*0* === 91) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1504 -> 1505 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1505 -> 1506 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "[", "ignoreCase": false} +) + +1501 -> 1507 conditional = ((???*0* | "." | {} | "[") !== {}) +- *0* s5 + ⚠️ pattern without value + +1507 -> 1508 call = (...) => s0() + +1507 -> 1509 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1509 -> 1510 call = (...) => s0() + +1509 -> 1511 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1511 -> 1512 call = (...) => s0() + +1511 -> 1513 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1513 -> 1514 call = (...) => s0() + +1509 -> 1515 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1515 -> 1516 call = (...) => s0() + +1515 -> 1517 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +1517 -> 1519 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1517 -> 1520 conditional = (???*0* === 93) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1520 -> 1521 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1521 -> 1522 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "]", "ignoreCase": false} +) + +1517 -> 1523 conditional = ((???*0* | "]" | {}) !== {}) +- *0* s9 + ⚠️ pattern without value + +1523 -> 1524 call = (...) => {"property": property, "computed": true}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1440 -> 1525 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1525 -> 1526 call = (...) => tail["reduce"](*arrow function 13694*, head)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1527 call = (...) => s0() + +0 -> 1528 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1528 -> 1529 call = (...) => s0() + +1528 -> 1530 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1530 -> 1531 call = (...) => s0() + +1530 -> 1532 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1532 -> 1533 call = (...) => s0() + +1532 -> 1534 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1534 -> 1535 call = (...) => s0() + +1534 -> 1536 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1536 -> 1537 call = (...) => {"type": "scalar_unary_expression", "operator": operator, "argument": argument}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1538 call = (...) => s0() + +0 -> 1539 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1539 -> 1540 call = (...) => s0() + +1539 -> 1541 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1541 -> 1543 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1541 -> 1544 conditional = (???*0* === 63) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1544 -> 1545 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1545 -> 1546 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "?", "ignoreCase": false} +) + +1541 -> 1547 conditional = ((???*0* | "?" | {}) !== {}) +- *0* s3 + ⚠️ pattern without value + +1547 -> 1548 call = (...) => s0() + +1547 -> 1549 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +1549 -> 1550 call = (...) => s0() + +1549 -> 1551 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1551 -> 1552 call = (...) => s0() + +1551 -> 1553 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1553 -> 1555 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1553 -> 1556 conditional = (???*0* === 58) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1556 -> 1557 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1557 -> 1558 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ":", "ignoreCase": false} +) + +1553 -> 1559 conditional = ((???*0* | ":" | {}) !== {}) +- *0* s7 + ⚠️ pattern without value + +1559 -> 1560 call = (...) => s0() + +1559 -> 1561 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +1561 -> 1562 call = (...) => s0() + +1561 -> 1563 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1563 -> 1564 call = (...) => { + "type": "scalar_conditional_expression", + "test": test, + "consequent": consequent, + "alternate": alternate +}(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1565 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1565 -> 1566 call = (...) => s0() + +0 -> 1567 call = (...) => s0() + +0 -> 1568 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1568 -> 1569 call = (...) => s0() + +1568 -> 1570 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1570 -> 1571 call = (...) => s0() + +1570 -> 1572 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1572 -> 1574 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1572 -> 1575 conditional = (???*0* === "??") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1575 -> 1576 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1576 -> 1577 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "??", "ignoreCase": false} +) + +1570 -> 1578 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1578 -> 1579 call = (...) => s0() + +1578 -> 1580 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1580 -> 1581 call = (...) => s0() + +1568 -> 1583 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1568 -> 1584 call = (...) => s0() + +1568 -> 1585 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1585 -> 1586 call = (...) => s0() + +1585 -> 1587 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1587 -> 1589 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1587 -> 1590 conditional = (???*0* === "??") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1590 -> 1591 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1591 -> 1592 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "??", "ignoreCase": false} +) + +1585 -> 1593 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1593 -> 1594 call = (...) => s0() + +1593 -> 1595 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1595 -> 1596 call = (...) => s0() + +1568 -> 1597 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1597 -> 1598 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1599 call = (...) => s0() + +0 -> 1600 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1600 -> 1601 call = (...) => s0() + +1600 -> 1602 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1602 -> 1603 call = (...) => s0() + +1602 -> 1604 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1604 -> 1605 call = (...) => s0() + +1604 -> 1606 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1606 -> 1607 call = (...) => s0() + +1600 -> 1609 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1600 -> 1610 call = (...) => s0() + +1600 -> 1611 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1611 -> 1612 call = (...) => s0() + +1611 -> 1613 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1613 -> 1614 call = (...) => s0() + +1613 -> 1615 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1615 -> 1616 call = (...) => s0() + +1600 -> 1617 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1617 -> 1618 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1619 call = (...) => s0() + +0 -> 1620 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1620 -> 1621 call = (...) => s0() + +1620 -> 1622 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1622 -> 1624 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1622 -> 1625 conditional = (???*0* === 61) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1625 -> 1626 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1626 -> 1627 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "=", "ignoreCase": false} +) + +1622 -> 1628 conditional = ((???*0* | "=" | {} | "!=" | "<>") === {}) +- *0* s5 + ⚠️ pattern without value + +1628 -> 1630 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1628 -> 1631 conditional = (???*0* === "!=") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1631 -> 1632 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1632 -> 1633 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "!=", "ignoreCase": false} +) + +1628 -> 1634 conditional = ((???*0* | "=" | {} | "!=" | "<>") === {}) +- *0* s5 + ⚠️ pattern without value + +1634 -> 1636 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1634 -> 1637 conditional = (???*0* === "<>") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1637 -> 1638 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1638 -> 1639 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "<>", "ignoreCase": false} +) + +1622 -> 1640 conditional = ((???*0* | "=" | {} | "!=" | "<>") !== {}) +- *0* s5 + ⚠️ pattern without value + +1640 -> 1641 call = (...) => s0() + +1640 -> 1642 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1642 -> 1643 call = (...) => s0() + +1620 -> 1645 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1620 -> 1646 call = (...) => s0() + +1620 -> 1647 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1647 -> 1649 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1647 -> 1650 conditional = (???*0* === 61) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1650 -> 1651 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1651 -> 1652 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "=", "ignoreCase": false} +) + +1647 -> 1653 conditional = ((???*0* | "=" | {} | "!=" | "<>") === {}) +- *0* s5 + ⚠️ pattern without value + +1653 -> 1655 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1653 -> 1656 conditional = (???*0* === "!=") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1656 -> 1657 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1657 -> 1658 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "!=", "ignoreCase": false} +) + +1653 -> 1659 conditional = ((???*0* | "=" | {} | "!=" | "<>") === {}) +- *0* s5 + ⚠️ pattern without value + +1659 -> 1661 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1659 -> 1662 conditional = (???*0* === "<>") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1662 -> 1663 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1663 -> 1664 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "<>", "ignoreCase": false} +) + +1647 -> 1665 conditional = ((???*0* | "=" | {} | "!=" | "<>") !== {}) +- *0* s5 + ⚠️ pattern without value + +1665 -> 1666 call = (...) => s0() + +1665 -> 1667 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1667 -> 1668 call = (...) => s0() + +1620 -> 1669 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1669 -> 1670 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1671 call = (...) => s0() + +0 -> 1672 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1672 -> 1673 call = (...) => s0() + +1672 -> 1674 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1674 -> 1676 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1674 -> 1677 conditional = (???*0* === "<=") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1677 -> 1678 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1678 -> 1679 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "<=", "ignoreCase": false} +) + +1674 -> 1680 conditional = ((???*0* | "<=" | {} | ">=" | "<" | ">") === {}) +- *0* s5 + ⚠️ pattern without value + +1680 -> 1682 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1680 -> 1683 conditional = (???*0* === ">=") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1683 -> 1684 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1684 -> 1685 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ">=", "ignoreCase": false} +) + +1680 -> 1686 conditional = ((???*0* | "<=" | {} | ">=" | "<" | ">") === {}) +- *0* s5 + ⚠️ pattern without value + +1686 -> 1688 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1686 -> 1689 conditional = (???*0* === 60) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1689 -> 1690 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1690 -> 1691 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "<", "ignoreCase": false} +) + +1686 -> 1692 conditional = ((???*0* | "<=" | {} | ">=" | "<" | ">") === {}) +- *0* s5 + ⚠️ pattern without value + +1692 -> 1694 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1692 -> 1695 conditional = (???*0* === 62) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1695 -> 1696 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1696 -> 1697 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ">", "ignoreCase": false} +) + +1674 -> 1698 conditional = ((???*0* | "<=" | {} | ">=" | "<" | ">") !== {}) +- *0* s5 + ⚠️ pattern without value + +1698 -> 1699 call = (...) => s0() + +1698 -> 1700 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1700 -> 1701 call = (...) => s0() + +1672 -> 1703 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1672 -> 1704 call = (...) => s0() + +1672 -> 1705 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1705 -> 1707 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1705 -> 1708 conditional = (???*0* === "<=") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1708 -> 1709 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1709 -> 1710 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "<=", "ignoreCase": false} +) + +1705 -> 1711 conditional = ((???*0* | "<=" | {} | ">=" | "<" | ">") === {}) +- *0* s5 + ⚠️ pattern without value + +1711 -> 1713 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1711 -> 1714 conditional = (???*0* === ">=") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1714 -> 1715 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1715 -> 1716 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ">=", "ignoreCase": false} +) + +1711 -> 1717 conditional = ((???*0* | "<=" | {} | ">=" | "<" | ">") === {}) +- *0* s5 + ⚠️ pattern without value + +1717 -> 1719 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1717 -> 1720 conditional = (???*0* === 60) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1720 -> 1721 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1721 -> 1722 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "<", "ignoreCase": false} +) + +1717 -> 1723 conditional = ((???*0* | "<=" | {} | ">=" | "<" | ">") === {}) +- *0* s5 + ⚠️ pattern without value + +1723 -> 1725 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1723 -> 1726 conditional = (???*0* === 62) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1726 -> 1727 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1727 -> 1728 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ">", "ignoreCase": false} +) + +1705 -> 1729 conditional = ((???*0* | "<=" | {} | ">=" | "<" | ">") !== {}) +- *0* s5 + ⚠️ pattern without value + +1729 -> 1730 call = (...) => s0() + +1729 -> 1731 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1731 -> 1732 call = (...) => s0() + +1672 -> 1733 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1733 -> 1734 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1735 call = (...) => s0() + +0 -> 1736 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1736 -> 1737 call = (...) => s0() + +1736 -> 1738 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1738 -> 1739 call = (...) => s0() + +1738 -> 1740 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1740 -> 1741 call = (...) => s0() + +1740 -> 1742 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +1742 -> 1744 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1742 -> 1745 conditional = (???*0* === 40) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1745 -> 1746 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1746 -> 1747 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "(", "ignoreCase": false} +) + +1742 -> 1748 conditional = ((???*0* | "(" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +1748 -> 1749 call = (...) => s0() + +1748 -> 1750 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1750 -> 1751 call = (...) => s0() + +1750 -> 1752 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1752 -> 1753 call = (...) => s0() + +1752 -> 1754 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +1754 -> 1756 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1754 -> 1757 conditional = (???*0* === 41) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1757 -> 1758 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1758 -> 1759 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ")", "ignoreCase": false} +) + +1754 -> 1760 conditional = ((???*0* | ")" | {}) !== {}) +- *0* s9 + ⚠️ pattern without value + +1760 -> 1761 call = (...) => {"type": "scalar_in_expression", "value": value, "list": list}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1762 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1762 -> 1763 call = (...) => s0() + +0 -> 1764 call = (...) => s0() + +0 -> 1765 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1765 -> 1766 call = (...) => s0() + +1765 -> 1767 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1767 -> 1768 call = (...) => s0() + +1767 -> 1769 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1769 -> 1770 call = (...) => s0() + +1769 -> 1771 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +1771 -> 1772 call = (...) => s0() + +1771 -> 1773 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1773 -> 1774 call = (...) => s0() + +1773 -> 1775 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1775 -> 1776 call = (...) => s0() + +1775 -> 1777 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1777 -> 1778 call = (...) => s0() + +1777 -> 1779 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +1779 -> 1780 call = (...) => s0() + +1779 -> 1781 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1781 -> 1782 call = (...) => {"type": "scalar_between_expression", "value": value, "begin": begin, "end": end}(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1783 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1783 -> 1784 call = (...) => s0() + +0 -> 1785 call = (...) => s0() + +0 -> 1786 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1786 -> 1787 call = (...) => s0() + +1786 -> 1788 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1788 -> 1790 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1788 -> 1791 conditional = (???*0* === 124) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1791 -> 1792 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1792 -> 1793 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "|", "ignoreCase": false} +) + +1788 -> 1794 conditional = ((???*0* | "|" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +1794 -> 1795 call = (...) => s0() + +1794 -> 1796 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1796 -> 1797 call = (...) => s0() + +1786 -> 1799 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1786 -> 1800 call = (...) => s0() + +1786 -> 1801 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1801 -> 1803 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1801 -> 1804 conditional = (???*0* === 124) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1804 -> 1805 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1805 -> 1806 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "|", "ignoreCase": false} +) + +1801 -> 1807 conditional = ((???*0* | "|" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +1807 -> 1808 call = (...) => s0() + +1807 -> 1809 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1809 -> 1810 call = (...) => s0() + +1786 -> 1811 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1811 -> 1812 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1813 call = (...) => s0() + +0 -> 1814 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1814 -> 1815 call = (...) => s0() + +1814 -> 1816 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1816 -> 1818 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1816 -> 1819 conditional = (???*0* === 94) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1819 -> 1820 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1820 -> 1821 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "^", "ignoreCase": false} +) + +1816 -> 1822 conditional = ((???*0* | "^" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +1822 -> 1823 call = (...) => s0() + +1822 -> 1824 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1824 -> 1825 call = (...) => s0() + +1814 -> 1827 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1814 -> 1828 call = (...) => s0() + +1814 -> 1829 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1829 -> 1831 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1829 -> 1832 conditional = (???*0* === 94) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1832 -> 1833 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1833 -> 1834 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "^", "ignoreCase": false} +) + +1829 -> 1835 conditional = ((???*0* | "^" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +1835 -> 1836 call = (...) => s0() + +1835 -> 1837 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1837 -> 1838 call = (...) => s0() + +1814 -> 1839 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1839 -> 1840 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1841 call = (...) => s0() + +0 -> 1842 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1842 -> 1843 call = (...) => s0() + +1842 -> 1844 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1844 -> 1846 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1844 -> 1847 conditional = (???*0* === 38) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1847 -> 1848 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1848 -> 1849 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "&", "ignoreCase": false} +) + +1844 -> 1850 conditional = ((???*0* | "&" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +1850 -> 1851 call = (...) => s0() + +1850 -> 1852 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1852 -> 1853 call = (...) => s0() + +1842 -> 1855 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1842 -> 1856 call = (...) => s0() + +1842 -> 1857 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1857 -> 1859 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1857 -> 1860 conditional = (???*0* === 38) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1860 -> 1861 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1861 -> 1862 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "&", "ignoreCase": false} +) + +1857 -> 1863 conditional = ((???*0* | "&" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +1863 -> 1864 call = (...) => s0() + +1863 -> 1865 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1865 -> 1866 call = (...) => s0() + +1842 -> 1867 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1867 -> 1868 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1869 call = (...) => s0() + +0 -> 1870 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1870 -> 1871 call = (...) => s0() + +1870 -> 1872 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1872 -> 1874 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1872 -> 1875 conditional = (???*0* === "<<") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1875 -> 1876 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1876 -> 1877 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "<<", "ignoreCase": false} +) + +1872 -> 1878 conditional = ((???*0* | "<<" | {} | ">>>" | ">>") === {}) +- *0* s5 + ⚠️ pattern without value + +1878 -> 1880 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1878 -> 1881 conditional = (???*0* === ">>>") +- *0* ???*1*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1881 -> 1882 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1882 -> 1883 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ">>>", "ignoreCase": false} +) + +1878 -> 1884 conditional = ((???*0* | "<<" | {} | ">>>" | ">>") === {}) +- *0* s5 + ⚠️ pattern without value + +1884 -> 1886 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1884 -> 1887 conditional = (???*0* === ">>") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1887 -> 1888 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1888 -> 1889 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ">>", "ignoreCase": false} +) + +1872 -> 1890 conditional = ((???*0* | "<<" | {} | ">>>" | ">>") !== {}) +- *0* s5 + ⚠️ pattern without value + +1890 -> 1891 call = (...) => s0() + +1890 -> 1892 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1892 -> 1893 call = (...) => s0() + +1870 -> 1895 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1870 -> 1896 call = (...) => s0() + +1870 -> 1897 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1897 -> 1899 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1897 -> 1900 conditional = (???*0* === "<<") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1900 -> 1901 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1901 -> 1902 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "<<", "ignoreCase": false} +) + +1897 -> 1903 conditional = ((???*0* | "<<" | {} | ">>>" | ">>") === {}) +- *0* s5 + ⚠️ pattern without value + +1903 -> 1905 member call = ???*0*["substr"](???*1*, 3) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1903 -> 1906 conditional = (???*0* === ">>>") +- *0* ???*1*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1906 -> 1907 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1907 -> 1908 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ">>>", "ignoreCase": false} +) + +1903 -> 1909 conditional = ((???*0* | "<<" | {} | ">>>" | ">>") === {}) +- *0* s5 + ⚠️ pattern without value + +1909 -> 1911 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1909 -> 1912 conditional = (???*0* === ">>") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1912 -> 1913 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1913 -> 1914 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ">>", "ignoreCase": false} +) + +1897 -> 1915 conditional = ((???*0* | "<<" | {} | ">>>" | ">>") !== {}) +- *0* s5 + ⚠️ pattern without value + +1915 -> 1916 call = (...) => s0() + +1915 -> 1917 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1917 -> 1918 call = (...) => s0() + +1870 -> 1919 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1919 -> 1920 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1921 call = (...) => s0() + +0 -> 1922 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1922 -> 1923 call = (...) => s0() + +1922 -> 1924 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1924 -> 1926 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1924 -> 1927 conditional = (???*0* === 43) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1927 -> 1928 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1928 -> 1929 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "+", "ignoreCase": false} +) + +1924 -> 1930 conditional = ((???*0* | "+" | {} | "-" | "||") === {}) +- *0* s5 + ⚠️ pattern without value + +1930 -> 1932 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1930 -> 1933 conditional = (???*0* === 45) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1933 -> 1934 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1934 -> 1935 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "-", "ignoreCase": false} +) + +1930 -> 1936 conditional = ((???*0* | "+" | {} | "-" | "||") === {}) +- *0* s5 + ⚠️ pattern without value + +1936 -> 1938 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1936 -> 1939 conditional = (???*0* === "||") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1939 -> 1940 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1940 -> 1941 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "||", "ignoreCase": false} +) + +1924 -> 1942 conditional = ((???*0* | "+" | {} | "-" | "||") !== {}) +- *0* s5 + ⚠️ pattern without value + +1942 -> 1943 call = (...) => s0() + +1942 -> 1944 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1944 -> 1945 call = (...) => s0() + +1922 -> 1947 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1922 -> 1948 call = (...) => s0() + +1922 -> 1949 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1949 -> 1951 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1949 -> 1952 conditional = (???*0* === 43) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1952 -> 1953 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1953 -> 1954 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "+", "ignoreCase": false} +) + +1949 -> 1955 conditional = ((???*0* | "+" | {} | "-" | "||") === {}) +- *0* s5 + ⚠️ pattern without value + +1955 -> 1957 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1955 -> 1958 conditional = (???*0* === 45) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1958 -> 1959 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1959 -> 1960 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "-", "ignoreCase": false} +) + +1955 -> 1961 conditional = ((???*0* | "+" | {} | "-" | "||") === {}) +- *0* s5 + ⚠️ pattern without value + +1961 -> 1963 member call = ???*0*["substr"](???*1*, 2) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1961 -> 1964 conditional = (???*0* === "||") +- *0* ???*1*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1964 -> 1965 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1965 -> 1966 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "||", "ignoreCase": false} +) + +1949 -> 1967 conditional = ((???*0* | "+" | {} | "-" | "||") !== {}) +- *0* s5 + ⚠️ pattern without value + +1967 -> 1968 call = (...) => s0() + +1967 -> 1969 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1969 -> 1970 call = (...) => s0() + +1922 -> 1971 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +1971 -> 1972 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 1973 call = (...) => s0() + +0 -> 1974 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1974 -> 1975 call = (...) => s0() + +1974 -> 1976 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1976 -> 1978 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1976 -> 1979 conditional = (???*0* === 42) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1979 -> 1980 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1980 -> 1981 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "*", "ignoreCase": false} +) + +1976 -> 1982 conditional = ((???*0* | "*" | {} | "/" | "%") === {}) +- *0* s5 + ⚠️ pattern without value + +1982 -> 1984 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1982 -> 1985 conditional = (???*0* === 47) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1985 -> 1986 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1986 -> 1987 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "/", "ignoreCase": false} +) + +1982 -> 1988 conditional = ((???*0* | "*" | {} | "/" | "%") === {}) +- *0* s5 + ⚠️ pattern without value + +1988 -> 1990 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1988 -> 1991 conditional = (???*0* === 37) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1991 -> 1992 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +1992 -> 1993 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "%", "ignoreCase": false} +) + +1976 -> 1994 conditional = ((???*0* | "*" | {} | "/" | "%") !== {}) +- *0* s5 + ⚠️ pattern without value + +1994 -> 1995 call = (...) => s0() + +1994 -> 1996 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +1996 -> 1997 call = (...) => s0() + +1974 -> 1999 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1974 -> 2000 call = (...) => s0() + +1974 -> 2001 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2001 -> 2003 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2001 -> 2004 conditional = (???*0* === 42) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2004 -> 2005 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2005 -> 2006 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "*", "ignoreCase": false} +) + +2001 -> 2007 conditional = ((???*0* | "*" | {} | "/" | "%") === {}) +- *0* s5 + ⚠️ pattern without value + +2007 -> 2009 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2007 -> 2010 conditional = (???*0* === 47) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2010 -> 2011 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2011 -> 2012 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "/", "ignoreCase": false} +) + +2007 -> 2013 conditional = ((???*0* | "*" | {} | "/" | "%") === {}) +- *0* s5 + ⚠️ pattern without value + +2013 -> 2015 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2013 -> 2016 conditional = (???*0* === 37) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2016 -> 2017 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2017 -> 2018 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "%", "ignoreCase": false} +) + +2001 -> 2019 conditional = ((???*0* | "*" | {} | "/" | "%") !== {}) +- *0* s5 + ⚠️ pattern without value + +2019 -> 2020 call = (...) => s0() + +2019 -> 2021 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +2021 -> 2022 call = (...) => s0() + +1974 -> 2023 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +2023 -> 2024 call = (...) => buildBinaryExpression(head, tail)(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 2025 call = (...) => s0() + +0 -> 2026 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2026 -> 2027 call = (...) => s0() + +0 -> 2028 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2028 -> 2029 call = (...) => s0() + +2028 -> 2030 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +2030 -> 2032 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2030 -> 2033 conditional = (???*0* === 58) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2033 -> 2034 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2034 -> 2035 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ":", "ignoreCase": false} +) + +2030 -> 2036 conditional = ((???*0* | ":" | {}) !== {}) +- *0* s3 + ⚠️ pattern without value + +2036 -> 2037 call = (...) => s0() + +2036 -> 2038 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +2038 -> 2039 call = (...) => s0() + +2038 -> 2040 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2040 -> 2041 call = (...) => {"key": key, "value": value}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2042 call = (...) => s0() + +0 -> 2043 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2043 -> 2044 call = (...) => s0() + +0 -> 2045 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2045 -> 2046 call = (...) => s0() + +2045 -> 2047 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +2047 -> 2049 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2047 -> 2050 conditional = (???*0* === 58) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2050 -> 2051 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2051 -> 2052 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ":", "ignoreCase": false} +) + +2047 -> 2053 conditional = ((???*0* | ":" | {}) !== {}) +- *0* s3 + ⚠️ pattern without value + +2053 -> 2054 call = (...) => s0() + +2053 -> 2055 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +2055 -> 2056 call = (...) => s0() + +2055 -> 2057 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2057 -> 2058 call = (...) => {"key": key, "value": value}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2059 call = (...) => s0() + +0 -> 2060 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2060 -> 2061 call = (...) => {"type": "collection_expression", "expression": expression}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2062 call = (...) => s0() + +0 -> 2063 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2063 -> 2064 call = (...) => s0() + +2063 -> 2065 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2065 -> 2067 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2065 -> 2068 conditional = (???*0* === 46) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2068 -> 2069 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2069 -> 2070 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ".", "ignoreCase": false} +) + +2065 -> 2071 conditional = ((???*0* | "." | {} | "[") !== {}) +- *0* s5 + ⚠️ pattern without value + +2071 -> 2072 call = (...) => s0() + +2071 -> 2073 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +2073 -> 2074 call = (...) => s0() + +2073 -> 2075 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2075 -> 2076 call = (...) => s0() + +2075 -> 2077 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +2077 -> 2078 call = (...) => {"property": property, "computed": false}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2063 -> 2079 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2079 -> 2080 call = (...) => s0() + +2079 -> 2081 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2081 -> 2083 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2081 -> 2084 conditional = (???*0* === 91) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2084 -> 2085 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2085 -> 2086 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "[", "ignoreCase": false} +) + +2081 -> 2087 conditional = ((???*0* | "." | {} | "[") !== {}) +- *0* s5 + ⚠️ pattern without value + +2087 -> 2088 call = (...) => s0() + +2087 -> 2089 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +2089 -> 2090 call = (...) => s0() + +2089 -> 2091 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2091 -> 2092 call = (...) => s0() + +2091 -> 2093 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2093 -> 2094 call = (...) => s0() + +2089 -> 2095 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2095 -> 2096 call = (...) => s0() + +2095 -> 2097 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +2097 -> 2099 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2097 -> 2100 conditional = (???*0* === 93) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2100 -> 2101 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2101 -> 2102 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "]", "ignoreCase": false} +) + +2097 -> 2103 conditional = ((???*0* | "]" | {}) !== {}) +- *0* s9 + ⚠️ pattern without value + +2103 -> 2104 call = (...) => {"property": property, "computed": true}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2063 -> 2105 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2105 -> 2107 member call = (???*0* | [] | {})["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2105 -> 2108 call = (...) => s0() + +2105 -> 2109 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2109 -> 2111 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2109 -> 2112 conditional = (???*0* === 46) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2112 -> 2113 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2113 -> 2114 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ".", "ignoreCase": false} +) + +2109 -> 2115 conditional = ((???*0* | "." | {} | "[") !== {}) +- *0* s5 + ⚠️ pattern without value + +2115 -> 2116 call = (...) => s0() + +2115 -> 2117 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +2117 -> 2118 call = (...) => s0() + +2117 -> 2119 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2119 -> 2120 call = (...) => s0() + +2119 -> 2121 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +2121 -> 2122 call = (...) => {"property": property, "computed": false}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2105 -> 2123 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2123 -> 2124 call = (...) => s0() + +2123 -> 2125 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2125 -> 2127 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2125 -> 2128 conditional = (???*0* === 91) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2128 -> 2129 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2129 -> 2130 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "[", "ignoreCase": false} +) + +2125 -> 2131 conditional = ((???*0* | "." | {} | "[") !== {}) +- *0* s5 + ⚠️ pattern without value + +2131 -> 2132 call = (...) => s0() + +2131 -> 2133 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +2133 -> 2134 call = (...) => s0() + +2133 -> 2135 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2135 -> 2136 call = (...) => s0() + +2135 -> 2137 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2137 -> 2138 call = (...) => s0() + +2133 -> 2139 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2139 -> 2140 call = (...) => s0() + +2139 -> 2141 conditional = ((???*0* | []) !== {}) +- *0* s8 + ⚠️ pattern without value + +2141 -> 2143 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2141 -> 2144 conditional = (???*0* === 93) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2144 -> 2145 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2145 -> 2146 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "]", "ignoreCase": false} +) + +2141 -> 2147 conditional = ((???*0* | "]" | {}) !== {}) +- *0* s9 + ⚠️ pattern without value + +2147 -> 2148 call = (...) => {"property": property, "computed": true}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2063 -> 2149 conditional = ((???*0* | [] | {}) !== {}) +- *0* s2 + ⚠️ pattern without value + +2149 -> 2150 call = (...) => tail["reduce"](*arrow function 16259*, head)(???*0*, (???*1* | [] | {})) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* s2 + ⚠️ pattern without value + +0 -> 2151 call = (...) => s0() + +0 -> 2152 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2152 -> 2153 call = (...) => {"type": "collection_subquery_expression", "expression": expression}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2154 call = (...) => s0() + +0 -> 2155 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2155 -> 2156 call = (...) => s0() + +0 -> 2157 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2157 -> 2158 call = (...) => {"type": "top_specification", "value": value}(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2161 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2162 member call = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2163 conditional = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2163 -> 2165 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2163 -> 2166 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2166 -> 2167 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [["0", "9"]], "inverted": false, "ignoreCase": false} +) + +0 -> 2168 conditional = ((???*0* | ???*1* | {}) !== {}) +- *0* s2 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +2168 -> 2170 member call = (???*0* | [] | {} | {"type": "number_constant", "value": ???*1*})["push"]((???*3* | ???*4* | {})) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*(text()) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(Number) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* s2 + ⚠️ pattern without value +- *4* ???*5*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +2168 -> 2173 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2168 -> 2174 member call = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2168 -> 2175 conditional = /^[0-9]/["test"](???*0*) +- *0* ???*1*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2175 -> 2177 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2175 -> 2178 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2178 -> 2179 call = (...) => (undefined | FreeVar(undefined))( + {"type": "class", "parts": [["0", "9"]], "inverted": false, "ignoreCase": false} +) + +0 -> 2180 conditional = ((???*0* | [] | {} | {"type": "number_constant", "value": ???*1*}) !== {}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*(text()) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(Number) + ⚠️ unknown global + ⚠️ This value might have side effects + +2180 -> 2181 call = (...) => {"type": "number_constant", "value": FreeVar(Number)(text())}() + +0 -> 2182 call = (...) => s0() + +0 -> 2183 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2183 -> 2184 call = (...) => s0() + +2183 -> 2185 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2185 -> 2187 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2185 -> 2188 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2188 -> 2189 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2189 -> 2190 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +2185 -> 2191 conditional = ((???*0* | "," | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +2191 -> 2192 call = (...) => s0() + +2191 -> 2193 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +2193 -> 2194 call = (...) => s0() + +2193 -> 2195 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2195 -> 2196 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2183 -> 2198 member call = (???*0* | [])["push"](???*1*) +- *0* s2 + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2183 -> 2199 call = (...) => s0() + +2183 -> 2200 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2200 -> 2202 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2200 -> 2203 conditional = (???*0* === 44) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2203 -> 2204 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2204 -> 2205 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ",", "ignoreCase": false} +) + +2200 -> 2206 conditional = ((???*0* | "," | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +2206 -> 2207 call = (...) => s0() + +2206 -> 2208 conditional = ((???*0* | []) !== {}) +- *0* s6 + ⚠️ pattern without value + +2208 -> 2209 call = (...) => s0() + +2208 -> 2210 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2210 -> 2211 call = (...) => v(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2183 -> 2212 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +2212 -> 2213 call = (...) => (head ? ???*0* : [])(???*1*, (???*2* | [])) +- *0* spread is not supported + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* s2 + ⚠️ pattern without value + +0 -> 2215 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2216 conditional = (???*0* === 40) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2216 -> 2217 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2217 -> 2218 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": "(", "ignoreCase": false} +) + +0 -> 2219 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2219 -> 2220 call = (...) => s0() + +2219 -> 2221 conditional = ((???*0* | []) !== {}) +- *0* s2 + ⚠️ pattern without value + +2221 -> 2222 call = (...) => s0() + +2221 -> 2223 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2223 -> 2224 call = (...) => s0() + +2223 -> 2225 conditional = ((???*0* | []) !== {}) +- *0* s4 + ⚠️ pattern without value + +2225 -> 2227 member call = ???*0*["charCodeAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2225 -> 2228 conditional = (???*0* === 41) +- *0* ???*1*["charCodeAt"](peg$currPos) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2228 -> 2229 conditional = ((0 | ???*0*) === 0) +- *0* updated with update expression + ⚠️ This value might have side effects + +2229 -> 2230 call = (...) => (undefined | FreeVar(undefined))( + {"type": "literal", "text": ")", "ignoreCase": false} +) + +2225 -> 2231 conditional = ((???*0* | ")" | {}) !== {}) +- *0* s5 + ⚠️ pattern without value + +2231 -> 2232 call = (...) => subquery(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2234 member call = ???*0*["reduce"]( + (...) => {"type": "scalar_binary_expression", "left": left, "operator": operator, "right": right}, + ???*1* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2235 call = ((...) => s0 | ???*0*)() +- *0* {}[???*1*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *1* ???*2*["startRule"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2237 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2237 -> 2239 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2239 -> 2240 call = (...) => {"type": "end"}() + +2239 -> 2241 call = (...) => (undefined | FreeVar(undefined))({"type": "end"}) + +2237 -> 2244 member call = ???*0*["charAt"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2237 -> 2246 call = (...) => { + "start": {"offset": startPos, "line": startPosDetails["line"], "column": startPosDetails["column"]}, + "end": {"offset": endPos, "line": endPosDetails["line"], "column": endPosDetails["column"]} +}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2237 -> 2247 call = (...) => { + "start": {"offset": startPos, "line": startPosDetails["line"], "column": startPosDetails["column"]}, + "end": {"offset": endPos, "line": endPosDetails["line"], "column": endPosDetails["column"]} +}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2237 -> 2248 call = (...) => ???*0*([], (???*1* ? ???*2* : null), ???*4*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["charAt"](peg$maxFailPos) + ⚠️ unknown callee object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2250 free var = FreeVar(module) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/resolved-explained.snapshot new file mode 100644 index 0000000000000..8e5259a5aa11c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/peg/resolved-explained.snapshot @@ -0,0 +1,3873 @@ +*anonymous function 10064* = (...) => "OR" + +*anonymous function 10192* = (...) => "NOT" + +*anonymous function 10796* = (...) => {"type": "identifier", "name": name} + +*anonymous function 11187* = (...) => (head + tail["join"]("")) + +*anonymous function 11339* = (...) => {"type": "parameter_name", "name": text()} + +*anonymous function 11668* = (...) => text() + +*anonymous function 11725* = (...) => seq + +*anonymous function 11890* = (...) => "\b" + +*anonymous function 12016* = (...) => "\f" + +*anonymous function 12142* = (...) => "\n" + +*anonymous function 12268* = (...) => "\r" + +*anonymous function 12394* = (...) => "\t" + +*anonymous function 12449* = (...) => text() + +*anonymous function 12577* = (...) => FreeVar(String)["fromCharCode"](FreeVar(parseInt)(digits, 16)) + +*anonymous function 1271* = (...) => "any character" + +*anonymous function 12829* = (...) => v + +*anonymous function 12892* = (...) => {"property": property, "alias": alias} + +*anonymous function 12977* = (...) => expression + +*anonymous function 13048* = (...) => {"type": "array_subquery_expression", "expression": expression} + +*anonymous function 13181* = (...) => {"type": "exists_subquery_expression", "expression": expression} + +*anonymous function 13315* = (...) => {"type": "scalar_subquery_expression", "expression": expression} + +*anonymous function 1343* = (...) => "end of input" + +*anonymous function 13449* = (...) => {"property": property, "computed": false} + +*anonymous function 13543* = (...) => {"property": property, "computed": true} + +*anonymous function 13636* = (...) => tail["reduce"](*arrow function 13694*, head) + +*anonymous function 13891* = (...) => {"type": "scalar_unary_expression", "operator": operator, "argument": argument} + +*anonymous function 1416* = (...) => expectation["description"] + +*anonymous function 14188* = (...) => { + "type": "scalar_conditional_expression", + "test": test, + "consequent": consequent, + "alternate": alternate +} + +*anonymous function 14448* = (...) => buildBinaryExpression(head, tail) + +*anonymous function 15047* = (...) => {"type": "scalar_in_expression", "value": value, "list": list} + +*anonymous function 15185* = (...) => {"type": "scalar_between_expression", "value": value, "begin": begin, "end": end} + +*anonymous function 15997* = (...) => {"key": key, "value": value} + +*anonymous function 16072* = (...) => {"type": "collection_expression", "expression": expression} + +*anonymous function 16201* = (...) => tail["reduce"](*arrow function 16259*, head) + +*anonymous function 16460* = (...) => {"type": "collection_subquery_expression", "expression": expression} + +*anonymous function 16598* = (...) => {"type": "top_specification", "value": value} + +*anonymous function 16713* = (...) => {"type": "number_constant", "value": FreeVar(Number)(text())} + +*anonymous function 16837* = (...) => (head ? ???*0* : []) +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 16925* = (...) => subquery + +*anonymous function 1822* = (...) => `\x0${hex(ch)}` + +*anonymous function 1920* = (...) => `\x${hex(ch)}` + +*anonymous function 2287* = (...) => `\x0${hex(ch)}` + +*anonymous function 2385* = (...) => `\x${hex(ch)}` + +*anonymous function 3852* = (...) => {"type": "sql", "body": body} + +*anonymous function 3949* = (...) => v + +*anonymous function 4000* = (...) => v + +*anonymous function 4064* = (...) => v + +*anonymous function 4134* = (...) => v + +*anonymous function 4211* = (...) => { + "type": "select_query", + "top": top, + "select": select, + "from": from, + "where": where, + "orderBy": orderBy +} + +*anonymous function 4474* = (...) => {"type": "select_specification", "*": true} + +*anonymous function 4589* = (...) => {"type": "select_specification", "properties": properties} + +*anonymous function 4716* = (...) => {"type": "select_specification", "value": value} + +*anonymous function 4902* = (...) => v + +*anonymous function 4960* = (...) => {"type": "object_property_list", "properties": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 5104* = (...) => v + +*anonymous function 5164* = (...) => {"type": "from_specification", "source": source, "joins": joins} + +*anonymous function 5303* = (...) => {"type": "from_source", "expression": expression, "alias": alias, "iteration": true} + +*anonymous function 5468* = (...) => v + +*anonymous function 5532* = (...) => {"type": "from_source", "expression": expression, "alias": alias} + +*anonymous function 5672* = (...) => {"type": "filter_condition", "condition": condition} + +*anonymous function 5793* = (...) => {"type": "sort_specification", "expressions": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 5936* = (...) => {"type": "sort_expression", "expression": expression, "order": order} + +*anonymous function 625* = (...) => `Expected ${describeExpected(expected)} but ${describeFound(found)} found.` + +*anonymous function 6287* = (...) => {"type": "scalar_function_expression", "name": name, "arguments": args, "udf": true} + +*anonymous function 6458* = (...) => {"type": "scalar_function_expression", "name": name, "arguments": args} + +*anonymous function 6748* = (...) => {"type": "scalar_object_expression", "properties": (head ? ???*0* : [])} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 702* = (...) => `"${literalEscape(expectation["text"])}"` + +*anonymous function 7046* = (...) => {"type": "scalar_array_expression", "elements": elements} + +*anonymous function 7257* = (...) => {"type": "undefined_constant"} + +*anonymous function 7337* = (...) => {"type": "null_constant"} + +*anonymous function 7412* = (...) => {"type": "boolean_constant", "value": false} + +*anonymous function 7527* = (...) => {"type": "boolean_constant", "value": true} + +*anonymous function 7869* = (...) => { + "type": "number_constant", + "value": (hex ? FreeVar(parseInt)(text(), 16) : FreeVar(parseFloat)(text())) +} + +*anonymous function 804* = (...) => `[${(expectation["inverted"] ? "^" : "")}${escapedParts}]` + +*anonymous function 8139* = (...) => {"type": "string_constant", "value": chars["join"]("")} + +*anonymous function 8336* = (...) => {"type": "array_constant", "elements": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 8472* = (...) => {"type": "object_constant", "properties": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +*anonymous function 9682* = (...) => "ASC" + +*anonymous function 9811* = (...) => "DESC" + +*anonymous function 9939* = (...) => "AND" + +*arrow function 13694* = (...) => {"type": "scalar_member_expression", "object": object, "property": property, "computed": computed} + +*arrow function 16259* = (...) => { + "type": "collection_member_expression", + "object": object, + "property": property, + "computed": computed +} + +*arrow function 169161* = (...) => {"type": "scalar_binary_expression", "left": left, "operator": operator, "right": right} + +DESCRIBE_EXPECTATION_FNS = { + "literal": (...) => `"${literalEscape(expectation["text"])}"`, + "class": (...) => `[${(expectation["inverted"] ? "^" : "")}${escapedParts}]`, + "any": (...) => "any character", + "end": (...) => "end of input", + "other": (...) => expectation["description"] +} + +alias#42 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +alias#44 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +alias#78 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +alternate = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +args#48 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +args#49 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +argument = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +begin = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +body = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +buildBinaryExpression = (...) => tail["reduce"](*arrow function 169161*, head) + +ch#14 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +ch#16 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +ch#17 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +ch#19 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +ch#20 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +chars = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +child = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +classEscape = (...) => ...[...](..., ...)["replace"](/\]/g, "\\]")["replace"](/\^/g, "\\^")["replace"](/-/g, "\\-")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 2287*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*) + +computed#86 = ???*0* +- *0* ???*1*["computed"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +computed#95 = ???*0* +- *0* ???*1*["computed"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +condition = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +consequent = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +ctor = (...) => undefined + +describeExpectation = (...) => DESCRIBE_EXPECTATION_FNS[expectation["type"]](expectation) + +describeExpected = (...) => ( + | undefined + | descriptions[0] + | `${descriptions[0]} or ${descriptions[1]}` + | `${descriptions["slice"](0, ???*0*)["join"](", ")}, or ${descriptions[???*1*]}` +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +describeFound = (...) => (found ? `"${literalEscape(found)}"` : "end of input") + +description#105 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +description#111 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +descriptions = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +details = ( + | {"line": 1, "column": 1} + | ???*0* + | {"line": (1 | ???*2* | ???*3*), "column": (1 | ???*6* | ???*7*)} +) +- *0* [][???*1*] + ⚠️ unknown array prototype methods or values +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* ???*4*["line"] + ⚠️ unknown object +- *4* [][???*5*] + ⚠️ unknown array prototype methods or values +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* ???*8*["column"] + ⚠️ unknown object +- *8* [][???*9*] + ⚠️ unknown array prototype methods or values +- *9* arguments[0] + ⚠️ function calls are not analysed yet + +digits = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +elements = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +end = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +endPos = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +endPosDetails = (undefined | {"line": 1, "column": 1} | ???*0* | {"line": ???*2*, "column": ???*4*}) +- *0* [][???*1*] + ⚠️ unknown array prototype methods or values +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["line"] + ⚠️ unknown object +- *3* details + ⚠️ circular variable reference +- *4* ???*5*["column"] + ⚠️ unknown object +- *5* details + ⚠️ circular variable reference + +error = (...) => undefined + +escapedParts = ("" | (("" | ???*0*) + ???*12*)) +- *0* (???*1* + ???*2*) + ⚠️ nested operation +- *1* escapedParts + ⚠️ circular variable reference +- *2* (???*3* ? ???*4* : ???*9*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* `${???*5*}-${???*7*}` + ⚠️ nested operation +- *5* ???*6*["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*) + ⚠️ unknown callee object +- *6* ???["replace"](/[\x00-\x0F]/g, *anonymous function 2287*) + ⚠️ unknown callee object +- *7* ???*8*["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*) + ⚠️ unknown callee object +- *8* ???["replace"](/[\x00-\x0F]/g, *anonymous function 2287*) + ⚠️ unknown callee object +- *9* ???*10*["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*) + ⚠️ unknown callee object +- *10* ???*11*["replace"](/[\x00-\x0F]/g, *anonymous function 2287*) + ⚠️ unknown callee object +- *11* ???["replace"](/\r/g, "\\r") + ⚠️ unknown callee object +- *12* (???*13* ? ???*14* : ???*21*) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* `${???*15*}-${???*18*}` + ⚠️ nested operation +- *15* ???*16*["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*) + ⚠️ unknown callee object +- *16* ???*17*["replace"](/[\x00-\x0F]/g, *anonymous function 2287*) + ⚠️ unknown callee object +- *17* ???["replace"](/\r/g, "\\r") + ⚠️ unknown callee object +- *18* ???*19*["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*) + ⚠️ unknown callee object +- *19* ???*20*["replace"](/[\x00-\x0F]/g, *anonymous function 2287*) + ⚠️ unknown callee object +- *20* ???["replace"](/\r/g, "\\r") + ⚠️ unknown callee object +- *21* ???*22*["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 2385*) + ⚠️ unknown callee object +- *22* ???*23*["replace"](/[\x00-\x0F]/g, *anonymous function 2287*) + ⚠️ unknown callee object +- *23* ???*24*["replace"](/\r/g, "\\r") + ⚠️ unknown callee object +- *24* ???["replace"](/\n/g, "\\n") + ⚠️ unknown callee object + +expectation#11 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expectation#12 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expectation#13 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expectation#21 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expectation#8 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expectation#9 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expected#120 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expected#124 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expected#22 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expected#28 = (...) => undefined + +expected#5 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +expected#7 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#42 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +expression#43 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#44 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#47 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#79 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#80 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#81 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#82 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#93 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +expression#96 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +found#124 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +found#27 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +found#5 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +found#7 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +from#32 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +from#33 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +from#34 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +head#1801 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#38 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#39 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#46 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#50 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#58 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#59 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#66 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#83 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#84 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#85 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#89 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#94 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +head#99 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +hex#56 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +hex#7 = (...) => ch["charCodeAt"](0)["toString"](16)["toUpperCase"]() + +i#22 = (???*0* | 0 | ???*1* | 1) +- *0* i + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +i#9 = (???*0* | 0 | ???*1*) +- *0* i + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +ignoreCase#107 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +ignoreCase#108 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +input = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +inverted = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +j = (???*0* | 1 | ???*1*) +- *0* j + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +joins = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +key = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +left = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +list = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +literalEscape = (...) => s["replace"](/\\/g, "\\\\")["replace"](/"/g, "\\\"")["replace"](/\0/g, "\\0")["replace"](/\t/g, "\\t")["replace"](/\n/g, "\\n")["replace"](/\r/g, "\\r")["replace"](/[\x00-\x0F]/g, *anonymous function 1822*)["replace"](/[\x10-\x1F\x7F-\x9F]/g, *anonymous function 1920*) + +location#105 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +location#106 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +location#123 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +location#124 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +location#28 = (...) => peg$computeLocation(peg$savedPos, peg$currPos) + +location#5 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +message#106 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +message#123 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +message#5 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +name#48 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +name#49 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +name#65 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +object#86 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +object#95 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +operator#1802 = ???*0* +- *0* ???*1*[1] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +operator#87 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +options = (???*0* | (???*1* ? (???*9* | ???*10*) : {})) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ((???*2* | ???*3*) !== ???*8*) + ⚠️ nested operation +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*7* : {}) + ⚠️ nested operation +- *4* (???*5* !== ???*6*) + ⚠️ nested operation +- *5* options + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* options + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* (???*11* ? ???*14* : {}) + ⚠️ nested operation +- *11* (???*12* !== ???*13*) + ⚠️ nested operation +- *12* options + ⚠️ circular variable reference +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* options + ⚠️ circular variable reference + +order = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +orderBy = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +p = (???*0* | ???*1* | ???*2*) +- *0* p + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +parent = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +parts = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +peg$FAILED = {} + +peg$SyntaxError = (...) => undefined + +peg$anyExpectation = (...) => {"type": "any"} + +peg$buildSimpleError = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +peg$buildStructuredError = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +peg$c0 = (...) => {"type": "sql", "body": body} + +peg$c1 = (...) => v + +peg$c10 = (...) => {"type": "select_specification", "value": value} + +peg$c100 = {"type": "literal", "text": "NOT", "ignoreCase": true} + +peg$c101 = (...) => "NOT" + +peg$c102 = "between" + +peg$c103 = {"type": "literal", "text": "BETWEEN", "ignoreCase": true} + +peg$c104 = "exists" + +peg$c105 = {"type": "literal", "text": "EXISTS", "ignoreCase": true} + +peg$c106 = "array" + +peg$c107 = {"type": "literal", "text": "ARRAY", "ignoreCase": true} + +peg$c108 = "null" + +peg$c109 = {"type": "literal", "text": "null", "ignoreCase": false} + +peg$c11 = "," + +peg$c110 = "true" + +peg$c111 = {"type": "literal", "text": "true", "ignoreCase": false} + +peg$c112 = "false" + +peg$c113 = {"type": "literal", "text": "false", "ignoreCase": false} + +peg$c114 = "udf" + +peg$c115 = {"type": "literal", "text": "udf", "ignoreCase": false} + +peg$c116 = (...) => {"type": "identifier", "name": name} + +peg$c117 = /^[a-zA-Z_]/ + +peg$c118 = {"type": "class", "parts": [["a", "z"], ["A", "Z"], "_"], "inverted": false, "ignoreCase": false} + +peg$c119 = /^[a-zA-Z0-9_]/ + +peg$c12 = {"type": "literal", "text": ",", "ignoreCase": false} + +peg$c120 = { + "type": "class", + "parts": [["a", "z"], ["A", "Z"], ["0", "9"], "_"], + "inverted": false, + "ignoreCase": false +} + +peg$c121 = (...) => (head + tail["join"]("")) + +peg$c122 = "@" + +peg$c123 = {"type": "literal", "text": "@", "ignoreCase": false} + +peg$c124 = (...) => {"type": "parameter_name", "name": text()} + +peg$c125 = "+" + +peg$c126 = {"type": "literal", "text": "+", "ignoreCase": false} + +peg$c127 = "~" + +peg$c128 = {"type": "literal", "text": "~", "ignoreCase": false} + +peg$c129 = "\\" + +peg$c13 = (...) => v + +peg$c130 = {"type": "literal", "text": "\\", "ignoreCase": false} + +peg$c131 = (...) => text() + +peg$c132 = (...) => seq + +peg$c133 = {"type": "any"} + +peg$c134 = "b" + +peg$c135 = {"type": "literal", "text": "b", "ignoreCase": false} + +peg$c136 = (...) => "\b" + +peg$c137 = "f" + +peg$c138 = {"type": "literal", "text": "f", "ignoreCase": false} + +peg$c139 = (...) => "\f" + +peg$c14 = (...) => {"type": "object_property_list", "properties": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +peg$c140 = "n" + +peg$c141 = {"type": "literal", "text": "n", "ignoreCase": false} + +peg$c142 = (...) => "\n" + +peg$c143 = "r" + +peg$c144 = {"type": "literal", "text": "r", "ignoreCase": false} + +peg$c145 = (...) => "\r" + +peg$c146 = "t" + +peg$c147 = {"type": "literal", "text": "t", "ignoreCase": false} + +peg$c148 = (...) => "\t" + +peg$c149 = (...) => text() + +peg$c15 = (...) => v + +peg$c150 = "u" + +peg$c151 = {"type": "literal", "text": "u", "ignoreCase": false} + +peg$c152 = (...) => FreeVar(String)["fromCharCode"](FreeVar(parseInt)(digits, 16)) + +peg$c153 = /^[0-9a-f]/i + +peg$c154 = {"type": "class", "parts": [["0", "9"], ["a", "f"]], "inverted": false, "ignoreCase": true} + +peg$c155 = (...) => v + +peg$c156 = (...) => {"property": property, "alias": alias} + +peg$c157 = (...) => expression + +peg$c158 = (...) => {"type": "array_subquery_expression", "expression": expression} + +peg$c159 = (...) => {"type": "exists_subquery_expression", "expression": expression} + +peg$c16 = (...) => {"type": "from_specification", "source": source, "joins": joins} + +peg$c160 = (...) => {"type": "scalar_subquery_expression", "expression": expression} + +peg$c161 = (...) => {"property": property, "computed": false} + +peg$c162 = (...) => {"property": property, "computed": true} + +peg$c163 = (...) => tail["reduce"](*arrow function 13694*, head) + +peg$c164 = (...) => {"type": "scalar_unary_expression", "operator": operator, "argument": argument} + +peg$c165 = "?" + +peg$c166 = {"type": "literal", "text": "?", "ignoreCase": false} + +peg$c167 = ":" + +peg$c168 = {"type": "literal", "text": ":", "ignoreCase": false} + +peg$c169 = (...) => { + "type": "scalar_conditional_expression", + "test": test, + "consequent": consequent, + "alternate": alternate +} + +peg$c17 = (...) => {"type": "from_source", "expression": expression, "alias": alias, "iteration": true} + +peg$c170 = "??" + +peg$c171 = {"type": "literal", "text": "??", "ignoreCase": false} + +peg$c172 = (...) => buildBinaryExpression(head, tail) + +peg$c173 = "=" + +peg$c174 = {"type": "literal", "text": "=", "ignoreCase": false} + +peg$c175 = "!=" + +peg$c176 = {"type": "literal", "text": "!=", "ignoreCase": false} + +peg$c177 = "<>" + +peg$c178 = {"type": "literal", "text": "<>", "ignoreCase": false} + +peg$c179 = "<=" + +peg$c18 = (...) => v + +peg$c180 = {"type": "literal", "text": "<=", "ignoreCase": false} + +peg$c181 = ">=" + +peg$c182 = {"type": "literal", "text": ">=", "ignoreCase": false} + +peg$c183 = "<" + +peg$c184 = {"type": "literal", "text": "<", "ignoreCase": false} + +peg$c185 = ">" + +peg$c186 = {"type": "literal", "text": ">", "ignoreCase": false} + +peg$c187 = (...) => {"type": "scalar_in_expression", "value": value, "list": list} + +peg$c188 = (...) => {"type": "scalar_between_expression", "value": value, "begin": begin, "end": end} + +peg$c189 = "|" + +peg$c19 = (...) => {"type": "from_source", "expression": expression, "alias": alias} + +peg$c190 = {"type": "literal", "text": "|", "ignoreCase": false} + +peg$c191 = "^" + +peg$c192 = {"type": "literal", "text": "^", "ignoreCase": false} + +peg$c193 = "&" + +peg$c194 = {"type": "literal", "text": "&", "ignoreCase": false} + +peg$c195 = "<<" + +peg$c196 = {"type": "literal", "text": "<<", "ignoreCase": false} + +peg$c197 = ">>>" + +peg$c198 = {"type": "literal", "text": ">>>", "ignoreCase": false} + +peg$c199 = ">>" + +peg$c2 = (...) => v + +peg$c20 = (...) => {"type": "filter_condition", "condition": condition} + +peg$c200 = {"type": "literal", "text": ">>", "ignoreCase": false} + +peg$c201 = "||" + +peg$c202 = {"type": "literal", "text": "||", "ignoreCase": false} + +peg$c203 = "/" + +peg$c204 = {"type": "literal", "text": "/", "ignoreCase": false} + +peg$c205 = "%" + +peg$c206 = {"type": "literal", "text": "%", "ignoreCase": false} + +peg$c207 = (...) => {"key": key, "value": value} + +peg$c208 = (...) => {"type": "collection_expression", "expression": expression} + +peg$c209 = (...) => tail["reduce"](*arrow function 16259*, head) + +peg$c21 = (...) => {"type": "sort_specification", "expressions": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +peg$c210 = (...) => {"type": "collection_subquery_expression", "expression": expression} + +peg$c211 = (...) => {"type": "top_specification", "value": value} + +peg$c212 = (...) => {"type": "number_constant", "value": FreeVar(Number)(text())} + +peg$c213 = (...) => (head ? ???*0* : []) +- *0* spread is not supported + ⚠️ This value might have side effects + +peg$c214 = (...) => subquery + +peg$c22 = (...) => {"type": "sort_expression", "expression": expression, "order": order} + +peg$c23 = "." + +peg$c24 = {"type": "literal", "text": ".", "ignoreCase": false} + +peg$c25 = "(" + +peg$c26 = {"type": "literal", "text": "(", "ignoreCase": false} + +peg$c27 = ")" + +peg$c28 = {"type": "literal", "text": ")", "ignoreCase": false} + +peg$c29 = (...) => {"type": "scalar_function_expression", "name": name, "arguments": args, "udf": true} + +peg$c3 = (...) => v + +peg$c30 = (...) => {"type": "scalar_function_expression", "name": name, "arguments": args} + +peg$c31 = "{" + +peg$c32 = {"type": "literal", "text": "{", "ignoreCase": false} + +peg$c33 = "}" + +peg$c34 = {"type": "literal", "text": "}", "ignoreCase": false} + +peg$c35 = (...) => {"type": "scalar_object_expression", "properties": (head ? ???*0* : [])} +- *0* spread is not supported + ⚠️ This value might have side effects + +peg$c36 = "[" + +peg$c37 = {"type": "literal", "text": "[", "ignoreCase": false} + +peg$c38 = "]" + +peg$c39 = {"type": "literal", "text": "]", "ignoreCase": false} + +peg$c4 = (...) => v + +peg$c40 = (...) => {"type": "scalar_array_expression", "elements": elements} + +peg$c41 = "undefined" + +peg$c42 = {"type": "literal", "text": "undefined", "ignoreCase": false} + +peg$c43 = (...) => {"type": "undefined_constant"} + +peg$c44 = (...) => {"type": "null_constant"} + +peg$c45 = (...) => {"type": "boolean_constant", "value": false} + +peg$c46 = (...) => {"type": "boolean_constant", "value": true} + +peg$c47 = "-" + +peg$c48 = {"type": "literal", "text": "-", "ignoreCase": false} + +peg$c49 = "0x" + +peg$c5 = (...) => { + "type": "select_query", + "top": top, + "select": select, + "from": from, + "where": where, + "orderBy": orderBy +} + +peg$c50 = {"type": "literal", "text": "0x", "ignoreCase": false} + +peg$c51 = /^[0-9]/ + +peg$c52 = {"type": "class", "parts": [["0", "9"]], "inverted": false, "ignoreCase": false} + +peg$c53 = (...) => { + "type": "number_constant", + "value": (hex ? FreeVar(parseInt)(text(), 16) : FreeVar(parseFloat)(text())) +} + +peg$c54 = "\"" + +peg$c55 = {"type": "literal", "text": "\"", "ignoreCase": false} + +peg$c56 = (...) => {"type": "string_constant", "value": chars["join"]("")} + +peg$c57 = "'" + +peg$c58 = {"type": "literal", "text": "'", "ignoreCase": false} + +peg$c59 = (...) => {"type": "array_constant", "elements": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +peg$c6 = "*" + +peg$c60 = (...) => {"type": "object_constant", "properties": ???*0*} +- *0* spread is not supported + ⚠️ This value might have side effects + +peg$c61 = /^[ \t\n\r]/ + +peg$c62 = {"type": "class", "parts": [" ", "\t", "\n", "\r"], "inverted": false, "ignoreCase": false} + +peg$c63 = "--" + +peg$c64 = {"type": "literal", "text": "--", "ignoreCase": false} + +peg$c65 = /^[\n\r]/ + +peg$c66 = {"type": "class", "parts": ["\n", "\r"], "inverted": false, "ignoreCase": false} + +peg$c67 = "select" + +peg$c68 = {"type": "literal", "text": "SELECT", "ignoreCase": true} + +peg$c69 = "top" + +peg$c7 = {"type": "literal", "text": "*", "ignoreCase": false} + +peg$c70 = {"type": "literal", "text": "TOP", "ignoreCase": true} + +peg$c71 = "from" + +peg$c72 = {"type": "literal", "text": "FROM", "ignoreCase": true} + +peg$c73 = "where" + +peg$c74 = {"type": "literal", "text": "WHERE", "ignoreCase": true} + +peg$c75 = "order" + +peg$c76 = {"type": "literal", "text": "ORDER", "ignoreCase": true} + +peg$c77 = "by" + +peg$c78 = {"type": "literal", "text": "BY", "ignoreCase": true} + +peg$c79 = "as" + +peg$c8 = (...) => {"type": "select_specification", "*": true} + +peg$c80 = {"type": "literal", "text": "AS", "ignoreCase": true} + +peg$c81 = "join" + +peg$c82 = {"type": "literal", "text": "JOIN", "ignoreCase": true} + +peg$c83 = "in" + +peg$c84 = {"type": "literal", "text": "IN", "ignoreCase": true} + +peg$c85 = "value" + +peg$c86 = {"type": "literal", "text": "VALUE", "ignoreCase": true} + +peg$c87 = "asc" + +peg$c88 = {"type": "literal", "text": "ASC", "ignoreCase": true} + +peg$c89 = (...) => "ASC" + +peg$c9 = (...) => {"type": "select_specification", "properties": properties} + +peg$c90 = "desc" + +peg$c91 = {"type": "literal", "text": "DESC", "ignoreCase": true} + +peg$c92 = (...) => "DESC" + +peg$c93 = "and" + +peg$c94 = {"type": "literal", "text": "AND", "ignoreCase": true} + +peg$c95 = (...) => "AND" + +peg$c96 = "or" + +peg$c97 = {"type": "literal", "text": "OR", "ignoreCase": true} + +peg$c98 = (...) => "OR" + +peg$c99 = "not" + +peg$classExpectation = (...) => {"type": "class", "parts": parts, "inverted": inverted, "ignoreCase": ignoreCase} + +peg$computeLocation = (...) => { + "start": {"offset": startPos, "line": startPosDetails["line"], "column": startPosDetails["column"]}, + "end": {"offset": endPos, "line": endPosDetails["line"], "column": endPosDetails["column"]} +} + +peg$computePosDetails = (...) => (undefined | details) + +peg$currPos = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +peg$endExpectation = (...) => {"type": "end"} + +peg$fail = (...) => (undefined | FreeVar(undefined)) + +peg$literalExpectation = (...) => {"type": "literal", "text": text, "ignoreCase": ignoreCase} + +peg$maxFailExpected = [] + +peg$maxFailPos = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +peg$otherExpectation = (...) => {"type": "other", "description": description} + +peg$parse = (...) => (undefined | peg$result) + +peg$parse_ = (...) => s0 + +peg$parseand = (...) => s0 + +peg$parsearray = (...) => s0 + +peg$parsearray_constant = (...) => s0 + +peg$parsearray_subquery_expression = (...) => s0 + +peg$parseas = (...) => s0 + +peg$parseasc = (...) => s0 + +peg$parsebetween = (...) => s0 + +peg$parseboolean_constant = (...) => s0 + +peg$parseby = (...) => s0 + +peg$parsecharactor_escape_sequence = (...) => s0 + +peg$parsecollection_expression = (...) => s0 + +peg$parsecollection_member_expression = (...) => s0 + +peg$parsecollection_primary_expression = (...) => s0 + +peg$parsecollection_subquery_expression = (...) => s0 + +peg$parsecomment = (...) => s0 + +peg$parseconstant = (...) => s0 + +peg$parsedesc = (...) => s0 + +peg$parsedouble_string_character = (...) => s0 + +peg$parseescape_character = (...) => s0 + +peg$parseescape_sequence = (...) => s0 + +peg$parseexists = (...) => s0 + +peg$parseexists_subquery_expression = (...) => s0 + +peg$parsefalse = (...) => s0 + +peg$parsefilter_condition = (...) => s0 + +peg$parsefrom = (...) => s0 + +peg$parsefrom_source = (...) => s0 + +peg$parsefrom_specification = (...) => s0 + +peg$parsehex_digit = (...) => s0 + +peg$parseidentifier = (...) => s0 + +peg$parseidentifier_name = (...) => s0 + +peg$parseidentifier_start = (...) => s0 + +peg$parsein = (...) => s0 + +peg$parsejoin = (...) => s0 + +peg$parsenon_escape_character = (...) => s0 + +peg$parsenot = (...) => s0 + +peg$parsenull = (...) => s0 + +peg$parsenull_constant = (...) => s0 + +peg$parsenumber_constant = (...) => s0 + +peg$parseobject_constant = (...) => s0 + +peg$parseobject_constant_property = (...) => s0 + +peg$parseobject_property = (...) => s0 + +peg$parseobject_property_list = (...) => s0 + +peg$parseor = (...) => s0 + +peg$parseorder = (...) => s0 + +peg$parseparameter_name = (...) => s0 + +peg$parsereserved = (...) => s0 + +peg$parsescalar_array_expression = (...) => s0 + +peg$parsescalar_between_expression = (...) => s0 + +peg$parsescalar_binary_additive_expression = (...) => s0 + +peg$parsescalar_binary_and_expression = (...) => s0 + +peg$parsescalar_binary_bitwise_and_expression = (...) => s0 + +peg$parsescalar_binary_bitwise_or_expression = (...) => s0 + +peg$parsescalar_binary_bitwise_xor_expression = (...) => s0 + +peg$parsescalar_binary_equality_expression = (...) => s0 + +peg$parsescalar_binary_multiplicative_expression = (...) => s0 + +peg$parsescalar_binary_or_expression = (...) => s0 + +peg$parsescalar_binary_relational_expression = (...) => s0 + +peg$parsescalar_binary_shift_expression = (...) => s0 + +peg$parsescalar_conditional_expression = (...) => s0 + +peg$parsescalar_expression_list = (...) => s0 + +peg$parsescalar_function_expression = (...) => s0 + +peg$parsescalar_in_expression = (...) => s0 + +peg$parsescalar_member_expression = (...) => s0 + +peg$parsescalar_object_element_property = (...) => s0 + +peg$parsescalar_object_expression = (...) => s0 + +peg$parsescalar_primary_expression = (...) => s0 + +peg$parsescalar_subquery_expression = (...) => s0 + +peg$parsescalar_unary_expression = (...) => s0 + +peg$parseselect = (...) => s0 + +peg$parseselect_query = (...) => s0 + +peg$parseselect_specification = (...) => s0 + +peg$parsesingle_escape_character = (...) => s0 + +peg$parsesingle_string_character = (...) => s0 + +peg$parsesort_expression = (...) => s0 + +peg$parsesort_specification = (...) => s0 + +peg$parsesource_character = (...) => s0 + +peg$parsesql = (...) => s0 + +peg$parsestring_constant = (...) => s0 + +peg$parsesubquery = (...) => s0 + +peg$parsesubquery_expression = (...) => s0 + +peg$parsetop = (...) => s0 + +peg$parsetop_specification = (...) => s0 + +peg$parsetrue = (...) => s0 + +peg$parseudf = (...) => s0 + +peg$parseunary_operator = (...) => s0 + +peg$parseundefined_constant = (...) => s0 + +peg$parseunicode_escape_sequence = (...) => s0 + +peg$parseunsigned_integer = (...) => s0 + +peg$parsevalue = (...) => s0 + +peg$parsewhere = (...) => s0 + +peg$parsewhitespace = (...) => s0 + +peg$posDetailsCache = [{"line": 1, "column": 1}] + +peg$result = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +peg$savedPos = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +peg$silentFails = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +peg$startRuleFunction = ((...) => s0 | ???*0*) +- *0* {}[???*1*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *1* ???*2*["startRule"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +peg$startRuleFunctions = {"sql": (...) => s0} + +peg$subclass = (...) => undefined + +pos = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +properties = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +property#77 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +property#78 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +property#83 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +property#84 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +property#86 = ???*0* +- *0* ???*1*["property"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +property#95 = ???*0* +- *0* ???*1*["property"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +right = ???*0* +- *0* ???*1*[3] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +s#15 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +s#18 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +s0#1019 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1026 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1031 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1049 = (???*0* | ???*1* | {}) +- *0* s0 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s0#1053 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1070 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1093 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1096 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1103 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1110 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1112 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1186 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1195 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1221 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#125 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1273 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1317 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1369 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1395 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1415 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1443 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1471 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1499 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1543 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1587 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1631 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1646 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1661 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1663 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1739 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1741 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1744 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1755 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#1784 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#187 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#201 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#229 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#279 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#282 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#284 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#312 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#323 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#376 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#419 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#436 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#443 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#448 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#450 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#497 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#525 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#567 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#609 = (???*0* | []) +- *0* s0 + ⚠️ pattern without value + +s0#613 = (???*0* | ???*1* | {}) +- *0* s0 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s0#617 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#644 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#654 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#664 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#674 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#684 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#694 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#704 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#714 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#724 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#734 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#744 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#754 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#764 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#774 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#784 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#794 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#804 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#814 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#824 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#834 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#844 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#854 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#864 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#886 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#893 = (???*0* | ???*1* | {}) +- *0* s0 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s0#897 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#909 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#917 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#930 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#952 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#974 = (???*0* | ???*1* | {}) +- *0* s0 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s0#978 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#980 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s0#982 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1019 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1031 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1053 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1070 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1096 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1103 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1110 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1112 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1186 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1195 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1221 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#125 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1273 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1317 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1369 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1395 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1415 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1443 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1471 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1499 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1543 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1587 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1631 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1646 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1661 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1663 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1739 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1741 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1744 = (???*0* | [] | {} | {"type": "number_constant", "value": ???*1*}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*(text()) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* FreeVar(Number) + ⚠️ unknown global + ⚠️ This value might have side effects + +s1#1755 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#1784 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#187 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#201 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#229 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#282 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#284 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#312 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#323 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#376 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#419 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#443 = (???*0* | "undefined" | {} | {"type": "undefined_constant"}) +- *0* s1 + ⚠️ pattern without value + +s1#448 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#450 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#454 = ( + | ???*0* + | "-" + | {} + | null + | { + "type": "number_constant", + "value": ((???*1* | "0x" | {} | null) ? ???*2* : ???*4*) + } +) +- *0* s1 + ⚠️ pattern without value +- *1* s2 + ⚠️ pattern without value +- *2* ???*3*(text(), 16) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* FreeVar(parseInt) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*(text()) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *5* FreeVar(parseFloat) + ⚠️ unknown global + ⚠️ This value might have side effects + +s1#497 = ( + | ???*0* + | "\"" + | {} + | {"type": "string_constant", "value": (???*1* | ???*3*)} + | "'" +) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["join"]("") + ⚠️ unknown callee object +- *2* s2 + ⚠️ pattern without value +- *3* ???*4*("") + ⚠️ unknown callee +- *4* []["join"] + ⚠️ non-num constant property on array + +s1#525 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#567 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#609 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#617 = ( + | ???*0* + | "--" + | {} + | [(???*1* | "--" | {} | [???*2*, (???*3* | [])]), (???*4* | [])] +) +- *0* s1 + ⚠️ pattern without value +- *1* s1 + ⚠️ pattern without value +- *2* s1 + ⚠️ circular variable reference +- *3* s2 + ⚠️ pattern without value +- *4* s2 + ⚠️ pattern without value + +s1#644 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#654 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#664 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#674 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#684 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#694 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#704 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#714 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#724 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#734 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#744 = (???*0* | ???*1* | {} | "ASC") +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s1#754 = (???*0* | ???*1* | {} | "DESC") +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 4) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s1#764 = (???*0* | ???*1* | {} | "AND") +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s1#774 = (???*0* | ???*1* | {} | "OR") +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 2) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s1#784 = (???*0* | ???*1* | {} | "NOT") +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substr"](peg$currPos, 3) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s1#794 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#804 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#814 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#824 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#834 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#844 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#854 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#886 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#897 = ( + | ???*0* + | ???*1* + | {} + | ((???*3* | ???*4* | {} | ???*6*) + (???*12* | ???*14*)) +) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* s1 + ⚠️ pattern without value +- *4* ???*5*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* (???*7* + (???*8* | ???*10*)) + ⚠️ nested operation +- *7* s1 + ⚠️ circular variable reference +- *8* ???*9*["join"]("") + ⚠️ unknown callee object +- *9* s2 + ⚠️ pattern without value +- *10* ???*11*("") + ⚠️ unknown callee +- *11* []["join"] + ⚠️ non-num constant property on array +- *12* ???*13*["join"]("") + ⚠️ unknown callee object +- *13* s2 + ⚠️ pattern without value +- *14* ???*15*("") + ⚠️ unknown callee +- *15* []["join"] + ⚠️ non-num constant property on array + +s1#909 = (???*0* | "@" | {} | {"type": "parameter_name", "name": ???*1*}) +- *0* s1 + ⚠️ pattern without value +- *1* ???*2*["substring"](peg$savedPos, peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s1#930 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#952 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s1#982 = (???*0* | "b" | {} | "\b" | "f" | "\f" | "n" | "\n" | "r" | "\r" | "t" | "\t") +- *0* s1 + ⚠️ pattern without value + +s10#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s10#323 = (???*0* | []) +- *0* s10 + ⚠️ pattern without value + +s11#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s11#323 = (???*0* | ")" | {}) +- *0* s11 + ⚠️ pattern without value + +s12 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s13 = (???*0* | []) +- *0* s13 + ⚠️ pattern without value + +s14 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s15 = (???*0* | []) +- *0* s15 + ⚠️ pattern without value + +s16 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#1019 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#1031 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#1053 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#1070 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1096 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1103 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1112 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1186 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1195 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1221 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#125 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#1251 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1273 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1317 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#132 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1369 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1395 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1415 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1443 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1471 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1499 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1543 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1587 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1631 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1646 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1663 = (???*0* | [] | {}) +- *0* s2 + ⚠️ pattern without value + +s2#1744 = (???*0* | ???*1* | {}) +- *0* s2 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s2#1755 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#1784 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#187 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#201 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#229 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#284 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#312 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#323 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#376 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#419 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#454 = (???*0* | "0x" | {} | null) +- *0* s2 + ⚠️ pattern without value + +s2#497 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#525 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#567 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#617 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#644 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#654 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#664 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#674 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#684 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#694 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#704 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#714 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#724 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#734 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#744 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#754 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#764 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#774 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#784 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#794 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#804 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#814 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#824 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#834 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#844 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#854 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#886 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#897 = (???*0* | []) +- *0* s2 + ⚠️ pattern without value + +s2#909 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#930 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s2#952 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1031 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1053 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1070 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1096 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1103 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1112 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1186 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1195 = (???*0* | "?" | {}) +- *0* s3 + ⚠️ pattern without value + +s3#1221 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#125 = (???*0* | []) +- *0* s3 + ⚠️ pattern without value + +s3#1251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1273 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1317 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1369 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1395 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1415 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1443 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1471 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1499 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1543 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1587 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1631 = (???*0* | ":" | {}) +- *0* s3 + ⚠️ pattern without value + +s3#1646 = (???*0* | ":" | {}) +- *0* s3 + ⚠️ pattern without value + +s3#1663 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1755 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#1784 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#187 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#201 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#229 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#284 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#312 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#323 = (???*0* | "." | {} | "(") +- *0* s3 + ⚠️ pattern without value + +s3#376 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#419 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#454 = (???*0* | [] | {}) +- *0* s3 + ⚠️ pattern without value + +s3#497 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#525 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#567 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#617 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s3#644 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#654 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#664 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#674 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#684 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#694 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#704 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#714 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#724 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#734 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#744 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#754 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#764 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#774 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#784 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#794 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#804 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#814 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#824 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#834 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#844 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#854 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s3#897 = (???*0* | ???*1* | {}) +- *0* s3 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s4#1031 = ( + | ???*0* + | ???*1* + | {} + | [ + ( + | ???*3* + | ???*4* + | {} + | [???*6*, (???*7* | ???*8* | {}), (???*10* | ???*11* | {}), (???*13* | ???*14* | {})] + ), + (???*16* | ???*17* | {}), + (???*19* | ???*20* | {}), + (???*22* | ???*23* | {}) + ] +) +- *0* s4 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* s4 + ⚠️ pattern without value +- *4* ???*5*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* s4 + ⚠️ circular variable reference +- *7* s5 + ⚠️ pattern without value +- *8* ???*9*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* s6 + ⚠️ pattern without value +- *11* ???*12*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* s7 + ⚠️ pattern without value +- *14* ???*15*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* s5 + ⚠️ pattern without value +- *17* ???*18*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *18* arguments[0] + ⚠️ function calls are not analysed yet +- *19* s6 + ⚠️ pattern without value +- *20* ???*21*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *21* arguments[0] + ⚠️ function calls are not analysed yet +- *22* s7 + ⚠️ pattern without value +- *23* ???*24*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *24* arguments[0] + ⚠️ function calls are not analysed yet + +s4#1053 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1070 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#1112 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1195 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#1221 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1273 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1317 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1369 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#1395 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#1415 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1443 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1471 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1499 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1543 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1587 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1631 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#1646 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#1663 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1755 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#1784 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#201 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#229 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#284 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#312 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#323 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#376 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#419 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s4#525 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#567 = (???*0* | []) +- *0* s4 + ⚠️ pattern without value + +s4#617 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1031 = (???*0* | ???*1* | {}) +- *0* s5 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s5#1053 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1070 = (???*0* | ")" | {}) +- *0* s5 + ⚠️ pattern without value + +s5#1112 = (???*0* | "." | {} | "[") +- *0* s5 + ⚠️ pattern without value + +s5#1195 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1221 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1273 = (???*0* | "=" | {} | "!=" | "<>") +- *0* s5 + ⚠️ pattern without value + +s5#1317 = (???*0* | "<=" | {} | ">=" | "<" | ">") +- *0* s5 + ⚠️ pattern without value + +s5#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1369 = (???*0* | "(" | {}) +- *0* s5 + ⚠️ pattern without value + +s5#1395 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1415 = (???*0* | "|" | {}) +- *0* s5 + ⚠️ pattern without value + +s5#1443 = (???*0* | "^" | {}) +- *0* s5 + ⚠️ pattern without value + +s5#1471 = (???*0* | "&" | {}) +- *0* s5 + ⚠️ pattern without value + +s5#1499 = (???*0* | "<<" | {} | ">>>" | ">>") +- *0* s5 + ⚠️ pattern without value + +s5#1543 = (???*0* | "+" | {} | "-" | "||") +- *0* s5 + ⚠️ pattern without value + +s5#1587 = (???*0* | "*" | {} | "/" | "%") +- *0* s5 + ⚠️ pattern without value + +s5#1631 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1646 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#1663 = (???*0* | "." | {} | "[") +- *0* s5 + ⚠️ pattern without value + +s5#1755 = (???*0* | "," | {}) +- *0* s5 + ⚠️ pattern without value + +s5#1784 = (???*0* | ")" | {}) +- *0* s5 + ⚠️ pattern without value + +s5#201 = (???*0* | "," | {}) +- *0* s5 + ⚠️ pattern without value + +s5#229 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#284 = (???*0* | "," | {}) +- *0* s5 + ⚠️ pattern without value + +s5#323 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#376 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#419 = (???*0* | "]" | {}) +- *0* s5 + ⚠️ pattern without value + +s5#454 = ( + | ???*0* + | "." + | {} + | [(???*1* | "." | {} | [???*2*, (???*3* | [] | {})]), (???*4* | [] | {})] +) +- *0* s5 + ⚠️ pattern without value +- *1* s5 + ⚠️ pattern without value +- *2* s5 + ⚠️ circular variable reference +- *3* s6 + ⚠️ pattern without value +- *4* s6 + ⚠️ pattern without value + +s5#525 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#567 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s5#617 = (???*0* | ???*1* | {}) +- *0* s5 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s6#1031 = (???*0* | ???*1* | {}) +- *0* s6 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s6#1112 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1195 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1221 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1251 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1273 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1317 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s6#1369 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1395 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1415 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1443 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1471 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1499 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1543 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1587 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1663 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#1755 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#201 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#229 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#284 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#323 = (???*0* | []) +- *0* s6 + ⚠️ pattern without value + +s6#376 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s6#454 = (???*0* | [] | {}) +- *0* s6 + ⚠️ pattern without value + +s6#525 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s6#567 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1031 = (???*0* | ???*1* | {}) +- *0* s7 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s7#1112 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1195 = (???*0* | ":" | {}) +- *0* s7 + ⚠️ pattern without value + +s7#1221 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1251 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1273 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1317 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1369 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1395 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1415 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1443 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1471 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1499 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1543 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1587 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1663 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#1755 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#201 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#229 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#284 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s7#323 = (???*0* | "(" | {} | ")") +- *0* s7 + ⚠️ pattern without value + +s7#376 = (???*0* | "," | {}) +- *0* s7 + ⚠️ pattern without value + +s7#454 = (???*0* | ???*1* | {}) +- *0* s7 + ⚠️ pattern without value +- *1* ???*2*["charAt"](peg$currPos) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +s7#525 = (???*0* | "," | {}) +- *0* s7 + ⚠️ pattern without value + +s7#567 = (???*0* | "," | {}) +- *0* s7 + ⚠️ pattern without value + +s8#1112 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s8#1195 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s8#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s8#1369 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s8#1395 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s8#1663 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s8#323 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s8#376 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s8#525 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s8#567 = (???*0* | []) +- *0* s8 + ⚠️ pattern without value + +s9#1112 = (???*0* | "]" | {}) +- *0* s9 + ⚠️ pattern without value + +s9#1195 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s9#132 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s9#1369 = (???*0* | ")" | {}) +- *0* s9 + ⚠️ pattern without value + +s9#1395 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s9#1663 = (???*0* | "]" | {}) +- *0* s9 + ⚠️ pattern without value + +s9#323 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s9#376 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s9#525 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +s9#567 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +select#31 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +select#32 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +select#33 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +select#34 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +seq = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +source#40 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +source#41 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +startPos = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +startPosDetails = (undefined | {"line": 1, "column": 1} | ???*0* | {"line": ???*2*, "column": ???*4*}) +- *0* [][???*1*] + ⚠️ unknown array prototype methods or values +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["line"] + ⚠️ unknown object +- *3* details + ⚠️ circular variable reference +- *4* ???*5*["column"] + ⚠️ unknown object +- *5* details + ⚠️ circular variable reference + +subquery = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +tail#1801 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#39 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#46 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#50 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#58 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#59 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#66 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#85 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#89 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#94 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +tail#99 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +test = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +text#107 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +text#28 = (...) => input["substring"](peg$savedPos, peg$currPos) + +top#31 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +top#32 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +top#33 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +top#34 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +v#30 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +v#31 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +v#32 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +v#33 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +v#38 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +v#40 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +v#43 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +v#77 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +value#37 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +value#90 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +value#91 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +value#92 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +value#97 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +where#33 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +where#34 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph-effects.snapshot new file mode 100644 index 0000000000000..c192700a9cae8 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph-effects.snapshot @@ -0,0 +1,2295 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 40..47#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "os", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 40..53#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 93..100#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "process", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 93..111#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "process", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Ident, + ), + ], + span: 122..129#1, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 149..156#1, + in_try: false, + }, + Member { + obj: FreeVar( + "process", + ), + prop: Constant( + Str( + Atom( + "arch", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Member, + ), + ], + span: 171..183#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "process", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 171..178#1, + in_try: false, + }, + Call { + func: Variable( + ( + "platform", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Call, + ), + ], + span: 188..198#0, + in_try: false, + }, + Call { + func: Variable( + ( + "endianness", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 2, + ), + ), + Expr( + Call, + ), + ], + span: 202..214#0, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Concat( + 11, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "platform", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 149..217#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 236..243#1, + in_try: false, + }, + Call { + func: Variable( + ( + "arch", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Call, + ), + ], + span: 255..261#0, + in_try: false, + }, + Call { + func: Variable( + ( + "platform", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Call, + ), + ], + span: 265..275#0, + in_try: false, + }, + Call { + func: Variable( + ( + "endianness", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 2, + ), + ), + Expr( + Call, + ), + ], + span: 279..291#0, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Concat( + 10, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Call( + 2, + Variable( + ( + "arch", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "platform", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 236..294#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 313..320#1, + in_try: false, + }, + Call { + func: Variable( + ( + "arch", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Call, + ), + ], + span: 332..338#0, + in_try: false, + }, + Member { + obj: FreeVar( + "process", + ), + prop: Constant( + Str( + Atom( + "platform", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Member, + ), + ], + span: 345..361#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "process", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 345..352#1, + in_try: false, + }, + Call { + func: Variable( + ( + "endianness", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 2, + ), + ), + Expr( + Call, + ), + ], + span: 366..378#0, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Concat( + 11, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Call( + 2, + Variable( + ( + "arch", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 5, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 313..381#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 400..407#1, + in_try: false, + }, + Member { + obj: FreeVar( + "process", + ), + prop: Constant( + Str( + Atom( + "arch", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Member, + ), + ], + span: 419..431#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "process", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 419..426#1, + in_try: false, + }, + Member { + obj: FreeVar( + "process", + ), + prop: Constant( + Str( + Atom( + "platform", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Member, + ), + ], + span: 438..454#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "process", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 438..445#1, + in_try: false, + }, + Call { + func: Variable( + ( + "endianness", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 2, + ), + ), + Expr( + Call, + ), + ], + span: 459..471#0, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Concat( + 12, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 400..474#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 493..500#1, + in_try: false, + }, + Member { + obj: Variable( + ( + "p", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "arch", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Member, + ), + ], + span: 512..518#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "p", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "platform", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 1, + ), + ), + Expr( + Member, + ), + ], + span: 522..532#0, + in_try: false, + }, + Call { + func: Variable( + ( + "endianness", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 2, + ), + ), + Expr( + Call, + ), + ], + span: 536..548#0, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Concat( + 12, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Member( + 3, + Variable( + ( + "p", + #2, + ), + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Member( + 3, + Variable( + ( + "p", + #2, + ), + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 493..551#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 570..577#1, + in_try: false, + }, + Member { + obj: Variable( + ( + "p", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "arch", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 0, + ), + ), + Expr( + Member, + ), + ], + span: 592..598#0, + in_try: false, + }, + Call { + func: Variable( + ( + "endianness", + #2, + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Tpl, + ), + Tpl( + Exprs( + 2, + ), + ), + Expr( + Call, + ), + ], + span: 622..634#0, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Concat( + 10, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Member( + 3, + Variable( + ( + "p", + #2, + ), + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Variable( + ( + "processPlatform", + #2, + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 8, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 570..637#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph-explained.snapshot new file mode 100644 index 0000000000000..f577e38ae5e62 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph-explained.snapshot @@ -0,0 +1,31 @@ +arch = FreeVar(require)("os")["arch"] + +binding1 = FreeVar(require)( + `esbuild-${FreeVar(process)["arch"]}-${platform()}-${endianness()}` +) + +binding2 = FreeVar(require)(`esbuild-${arch()}-${platform()}-${endianness()}`) + +binding3 = FreeVar(require)( + `esbuild-${arch()}-${FreeVar(process)["platform"]}-${endianness()}` +) + +binding4 = FreeVar(require)( + `esbuild-${FreeVar(process)["arch"]}-${FreeVar(process)["platform"]}-${endianness()}` +) + +binding5 = FreeVar(require)( + `esbuild-${p["arch"]}-${p["platform"]}-${endianness()}` +) + +binding6 = FreeVar(require)( + `esbuild-${p["arch"]}-${processPlatform}-${endianness()}` +) + +endianness = FreeVar(require)("os")["endianness"] + +p = FreeVar(process) + +platform = FreeVar(require)("os")["platform"] + +processPlatform = FreeVar(require)("process")["platform"] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph.snapshot new file mode 100644 index 0000000000000..d33faf4cf8931 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/graph.snapshot @@ -0,0 +1,548 @@ +[ + ( + "arch", + Member( + 5, + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "os", + ), + ), + ), + ], + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + ), + ( + "binding1", + Call( + 13, + FreeVar( + "require", + ), + [ + Concat( + 11, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "platform", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ], + ), + ), + ( + "binding2", + Call( + 12, + FreeVar( + "require", + ), + [ + Concat( + 10, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Call( + 2, + Variable( + ( + "arch", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "platform", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ], + ), + ), + ( + "binding3", + Call( + 13, + FreeVar( + "require", + ), + [ + Concat( + 11, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Call( + 2, + Variable( + ( + "arch", + #2, + ), + ), + [], + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ], + ), + ), + ( + "binding4", + Call( + 14, + FreeVar( + "require", + ), + [ + Concat( + 12, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Member( + 3, + FreeVar( + "process", + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ], + ), + ), + ( + "binding5", + Call( + 14, + FreeVar( + "require", + ), + [ + Concat( + 12, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Member( + 3, + Variable( + ( + "p", + #2, + ), + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Member( + 3, + Variable( + ( + "p", + #2, + ), + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ], + ), + ), + ( + "binding6", + Call( + 12, + FreeVar( + "require", + ), + [ + Concat( + 10, + [ + Constant( + Str( + Atom( + "esbuild-", + ), + ), + ), + Member( + 3, + Variable( + ( + "p", + #2, + ), + ), + Constant( + Str( + Atom( + "arch", + ), + ), + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Variable( + ( + "processPlatform", + #2, + ), + ), + Constant( + Str( + Atom( + "-", + ), + ), + ), + Call( + 2, + Variable( + ( + "endianness", + #2, + ), + ), + [], + ), + ], + ), + ], + ), + ), + ( + "endianness", + Member( + 5, + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "os", + ), + ), + ), + ], + ), + Constant( + Str( + Atom( + "endianness", + ), + ), + ), + ), + ), + ( + "p", + FreeVar( + "process", + ), + ), + ( + "platform", + Member( + 5, + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "os", + ), + ), + ), + ], + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + ), + ( + "processPlatform", + Member( + 5, + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "process", + ), + ), + ), + ], + ), + Constant( + Str( + Atom( + "platform", + ), + ), + ), + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/input.js new file mode 100644 index 0000000000000..4612da11a57dc --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/input.js @@ -0,0 +1,19 @@ +const { platform, endianness, arch } = require("os"); +const { platform: processPlatform } = require("process"); + +let p = process; + +const binding1 = require(`esbuild-${ + process.arch +}-${platform()}-${endianness()}`); +const binding2 = require(`esbuild-${arch()}-${platform()}-${endianness()}`); +const binding3 = require(`esbuild-${arch()}-${ + process.platform +}-${endianness()}`); +const binding4 = require(`esbuild-${process.arch}-${ + process.platform +}-${endianness()}`); +const binding5 = require(`esbuild-${p.arch}-${p.platform}-${endianness()}`); +const binding6 = require(`esbuild-${ + p.arch +}-${processPlatform}-${endianness()}`); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/resolved-effects.snapshot new file mode 100644 index 0000000000000..437f7e9e19b12 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/resolved-effects.snapshot @@ -0,0 +1,79 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 call = require*0*("os") +- *0* require: The require method from CommonJS + +0 -> 3 free var = FreeVar(require) + +0 -> 4 call = require*0*("process") +- *0* require: The require method from CommonJS + +0 -> 5 free var = FreeVar(process) + +0 -> 6 free var = FreeVar(require) + +0 -> 8 free var = FreeVar(process) + +0 -> 9 call = os.process*0*() +- *0* os.process: The Node.js os.process method: https://nodejs.org/api/os.html#os_os_process + +0 -> 10 call = os.endianness*0*() +- *0* os.endianness: The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness + +0 -> 11 call = require*0*("esbuild-x64-linux-LE") +- *0* require: The require method from CommonJS + +0 -> 12 free var = FreeVar(require) + +0 -> 13 call = os.arch*0*() +- *0* os.arch: The Node.js os.arch method: https://nodejs.org/api/os.html#os_os_arch + +0 -> 14 call = os.process*0*() +- *0* os.process: The Node.js os.process method: https://nodejs.org/api/os.html#os_os_process + +0 -> 15 call = os.endianness*0*() +- *0* os.endianness: The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness + +0 -> 16 call = require*0*("esbuild-x64-linux-LE") +- *0* require: The require method from CommonJS + +0 -> 17 free var = FreeVar(require) + +0 -> 18 call = os.arch*0*() +- *0* os.arch: The Node.js os.arch method: https://nodejs.org/api/os.html#os_os_arch + +0 -> 20 free var = FreeVar(process) + +0 -> 21 call = os.endianness*0*() +- *0* os.endianness: The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness + +0 -> 22 call = require*0*("esbuild-x64-linux-LE") +- *0* require: The require method from CommonJS + +0 -> 23 free var = FreeVar(require) + +0 -> 25 free var = FreeVar(process) + +0 -> 27 free var = FreeVar(process) + +0 -> 28 call = os.endianness*0*() +- *0* os.endianness: The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness + +0 -> 29 call = require*0*("esbuild-x64-linux-LE") +- *0* require: The require method from CommonJS + +0 -> 30 free var = FreeVar(require) + +0 -> 33 call = os.endianness*0*() +- *0* os.endianness: The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness + +0 -> 34 call = require*0*("esbuild-x64-linux-LE") +- *0* require: The require method from CommonJS + +0 -> 35 free var = FreeVar(require) + +0 -> 37 call = os.endianness*0*() +- *0* os.endianness: The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness + +0 -> 38 call = require*0*("esbuild-x64-linux-LE") +- *0* require: The require method from CommonJS diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/resolved-explained.snapshot new file mode 100644 index 0000000000000..22c640dea5101 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/process-and-os/resolved-explained.snapshot @@ -0,0 +1,25 @@ +arch = os.arch*0* +- *0* os.arch: The Node.js os.arch method: https://nodejs.org/api/os.html#os_os_arch + +binding1 = module + +binding2 = module + +binding3 = module + +binding4 = module + +binding5 = module + +binding6 = module + +endianness = os.endianness*0* +- *0* os.endianness: The Node.js os.endianness method: https://nodejs.org/api/os.html#os_os_endianness + +p = process*0* +- *0* process: The Node.js process module: https://nodejs.org/api/process.html + +platform = os.process*0* +- *0* os.process: The Node.js os.process method: https://nodejs.org/api/os.html#os_os_process + +processPlatform = "linux" diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/graph-explained.snapshot new file mode 100644 index 0000000000000..d9891d99f1a1c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/graph-explained.snapshot @@ -0,0 +1,6782 @@ +$a = (???*0* | nd() | he(c) | (ce ? je(a, c) : ke(a, c))) +- *0* $a + ⚠️ pattern without value + +$b = (...) => (a | b | null) + +$c = (...) => undefined + +$d = [9, 13, 27, 32] + +$e = Ze("animationend") + +$f = (...) => undefined + +$g = (!(1) | !(0)) + +$h = { + "readContext": Vg, + "useCallback": Bi, + "useContext": Vg, + "useEffect": ji, + "useImperativeHandle": zi, + "useInsertionEffect": wi, + "useLayoutEffect": xi, + "useMemo": Ci, + "useReducer": gi, + "useRef": si, + "useState": *anonymous function 73223*, + "useDebugValue": Ai, + "useDeferredValue": *anonymous function 73283*, + "useTransition": *anonymous function 73380*, + "useMutableSource": hi, + "useSyncExternalStore": ii, + "useId": Fi, + "unstable_isNewReconciler": !(1) +} + +$i = (...) => (null | b["child"]) + +$k = (...) => ((bj(a) ? 1 : 0) | 11 | 14 | 2) + +*anonymous function 10089* = (...) => d + +*anonymous function 100988* = (...) => undefined + +*anonymous function 10119* = (...) => undefined + +*anonymous function 10152* = (...) => undefined + +*anonymous function 108286* = (...) => undefined + +*anonymous function 114743* = (...) => null + +*anonymous function 117815* = (...) => ( + | undefined + | ???*0* + | b + | null + | pj(a, b, c) + | b["child"] + | cj(a, b, b["type"], b["pendingProps"], c) + | yj(a, b, c) + | ej(a, b, c) +) +- *0* zj(a, b, c) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +*anonymous function 126145* = (...) => undefined + +*anonymous function 126252* = (...) => undefined + +*anonymous function 126382* = (...) => undefined + +*anonymous function 126480* = (...) => undefined + +*anonymous function 126604* = (...) => undefined + +*anonymous function 127055* = (...) => undefined + +*anonymous function 127285* = (...) => undefined + +*anonymous function 127435* = (...) => undefined + +*anonymous function 127571* = (...) => undefined + +*anonymous function 127654* = (...) => undefined + +*anonymous function 127846* = (...) => undefined + +*anonymous function 127923* = (...) => undefined + +*anonymous function 128036* = (...) => undefined + +*anonymous function 128133* = (...) => C + +*anonymous function 128157* = (...) => (undefined | ???*0*) +- *0* b() + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +*anonymous function 128216* = (...) => undefined + +*anonymous function 129223* = (...) => ((null === a) ? null : a["stateNode"]) + +*anonymous function 129753* = (...) => dl(a, b, null, c) + +*anonymous function 129905* = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +*anonymous function 130256* = (...) => (null | a) + +*anonymous function 130523* = (...) => Sk(a) + +*anonymous function 130565* = (...) => sl(null, a, b, !(0), c) + +*anonymous function 130658* = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +*anonymous function 131212* = (...) => sl(null, a, b, !(1), c) + +*anonymous function 131315* = (...) => (a["_reactRootContainer"] ? !(0) : !(1)) + +*anonymous function 131389* = (...) => undefined + +*anonymous function 131418* = (...) => undefined + +*anonymous function 131559* = (...) => sl(a, b, c, !(1), d) + +*anonymous function 13525* = (...) => undefined + +*anonymous function 13573* = (...) => a(b, c, d, e) + +*anonymous function 13608* = (...) => undefined + +*anonymous function 14731* = (...) => undefined + +*anonymous function 14754* = (...) => undefined + +*anonymous function 17157* = (...) => undefined + +*anonymous function 17435* = (...) => undefined + +*anonymous function 2285* = (...) => undefined + +*anonymous function 23424* = (...) => undefined + +*anonymous function 2443* = (...) => undefined + +*anonymous function 2564* = (...) => undefined + +*anonymous function 2705* = (...) => undefined + +*anonymous function 27645* = (...) => undefined + +*anonymous function 27843* = (...) => undefined + +*anonymous function 28013* = (...) => undefined + +*anonymous function 28108* = (...) => (a["timeStamp"] || FreeVar(Date)["now"]()) + +*anonymous function 28404* = (...) => ((???*0* === a["relatedTarget"]) ? ((a["fromElement"] === a["srcElement"]) ? a["toElement"] : a["fromElement"]) : a["relatedTarget"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 28530* = (...) => (a["movementX"] | wd) + +*anonymous function 28699* = (...) => (???*0* ? a["movementY"] : xd) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 28936* = (...) => (???*0* ? a["clipboardData"] : FreeVar(window)["clipboardData"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 29891* = (...) => ( + | b + | (("keypress" === a["type"]) ? ???*0* : ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? (Nd[a["keyCode"]] || "Unidentified") : "")) +) +- *0* ((13 === a) ? "Enter" : FreeVar(String)["fromCharCode"](a)) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +*anonymous function 3008* = (...) => undefined + +*anonymous function 30217* = (...) => (("keypress" === a["type"]) ? od(a) : 0) + +*anonymous function 30272* = (...) => ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? a["keyCode"] : 0) + +*anonymous function 30346* = (...) => (("keypress" === a["type"]) ? od(a) : ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? a["keyCode"] : 0)) + +*anonymous function 30803* = (...) => (???*0* ? a["deltaX"] : (???*1* ? ???*2* : 0)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 30887* = (...) => (???*0* ? a["deltaY"] : (???*1* ? ???*2* : (???*3* ? ???*4* : 0))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 3119* = (...) => undefined + +*anonymous function 3196* = (...) => undefined + +*anonymous function 3280* = (...) => undefined + +*anonymous function 3354* = (...) => undefined + +*anonymous function 39904* = (...) => undefined + +*anonymous function 40883* = (...) => undefined + +*anonymous function 4580* = (...) => undefined + +*anonymous function 45964* = (...) => Hf["resolve"](null)["then"](a)["catch"](If) + +*anonymous function 46048* = (...) => undefined + +*anonymous function 4744* = (...) => undefined + +*anonymous function 4883* = (...) => undefined + +*anonymous function 5021* = (...) => undefined + +*anonymous function 5213* = (...) => undefined + +*anonymous function 55504* = (...) => (???*0* ? (Vb(a) === a) : !(1)) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 55574* = (...) => undefined + +*anonymous function 55754* = (...) => undefined + +*anonymous function 55941* = (...) => undefined + +*anonymous function 58064* = (...) => undefined + +*anonymous function 61566* = (...) => b(e, a) + +*anonymous function 62327* = (...) => b(e, a) + +*anonymous function 67764* = (...) => undefined + +*anonymous function 6811* = (...) => undefined + +*anonymous function 6885* = (...) => undefined + +*anonymous function 69020* = (...) => undefined + +*anonymous function 69089* = (...) => undefined + +*anonymous function 71076* = (...) => a + +*anonymous function 71188* = (...) => ti(4194308, 4, yi["bind"](null, b, a), c) + +*anonymous function 71305* = (...) => ti(4194308, 4, a, b) + +*anonymous function 71364* = (...) => ti(4, 2, a, b) + +*anonymous function 71406* = (...) => a + +*anonymous function 71500* = (...) => [d["memoizedState"], a] + +*anonymous function 71750* = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 71860* = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 71915* = (...) => [b, a] + +*anonymous function 72018* = (...) => undefined + +*anonymous function 72052* = (...) => c + +*anonymous function 72352* = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 72781* = (...) => fi(ei) + +*anonymous function 72842* = (...) => Di(b, O["memoizedState"], a) + +*anonymous function 72911* = (...) => [a, b] + +*anonymous function 73223* = (...) => gi(ei) + +*anonymous function 73283* = (...) => ((null === O) ? ???*0* : Di(b, O["memoizedState"], a)) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 73380* = (...) => [a, b] + +*anonymous function 73860* = (...) => undefined + +*anonymous function 74018* = (...) => undefined + +*anonymous function 74191* = (...) => d(e) + +*anonymous function 74226* = (...) => undefined + +*anonymous function 74327* = (...) => undefined + +*anonymous function 86042* = (...) => (undefined | FreeVar(undefined)) + +*anonymous function 86340* = (...) => undefined + +*anonymous function 86357* = (...) => undefined + +*anonymous function 87803* = (...) => undefined + +*anonymous function 9947* = (...) => e["call"](???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 9983* = (...) => undefined + +A = FreeVar(Object)["assign"] + +Aa = FreeVar(Symbol)["for"]("react.profiler") + +Ab = (null | [a] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Ac = (...) => undefined + +Ad = A( + {}, + ud, + { + "screenX": 0, + "screenY": 0, + "clientX": 0, + "clientY": 0, + "pageX": 0, + "pageY": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "getModifierState": zd, + "button": 0, + "buttons": 0, + "relatedTarget": *anonymous function 28404*, + "movementX": *anonymous function 28530*, + "movementY": *anonymous function 28699* + } +) + +Ae = (...) => undefined + +Af = (...) => undefined + +Ag = (...) => undefined + +Ah = (...) => a + +Ai = (...) => undefined + +Aj = (???*0* | *anonymous function 86042*) +- *0* Aj + ⚠️ pattern without value + +Ak = (null | a) + +B = ca["unstable_now"] + +Ba = FreeVar(Symbol)["for"]("react.provider") + +Bb = (...) => undefined + +Bc = (...) => undefined + +Bd = rd(Ad) + +Be = (...) => undefined + +Bf = (...) => undefined + +Bg = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +Bh = vh(!(0)) + +Bi = (...) => (d[0] | a) + +Bj = (???*0* | *anonymous function 86340*) +- *0* Bj + ⚠️ pattern without value + +Bk = (???*0* | B()) +- *0* unsupported expression + ⚠️ This value might have side effects + +C = ( + | 0 + | 1 + | e + | 4 + | e + | b + | (((0 !== c) && ???*0*) ? c : 4) + | c + | d + | d + | g + | (???*1* ? 16 : a) + | c + | a + | c +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Ca = FreeVar(Symbol)["for"]("react.context") + +Cb = (...) => (( + || !(a) + || ((5 !== a["tag"]) && (6 !== a["tag"]) && (13 !== a["tag"]) && (3 !== a["tag"])) +) ? null : a) + +Cc = (...) => undefined + +Cd = A({}, Ad, {"dataTransfer": 0}) + +Ce = (...) => undefined + +Cf = (null | dd) + +Cg = (...) => (undefined | ((null !== b) ? ???*0* : !(1)) | ???*1* | !(1)) +- *0* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ((null !== b) ? ???*2* : !(1)) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Ch = vh(!(1)) + +Ci = (...) => (d[0] | a) + +Cj = (???*0* | *anonymous function 86357*) +- *0* Cj + ⚠️ pattern without value + +Ck = (0 | yc()) + +D = (...) => undefined + +Da = FreeVar(Symbol)["for"]("react.forward_ref") + +Db = (...) => (a[Pf] || null) + +Dc = (...) => (???*0* ? (???*1* ? ((0 !== ???*2*) ? 16 : 536870912) : 4) : 1) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +Dd = rd(Cd) + +De = (...) => (undefined | te(qe)) + +Df = (null | {"focusedElem": a, "selectionRange": c} | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Dg = (...) => ((0 !== ???*0*) && (0 === ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Dh = {} + +Di = (...) => (???*0* | b) +- *0* ???*1* + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Dj = (???*0* | *anonymous function 87803*) +- *0* Dj + ⚠️ pattern without value + +Dk = (...) => undefined + +E = (...) => undefined + +Ea = FreeVar(Symbol)["for"]("react.suspense") + +Eb = (...) => undefined + +Ec = (???*0* | *anonymous function 127654*) +- *0* Ec + ⚠️ pattern without value + +Ed = A({}, ud, {"relatedTarget": 0}) + +Ee = (...) => (undefined | te(b)) + +Ef = (...) => ( + || ("textarea" === a) + || ("noscript" === a) + || ("string" === typeof(b["children"])) + || ("number" === typeof(b["children"])) + || ( + && ("object" === typeof(b["dangerouslySetInnerHTML"])) + && (null !== b["dangerouslySetInnerHTML"]) + && (null != b["dangerouslySetInnerHTML"]["__html"]) + ) +) + +Eg = (...) => undefined + +Eh = Uf(Dh) + +Ei = (...) => undefined + +Ej = (...) => undefined + +Ek = (...) => undefined + +F#292 = (u["stateNode"] | Kb(w, x) | "onMouseLeave" | "onPointerLeave" | null | t | x | vf(F)) + +F#678 = ???*0* +- *0* F + ⚠️ pattern without value + +F#685 = ???*0* +- *0* F + ⚠️ pattern without value + +F#843 = Ri(f, h, b) + +F#883 = h["sibling"] + +Fa = FreeVar(Symbol)["for"]("react.suspense_list") + +Fb = (...) => undefined + +Fc = (???*0* | *anonymous function 127923*) +- *0* Fc + ⚠️ pattern without value + +Fd = rd(Ed) + +Fe = (...) => (undefined | te(b)) + +Ff = (("function" === typeof(FreeVar(setTimeout))) ? FreeVar(setTimeout) : ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Fg = (...) => undefined + +Fh = Uf(Dh) + +Fi = (...) => di()["memoizedState"] + +Fj = (...) => (undefined | null | (???*0* ? b : null) | ???*1* | b["child"]) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Fk = (...) => null + +G = (...) => undefined + +Ga = FreeVar(Symbol)["for"]("react.memo") + +Gb = ((...) => a(b) | Rk) + +Gc = (???*0* | *anonymous function 128036*) +- *0* Gc + ⚠️ pattern without value + +Gd = A( + {}, + sd, + {"animationName": 0, "elapsedTime": 0, "pseudoElement": 0} +) + +Ge = (...) => (((a === b) && ((0 !== a) || (???*0* === ???*1*))) || ((a !== a) && (b !== b))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Gf = (("function" === typeof(FreeVar(clearTimeout))) ? FreeVar(clearTimeout) : ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Gg = (...) => (!(1) | ???*0* | !(0)) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Gh = Uf(Dh) + +Gi = (...) => undefined + +Gj = (...) => undefined + +Gk = (...) => ac(a, b) + +H = Uf(Vf) + +Ha = FreeVar(Symbol)["for"]("react.lazy") + +Hb = ((...) => undefined | Sk) + +Hc = (???*0* | *anonymous function 128133*) +- *0* Hc + ⚠️ pattern without value + +Hd = rd(Gd) + +He = (("function" === typeof(FreeVar(Object)["is"])) ? FreeVar(Object)["is"] : Ge) + +Hf = (("function" === typeof(FreeVar(Promise))) ? FreeVar(Promise) : ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Hg = (...) => undefined + +Hh = (...) => a + +Hi = (...) => ((a === N) || ((null !== b) && (b === N))) + +Hj = (FreeVar(Infinity) | (B() + 500)) + +Hk = (...) => ( + | null + | ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) +) + +I = (!(1) | !(0)) + +Ia = FreeVar(Symbol)["for"]("react.offscreen") + +Ib = (!(1) | !(0)) + +Ic = (???*0* | *anonymous function 128157*) +- *0* Ic + ⚠️ pattern without value + +Id = A({}, sd, {"clipboardData": *anonymous function 28936*}) + +Ie = (...) => (!(0) | !(1)) + +If = (...) => undefined + +Ig = (...) => undefined + +Ih = (...) => undefined + +Ii = (...) => undefined + +Ij = (...) => undefined + +Ik = (...) => (d | !(1)) + +J#292 = ((!(t) && ("scroll" === a)) | Vb(n) | ((null == k) ? h : ue(k)) | F) + +J#431 = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +J#673 = n["memoizedState"] + +J#843 = Vi(g) + +J#883 = t["sibling"] + +Ja = FreeVar(Symbol)["iterator"] + +Jb = (...) => (undefined | a(b, c) | Gb(a, b, c)) + +Jc = (!(1) | !(0)) + +Jd = rd(Id) + +Je = (...) => a + +Jf = (("function" === typeof(FreeVar(queueMicrotask))) ? FreeVar(queueMicrotask) : (("undefined" !== typeof(Hf)) ? *anonymous function 45964* : Ff)) + +Jg = (...) => undefined + +Jh = (...) => undefined + +Ji = (...) => undefined + +Jj = (...) => (undefined | ???*0* | null | (???*3* ? ???*4* : null)) +- *0* (???*1* ? ???*2* : null) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Jk = (...) => T + +K = (0 | ???*0* | e | c | b | c | h | e) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +Ka = (...) => (null | (("function" === typeof(a)) ? a : null)) + +Kb = (...) => (null | c) + +Kc = [] + +Kd = A({}, sd, {"data": 0}) + +Ke = (...) => (undefined | {"node": c, "offset": ???*0*}) +- *0* unsupported expression + ⚠️ This value might have side effects + +Kf = (...) => (undefined | FreeVar(undefined)) + +Kg = ua["ReactCurrentBatchConfig"] + +Kh = (...) => undefined + +Ki = (...) => {"value": a, "source": b, "stack": e, "digest": null} + +Kj = (!(1) | g | h) + +Kk = (...) => ((null === a) ? ai : a) + +L = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +La = (???*0* | ((b && b[1]) || "")) +- *0* La + ⚠️ pattern without value + +Lb = (!(1) | !(0)) + +Lc = (null | Tc(Lc, a, b, c, d, e)) + +Ld = rd(Kd) + +Le = (...) => ((a && b) ? ((a === b) ? !(0) : ((a && (3 === a["nodeType"])) ? !(1) : ((b && (3 === b["nodeType"])) ? Le(a, b["parentNode"]) : (???*0* ? a["contains"](b) : (a["compareDocumentPosition"] ? !(!(???*1*)) : !(1)))))) : !(1)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Lf = (...) => (null | a) + +Lg = (...) => b + +Lh = (...) => undefined + +Li = (...) => {"value": a, "source": null, "stack": ((null != c) ? c : null), "digest": ((null != b) ? b : null)} + +Lj = (("function" === typeof(FreeVar(WeakSet))) ? FreeVar(WeakSet) : FreeVar(Set)) + +Lk = (...) => a + +M = Uf(0) + +Ma = (...) => ` +${La}${a}` + +Mb = {} + +Mc = (null | Tc(Mc, a, b, c, d, e)) + +Md = { + "Esc": "Escape", + "Spacebar": " ", + "Left": "ArrowLeft", + "Up": "ArrowUp", + "Right": "ArrowRight", + "Down": "ArrowDown", + "Del": "Delete", + "Win": "OS", + "Menu": "ContextMenu", + "Apps": "ContextMenu", + "Scroll": "ScrollLock", + "MozPrintableKey": "Unidentified" +} + +Me = (...) => b + +Mf = (...) => (a | null) + +Mg = Uf(null) + +Mh = (...) => (b | null) + +Mi = (...) => undefined + +Mj = (...) => undefined + +Mk = (...) => undefined + +N = (null | b) + +Na = (!(1) | !(0)) + +Nb = (...) => undefined + +Nc = (null | Tc(Nc, a, b, c, d, e)) + +Nd = { + 8: "Backspace", + 9: "Tab", + 12: "Clear", + 13: "Enter", + 16: "Shift", + 17: "Control", + 18: "Alt", + 19: "Pause", + 20: "CapsLock", + 27: "Escape", + 32: " ", + 33: "PageUp", + 34: "PageDown", + 35: "End", + 36: "Home", + 37: "ArrowLeft", + 38: "ArrowUp", + 39: "ArrowRight", + 40: "ArrowDown", + 45: "Insert", + 46: "Delete", + 112: "F1", + 113: "F2", + 114: "F3", + 115: "F4", + 116: "F5", + 117: "F6", + 118: "F7", + 119: "F8", + 120: "F9", + 121: "F10", + 122: "F11", + 123: "F12", + 144: "NumLock", + 145: "ScrollLock", + 224: "Meta" +} + +Ne = (...) => ( + && b + && ( + || ( + && ("input" === b) + && ( + || ("text" === a["type"]) + || ("search" === a["type"]) + || ("tel" === a["type"]) + || ("url" === a["type"]) + || ("password" === a["type"]) + ) + ) + || ("textarea" === b) + || ("true" === a["contentEditable"]) + ) +) + +Nf = FreeVar(Math)["random"]()["toString"](36)["slice"](2) + +Ng = (null | a) + +Nh = [] + +Ni = (("function" === typeof(FreeVar(WeakMap))) ? FreeVar(WeakMap) : FreeVar(Map)) + +Nj = (...) => undefined + +Nk = (...) => undefined + +O = (null | ???*0* | a) +- *0* unsupported expression + ⚠️ This value might have side effects + +Oa = (...) => ("" | k | (???*0* ? Ma(a) : "")) +- *0* unsupported expression + ⚠️ This value might have side effects + +Ob = (!(1) | !(0)) + +Oc = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +Od = {"Alt": "altKey", "Control": "ctrlKey", "Meta": "metaKey", "Shift": "shiftKey"} + +Oe = (...) => undefined + +Of = `__reactFiber$${Nf}` + +Og = (null | ???*0* | a) +- *0* unsupported expression + ⚠️ This value might have side effects + +Oh = (...) => undefined + +Oi = (...) => c + +Oj = !(1) + +Ok = (...) => a + +P = (null | ???*0* | a | b | a) +- *0* unsupported expression + ⚠️ This value might have side effects + +Pa = (...) => (undefined | Ma(a["type"]) | Ma("Lazy") | Ma("Suspense") | Ma("SuspenseList") | ???*0* | "") +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Pb = (null | a) + +Pc = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +Pd = (...) => (b["getModifierState"] ? b["getModifierState"](a) : (???*0* ? !(!(b[a])) : !(1))) +- *0* unsupported expression + ⚠️ This value might have side effects + +Pe = (ia && ???*0* && ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Pf = `__reactProps$${Nf}` + +Pg = (null | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Ph = ua["ReactCurrentDispatcher"] + +Pi = (!(0) | !(1)) + +Pj = (...) => n + +Pk = (...) => (!(1) | !(0)) + +Q = (...) => undefined + +Qa = (...) => ( + | null + | (a["displayName"] || a["name"] || null) + | a + | "Fragment" + | "Portal" + | "Profiler" + | "StrictMode" + | "Suspense" + | "SuspenseList" + | `${(a["displayName"] || "Context")}.Consumer` + | `${(a["_context"]["displayName"] || "Context")}.Provider` + | ???*0* + | Qa(a(b)) +) +- *0* ((null !== b) ? b : (Qa(a["type"]) || "Memo")) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Qb = (!(1) | !(0)) + +Qc = [] + +Qd = A( + {}, + ud, + { + "key": *anonymous function 29891*, + "code": 0, + "location": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "repeat": 0, + "locale": 0, + "getModifierState": zd, + "charCode": *anonymous function 30217*, + "keyCode": *anonymous function 30272*, + "which": *anonymous function 30346* + } +) + +Qe = (null | xa) + +Qf = `__reactListeners$${Nf}` + +Qg = (...) => undefined + +Qh = ua["ReactCurrentBatchConfig"] + +Qi = (d | null) + +Qj = (...) => undefined + +Qk = (...) => null + +R = (null | a) + +Ra = (...) => ( + | "Cache" + | `${(b["displayName"] || "Context")}.Consumer` + | `${(b["_context"]["displayName"] || "Context")}.Provider` + | "DehydratedFragment" + | ???*0* + | "Fragment" + | b + | "Portal" + | "Root" + | "Text" + | Qa(b) + | ((b === za) ? "StrictMode" : "Mode") + | "Offscreen" + | "Profiler" + | "Scope" + | "Suspense" + | "SuspenseList" + | "TracingMarker" + | (b["displayName"] || b["name"] || null) + | null +) +- *0* ( + || b["displayName"] + || (("" !== a) ? ("ForwardRef(" + a + ")") : "ForwardRef") + ) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Rb = (null | l) + +Rc = "mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit"["split"](" ") + +Rd = rd(Qd) + +Re = (null | d | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Rf = `__reactHandles$${Nf}` + +Rg = (...) => undefined + +Rh = (0 | f) + +Ri = (...) => c + +Rj = (...) => undefined + +Rk = (...) => (undefined | a(b)) + +S = (...) => b + +Sa = (...) => (undefined | a | "") + +Sb = {"onError": *anonymous function 17435*} + +Sc = (...) => undefined + +Sd = A( + {}, + Ad, + { + "pointerId": 0, + "width": 0, + "height": 0, + "pressure": 0, + "tangentialPressure": 0, + "tiltX": 0, + "tiltY": 0, + "twist": 0, + "pointerType": 0, + "isPrimary": 0 + } +) + +Se = (null | d | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Sf = [] + +Sg = (...) => undefined + +Sh = (!(1) | !(0)) + +Si = (???*0* | null) +- *0* unknown new expression + ⚠️ This value might have side effects + +Sj = (...) => undefined + +Sk = (...) => (undefined | a()) + +T = (3 | 0 | 1 | 2 | 4 | 6 | 5) + +Ta = (...) => (???*0* && ("input" === a["toLowerCase"]()) && (("checkbox" === b) || ("radio" === b))) +- *0* unsupported expression + ⚠️ This value might have side effects + +Tb = (...) => undefined + +Tc = (...) => (???*0* | a) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Td = rd(Sd) + +Te = (!(1) | !(0)) + +Tf = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +Tg = (...) => undefined + +Th = (!(1) | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Ti = (...) => undefined + +Tj = (...) => undefined + +Tk = (...) => (undefined | FreeVar(undefined)) + +U = (!(1) | (???*0* || (null !== c["memoizedState"])) | d | (???*1* || m) | l | k | l) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Ua = (...) => ( + | undefined + | { + "getValue": *anonymous function 10089*, + "setValue": *anonymous function 10119*, + "stopTracking": *anonymous function 10152* + } +) + +Ub = (...) => undefined + +Uc = (...) => (???*0* | !(0) | !(1)) +- *0* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Ud = A( + {}, + ud, + { + "touches": 0, + "targetTouches": 0, + "changedTouches": 0, + "altKey": 0, + "metaKey": 0, + "ctrlKey": 0, + "shiftKey": 0, + "getModifierState": zd + } +) + +Ue = (...) => undefined + +Uf = (...) => {"current": a} + +Ug = (!(0) | !(1) | ((0 !== ???*0*) ? !(0) : !(1))) +- *0* unsupported expression + ⚠️ This value might have side effects + +Uh = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +Ui = (...) => undefined + +Uj = (...) => ((5 === a["tag"]) || (3 === a["tag"]) || (4 === a["tag"])) + +Uk = (...) => undefined + +V = ( + | null + | b + | a + | b["return"] + | a + | m + | y + | a + | e + | k + | f + | c + | b["return"] + | c + | b["return"] + | h + | b["return"] + | a["current"] + | l + | q + | r + | y + | f + | g + | x + | f["return"] + | w + | u + | F + | h["return"] +) + +Va = (...) => undefined + +Vb = (...) => ((3 === b["tag"]) ? c : null) + +Vc = (...) => (undefined | FreeVar(undefined)) + +Vd = rd(Ud) + +Ve = (...) => c + +Vf = {} + +Vg = (...) => b + +Vh = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +Vi = (...) => (a | null) + +Vj = (...) => (undefined | null | a["stateNode"]) + +Vk = (...) => undefined + +W = (...) => undefined + +Wa = (...) => (!(1) | !(0) | ((a !== c) ? !(0) : !(1))) + +Wb = (...) => (b["dehydrated"] | null) + +Wc = (...) => (b | c | null) + +Wd = A( + {}, + sd, + {"propertyName": 0, "elapsedTime": 0, "pseudoElement": 0} +) + +We = { + "animationend": Ve("Animation", "AnimationEnd"), + "animationiteration": Ve("Animation", "AnimationIteration"), + "animationstart": Ve("Animation", "AnimationStart"), + "transitionend": Ve("Transition", "TransitionEnd") +} + +Wf = Uf(!(1)) + +Wg = (null | [a]) + +Wh = (...) => (!(1) | !(0)) + +Wi = (...) => (???*0* | a) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Wj = (...) => undefined + +Wk = (???*0* | *anonymous function 117815*) +- *0* Wk + ⚠️ pattern without value + +X = (null | d | c["stateNode"]["containerInfo"] | h["stateNode"] | h["stateNode"]["containerInfo"]) + +Xa = (...) => (undefined | null | (a["activeElement"] || a["body"]) | a["body"]) + +Xb = (...) => undefined + +Xc = (...) => (!(1) | ???*0* | !(0)) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Xd = rd(Wd) + +Xe = {} + +Xf = (Vf | H["current"]) + +Xg = (...) => undefined + +Xh = (...) => a + +Xi = ua["ReactCurrentOwner"] + +Xj = (...) => undefined + +Xk = (...) => null + +Y = (null | ???*0* | b | c | b) +- *0* unsupported expression + ⚠️ This value might have side effects + +Ya = (...) => A( + {}, + b, + { + "defaultChecked": ???*0*, + "defaultValue": ???*1*, + "value": ???*2*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +Yb = (...) => (((b !== a) ? null : a) | a | b | ((c["stateNode"]["current"] === c) ? a : b)) + +Yc = (...) => ( + | a + | ((3 === b["tag"]) ? b["stateNode"]["containerInfo"] : null) + | null +) + +Yd = A( + {}, + Ad, + { + "deltaX": *anonymous function 30803*, + "deltaY": *anonymous function 30887*, + "deltaZ": 0, + "deltaMode": 0 + } +) + +Ye = ({} | FreeVar(document)["createElement"]("div")["style"]) + +Yf = (...) => (Vf | d["__reactInternalMemoizedMaskedChildContext"] | e) + +Yg = (...) => Zg(a, d) + +Yh = { + "readContext": Vg, + "useCallback": *anonymous function 71076*, + "useContext": Vg, + "useEffect": vi, + "useImperativeHandle": *anonymous function 71188*, + "useLayoutEffect": *anonymous function 71305*, + "useInsertionEffect": *anonymous function 71364*, + "useMemo": *anonymous function 71406*, + "useReducer": *anonymous function 71500*, + "useRef": *anonymous function 71750*, + "useState": qi, + "useDebugValue": Ai, + "useDeferredValue": *anonymous function 71860*, + "useTransition": *anonymous function 71915*, + "useMutableSource": *anonymous function 72018*, + "useSyncExternalStore": *anonymous function 72052*, + "useId": *anonymous function 72352*, + "unstable_isNewReconciler": !(1) +} + +Yi = (...) => undefined + +Yj = (!(1) | e | !(0)) + +Yk = (...) => undefined + +Z = (0 | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Za = (...) => undefined + +Zb = (...) => ((null !== a) ? $b(a) : null) + +Zc = (...) => undefined + +Zd = rd(Yd) + +Ze = (...) => (Xe[a] | a | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Zf = (...) => ((null !== a) && (???*0* !== a)) +- *0* unsupported expression + ⚠️ This value might have side effects + +Zg = (...) => ((3 === c["tag"]) ? c["stateNode"] : null) + +Zh = { + "readContext": Vg, + "useCallback": Bi, + "useContext": Vg, + "useEffect": ji, + "useImperativeHandle": zi, + "useInsertionEffect": wi, + "useLayoutEffect": xi, + "useMemo": Ci, + "useReducer": fi, + "useRef": si, + "useState": *anonymous function 72781*, + "useDebugValue": Ai, + "useDeferredValue": *anonymous function 72842*, + "useTransition": *anonymous function 72911*, + "useMutableSource": hi, + "useSyncExternalStore": ii, + "useId": Fi, + "unstable_isNewReconciler": !(1) +} + +Zi = (...) => (???*0* | b["child"]) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Zj = (...) => undefined + +Zk = (...) => undefined + +a#10 = arguments[0] + +a#1001 = arguments[0] + +a#1004 = arguments[0] + +a#1008 = (arguments[0] | Zb(a)) + +a#101 = arguments[0] + +a#1011 = ???*0* +- *0* a + ⚠️ pattern without value + +a#1012 = arguments[0] + +a#1013 = arguments[0] + +a#1014 = ( + | arguments[0] + | FreeVar(Object)["keys"](a)["join"](",") + | Zb(b) + | ((null === a) ? null : a["stateNode"]) +) + +a#1016 = arguments[0] + +a#1017 = arguments[0] + +a#1018 = (arguments[0] | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +a#1019 = arguments[0] + +a#102 = (arguments[0] | a["style"]) + +a#1020 = arguments[0] + +a#1023 = arguments[0] + +a#104 = arguments[0] + +a#107 = arguments[0] + +a#108 = ( + | arguments[0] + | (a["target"] || a["srcElement"] || FreeVar(window)) + | a["correspondingUseElement"] +) + +a#109 = (arguments[0] | Cb(a)) + +a#11 = arguments[0] + +a#111 = arguments[0] + +a#112 = (zb | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +a#114 = arguments[0] + +a#116 = arguments[0] + +a#119 = (arguments[0] | a["type"] | !(d) | !(1)) + +a#12 = arguments[0] + +a#122 = ???*0* +- *0* a + ⚠️ pattern without value + +a#123 = arguments[0] + +a#126 = arguments[0] + +a#127 = arguments[0] + +a#128 = arguments[0] + +a#13 = arguments[0] + +a#131 = (arguments[0] | b | b["return"]) + +a#133 = (arguments[0] | a["alternate"]) + +a#135 = arguments[0] + +a#136 = arguments[0] + +a#14 = arguments[0] + +a#15 = arguments[0] + +a#151 = (arguments[0] | Yb(a)) + +a#152 = (arguments[0] | a["child"] | a["sibling"]) + +a#154 = arguments[0] + +a#157 = (arguments[0] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +a#158 = arguments[0] + +a#159 = (arguments[0] | a["entanglements"]) + +a#16 = arguments[0] + +a#161 = arguments[0] + +a#162 = arguments[0] + +a#165 = (arguments[0] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#166 = rc + +a#167 = arguments[0] + +a#168 = (arguments[0] | a["eventTimes"]) + +a#169 = (arguments[0] | a["expirationTimes"]) + +a#17 = arguments[0] + +a#171 = (arguments[0] | a["entanglements"]) + +a#173 = (arguments[0] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +a#174 = arguments[0] + +a#175 = ( + | arguments[0] + | { + "blockedOn": b, + "domEventName": c, + "eventSystemFlags": d, + "nativeEvent": f, + "targetContainers": [e] + } +) + +a#176 = arguments[0] + +a#177 = arguments[0] + +a#18 = arguments[0] + +a#183 = arguments[0] + +a#186 = arguments[0] + +a#188 = arguments[0] + +a#189 = arguments[0] + +a#19 = arguments[0] + +a#193 = arguments[0] + +a#196 = arguments[0] + +a#199 = arguments[0] + +a#20 = arguments[0] + +a#203 = (arguments[0] | xb(d) | Wc(a) | null | Wb(b)) + +a#206 = arguments[0] + +a#207 = (???*0* | 0 | ???*1*) +- *0* a + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +a#208 = (arguments[0] | a["charCode"] | 13 | b) + +a#21 = arguments[0] + +a#211 = arguments[0] + +a#213 = ???*0*["nativeEvent"] +- *0* unsupported expression + ⚠️ This value might have side effects + +a#214 = ???*0*["nativeEvent"] +- *0* unsupported expression + ⚠️ This value might have side effects + +a#216 = arguments[0] + +a#217 = arguments[0] + +a#218 = arguments[0] + +a#219 = arguments[0] + +a#22 = arguments[0] + +a#220 = arguments[0] + +a#221 = (arguments[0] | Od[a]) + +a#223 = (arguments[0] | od(a)) + +a#225 = arguments[0] + +a#226 = arguments[0] + +a#227 = arguments[0] + +a#228 = arguments[0] + +a#229 = arguments[0] + +a#23 = arguments[0] + +a#230 = arguments[0] + +a#231 = (arguments[0] | a["detail"]) + +a#232 = (arguments[0] | b["data"]) + +a#233 = (arguments[0] | nd()) + +a#235 = arguments[0] + +a#236 = arguments[0] + +a#237 = arguments[0] + +a#238 = arguments[0] + +a#239 = arguments[0] + +a#24 = arguments[0] + +a#244 = arguments[0] + +a#246 = arguments[0] + +a#247 = arguments[0] + +a#248 = arguments[0] + +a#249 = arguments[0] + +a#25 = arguments[0] + +a#250 = arguments[0] + +a#251 = arguments[0] + +a#253 = (arguments[0] | a["firstChild"]) + +a#254 = (arguments[0] | 0 | d) + +a#26 = (arguments[0] | ((Ja && a[Ja]) || a["@@iterator"])) + +a#260 = arguments[0] + +a#261 = (FreeVar(window) | b["contentWindow"]) + +a#265 = arguments[0] + +a#266 = ( + | arguments[0] + | d["end"] + | b + | ((???*0* && b["defaultView"]) || FreeVar(window)) + | a["getSelection"]() + | c + | a["parentNode"] + | b[c] +) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#269 = arguments[0] + +a#27 = arguments[0] + +a#270 = arguments[0] + +a#271 = arguments[0] + +a#272 = arguments[0] + +a#274 = arguments[0] + +a#275 = (arguments[0] | Rb) + +a#280 = arguments[0] + +a#281 = arguments[0] + +a#282 = arguments[0] + +a#285 = arguments[0] + +a#286 = arguments[0] + +a#3 = arguments[0] + +a#30 = (arguments[0] | (a ? (a["displayName"] || a["name"]) : "")) + +a#307 = arguments[0] + +a#308 = (arguments[0] | a["return"]) + +a#310 = (arguments[0] | a["return"]) + +a#311 = arguments[0] + +a#313 = arguments[0] + +a#314 = arguments[0] + +a#316 = arguments[0] + +a#317 = arguments[0] + +a#318 = arguments[0] + +a#320 = arguments[0] + +a#324 = (arguments[0] | a["nextSibling"]) + +a#327 = (arguments[0] | a["previousSibling"]) + +a#331 = (arguments[0] | Mf(a) | c) + +a#335 = (arguments[0] | (a[Of] || a[uf])) + +a#336 = arguments[0] + +a#337 = arguments[0] + +a#338 = arguments[0] + +a#339 = arguments[0] + +a#340 = arguments[0] + +a#341 = (arguments[0] | a["stateNode"]) + +a#342 = (arguments[0] | a["childContextTypes"]) + +a#344 = arguments[0] + +a#345 = arguments[0] + +a#346 = ( + | arguments[0] + | ( + || (???*0* && a["__reactInternalMemoizedMergedChildContext"]) + || Vf + ) + | a["stateNode"] +) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#347 = (arguments[0] | bg(a, b, Xf)) + +a#348 = arguments[0] + +a#349 = arguments[0] + +a#350 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +a#356 = arguments[0] + +a#357 = (arguments[0] | sg) + +a#359 = arguments[0] + +a#360 = arguments[0] + +a#361 = arguments[0] + +a#362 = arguments[0] + +a#363 = arguments[0] + +a#364 = arguments[0] + +a#369 = (arguments[0] | a["return"]) + +a#370 = (arguments[0] | a["memoizedState"] | ((null !== a) ? a["dehydrated"] : null) | a["nextSibling"]) + +a#378 = (yg | Lf(a["nextSibling"])) + +a#380 = arguments[0] + +a#381 = (arguments[0] | a["defaultProps"]) + +a#384 = arguments[0] + +a#385 = (arguments[0] | a["return"]) + +a#387 = (arguments[0] | a["dependencies"]) + +a#388 = (arguments[0] | {"context": a, "memoizedValue": b, "next": null}) + +a#390 = arguments[0] + +a#391 = arguments[0] + +a#392 = (arguments[0] | a["return"]) + +a#393 = arguments[0] + +a#394 = (arguments[0] | a["updateQueue"]) + +a#395 = arguments[0] + +a#396 = arguments[0] + +a#398 = arguments[0] + +a#4 = arguments[0] + +a#400 = (arguments[0] | c["lastBaseUpdate"]) + +a#404 = arguments[0] + +a#412 = (arguments[0] | b["effects"]) + +a#415 = arguments[0] + +a#416 = (arguments[0] | a["_reactInternals"]) + +a#417 = (arguments[0] | a["_reactInternals"]) + +a#418 = (arguments[0] | a["_reactInternals"]) + +a#419 = (arguments[0] | a["_reactInternals"]) + +a#420 = (arguments[0] | a["stateNode"]) + +a#421 = (arguments[0] | a["stateNode"]) + +a#422 = (arguments[0] | b["state"]) + +a#423 = arguments[0] + +a#424 = (arguments[0] | c["ref"]) + +a#428 = arguments[0] + +a#429 = ( + | arguments[0] + | FreeVar(Object)["prototype"]["toString"]["call"](b) +) + +a#430 = arguments[0] + +a#431 = arguments[0] + +a#435 = (arguments[0] | ???*0*) +- *0* unknown new expression + ⚠️ This value might have side effects + +a#436 = (arguments[0] | wh(a, b)) + +a#439 = arguments[0] + +a#440 = arguments[0] + +a#441 = arguments[0] + +a#442 = arguments[0] + +a#443 = arguments[0] + +a#445 = arguments[0] + +a#447 = ( + | arguments[0] + | (a["get"](c) || null) + | (a["get"](((null === d["key"]) ? c : d["key"])) || null) +) + +a#453 = arguments[0] + +a#458 = arguments[0] + +a#459 = (arguments[0] | d | h) + +a#471 = arguments[0] + +a#472 = (arguments[0] | b["nodeType"] | ((8 === a) ? b["parentNode"] : b) | a["tagName"]) + +a#474 = arguments[0] + +a#475 = arguments[0] + +a#476 = arguments[0] + +a#482 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +a#484 = arguments[0] + +a#485 = (arguments[0] | c(d, e)) + +a#488 = (0 !== Uh) + +a#489 = {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + +a#49 = (arguments[0] | Oa(a["type"], !(1)) | Oa(a["type"]["render"], !(1)) | Oa(a["type"], !(0))) + +a#490 = ( + | N["alternate"] + | ((null !== a) ? a["memoizedState"] : null) + | O["next"] + | { + "memoizedState": O["memoizedState"], + "baseState": O["baseState"], + "baseQueue": O["baseQueue"], + "queue": O["queue"], + "next": null + } +) + +a#493 = arguments[0] + +a#494 = (arguments[0] | c["interleaved"]) + +a#5 = (arguments[0] | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +a#50 = ( + | arguments[0] + | a["displayName"] + | (b["displayName"] || b["name"] || "") + | (("" !== a) ? `ForwardRef(${a})` : "ForwardRef") + | a["_init"] +) + +a#501 = arguments[0] + +a#504 = arguments[0] + +a#506 = (arguments[0] | {"getSnapshot": b, "value": c}) + +a#507 = arguments[0] + +a#508 = arguments[0] + +a#510 = (arguments[0] | a["value"]) + +a#513 = arguments[0] + +a#514 = ( + | arguments[0] + | a() + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": ei, + "lastRenderedState": a + } + | ???*0* +) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#515 = ( + | arguments[0] + | {"tag": a, "create": b, "destroy": c, "deps": d, "next": null} +) + +a#517 = arguments[0] + +a#518 = arguments[0] + +a#521 = arguments[0] + +a#522 = arguments[0] + +a#523 = arguments[0] + +a#524 = arguments[0] + +a#525 = (arguments[0] | a()) + +a#528 = arguments[0] + +a#53 = (arguments[0] | b["render"] | (a["displayName"] || a["name"] || "")) + +a#530 = arguments[0] + +a#531 = (arguments[0] | a()) + +a#532 = arguments[0] + +a#533 = arguments[0] + +a#537 = arguments[0] + +a#539 = arguments[0] + +a#54 = arguments[0] + +a#545 = arguments[0] + +a#546 = arguments[0] + +a#547 = arguments[0] + +a#549 = arguments[0] + +a#55 = (arguments[0] | a["nodeName"]) + +a#550 = arguments[0] + +a#551 = arguments[0] + +a#552 = arguments[0] + +a#553 = (arguments[0] | a()) + +a#554 = ( + | arguments[0] + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": a, + "lastRenderedState": b + } + | ???*0* +) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#555 = (arguments[0] | {"current": a}) + +a#556 = arguments[0] + +a#557 = (qi(!(1)) | Ei["bind"](null, a[1])) + +a#559 = arguments[0] + +a#56 = arguments[0] + +a#562 = ci() + +a#565 = arguments[0] + +a#566 = fi(ei)[0] + +a#568 = arguments[0] + +a#569 = gi(ei)[0] + +a#570 = arguments[0] + +a#573 = arguments[0] + +a#574 = arguments[0] + +a#578 = arguments[0] + +a#580 = arguments[0] + +a#585 = (arguments[0] | Ui["bind"](null, a, b, c)) + +a#587 = (arguments[0] | a["return"]) + +a#589 = arguments[0] + +a#59 = arguments[0] + +a#590 = arguments[0] + +a#591 = arguments[0] + +a#592 = (arguments[0] | yh(c["type"], null, d, b, b["mode"], e) | wh(f, d)) + +a#595 = arguments[0] + +a#597 = (arguments[0] | ((null !== f) ? ???*0* : c)) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#599 = arguments[0] + +a#6 = arguments[0] + +a#600 = arguments[0] + +a#601 = arguments[0] + +a#605 = arguments[0] + +a#606 = arguments[0] + +a#607 = arguments[0] + +a#608 = arguments[0] + +a#609 = ( + | arguments[0] + | b["memoizedState"] + | a["dehydrated"] + | d["fallback"] + | Ah(a, d, c, null) + | f["sibling"] +) + +a#61 = arguments[0] + +a#612 = arguments[0] + +a#613 = (arguments[0] | rj(b, b["pendingProps"]["children"])) + +a#614 = (arguments[0] | f["treeContext"]) + +a#619 = arguments[0] + +a#620 = arguments[0] + +a#621 = ( + | arguments[0] + | b["child"] + | a["child"] + | a["return"] + | a["sibling"] + | c["alternate"] + | e["alternate"] + | e["sibling"] +) + +a#628 = arguments[0] + +a#629 = (arguments[0] | b["child"] | a["sibling"]) + +a#63 = arguments[0] + +a#631 = (arguments[0] | $i(a, b, c)) + +a#634 = arguments[0] + +a#639 = (arguments[0] | b["stateNode"]) + +a#64 = (arguments[0] | d) + +a#644 = arguments[0] + +a#645 = arguments[0] + +a#646 = arguments[0] + +a#647 = ( + | arguments[0] + | Hh(Eh["current"]) + | (0 !== ???*0*) + | kb(c) + | g["createElement"]("div") + | a["removeChild"](a["firstChild"]) + | g["createElement"](c, {"is": d["is"]}) + | g["createElement"](c) + | g["createElementNS"](a, c) + | xg + | b["child"] + | d + | g["dependencies"] + | a["sibling"] + | Mh(g) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#65 = ( + | arguments[0] + | ( + || a + || (("undefined" !== typeof(FreeVar(document))) ? FreeVar(document) : ???*0*) + ) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#665 = (arguments[0] | b["flags"] | b["memoizedState"]) + +a#667 = arguments[0] + +a#670 = arguments[0] + +a#673 = (arguments[0] | Me() | b["child"] | b["sibling"]) + +a#68 = arguments[0] + +a#687 = arguments[0] + +a#69 = arguments[0] + +a#691 = arguments[0] + +a#695 = (arguments[0] | c) + +a#697 = arguments[0] + +a#698 = arguments[0] + +a#699 = (arguments[0] | a["return"] | a["sibling"] | a["child"]) + +a#7 = (arguments[0] | a["toLowerCase"]()["slice"](0, 5)) + +a#70 = arguments[0] + +a#703 = (arguments[0] | a["stateNode"] | a["child"] | a["sibling"]) + +a#704 = (arguments[0] | a["stateNode"] | a["child"] | a["sibling"]) + +a#705 = arguments[0] + +a#706 = (arguments[0] | X) + +a#71 = arguments[0] + +a#713 = arguments[0] + +a#716 = arguments[0] + +a#721 = arguments[0] + +a#74 = arguments[0] + +a#756 = arguments[0] + +a#76 = arguments[0] + +a#763 = arguments[0] + +a#764 = arguments[0] + +a#768 = arguments[0] + +a#77 = (arguments[0] | a["options"]) + +a#781 = arguments[0] + +a#785 = arguments[0] + +a#8 = arguments[0] + +a#801 = (arguments[0] | C | FreeVar(window)["event"] | ((???*0* === a) ? 16 : jd(a["type"]))) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#802 = arguments[0] + +a#803 = arguments[0] + +a#807 = arguments[0] + +a#817 = (arguments[0] | Jk(a, b)) + +a#818 = arguments[0] + +a#819 = arguments[0] + +a#82 = arguments[0] + +a#827 = (arguments[0] | a["expirationTimes"]) + +a#829 = arguments[0] + +a#83 = arguments[0] + +a#831 = arguments[0] + +a#834 = arguments[0] + +a#838 = (arguments[0] | wh(a["current"], null)) + +a#843 = arguments[0] + +a#861 = nk["current"] + +a#863 = arguments[0] + +a#868 = arguments[0] + +a#869 = (arguments[0] | b["return"]) + +a#87 = arguments[0] + +a#877 = arguments[0] + +a#88 = arguments[0] + +a#880 = (arguments[0] | Qi) + +a#883 = (Dc(yk) | xk) + +a#89 = arguments[0] + +a#9 = arguments[0] + +a#90 = arguments[0] + +a#909 = (arguments[0] | dh(a, b, 1)) + +a#91 = *anonymous function 13608* + +a#910 = (arguments[0] | Ki(c, a) | Ri(b, a, 1) | L()) + +a#915 = arguments[0] + +a#916 = (arguments[0] | Zg(a, b)) + +a#917 = arguments[0] + +a#918 = arguments[0] + +a#919 = (arguments[0] | b["pendingProps"] | Lg(d, a) | !(0) | !(1)) + +a#94 = arguments[0] + +a#940 = arguments[0] + +a#941 = arguments[0] + +a#942 = arguments[0] + +a#943 = (arguments[0] | a["prototype"]) + +a#944 = (arguments[0] | a["$$typeof"]) + +a#946 = arguments[0] + +a#947 = (arguments[0] | Bg(12, c, b, ???*0*) | Bg(13, c, b, e) | Bg(19, c, b, e)) +- *0* unsupported expression + ⚠️ This value might have side effects + +a#948 = (arguments[0] | Bg(7, a, d, b)) + +a#949 = (arguments[0] | Bg(22, a, d, b)) + +a#950 = (arguments[0] | Bg(6, a, null, b)) + +a#951 = arguments[0] + +a#952 = arguments[0] + +a#953 = (arguments[0] | ???*0*) +- *0* unknown new expression + ⚠️ This value might have side effects + +a#954 = arguments[0] + +a#955 = (arguments[0] | a["_reactInternals"]) + +a#96 = arguments[0] + +a#960 = (arguments[0] | cl(c, d, !(0), a, e, f, g, h, k)) + +a#961 = (arguments[0] | dh(e, b, g)) + +a#962 = (arguments[0] | a["current"]) + +a#963 = (arguments[0] | a["memoizedState"]) + +a#965 = (arguments[0] | a["alternate"]) + +a#967 = arguments[0] + +a#968 = arguments[0] + +a#969 = arguments[0] + +a#970 = ???*0*["_internalRoot"] +- *0* unsupported expression + ⚠️ This value might have side effects + +a#973 = arguments[0] + +a#974 = (arguments[0] | {"blockedOn": null, "target": a, "priority": b}) + +a#976 = arguments[0] + +a#977 = arguments[0] + +a#979 = arguments[0] + +a#982 = hl(g) + +a#984 = hl(k) + +a#986 = arguments[0] + +a#989 = hl(g) + +a#99 = arguments[0] + +a#990 = arguments[0] + +a#994 = arguments[0] + +a#997 = arguments[0] + +aa = FreeVar(require)("react") + +ab = (...) => undefined + +ac = ca["unstable_scheduleCallback"] + +ad = (...) => undefined + +ae = (ia && ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +af = Ze("animationiteration") + +ag = (...) => undefined + +ah = (...) => undefined + +ai = { + "readContext": Vg, + "useCallback": Q, + "useContext": Q, + "useEffect": Q, + "useImperativeHandle": Q, + "useInsertionEffect": Q, + "useLayoutEffect": Q, + "useMemo": Q, + "useReducer": Q, + "useRef": Q, + "useState": Q, + "useDebugValue": Q, + "useDeferredValue": Q, + "useTransition": Q, + "useMutableSource": Q, + "useSyncExternalStore": Q, + "useId": Q, + "unstable_isNewReconciler": !(1) +} + +aj = (...) => (???*0* | ???*1* | $i(a, b, e)) +- *0* cj(a, b, f, d, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +ak = (...) => undefined + +al = (...) => undefined + +b#100 = ( + | arguments[0] + | (b + a["charAt"](0)["toUpperCase"]() + a["substring"](1)) +) + +b#1001 = arguments[1] + +b#1004 = (arguments[1] | c["name"] | 0 | ???*0* | c["value"]) +- *0* updated with update expression + ⚠️ This value might have side effects + +b#101 = arguments[1] + +b#1012 = arguments[1] + +b#1013 = (arguments[1] | cl(a, 1, !(1), null, null, c, !(1), d, e)) + +b#1014 = a["_reactInternals"] + +b#1017 = arguments[1] + +b#1018 = ( + | arguments[1] + | fl(b, null, a, 1, ((null != c) ? c : null), e, !(1), f, g) +) + +b#1019 = arguments[1] + +b#102 = arguments[1] + +b#1023 = arguments[1] + +b#104 = arguments[1] + +b#107 = arguments[1] + +b#109 = (a["stateNode"] | Db(b)) + +b#11 = a[0] + +b#112 = Ab + +b#114 = arguments[1] + +b#116 = arguments[1] + +b#119 = arguments[1] + +b#123 = arguments[1] + +b#127 = arguments[1] + +b#128 = arguments[1] + +b#131 = (a | b["return"]) + +b#133 = a["memoizedState"] + +b#136 = (a["alternate"] | Vb(a)) + +b#152 = $b(a) + +b#156 = ???*0* +- *0* b + ⚠️ pattern without value + +b#159 = (arguments[1] | a["entangledLanes"] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +b#161 = arguments[1] + +b#162 = arguments[1] + +b#167 = [] + +b#168 = (arguments[1] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#169 = (arguments[1] | a["entanglements"]) + +b#171 = arguments[1] + +b#174 = arguments[1] + +b#175 = (arguments[1] | Cb(b) | a["targetContainers"]) + +b#176 = arguments[1] + +b#177 = (Wc(a["target"]) | c["tag"] | Wb(c)) + +b#183 = (a["targetContainers"] | Cb(c)) + +b#186 = arguments[1] + +b#188 = arguments[1] + +b#189 = (...) => ad(b, a) + +b#190 = arguments[0] + +b#193 = arguments[1] + +b#196 = arguments[1] + +b#199 = arguments[1] + +b#20 = a["replace"](ra, sa) + +b#203 = (arguments[1] | Vb(a)) + +b#207 = ld + +b#208 = a["keyCode"] + +b#21 = a["replace"](ra, sa) + +b#211 = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +b#212 = (arguments[0] | a[c]) + +b#22 = a["replace"](ra, sa) + +b#221 = ???*0*["nativeEvent"] +- *0* unsupported expression + ⚠️ This value might have side effects + +b#223 = (Md[a["key"]] || a["key"]) + +b#230 = arguments[1] + +b#232 = arguments[1] + +b#233 = arguments[1] + +b#235 = (a && a["nodeName"] && a["nodeName"]["toLowerCase"]()) + +b#236 = (arguments[1] | oe(b, "onChange")) + +b#238 = ue(a) + +b#239 = arguments[1] + +b#244 = [] + +b#246 = arguments[1] + +b#248 = arguments[1] + +b#249 = arguments[1] + +b#25 = (arguments[1] | e["attributeName"]) + +b#250 = arguments[1] + +b#251 = arguments[1] + +b#254 = arguments[1] + +b#260 = arguments[1] + +b#261 = (Xa() | Xa(a["document"])) + +b#265 = (a && a["nodeName"] && a["nodeName"]["toLowerCase"]()) + +b#266 = (Me() | d["start"] | (c["ownerDocument"] || FreeVar(document)) | b["createRange"]() | []) + +b#269 = (arguments[1] | ???*0*) +- *0* unknown new expression + ⚠️ This value might have side effects + +b#27 = c["stack"]["trim"]()["match"](/\n( *(at )?)/) + +b#270 = arguments[1] + +b#271 = We[a] + +b#272 = arguments[1] + +b#274 = arguments[1] + +b#275 = (arguments[1] | (0 !== ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#280 = arguments[1] + +b#281 = arguments[1] + +b#282 = ((9 === a["nodeType"]) ? a : a["ownerDocument"]) + +b#284 = arguments[0] + +b#285 = arguments[1] + +b#286 = arguments[1] + +b#3 = ( + | `https://reactjs.org/docs/error-decoder.html?invariant=${a}` + | `${b}${`&args[]=${FreeVar(encodeURIComponent)(FreeVar(arguments)[c])}`}` +) + +b#30 = (arguments[1] | *anonymous function 6811*) + +b#307 = arguments[1] + +b#308 = arguments[1] + +b#311 = arguments[1] + +b#314 = (arguments[1] | zf(b)) + +b#316 = arguments[1] + +b#320 = arguments[1] + +b#324 = (a["nodeType"] | a["data"]) + +b#327 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +b#331 = (a[Of] | (c[uf] || c[Of])) + +b#340 = arguments[1] + +b#341 = arguments[1] + +b#344 = arguments[1] + +b#345 = (arguments[1] | b["childContextTypes"]) + +b#347 = arguments[1] + +b#350 = C + +b#356 = arguments[1] + +b#357 = arguments[1] + +b#361 = (arguments[1] | a["deletions"]) + +b#362 = ( + | arguments[1] + | (( + || (1 !== b["nodeType"]) + || (c["toLowerCase"]() !== b["nodeName"]["toLowerCase"]()) + ) ? null : b) + | ((("" === a["pendingProps"]) || (3 !== b["nodeType"])) ? null : b) + | ((8 !== b["nodeType"]) ? null : b) +) + +b#364 = (yg | Lf(c["nextSibling"])) + +b#370 = ( + | ???*0* + | (3 !== a["tag"]) + | (5 !== a["tag"]) + | a["type"] + | (("head" !== b) && ("body" !== b) && !(Ef(a["type"], a["memoizedProps"]))) + | yg + | Lf(b["nextSibling"]) + | 0 + | ???*1* +) +- *0* b + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +b#381 = (arguments[1] | A({}, b)) + +b#384 = Mg["current"] + +b#385 = arguments[1] + +b#387 = arguments[1] + +b#388 = a["_currentValue"] + +b#391 = arguments[1] + +b#392 = arguments[1] + +b#394 = arguments[1] + +b#395 = arguments[1] + +b#396 = arguments[1] + +b#398 = (arguments[1] | b["updateQueue"] | b["shared"]) + +b#4 = arguments[1] + +b#400 = arguments[1] + +b#404 = (arguments[1] | e["shared"]["interleaved"]) + +b#412 = (arguments[1] | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +b#415 = (arguments[1] | a["memoizedState"]) + +b#417 = (arguments[1] | dh(a, f, e)) + +b#418 = (arguments[1] | dh(a, f, e)) + +b#419 = (arguments[1] | dh(a, e, d)) + +b#420 = arguments[1] + +b#421 = (arguments[1] | ???*0*) +- *0* unknown new expression + ⚠️ This value might have side effects + +b#422 = arguments[1] + +b#423 = (arguments[1] | e["state"]) + +b#424 = (arguments[1] | *anonymous function 58064*) + +b#428 = (e["refs"] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#429 = arguments[1] + +b#430 = a["_init"] + +b#431 = (...) => undefined + +b#432 = arguments[0] + +b#435 = (arguments[1] | b["sibling"]) + +b#436 = arguments[1] + +b#437 = arguments[0] + +b#438 = arguments[0] + +b#439 = (arguments[1] | xh(c, a["mode"], d) | e(b, c)) + +b#440 = arguments[1] + +b#441 = (arguments[1] | zh(c, a["mode"], d) | e(b, (c["children"] || []))) + +b#442 = (arguments[1] | Ah(c, a["mode"], d, f) | e(b, c)) + +b#443 = (arguments[1] | xh(`${b}`, a["mode"], c) | zh(b, a["mode"], c) | Ah(b, a["mode"], c, null)) + +b#445 = arguments[1] + +b#447 = arguments[1] + +b#472 = ( + | arguments[1] + | (???*0* ? b["namespaceURI"] : lb(null, "")) + | b["documentElement"] + | (a["namespaceURI"] || null) + | lb(b, a) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#474 = Hh(Eh["current"]) + +b#476 = (a | b["child"] | b["return"] | b["sibling"]) + +b#484 = arguments[1] + +b#485 = (arguments[1] | ((null !== O) && (null !== O["next"]))) + +b#490 = ((null === P) ? N["memoizedState"] : P["next"]) + +b#493 = arguments[1] + +b#494 = di() + +b#5 = arguments[1] + +b#50 = (a["render"] | (a["displayName"] || null) | a["_payload"]) + +b#501 = di() + +b#504 = arguments[1] + +b#506 = (arguments[1] | N["updateQueue"] | {"lastEffect": null, "stores": null}) + +b#507 = arguments[1] + +b#508 = arguments[1] + +b#510 = a["getSnapshot"] + +b#513 = Zg(a, 1) + +b#514 = ci() + +b#515 = (arguments[1] | N["updateQueue"] | {"lastEffect": null, "stores": null}) + +b#517 = arguments[1] + +b#518 = arguments[1] + +b#521 = arguments[1] + +b#522 = arguments[1] + +b#523 = arguments[1] + +b#524 = arguments[1] + +b#525 = arguments[1] + +b#528 = arguments[1] + +b#53 = a["type"] + +b#530 = (arguments[1] | ((???*0* === b) ? null : b)) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#531 = (arguments[1] | ((???*0* === b) ? null : b)) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#532 = arguments[1] + +b#533 = arguments[1] + +b#537 = arguments[1] + +b#539 = arguments[1] + +b#545 = a["alternate"] + +b#546 = arguments[1] + +b#547 = arguments[1] + +b#549 = arguments[1] + +b#55 = a["type"] + +b#550 = arguments[1] + +b#551 = arguments[1] + +b#552 = arguments[1] + +b#553 = (arguments[1] | ((???*0* === b) ? null : b)) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#554 = (arguments[1] | ((???*0* !== c) ? c(b) : b)) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#555 = ci() + +b#557 = a[0] + +b#559 = arguments[1] + +b#56 = (Ta(a) ? "checked" : "value") + +b#562 = ( + | R["identifierPrefix"] + | `:${b}R${c}` + | `${b}${`H${c["toString"](32)}`}` + | `${b}:` + | `:${b}r${c["toString"](32)}:` +) + +b#565 = di() + +b#566 = di()["memoizedState"] + +b#568 = di() + +b#569 = di()["memoizedState"] + +b#570 = arguments[1] + +b#573 = arguments[1] + +b#574 = arguments[1] + +b#578 = arguments[1] + +b#580 = arguments[1] + +b#585 = arguments[1] + +b#587 = ( + | ???*0* + | (13 === a["tag"]) + | a["memoizedState"] + | ((null !== b) ? ((null !== b["dehydrated"]) ? !(0) : !(1)) : !(0)) +) +- *0* b + ⚠️ pattern without value + +b#589 = (arguments[1] | ch(???*0*, 1)) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#590 = arguments[1] + +b#591 = arguments[1] + +b#592 = arguments[1] + +b#595 = arguments[1] + +b#597 = arguments[1] + +b#599 = arguments[1] + +b#600 = arguments[1] + +b#601 = arguments[1] + +b#605 = arguments[1] + +b#606 = a["stateNode"] + +b#607 = arguments[1] + +b#609 = arguments[1] + +b#612 = ( + | arguments[1] + | qj({"mode": "visible", "children": b}, a["mode"], 0, null) +) + +b#613 = arguments[1] + +b#614 = (arguments[1] | vj["bind"](null, a) | rj(b, d["children"])) + +b#619 = arguments[1] + +b#620 = arguments[1] + +b#621 = arguments[1] + +b#628 = arguments[1] + +b#629 = arguments[1] + +b#631 = arguments[1] + +b#634 = arguments[1] + +b#639 = arguments[1] + +b#64 = a["_valueTracker"] + +b#644 = arguments[1] + +b#645 = (arguments[1] | a["tail"] | b["sibling"]) + +b#646 = ((null !== a["alternate"]) && (a["alternate"]["child"] === a["child"])) + +b#647 = (arguments[1] | f["tail"]) + +b#665 = arguments[1] + +b#667 = arguments[1] + +b#67 = ???*0* +- *0* b + ⚠️ pattern without value + +b#670 = arguments[1] + +b#673 = (arguments[1] | V) + +b#68 = arguments[1] + +b#687 = arguments[1] + +b#69 = arguments[1] + +b#691 = (arguments[1] | b["updateQueue"] | ((null !== b) ? b["lastEffect"] : null) | b["next"]) + +b#695 = a["ref"] + +b#697 = (a["alternate"] | a["stateNode"]) + +b#7 = arguments[1] + +b#70 = (arguments[1] | b["checked"]) + +b#703 = (arguments[1] | c["parentNode"] | c) + +b#704 = arguments[1] + +b#705 = arguments[1] + +b#706 = arguments[1] + +b#71 = arguments[1] + +b#713 = a["updateQueue"] + +b#715 = arguments[0] + +b#716 = (arguments[1] | b["child"] | b["sibling"]) + +b#721 = (arguments[1] | d) + +b#74 = (arguments[1] | `${a["_wrapperState"]["initialValue"]}`) + +b#756 = a["flags"] + +b#76 = arguments[1] + +b#763 = arguments[1] + +b#764 = arguments[1] + +b#768 = V + +b#77 = (arguments[1] | {} | null | a[e]) + +b#781 = V + +b#785 = V + +b#8 = arguments[1] + +b#802 = arguments[1] + +b#803 = (arguments[1] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#807 = (arguments[1] | Jk(a, d) | d | 0 | T | Ok(a, e) | Ok(a, f) | ???*0* | a["eventTimes"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +b#817 = (arguments[1] | uk) + +b#819 = (a | c | b["return"] | b["sibling"]) + +b#82 = arguments[1] + +b#827 = (arguments[1] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +b#829 = (uc(a, 0) | d) + +b#83 = (arguments[1] | b["defaultValue"] | c | "") + +b#831 = arguments[1] + +b#834 = K + +b#838 = (arguments[1] | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +b#843 = (arguments[1] | Z | y | ???*0* | na) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +b#863 = arguments[1] + +b#868 = Wk(a["alternate"], a, gj) + +b#869 = (a | b["sibling"]) + +b#87 = arguments[1] + +b#877 = arguments[1] + +b#88 = a["textContent"] + +b#880 = arguments[1] + +b#883 = pk["transition"] + +b#9 = arguments[1] + +b#90 = arguments[1] + +b#909 = (arguments[1] | Ki(c, b) | Oi(a, b, 1) | L()) + +b#910 = (arguments[1] | dh(b, a, 1) | b["return"]) + +b#915 = (arguments[1] | L()) + +b#916 = (arguments[1] | 1 | sc) + +b#917 = a["memoizedState"] + +b#918 = arguments[1] + +b#919 = ( + | arguments[1] + | kj(null, b, d, !(0), f, c) + | b["child"] + | dj(null, b, d, a, c) + | ij(null, b, d, a, c) + | Zi(null, b, d, a, c) + | aj(null, b, d, Lg(d["type"], a), c) + | mj(a, b, d, c, e) + | $i(a, b, c) +) + +b#92 = arguments[0] + +b#94 = (arguments[1] | mb["firstChild"]) + +b#940 = arguments[1] + +b#941 = arguments[1] + +b#942 = arguments[1] + +b#946 = (arguments[1] | a["dependencies"]) + +b#947 = (arguments[1] | Bg(g, c, b, e)) + +b#948 = arguments[1] + +b#949 = arguments[1] + +b#950 = arguments[1] + +b#951 = ( + | arguments[1] + | Bg(4, ((null !== a["children"]) ? a["children"] : []), a["key"], b) +) + +b#952 = arguments[1] + +b#953 = (arguments[1] | 1 | ???*0* | 0) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +b#954 = arguments[1] + +b#955 = ( + | a + | b["stateNode"]["context"] + | b["stateNode"]["__reactInternalMemoizedMergedChildContext"] + | b["return"] +) + +b#96 = arguments[1] + +b#960 = arguments[1] + +b#961 = (arguments[1] | ch(f, g)) + +b#963 = arguments[1] + +b#965 = arguments[1] + +b#969 = ???*0*["_internalRoot"] +- *0* unsupported expression + ⚠️ This value might have side effects + +b#970 = a["containerInfo"] + +b#974 = Hc() + +b#979 = arguments[1] + +b#986 = arguments[1] + +b#990 = a["stateNode"] + +b#992 = Zg(a, 1) + +b#994 = Zg(a, 134217728) + +b#997 = lh(a) + +ba = ("onCompositionStart" | "onCompositionEnd" | "onCompositionUpdate" | ???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unknown new expression + ⚠️ This value might have side effects + +bb = (...) => (undefined | FreeVar(undefined)) + +bc = ca["unstable_cancelCallback"] + +bd = (...) => undefined + +be = (null | FreeVar(document)["documentMode"]) + +bf = Ze("animationstart") + +bg = (...) => (c | A({}, c, d)) + +bh = (...) => undefined + +bi = (...) => a + +bj = (...) => !((!(a) || !(a["isReactComponent"]))) + +bk = (...) => undefined + +bl = (...) => undefined + +c#1001 = C + +c#1004 = ( + | arguments[2] + | a + | c["parentNode"] + | c["querySelectorAll"]( + `input[name=${FreeVar(JSON)["stringify"](`${b}`)}][type="radio"]` + ) +) + +c#101 = arguments[2] + +c#1012 = ((???*0* && (???*1* !== FreeVar(arguments)[2])) ? FreeVar(arguments)[2] : null) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +c#1013 = (!(1) | !(0)) + +c#1017 = arguments[2] + +c#1018 = (arguments[2] | d[a]) + +c#1019 = arguments[2] + +c#102 = (???*0* | "cssFloat") +- *0* c + ⚠️ pattern without value + +c#1023 = arguments[2] + +c#116 = arguments[2] + +c#119 = (a["stateNode"] | d[b]) + +c#123 = arguments[2] + +c#127 = arguments[2] + +c#128 = arguments[2] + +c#131 = (a | b["return"]) + +c#136 = (a | d | e | f) + +c#159 = (a["pendingLanes"] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#162 = a["suspendedLanes"] + +c#167 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#168 = arguments[2] + +c#169 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +c#171 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +c#175 = arguments[2] + +c#176 = arguments[2] + +c#177 = Vb(b) + +c#183 = ( + | Yc(a["domEventName"], a["eventSystemFlags"], b[0], a["nativeEvent"]) + | a["nativeEvent"] +) + +c#186 = arguments[2] + +c#189 = (1 | ???*0* | 0 | Qc[0]) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#193 = arguments[2] + +c#196 = arguments[2] + +c#199 = arguments[2] + +c#203 = (arguments[2] | b["tag"]) + +c#207 = b["length"] + +c#212 = ???*0* +- *0* c + ⚠️ pattern without value + +c#236 = (arguments[2] | ???*0*) +- *0* unknown new expression + ⚠️ This value might have side effects + +c#246 = arguments[2] + +c#25 = ( + | arguments[2] + | null + | (((3 === e) || ((4 === e) && (!(0) === c))) ? "" : `${c}`) +) + +c#251 = FreeVar(Object)["keys"](a) + +c#254 = (Je(a) | c["nextSibling"] | c["parentNode"] | ???*0* | Je(c)) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#261 = ( + | ("string" === typeof(b["contentWindow"]["location"]["href"])) + | !(1) +) + +c#266 = (a["focusedElem"] | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#269 = arguments[2] + +c#270 = {} + +c#271 = ???*0* +- *0* c + ⚠️ pattern without value + +c#274 = arguments[2] + +c#275 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#280 = (b[of] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#281 = arguments[2] + +c#285 = (arguments[2] | e["bind"](null, b, c, a)) + +c#286 = arguments[2] + +c#29 = ???*0* +- *0* c + ⚠️ pattern without value + +c#3 = (1 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#30 = FreeVar(Error)["prepareStackTrace"] + +c#307 = arguments[2] + +c#308 = `${b}Capture` + +c#311 = (arguments[2] | c["return"]) + +c#314 = arguments[2] + +c#320 = (b | e["data"] | e) + +c#327 = a["data"] + +c#331 = (a["parentNode"] | b["alternate"] | a[Of]) + +c#341 = a["type"]["contextTypes"] + +c#344 = arguments[2] + +c#345 = arguments[2] + +c#347 = arguments[2] + +c#350 = eg + +c#357 = (arguments[2] | (c + 1)) + +c#361 = Bg(5, null, null, 0) + +c#362 = ( + | a["type"] + | ((null !== qg) ? {"id": rg, "overflow": sg} : null) + | Bg(18, null, null, 0) +) + +c#364 = b + +c#370 = a["data"] + +c#381 = ???*0* +- *0* c + ⚠️ pattern without value + +c#385 = arguments[2] + +c#391 = arguments[2] + +c#392 = (a["alternate"] | a) + +c#396 = arguments[2] + +c#398 = (arguments[2] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +c#400 = ( + | a["updateQueue"] + | c["firstBaseUpdate"] + | c["next"] + | { + "baseState": d["baseState"], + "firstBaseUpdate": e, + "lastBaseUpdate": f, + "shared": d["shared"], + "effects": d["effects"] + } +) + +c#404 = arguments[2] + +c#412 = arguments[2] + +c#415 = ( + | arguments[2] + | c(d, b) + | (((null === c) || (???*0* === c)) ? b : A({}, b, c)) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#417 = arguments[2] + +c#418 = arguments[2] + +c#419 = L() + +c#420 = arguments[2] + +c#421 = arguments[2] + +c#422 = arguments[2] + +c#423 = arguments[2] + +c#424 = (arguments[2] | c["_owner"]) + +c#431 = (...) => null + +c#432 = arguments[1] + +c#434 = arguments[0] + +c#437 = arguments[1] + +c#439 = arguments[2] + +c#440 = arguments[2] + +c#441 = arguments[2] + +c#442 = arguments[2] + +c#443 = ( + | arguments[2] + | yh(b["type"], b["key"], b["props"], null, a["mode"], c) +) + +c#445 = arguments[2] + +c#447 = arguments[2] + +c#474 = lb(b, a["type"]) + +c#476 = (b["memoizedState"] | c["dehydrated"]) + +c#484 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#485 = arguments[2] + +c#494 = b["queue"] + +c#501 = b["queue"] + +c#504 = N + +c#506 = (arguments[2] | b["stores"]) + +c#507 = arguments[2] + +c#508 = arguments[2] + +c#510 = b() + +c#515 = (arguments[2] | b["lastEffect"]) + +c#517 = arguments[2] + +c#518 = arguments[2] + +c#52 = ???*0* +- *0* c + ⚠️ pattern without value + +c#528 = ( + | arguments[2] + | (((null !== c) && (???*0* !== c)) ? c["concat"]([a]) : null) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#530 = di() + +c#531 = di() + +c#532 = (arguments[2] | yc()) + +c#533 = C + +c#537 = ( + | arguments[2] + | {"lane": d, "action": c, "hasEagerState": !(1), "eagerState": null, "next": null} + | Yg(a, b, c, d) +) + +c#539 = (arguments[2] | Yg(a, b, e, d)) + +c#546 = a["pending"] + +c#547 = (arguments[2] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +c#550 = ( + | arguments[2] + | (((null !== c) && (???*0* !== c)) ? c["concat"]([a]) : null) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#553 = ci() + +c#554 = arguments[2] + +c#559 = (arguments[2] | c() | b()) + +c#56 = FreeVar(Object)["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + +c#562 = (sg | (???*0*["toString"](32) + c) | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +c#570 = ("" | (c + Pa(d))) + +c#573 = arguments[2] + +c#576 = ???*0* +- *0* c + ⚠️ pattern without value + +c#578 = (arguments[2] | ch(???*0*, c)) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#580 = (arguments[2] | ch(???*0*, c)) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#584 = b["stack"] + +c#585 = arguments[2] + +c#589 = arguments[2] + +c#590 = arguments[2] + +c#591 = (arguments[2] | c["render"] | bi()) + +c#592 = (arguments[2] | c["compare"] | ((null !== c) ? c : Ie)) + +c#595 = arguments[2] + +c#597 = arguments[2] + +c#599 = b["ref"] + +c#600 = (arguments[2] | Xh(a, b, c, d, f, e)) + +c#601 = arguments[2] + +c#605 = arguments[2] + +c#607 = arguments[2] + +c#609 = (arguments[2] | b["deletions"]) + +c#613 = arguments[2] + +c#614 = arguments[2] + +c#619 = arguments[2] + +c#620 = arguments[2] + +c#621 = (arguments[2] | b["child"] | c["sibling"] | e | null) + +c#629 = (arguments[2] | wh(a, a["pendingProps"]) | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#631 = arguments[2] + +c#634 = (b["child"] | c["child"] | c["return"] | c["sibling"]) + +c#639 = (arguments[2] | null | {} | k) + +c#64 = b["getValue"]() + +c#644 = arguments[2] + +c#645 = (null | b | a["tail"] | c["sibling"]) + +c#646 = (0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +c#647 = ( + | arguments[2] + | b["type"] + | Hh(Gh["current"]) + | b["memoizedProps"] + | b["child"] + | c["sibling"] + | a["updateQueue"] + | f["last"] + | M["current"] +) + +c#667 = a["ref"] + +c#670 = arguments[2] + +c#673 = ( + | {"start": a["selectionStart"], "end": a["selectionEnd"]} + | ((???*0* && c["defaultView"]) || FreeVar(window)) + | a["ownerDocument"] + | d["anchorNode"] + | null + | (((???*1* === h) || (???*2* === k)) ? null : {"start": h, "end": k}) + | (c || {"start": 0, "end": 0}) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +c#68 = b["checked"] + +c#687 = arguments[2] + +c#69 = ( + | ((null == b["defaultValue"]) ? "" : b["defaultValue"]) + | Sa(((null != b["value"]) ? b["value"] : c)) +) + +c#691 = (???*0* | c["next"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#695 = a["stateNode"] + +c#7 = arguments[2] + +c#703 = (arguments[2] | c["_reactRootContainer"]) + +c#704 = arguments[2] + +c#705 = (arguments[2] | c["child"] | c["sibling"]) + +c#706 = (arguments[2] | c["stateNode"]) + +c#71 = Sa(b["value"]) + +c#713 = (a["stateNode"] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +c#716 = b["deletions"] + +c#721 = (a["alternate"] | r["return"]) + +c#74 = (arguments[2] | a["name"]) + +c#756 = (a["return"] | c["return"]) + +c#76 = arguments[2] + +c#763 = arguments[2] + +c#764 = arguments[2] + +c#768 = (b["alternate"] | null | b["child"]["stateNode"] | h | b["sibling"]) + +c#77 = (arguments[2] | 0 | ???*0* | `${Sa(c)}`) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#781 = b["sibling"] + +c#785 = b["return"] + +c#8 = arguments[2] + +c#802 = arguments[2] + +c#803 = (a["callbackNode"] | null | fc | gc | hc | jc | Gk(c, Hk["bind"](null, a))) + +c#807 = (a["callbackNode"] | qk) + +c#817 = tk + +c#819 = (b["updateQueue"] | c["stores"] | b["child"]) + +c#827 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +c#829 = (Jk(a, b) | Ok(a, d) | qk) + +c#83 = (b["value"] | b["children"] | c[0] | b) + +c#831 = K + +c#834 = pk["transition"] + +c#838 = (a["timeoutHandle"] | Y["return"] | c["return"] | Wg[b]) + +c#843 = (Y | c["return"]) + +c#863 = K + +c#869 = (b["alternate"] | Fj(c, b, gj) | Jj(c, b)) + +c#87 = (Sa(b["value"]) | `${c}`) + +c#877 = arguments[2] + +c#880 = (arguments[2] | a["finishedWork"] | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#883 = C + +c#9 = arguments[2] + +c#909 = arguments[2] + +c#910 = arguments[2] + +c#915 = arguments[2] + +c#916 = L() + +c#917 = (0 | b["retryLane"]) + +c#918 = (0 | e["retryLane"]) + +c#919 = (arguments[2] | Ch(b, null, d, c) | c["sibling"]) + +c#92 = arguments[1] + +c#941 = arguments[2] + +c#942 = arguments[2] + +c#946 = (a["alternate"] | Bg(a["tag"], b, a["key"], a["mode"])) + +c#947 = arguments[2] + +c#948 = arguments[2] + +c#949 = arguments[2] + +c#950 = arguments[2] + +c#951 = arguments[2] + +c#952 = arguments[2] + +c#953 = arguments[2] + +c#954 = arguments[2] + +c#955 = a["type"] + +c#96 = a["firstChild"] + +c#960 = (arguments[2] | a["current"]) + +c#961 = (arguments[2] | el(c)) + +c#963 = a["retryLane"] + +c#974 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#979 = arguments[2] + +c#986 = arguments[2] + +c#990 = tc(b["pendingLanes"]) + +c#992 = L() + +c#994 = L() + +c#997 = Zg(a, b) + +ca = FreeVar(require)("scheduler") + +cb = (...) => undefined + +cc = ca["unstable_shouldYield"] + +cd = ua["ReactCurrentBatchConfig"] + +ce = (ia && ???*0* && !(be)) +- *0* unsupported expression + ⚠️ This value might have side effects + +cf = Ze("transitionend") + +cg = (...) => !(0) + +ch = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null} + +ci = (...) => P + +cj = (...) => (???*0* | dj(a, b, c, d, e)) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +ck = (...) => undefined + +cl = (...) => a + +d#1004 = c[b] + +d#1013 = ("" | b["identifierPrefix"]) + +d#1018 = (((null != c) && c["hydratedSources"]) || null) + +d#102 = (0 === c["indexOf"]("--")) + +d#1023 = arguments[3] + +d#119 = ( + | Db(c) + | !(d["disabled"]) + | !((("button" === a) || ("input" === a) || ("select" === a) || ("textarea" === a))) +) + +d#123 = arguments[3] + +d#127 = arguments[3] + +d#128 = arguments[3] + +d#136 = (b | e["return"] | f | e) + +d#159 = (0 | tc(h) | tc(f) | tc(g) | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +d#162 = a["pingedLanes"] + +d#169 = a["eventTimes"] + +d#171 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +d#175 = arguments[3] + +d#176 = arguments[3] + +d#183 = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +d#189 = (Kc[c] | Qc[c]) + +d#193 = arguments[3] + +d#196 = arguments[3] + +d#199 = arguments[3] + +d#203 = arguments[3] + +d#207 = (???*0* | 1 | ???*1*) +- *0* d + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +d#212 = arguments[1] + +d#236 = arguments[3] + +d#25 = (arguments[3] | e["attributeNamespace"]) + +d#251 = (FreeVar(Object)["keys"](b) | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d#254 = (???*0* | (a + c["textContent"]["length"])) +- *0* d + ⚠️ pattern without value + +d#264 = ???*0* +- *0* d + ⚠️ pattern without value + +d#266 = ( + | a["selectionRange"] + | ((???*0* === d["end"]) ? f : FreeVar(Math)["min"](d["end"], e)) + | f +) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#269 = ( + | ((c["window"] === c) ? c["document"] : ((9 === c["nodeType"]) ? c : c["ownerDocument"])) + | Qe + | {"start": d["selectionStart"], "end": d["selectionEnd"]} + | ( + || (d["ownerDocument"] && d["ownerDocument"]["defaultView"]) + || FreeVar(window) + )["getSelection"]() + | { + "anchorNode": d["anchorNode"], + "anchorOffset": d["anchorOffset"], + "focusNode": d["focusNode"], + "focusOffset": d["focusOffset"] + } + | oe(Re, "onSelect") +) + +d#274 = (a["type"] || "unknown-event") + +d#275 = (a[c] | d["listeners"]) + +d#280 = `${a}__bubble` + +d#281 = (0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +d#285 = arguments[3] + +d#286 = (arguments[3] | ???*0* | d["return"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#292 = (f | oe(d, "onBeforeInput")) + +d#30 = (l | l | l) + +d#308 = [] + +d#311 = arguments[3] + +d#320 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d#341 = a["stateNode"] + +d#345 = (a["stateNode"] | d["getChildContext"]()) + +d#347 = a["stateNode"] + +d#350 = (c[a] | d(!(0))) + +d#357 = (rg | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +d#364 = xg + +d#385 = a["alternate"] + +d#391 = arguments[3] + +d#396 = (a["updateQueue"] | d["shared"]) + +d#398 = (b["lanes"] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +d#400 = (a["alternate"] | d["updateQueue"]) + +d#404 = arguments[3] + +d#412 = (a[b] | c) + +d#415 = arguments[3] + +d#417 = L() + +d#418 = L() + +d#419 = lh(a) + +d#420 = arguments[3] + +d#421 = (!(1) | b["contextTypes"] | ((null !== d) && (???*0* !== d))) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#422 = arguments[3] + +d#423 = arguments[3] + +d#424 = c["stateNode"] + +d#431 = (...) => a + +d#432 = b["deletions"] + +d#434 = (arguments[1] | d["sibling"]) + +d#437 = (arguments[2] | b["alternate"] | d["index"]) + +d#439 = arguments[3] + +d#440 = ( + | arguments[3] + | e(b, c["props"]) + | yh(c["type"], c["key"], c["props"], null, a["mode"], d) +) + +d#441 = arguments[3] + +d#442 = arguments[3] + +d#443 = b["_init"] + +d#445 = arguments[3] + +d#447 = arguments[3] + +d#459 = ( + | arguments[1] + | e(l, f["props"]["children"]) + | e(l, f["props"]) + | Ah(f["props"]["children"], a["mode"], h, f["key"]) + | e(d, (f["children"] || [])) + | d["sibling"] + | zh(f, a["mode"], h) + | e(d, f) + | xh(f, a["mode"], h) +) + +d#485 = arguments[3] + +d#494 = ( + | O + | d["baseState"] + | (l["hasEagerState"] ? l["eagerState"] : a(d, l["action"])) +) + +d#501 = c["dispatch"] + +d#504 = (di() | d["queue"]) + +d#507 = arguments[3] + +d#512 = ???*0* +- *0* d + ⚠️ pattern without value + +d#515 = (arguments[3] | c["next"]) + +d#517 = arguments[3] + +d#518 = (arguments[3] | ((???*0* === d) ? null : d)) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#530 = c["memoizedState"] + +d#531 = c["memoizedState"] + +d#533 = Qh["transition"] + +d#537 = lh(a) + +d#539 = lh(a) + +d#547 = (b["lanes"] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +d#554 = ci() + +d#559 = N + +d#56 = (`${a[b]}` | `${a}` | `${a}`) + +d#562 = rg + +d#570 = (b | d["return"]) + +d#578 = b["value"] + +d#580 = a["type"]["getDerivedStateFromError"] + +d#585 = (a["pingCache"] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#589 = arguments[3] + +d#590 = arguments[3] + +d#591 = (arguments[3] | Xh(a, b, c, d, f, e)) + +d#592 = arguments[3] + +d#595 = (arguments[3] | f) + +d#597 = (b["pendingProps"] | ((null !== f) ? f["baseLanes"] : c) | ???*0* | c) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#600 = (arguments[3] | bi()) + +d#601 = (arguments[3] | !(0) | h | !(1) | l) + +d#605 = (arguments[3] | b["stateNode"]) + +d#607 = arguments[3] + +d#609 = ( + | b["pendingProps"] + | b["mode"] + | b["child"] + | wh(e, k) + | f + | wh(f, {"mode": "visible", "children": d["children"]}) +) + +d#613 = arguments[3] + +d#614 = ( + | arguments[3] + | Li(FreeVar(Error)(p(422))) + | qj({"mode": "visible", "children": d["children"]}, e, 0, null) + | (e["nextSibling"] && e["nextSibling"]["dataset"]) + | h + | Li(f, d, ???*0*) + | R + | Li(FreeVar(Error)(p(421))) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#619 = a["alternate"] + +d#620 = arguments[3] + +d#621 = (b["pendingProps"] | M["current"] | ???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +d#631 = (b["type"]["_context"] | b["memoizedState"] | (0 !== ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#639 = (arguments[3] | Ya(a, d) | A({}, d, {"value": ???*0*}) | gb(a, d)) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#64 = ( + | "" + | (Ta(a) ? (a["checked"] ? "true" : "false") : a["value"]) +) + +d#644 = arguments[3] + +d#645 = (null | c) + +d#646 = (0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +d#647 = ( + | b["pendingProps"] + | b["stateNode"] + | e + | !(!(d["autoFocus"])) + | !(0) + | !(1) + | ((9 === c["nodeType"]) ? c : c["ownerDocument"])["createTextNode"](d) + | b["memoizedState"] + | (null !== d) + | (0 !== ???*0*) + | g["updateQueue"] + | c + | (null !== b["memoizedState"]) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#669 = ???*0* +- *0* d + ⚠️ pattern without value + +d#672 = ???*0* +- *0* d + ⚠️ pattern without value + +d#673 = ((c["getSelection"] && c["getSelection"]()) | d["focusOffset"]) + +d#687 = (b["updateQueue"] | ((null !== d) ? d["lastEffect"] : null) | d["next"]) + +d#69 = ((null != b["checked"]) ? b["checked"] : b["defaultChecked"]) + +d#691 = c["create"] + +d#7 = arguments[3] + +d#703 = a["tag"] + +d#704 = a["tag"] + +d#706 = (X | c["updateQueue"] | d["lastEffect"] | d["next"] | c["stateNode"] | U) + +d#71 = b["type"] + +d#715 = ck["bind"](null, a, b) + +d#716 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d#721 = (a["flags"] | r) + +d#74 = b["type"] + +d#756 = c + +d#764 = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#768 = b["stateNode"] + +d#77 = arguments[3] + +d#785 = b["stateNode"] + +d#8 = arguments[3] + +d#802 = arguments[3] + +d#803 = uc(a, ((a === R) ? Z : 0)) + +d#807 = (uc(a, ((a === R) ? Z : 0)) | e | f | ???*0* | ???*1*) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +d#819 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d#827 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +d#829 = xc(a) + +d#834 = C + +d#838 = (c | d["type"]["childContextTypes"] | c["interleaved"]) + +d#843 = (N["memoizedState"] | d["next"]) + +d#863 = Kk() + +d#87 = Sa(b["defaultValue"]) + +d#877 = C + +d#880 = (arguments[3] | a["onRecoverableError"]) + +d#883 = (!(1) | !(0)) + +d#9 = arguments[3] + +d#910 = b["stateNode"] + +d#915 = a["pingCache"] + +d#918 = a["stateNode"] + +d#919 = ( + | b["type"] + | b["elementType"] + | e(d["_payload"]) + | b["pendingProps"] + | g["element"] + | b["type"]["_context"] + | b["pendingProps"]["children"] + | d(e) +) + +d#92 = arguments[2] + +d#941 = arguments[3] + +d#942 = arguments[3] + +d#947 = (arguments[3] | a | null) + +d#948 = arguments[3] + +d#949 = arguments[3] + +d#952 = arguments[3] + +d#953 = arguments[3] + +d#954 = ((???*0* && (???*1* !== FreeVar(arguments)[3])) ? FreeVar(arguments)[3] : null) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +d#960 = (arguments[3] | L()) + +d#961 = (arguments[3] | ((???*0* === d) ? null : d)) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#979 = (arguments[3] | *anonymous function 127055* | *anonymous function 127285*) + +d#986 = arguments[3] + +d#997 = L() + +da = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +db = (...) => (undefined | FreeVar(undefined)) + +dc = ca["unstable_requestPaint"] + +dd = (!(0) | !(1) | !(!(Cf))) + +de = (ia && (!(ae) || (be && ???*0* && ???*1*))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +df = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +dg = (...) => undefined + +dh = (...) => (null | Zg(a, c)) + +di = (...) => P + +dj = (...) => (???*0* | b["child"]) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +dk = (...) => undefined + +dl = (...) => { + "$$typeof": wa, + "key": ((null == d) ? null : `${d}`), + "children": a, + "containerInfo": b, + "implementation": c +} + +e#1004 = Db(d) + +e#1013 = (ll | b["onRecoverableError"]) + +e#1018 = (!(1) | !(0) | c["_getVersion"] | e(c["_source"])) + +e#102 = rb(c, b[c], d) + +e#123 = arguments[4] + +e#127 = arguments[4] + +e#128 = arguments[4] + +e#136 = c["return"] + +e#159 = (a["suspendedLanes"] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#162 = a["expirationTimes"] + +e#169 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +e#171 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +e#175 = arguments[4] + +e#176 = arguments[4] + +e#193 = C + +e#196 = C + +e#199 = (Yc(a, b, c, d) | f) + +e#207 = (???*0* ? kd["value"] : kd["textContent"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#212 = arguments[2] + +e#25 = ((z["hasOwnProperty"](b) ? z[b] : null) | e["type"]) + +e#251 = c[d] + +e#266 = (c["textContent"]["length"] | d | Ke(c, f)) + +e#275 = d["event"] + +e#285 = (ed | gd | fd | ???*0* | !(0)) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#286 = arguments[4] + +e#292 = (xb(c) | ???*0*) +- *0* unknown new expression + ⚠️ This value might have side effects + +e#30 = l["stack"]["split"]("\n") + +e#308 = (a | f) + +e#311 = arguments[4] + +e#320 = c["nextSibling"] + +e#341 = {} + +e#345 = ???*0* +- *0* e + ⚠️ pattern without value + +e#354 = ???*0* +- *0* e + ⚠️ pattern without value + +e#357 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +e#391 = b["interleaved"] + +e#396 = (d["pending"] | d["interleaved"]) + +e#400 = (null | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#404 = (a["updateQueue"] | b | e["next"]) + +e#412 = d["callback"] + +e#417 = lh(a) + +e#418 = lh(a) + +e#419 = ch(c, d) + +e#420 = arguments[4] + +e#421 = (Vf | (Zf(b) ? Xf : H["current"])) + +e#423 = a["stateNode"] + +e#424 = d + +e#431 = (...) => a + +e#445 = (((null !== b) ? b["key"] : null) | c["_init"]) + +e#447 = arguments[4] + +e#449 = arguments[0] + +e#454 = arguments[0] + +e#485 = arguments[4] + +e#494 = (d["baseQueue"] | f | a | e["next"]) + +e#501 = (c["pending"] | e["next"]) + +e#504 = b() + +e#517 = ci() + +e#518 = di() + +e#537 = L() + +e#539 = ( + | {"lane": d, "action": c, "hasEagerState": !(1), "eagerState": null, "next": null} + | L() +) + +e#559 = ci() + +e#56 = c["get"] + +e#570 = ( + | c + | ` +Error generating stack: ${f["message"]} +${f["stack"]}` +) + +e#580 = b["value"] + +e#585 = (???*0* | d["get"](b)) +- *0* unknown new expression + ⚠️ This value might have side effects + +e#589 = arguments[4] + +e#591 = arguments[4] + +e#592 = arguments[4] + +e#595 = arguments[4] + +e#597 = d["children"] + +e#600 = arguments[4] + +e#601 = arguments[4] + +e#605 = arguments[4] + +e#607 = arguments[4] + +e#609 = (M["current"] | ???*0* | a["memoizedState"] | a["child"]) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +e#614 = (arguments[4] | b["mode"] | 2 | 8 | 32 | 268435456 | 0 | ((0 !== ???*0*) ? 0 : e)) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#620 = arguments[4] + +e#621 = (d["revealOrder"] | null | c | b["child"] | c["sibling"] | a) + +e#631 = (b["memoizedProps"]["value"] | b["memoizedState"]) + +e#639 = (a["memoizedProps"] | Ya(a, e) | A({}, e, {"value": ???*0*}) | gb(a, e)) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#646 = (a["child"] | e["sibling"]) + +e#647 = ( + | Hh(Gh["current"]) + | 0 + | ???*0* + | null + | ["children", h] + | ["children", `${h}`] + | d + | Ya(a, d) + | A({}, d, {"value": ???*1*}) + | gb(a, d) +) +- *0* updated with update expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +e#673 = d["anchorOffset"] + +e#687 = (???*0* | e["next"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#706 = (Yj | ???*0* | e["next"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#716 = c[d] + +e#721 = (a["stateNode"] | a["child"] | q["stateNode"]) + +e#756 = d["stateNode"] + +e#764 = V + +e#768 = ((b["elementType"] === b["type"]) ? c["memoizedProps"] : Lg(b["type"], c["memoizedProps"])) + +e#77 = (0 | ???*0* | b["hasOwnProperty"](`$${a[c]["value"]}`)) +- *0* updated with update expression + ⚠️ This value might have side effects + +e#785 = b["return"] + +e#807 = (K | xc(a) | a["current"]["alternate"] | a["suspendedLanes"] | ???*0* | g) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#819 = (c[d] | e["value"]) + +e#838 = d["next"] + +e#843 = d["queue"] + +e#865 = ???*0* +- *0* e + ⚠️ pattern without value + +e#877 = pk["transition"] + +e#880 = (a["finishedLanes"] | b[c]) + +e#883 = K + +e#9 = arguments[4] + +e#918 = a["memoizedState"] + +e#919 = ( + | Yf(b, H["current"]) + | Xh(null, b, d, a, e, c) + | d["_init"] + | ???*0* + | b["pendingProps"] + | ((b["elementType"] === d) ? e : Lg(d, e)) + | f["element"] + | Ki(FreeVar(Error)(p(423)), b) + | Ki(FreeVar(Error)(p(424)), b) + | b["type"] + | Vg(e) + | Lg(d, b["pendingProps"]) + | Lg(d["type"], e) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#92 = arguments[3] + +e#947 = (arguments[4] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +e#952 = arguments[4] + +e#953 = arguments[4] + +e#960 = (arguments[4] | lh(c)) + +e#961 = b["current"] + +e#979 = (arguments[4] | a["lastChild"]) + +e#986 = (arguments[4] | *anonymous function 127571*) + +ea = {} + +eb = FreeVar(Array)["isArray"] + +ec = ca["unstable_getCurrentPriorityLevel"] + +ed = (...) => undefined + +ee = FreeVar(String)["fromCharCode"](32) + +ef = "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ") + +eg = (null | [a] | eg["slice"]((a + 1))) + +eh = (...) => undefined + +ei = (...) => (("function" === typeof(b)) ? b(a) : b) + +ej = (...) => (???*0* | b["child"]) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +ek = (...) => undefined + +el = (...) => (Vf | bg(a, c, b) | b) + +f#1018 = ("" | c["identifierPrefix"]) + +f#123 = arguments[5] + +f#127 = arguments[5] + +f#128 = arguments[5] + +f#136 = (e["alternate"] | e["child"] | f["sibling"]) + +f#159 = (a["pingedLanes"] | ???*0* | ???*1*) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +f#162 = (a["pendingLanes"] | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +f#169 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +f#175 = arguments[5] + +f#176 = e["pointerId"] + +f#193 = cd["transition"] + +f#196 = cd["transition"] + +f#199 = (Cb(e) | Yc(a, b, c, d)) + +f#207 = e["length"] + +f#212 = arguments[3] + +f#266 = (FreeVar(Math)["min"](d["start"], e) | e) + +f#275 = (???*0* | k) +- *0* unsupported expression + ⚠️ This value might have side effects + +f#286 = (d | g) + +f#30 = d["stack"]["split"]("\n") + +f#308 = (e["stateNode"] | Kb(a, c) | Kb(a, b)) + +f#311 = b["_reactName"] + +f#341 = ???*0* +- *0* f + ⚠️ pattern without value + +f#357 = ((???*0* + e) | ???*1*["toString"](32)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +f#400 = (null | g | ???*0* | b) +- *0* unsupported expression + ⚠️ This value might have side effects + +f#404 = (e["firstBaseUpdate"] | l) + +f#417 = ch(d, e) + +f#418 = ch(d, e) + +f#420 = arguments[5] + +f#421 = (b["contextType"] | Vg(f) | (???*0* ? Yf(a, e) : Vf)) +- *0* unsupported expression + ⚠️ This value might have side effects + +f#423 = (b["contextType"] | (Zf(b) ? Xf : H["current"]) | b["getDerivedStateFromProps"]) + +f#424 = `${a}` + +f#431 = (...) => (???*0* | c) +- *0* c + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +f#440 = c["type"] + +f#442 = arguments[4] + +f#447 = d["_init"] + +f#459 = (arguments[2] | f["props"]["children"] | `${f}`) + +f#485 = (arguments[5] | 0 | (f + 1)) + +f#494 = (c["pending"] | e["next"] | e["lane"]) + +f#501 = (b["memoizedState"] | a(f, g["action"])) + +f#504 = !(He(d["memoizedState"], e)) + +f#518 = (???*0* | g["destroy"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +f#539 = (a["alternate"] | b["lastRenderedReducer"]) + +f#559 = {"value": c, "getSnapshot": b} + +f#56 = c["set"] + +f#572 = ???*0* +- *0* f + ⚠️ pattern without value + +f#580 = a["stateNode"] + +f#591 = b["ref"] + +f#592 = (c["type"] | a["child"]) + +f#595 = a["memoizedProps"] + +f#597 = ((null !== a) ? a["memoizedState"] : null) + +f#600 = ((Zf(c) ? Xf : H["current"]) | Yf(b, f)) + +f#601 = (!(0) | !(1)) + +f#605 = arguments[5] + +f#609 = ( + | !(1) + | !(0) + | b["child"] + | qj(g, d, 0, null) + | d["fallback"] + | wh(h, f) + | Ah(f, g, c, null) + | a["child"] +) + +f#614 = (arguments[5] | d["fallback"] | Ah(f, e, g, null) | FreeVar(Error)(p(419))) + +f#620 = a["memoizedState"] + +f#621 = d["tail"] + +f#639 = (null | [] | (f || [])) + +f#647 = ( + | b["memoizedProps"] + | ???*0* + | d["value"] + | (d["nodeValue"] !== c) + | !(1) + | Gg(b) + | b["memoizedState"] + | ((null !== f) ? f["dehydrated"] : null) + | !(0) + | c +) +- *0* f + ⚠️ pattern without value + +f#673 = d["focusNode"] + +f#687 = e["destroy"] + +f#706 = (e | f["tag"]) + +f#716 = a + +f#721 = (a["memoizedProps"] | (null !== e["memoizedState"]) | e["style"]) + +f#756 = Vj(a) + +f#764 = (e["child"] | f["sibling"]) + +f#768 = b["updateQueue"] + +f#785 = b["return"] + +f#807 = (Kk() | xc(a) | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +f#819 = e["getSnapshot"] + +f#838 = c["pending"] + +f#843 = (a | ???*0* | g | f["return"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +f#880 = (???*0* | (0 !== ???*1*) | pk["transition"] | a["pendingLanes"]) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +f#883 = V + +f#9 = arguments[5] + +f#919 = ( + | bi() + | !(0) + | !(1) + | b["memoizedState"] + | { + "element": d, + "isDehydrated": !(1), + "cache": g["cache"], + "pendingSuspenseBoundaries": g["pendingSuspenseBoundaries"], + "transitions": g["transitions"] + } + | ((null !== a) ? a["memoizedProps"] : null) + | b["memoizedProps"] + | b["child"] + | g["sibling"] + | g +) + +f#947 = arguments[5] + +f#953 = (arguments[5] | Bg(3, null, null, b)) + +f#960 = (arguments[5] | ch(d, e)) + +f#961 = L() + +f#979 = d + +f#986 = c["_reactRootContainer"] + +fa = (...) => undefined + +fb = (...) => (undefined | FreeVar(undefined)) + +fc = ca["unstable_ImmediatePriority"] + +fd = (...) => undefined + +fe = (!(1) | !(0)) + +ff = (...) => undefined + +fg = (!(1) | !(0)) + +fh = (...) => (undefined | FreeVar(undefined)) + +fi = (...) => [b["memoizedState"], c["dispatch"]] + +fj = Uf(0) + +fk = (...) => undefined + +fl = (...) => a + +g#1018 = (ll | c["onRecoverableError"]) + +g#123 = arguments[6] + +g#127 = arguments[6] + +g#128 = arguments[6] + +g#136 = (!(1) | !(0)) + +g#159 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +g#162 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +g#207 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +g#212 = arguments[4] + +g#266 = Ke(c, d) + +g#275 = (???*0* | ???*1* | 0) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +g#286 = (d["tag"] | d["return"] | g["return"] | Wc(h)) + +g#292 = [] + +g#30 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +g#311 = [] + +g#357 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +g#400 = { + "eventTime": c["eventTime"], + "lane": c["lane"], + "tag": c["tag"], + "payload": c["payload"], + "callback": c["callback"], + "next": null +} + +g#404 = (e["lastBaseUpdate"] | k | 0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +g#420 = arguments[6] + +g#431 = (...) => b + +g#449 = (arguments[1] | 0 | f(n, g, w) | f(u, g, w) | f(x, g, w)) + +g#454 = (arguments[1] | 0 | f(t, g, w) | f(n, g, w)) + +g#494 = (e["next"] | null | d) + +g#501 = (???*0* | g["next"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +g#518 = O["memoizedState"] + +g#539 = b["lastRenderedState"] + +g#592 = f["memoizedProps"] + +g#601 = b["stateNode"] + +g#605 = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +g#609 = ( + | (0 !== ???*0*) + | d["children"] + | {"mode": "hidden", "children": g} + | b["mode"] + | a["child"]["memoizedState"] + | ((null === g) ? oj(c) : {"baseLanes": ???*1*, "cachePool": null, "transitions": g["transitions"]}) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +g#614 = arguments[6] + +g#639 = ???*0* +- *0* g + ⚠️ pattern without value + +g#647 = ( + | ???*0* + | ((9 === e["nodeType"]) ? e : e["ownerDocument"]) + | a + | vb(c, d) + | f["rendering"] + | Mh(a) + | f["alternate"] +) +- *0* g + ⚠️ pattern without value + +g#673 = (0 | (g + q["nodeValue"]["length"])) + +g#706 = f["destroy"] + +g#716 = b + +g#721 = ( + | ((null !== c) ? c["memoizedProps"] : f) + | 0 + | (g + 2) + | (((???*0* !== k) && (null !== k) && k["hasOwnProperty"]("display")) ? k["display"] : null) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +g#756 = d["stateNode"]["containerInfo"] + +g#764 = (((null !== e["memoizedState"]) || Kj) | V) + +g#768 = b["updateQueue"] + +g#785 = b["return"] + +g#807 = (???*0* | b[g]) +- *0* unsupported expression + ⚠️ This value might have side effects + +g#824 = ???*0* +- *0* g + ⚠️ pattern without value + +g#838 = f["next"] + +g#843 = c["return"] + +g#880 = C + +g#883 = (f["child"] | V | w) + +g#9 = arguments[6] + +g#919 = ( + | b["memoizedState"] + | e["children"] + | null + | e["value"] + | f["child"] + | ((f["type"] === b["type"]) ? null : f["child"]) + | f["return"] + | f["sibling"] + | f + | g["return"] +) + +g#947 = (2 | 1 | 5 | 8 | 10 | 9 | 11 | 14 | 16) + +g#953 = arguments[6] + +g#960 = arguments[6] + +g#961 = lh(e) + +g#979 = fl(b, d, a, 0, null, !(1), !(1), "", ql) + +g#986 = (f | rl(c, b, a, e, d)) + +gb = (...) => A( + {}, + b, + { + "value": ???*0*, + "defaultValue": ???*1*, + "children": `${a["_wrapperState"]["initialValue"]}` + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +gc = ca["unstable_UserBlockingPriority"] + +gd = (...) => undefined + +ge = (...) => (undefined | (???*0* !== $d["indexOf"](b["keyCode"])) | (229 !== b["keyCode"]) | !(0) | !(1)) +- *0* unsupported expression + ⚠️ This value might have side effects + +gf = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +gg = (!(1) | !(0)) + +gh = (...) => undefined + +gi = (...) => [f, d] + +gj = (???*0* | 0 | fj["current"] | b) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +gk = (B() | 0) + +gl = (...) => g + +h#123 = arguments[7] + +h#127 = arguments[7] + +h#128 = arguments[7] + +h#136 = (e["child"] | h["sibling"] | f["child"]) + +h#159 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +h#162 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +h#275 = (d[g] | h["listener"]) + +h#286 = (d["stateNode"]["containerInfo"] | h["parentNode"]) + +h#292 = ( + | df["get"](a) + | ???*0* + | (("mouseover" === a) || ("pointerover" === a)) + | ((e["window"] === e) ? e : (???*1* ? (h["defaultView"] || h["parentWindow"]) : FreeVar(window))) + | e["ownerDocument"] + | (d ? ue(d) : FreeVar(window)) +) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +h#30 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +h#311 = (c | l) + +h#404 = (e["shared"]["pending"] | m["lastBaseUpdate"] | f | h["next"] | r["next"]) + +h#431 = (...) => (???*0* | b) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +h#449 = arguments[2] + +h#454 = (arguments[2] | l["call"](h)) + +h#459 = ( + | arguments[3] + | yh(f["type"], f["key"], f["props"], null, a["mode"], h) +) + +h#494 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +h#539 = f(g, c) + +h#601 = (b["memoizedProps"] | ($g || oh(b, c, h, d, r, k, l))) + +h#605 = (( + && g + && ("function" !== typeof(c["getDerivedStateFromError"])) +) ? null : d["render"]()) + +h#609 = ( + | ???*0* + | g + | (((null !== a) && (null === a["memoizedState"])) ? !(1) : (0 !== ???*1*)) + | e["dehydrated"] + | e["sibling"] +) +- *0* h + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +h#614 = (d["dgst"] | (0 !== ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +h#639 = (e[l] | ((null != e) ? e[l] : ???*0*) | (h ? h["__html"] : ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +h#647 = (f[g] | e) + +h#673 = (???*0* | (g + e) | g) +- *0* unsupported expression + ⚠️ This value might have side effects + +h#708 = ???*0* +- *0* h + ⚠️ pattern without value + +h#712 = ???*0* +- *0* h + ⚠️ pattern without value + +h#716 = (g | h["return"]) + +h#721 = (a["type"] | q["stateNode"]) + +h#756 = Vj(a) + +h#764 = (e["alternate"] | Kj) + +h#768 = b["stateNode"] + +h#785 = b["sibling"] + +h#810 = ???*0* +- *0* h + ⚠️ pattern without value + +h#843 = (c | k) + +h#880 = K + +h#883 = (f["deletions"] | V) + +h#919 = (f["dependencies"] | g["alternate"]) + +h#953 = arguments[7] + +h#960 = arguments[7] + +h#979 = d + +h#986 = e + +ha = (...) => undefined + +hb = (...) => undefined + +hc = ca["unstable_NormalPriority"] + +hd = (...) => (undefined | FreeVar(undefined)) + +he = (...) => ((("object" === typeof(a)) && ???*0*) ? a["data"] : null) +- *0* unsupported expression + ⚠️ This value might have side effects + +hf = ef[gf] + +hg = (...) => undefined + +hh = (???*0* | 0) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +hi = (...) => undefined + +hj = (...) => undefined + +hk = (...) => undefined + +hl = (...) => (undefined | null | a["child"]["stateNode"]) + +ia = !(( + || ("undefined" === typeof(FreeVar(window))) + || ("undefined" === typeof(FreeVar(window)["document"])) + || ("undefined" === typeof(FreeVar(window)["document"]["createElement"])) +)) + +ib = (...) => undefined + +ic = ca["unstable_LowPriority"] + +id = (null | a) + +ie = (!(1) | !(0)) + +ig = (...) => undefined + +ih = (...) => undefined + +ii = (...) => e + +ij = (...) => kj(a, b, c, d, f, e) + +ik = (...) => undefined + +il = (...) => undefined + +ja = FreeVar(Object)["prototype"]["hasOwnProperty"] + +jb = (...) => undefined + +jc = ca["unstable_IdlePriority"] + +jd = (...) => (undefined | 1 | 4 | 16 | 536870912) + +je = (...) => (undefined | he(b) | null | ee | ???*0*) +- *0* (((a === ee) && fe) ? null : a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +jf = hf["toLowerCase"]() + +jg = (...) => null + +jh = ???*0*["refs"] +- *0* unknown new expression + ⚠️ This value might have side effects + +ji = (...) => ui(2048, 8, a, b) + +jj = (...) => undefined + +jk = (...) => undefined + +jl = (...) => undefined + +k#123 = arguments[8] + +k#127 = arguments[8] + +k#128 = arguments[8] + +k#162 = e[g] + +k#275 = h["instance"] + +k#286 = (g["tag"] | g["stateNode"]["containerInfo"]) + +k#292 = ( + | td + | Rd + | Fd + | Bd + | Dd + | Vd + | Hd + | Xd + | vd + | Zd + | Jd + | Td + | (("mouseout" === a) || ("pointerout" === a)) + | d + | null + | (h["nodeName"] && h["nodeName"]["toLowerCase"]()) + | h["nodeName"] +) + +k#30 = ( + | ` +${e[g]["replace"](" at new ", " at ")}` + | k["replace"]("", a["displayName"]) +) + +k#311 = (h["alternate"] | Kb(c, f)) + +k#404 = (h | null | q) + +k#431 = (...) => (m(a, b, c["props"]["children"], d, c["key"]) | ???*0* | d) +- *0* d + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +k#449 = arguments[3] + +k#454 = arguments[3] + +k#459 = (f["key"] | f["type"]) + +k#494 = (null | ???*0* | q) +- *0* unsupported expression + ⚠️ This value might have side effects + +k#539 = b["interleaved"] + +k#601 = ( + | g["context"] + | b["memoizedState"] + | c["contextType"] + | Vg(k) + | (Zf(c) ? Xf : H["current"]) + | Yf(b, k) +) + +k#609 = {"mode": "hidden", "children": d["children"]} + +k#639 = (d[l] | (k ? k["__html"] : ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +k#647 = (h[f] | (k ? k["__html"] : ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +k#673 = (???*0* | (g + d) | g) +- *0* unsupported expression + ⚠️ This value might have side effects + +k#716 = e["alternate"] + +k#721 = (a["updateQueue"] | q["memoizedProps"]["style"]) + +k#762 = ???*0* +- *0* k + ⚠️ pattern without value + +k#764 = ( + | (((null !== h) && (null !== h["memoizedState"])) || U) + | g["child"] +) + +k#768 = b["memoizedProps"] + +k#789 = ???*0* +- *0* k + ⚠️ pattern without value + +k#792 = ???*0* +- *0* k + ⚠️ pattern without value + +k#794 = ???*0* +- *0* k + ⚠️ pattern without value + +k#796 = ???*0* +- *0* k + ⚠️ pattern without value + +k#797 = ???*0* +- *0* k + ⚠️ pattern without value + +k#843 = (b | l | FreeVar(Error)(p(426)) | Ki(k, h)) + +k#883 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +k#919 = (h["firstContext"] | ch(???*0*, ???*1*) | f["alternate"] | k["next"]) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +k#953 = arguments[8] + +k#960 = arguments[8] + +k#979 = cl(a, 0, !(1), null, null, !(1), !(1), "", ql) + +ka = /^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/ + +kb = (...) => ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" +) + +kc = (null | wl["inject"](vl)) + +kd = (null | e) + +ke = (...) => ( + | undefined + | ((("compositionend" === a) || (!(ae) && ge(a, b))) ? ???*0* : null) + | null + | b["char"] + | FreeVar(String)["fromCharCode"](b["which"]) + | ((de && ("ko" !== b["locale"])) ? null : b["data"]) +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +kf = (hf[0]["toUpperCase"]() + hf["slice"](1)) + +kg = [] + +kh = (...) => undefined + +ki = (...) => c(*anonymous function 67764*) + +kj = (...) => ($i(a, b, f) | b["child"]) + +kk = (...) => undefined + +kl = (...) => null + +l#123 = FreeVar(Array)["prototype"]["slice"]["call"](FreeVar(arguments), 3) + +l#128 = Pb + +l#275 = h["currentTarget"] + +l#311 = h["stateNode"] + +l#36 = ???*0* +- *0* l + ⚠️ pattern without value + +l#39 = ???*0* +- *0* l + ⚠️ pattern without value + +l#404 = (k["next"] | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +l#42 = ???*0* +- *0* l + ⚠️ pattern without value + +l#43 = ???*0* +- *0* l + ⚠️ pattern without value + +l#431 = (...) => (???*0* | b) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +l#449 = (null | n | u | x) + +l#454 = (Ka(h) | null | t | n) + +l#459 = (d | l["sibling"] | f["key"] | f["_init"]) + +l#494 = (f | l["next"]) + +l#543 = ???*0* +- *0* l + ⚠️ pattern without value + +l#601 = ( + | c["contextType"] + | Vg(l) + | (Zf(c) ? Xf : H["current"]) + | Yf(b, l) + | ((b["type"] === b["elementType"]) ? h : Lg(b["type"], h)) + | ($g || oh(b, c, l, d, r, n, k) || !(1)) +) + +l#639 = (???*0* | f) +- *0* l + ⚠️ pattern without value + +l#673 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +l#720 = ???*0* +- *0* l + ⚠️ pattern without value + +l#721 = (vb(h, f) | U | (null !== a["memoizedState"])) + +l#764 = U + +l#768 = b["alternate"] + +l#843 = k + +l#883 = h[k] + +l#919 = (f["updateQueue"] | l["shared"]) + +la = {} + +lb = (...) => (((null == a) || ("http://www.w3.org/1999/xhtml" === a)) ? kb(b) : ((("http://www.w3.org/2000/svg" === a) && ("foreignObject" === b)) ? "http://www.w3.org/1999/xhtml" : a)) + +lc = (null | wl) + +ld = (null | ???*0* | (???*1* ? kd["value"] : kd["textContent"])) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +le = { + "color": !(0), + "date": !(0), + "datetime": !(0), + "datetime-local": !(0), + "email": !(0), + "month": !(0), + "number": !(0), + "password": !(0), + "range": !(0), + "search": !(0), + "tel": !(0), + "text": !(0), + "time": !(0), + "url": !(0), + "week": !(0) +} + +lf = "abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting"["split"](" ") + +lg = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +lh = (...) => (1 | ???*0* | ???*1* | a) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +li = (...) => a + +lj = (...) => undefined + +lk = (...) => undefined + +ll = (("function" === typeof(FreeVar(reportError))) ? FreeVar(reportError) : *anonymous function 126145*) + +m#125 = ???*0* +- *0* m + ⚠️ pattern without value + +m#404 = (a["alternate"] | m["updateQueue"] | ???*0* | y) +- *0* unsupported expression + ⚠️ This value might have side effects + +m#431 = (...) => (???*0* | b) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +m#449 = (null | n | u | x) + +m#454 = (g | null | x | d(e, m)) + +m#494 = l["lane"] + +m#601 = ( + | c["getDerivedStateFromProps"] + | ( + || ("function" === typeof(y)) + || ("function" === typeof(g["getSnapshotBeforeUpdate"])) + ) +) + +m#673 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +m#721 = (k[g] | ((null !== c) && (null !== c["memoizedState"])) | a["child"] | m["sibling"] | null | q) + +m#768 = l["memoizedState"] + +m#843 = h + +m#883 = V + +m#919 = l["pending"] + +ma = {} + +mb = (???*0* | (mb || FreeVar(document)["createElement"]("div"))) +- *0* mb + ⚠️ pattern without value + +mc = (...) => undefined + +md = (null | e["slice"](a, (???*0* ? ???*1* : ???*2*)) | ???*3*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +me = (...) => (("input" === b) ? !(!(le[a["type"]])) : (("textarea" === b) ? !(0) : !(1))) + +mf = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +mg = (null | a | kg[???*0*]) +- *0* unsupported expression + ⚠️ This value might have side effects + +mh = (...) => undefined + +mi = (...) => undefined + +mj = (...) => b["child"] + +mk = FreeVar(Math)["ceil"] + +ml = (...) => undefined + +n#292 = ( + | a + | "focus" + | "blur" + | (c["relatedTarget"] || c["fromElement"]) + | (c["relatedTarget"] || c["toElement"]) + | (n ? Wc(n) : null) + | null + | d +) + +n#404 = (a | t["payload"]) + +n#431 = (...) => l + +n#449 = r(e, u, h[w], k) + +n#454 = (h["next"]() | q(e, n["value"], k) | y(m, e, w, n["value"], k)) + +n#601 = b["memoizedState"] + +n#673 = (b["alternate"] | Oj) + +n#721 = r["stateNode"] + +n#843 = b["updateQueue"] + +n#883 = f["alternate"] + +na#292 = (ve | Fe | De | Ee | na(a, d)) + +na#860 = ???*0* +- *0* na + ⚠️ pattern without value + +na#903 = ???*0* +- *0* na + ⚠️ pattern without value + +na#907 = ???*0* +- *0* na + ⚠️ pattern without value + +nb = *anonymous function 13449*(*anonymous function 13608*) + +nc = (...) => ((0 === a) ? 32 : ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +nd = (...) => (md | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +ne = (...) => undefined + +nf = (...) => undefined + +ng = (0 | b | kg[???*0*]) +- *0* unsupported expression + ⚠️ This value might have side effects + +nh = { + "isMounted": *anonymous function 55504*, + "enqueueSetState": *anonymous function 55574*, + "enqueueReplaceState": *anonymous function 55754*, + "enqueueForceUpdate": *anonymous function 55941* +} + +ni = (...) => undefined + +nj = {"dehydrated": null, "treeContext": null, "retryLane": 0} + +nk = ua["ReactCurrentDispatcher"] + +nl = (...) => undefined + +oa = (...) => (!(0) | !(1) | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +ob = (...) => (undefined | FreeVar(undefined)) + +oc = (FreeVar(Math)["clz32"] ? FreeVar(Math)["clz32"] : nc) + +od = (...) => ((???*0* || (13 === a)) ? a : 0) +- *0* unsupported expression + ⚠️ This value might have side effects + +oe = (...) => d + +of = `__reactEvents$${Nf}` + +og = [] + +oh = (...) => (("function" === typeof(a["shouldComponentUpdate"])) ? a["shouldComponentUpdate"](d, f, g) : ((b["prototype"] && b["prototype"]["isPureReactComponent"]) ? (!(Ie(c, d)) || !(Ie(e, f))) : !(0))) + +oi = (...) => (undefined | !(He(a, c)) | !(0)) + +oj = (...) => {"baseLanes": a, "cachePool": null, "transitions": null} + +ok = ua["ReactCurrentOwner"] + +ol = (...) => !(( + || !(a) + || ((1 !== a["nodeType"]) && (9 !== a["nodeType"]) && (11 !== a["nodeType"])) +)) + +p = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` + +pa = (...) => (undefined | !(1) | !(0) | !(c["acceptsBooleans"]) | (("data-" !== a) && ("aria-" !== a))) + +pb = { + "animationIterationCount": !(0), + "aspectRatio": !(0), + "borderImageOutset": !(0), + "borderImageSlice": !(0), + "borderImageWidth": !(0), + "boxFlex": !(0), + "boxFlexGroup": !(0), + "boxOrdinalGroup": !(0), + "columnCount": !(0), + "columns": !(0), + "flex": !(0), + "flexGrow": !(0), + "flexPositive": !(0), + "flexShrink": !(0), + "flexNegative": !(0), + "flexOrder": !(0), + "gridArea": !(0), + "gridRow": !(0), + "gridRowEnd": !(0), + "gridRowSpan": !(0), + "gridRowStart": !(0), + "gridColumn": !(0), + "gridColumnEnd": !(0), + "gridColumnSpan": !(0), + "gridColumnStart": !(0), + "fontWeight": !(0), + "lineClamp": !(0), + "lineHeight": !(0), + "opacity": !(0), + "order": !(0), + "orphans": !(0), + "tabSize": !(0), + "widows": !(0), + "zIndex": !(0), + "zoom": !(0), + "fillOpacity": !(0), + "floodOpacity": !(0), + "stopOpacity": !(0), + "strokeDasharray": !(0), + "strokeDashoffset": !(0), + "strokeMiterlimit": !(0), + "strokeOpacity": !(0), + "strokeWidth": !(0) +} + +pc = FreeVar(Math)["log"] + +pd = (...) => !(0) + +pe = (null | b) + +pf = (...) => undefined + +pg = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +ph = (...) => b + +pi = (...) => undefined + +pj = (...) => (???*0* | (f ? ???*1* : rj(b, g)) | sj(a, b, g, d, h, e, c) | d) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +pk = ua["ReactCurrentBatchConfig"] + +pl = (...) => !(( + || !(a) + || ( + && (1 !== a["nodeType"]) + && (9 !== a["nodeType"]) + && (11 !== a["nodeType"]) + && ( + || (8 !== a["nodeType"]) + || (" react-mount-point-unstable " !== a["nodeValue"]) + ) + ) +)) + +q#404 = (e["baseState"] | n["call"](y, q, r) | n | A({}, q, r)) + +q#431 = (...) => (???*0* | q(a, d(b["_payload"]), c) | null) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +q#494 = { + "lane": m, + "action": l["action"], + "hasEagerState": l["hasEagerState"], + "eagerState": l["eagerState"], + "next": null +} + +q#601 = ( + | ( + || ("function" === typeof(m)) + || ("function" === typeof(g["getSnapshotBeforeUpdate"])) + ) + | b["pendingProps"] +) + +q#673 = (a | y | r) + +q#721 = (k[(g + 1)] | ???*0* | a | q["child"] | q["return"] | q["sibling"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +q#768 = m["dehydrated"] + +q#843 = m["tag"] + +q#883 = m["child"] + +qa = (...) => (!(0) | !(1) | !(b) | (!(1) === b) | FreeVar(isNaN)(b) | (FreeVar(isNaN)(b) || ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +qb = ["Webkit", "ms", "Moz", "O"] + +qc = FreeVar(Math)["LN2"] + +qd = (...) => !(1) + +qe = (null | ???*0* | c) +- *0* unsupported expression + ⚠️ This value might have side effects + +qf = (...) => undefined + +qg = (null | a | og[???*0*] | b) +- *0* unsupported expression + ⚠️ This value might have side effects + +qh = (...) => undefined + +qi = (...) => [b["memoizedState"], a] + +qj = (...) => a + +qk = (null | b) + +ql = (...) => undefined + +r#404 = ( + | h["lane"] + | b + | (("function" === typeof(n)) ? n["call"](y, q, r) : n) + | e["effects"] + | h +) + +r#431 = (...) => ( + | ((null !== e) ? null : h(a, b, `${c}`, d)) + | ((c["key"] === e) ? k(a, b, c, d) : null) + | ((c["key"] === e) ? l(a, b, c, d) : null) + | ???*0* + | ((null !== e) ? null : m(a, b, c, d, null)) + | null +) +- *0* r(a, b, e(c["_payload"]), d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +r#601 = (b["memoizedState"] | g["context"]) + +r#673 = (null | q | q["parentNode"]) + +r#721 = (e["_wrapperState"]["wasMultiple"] | V) + +r#778 = ???*0* +- *0* r + ⚠️ pattern without value + +r#843 = m["alternate"] + +r#883 = m["sibling"] + +ra = /[\-:]([a-z])/g + +rb = (...) => (((null == b) || ("boolean" === typeof(b)) || ("" === b)) ? "" : ((c || ("number" !== typeof(b)) || (0 === b) || (pb["hasOwnProperty"](a) && pb[a])) ? `${b}`["trim"]() : `${b}px`)) + +rc = (64 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +rd = (...) => b + +re = (...) => undefined + +rf = `_reactListening${FreeVar(Math)["random"]()["toString"](36)["slice"](2)}` + +rg = (1 | ???*0* | og[???*1*] | a["id"]) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +rh = (...) => undefined + +ri = (...) => (undefined | FreeVar(undefined)) + +rj = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +rk = (0 | ???*0* | ???*1*) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +rl = (...) => (g | k) + +sa = (...) => a[1]["toUpperCase"]() + +sb = (...) => undefined + +sc = (4194304 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +sd = { + "eventPhase": 0, + "bubbles": 0, + "cancelable": 0, + "timeStamp": *anonymous function 28108*, + "defaultPrevented": 0, + "isTrusted": 0 +} + +se = (...) => undefined + +sf = (...) => undefined + +sg = ("" | (f + a) | a | og[???*0*] | a["overflow"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +sh = (...) => (b["ref"] | b | a) + +si = (...) => di()["memoizedState"] + +sj = (...) => (???*0* | f | tj(a, b, g, null) | tj(a, b, g, d) | b) +- *0* tj(a, b, g, d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +sk = (0 | ???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +sl = (...) => hl(g) + +t#292 = ((0 !== ???*0*) | [] | Bd | Td | ???*1* | k | vf(t) | null) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unknown new expression + ⚠️ This value might have side effects + +t#404 = h + +t#431 = (...) => l + +t#454 = r(e, m, n["value"], k) + +t#673 = n["memoizedProps"] + +t#724 = ???*0* +- *0* t + ⚠️ pattern without value + +t#726 = ???*0* +- *0* t + ⚠️ pattern without value + +t#729 = ???*0* +- *0* t + ⚠️ pattern without value + +t#733 = ???*0* +- *0* t + ⚠️ pattern without value + +t#736 = ???*0* +- *0* t + ⚠️ pattern without value + +t#738 = ???*0* +- *0* t + ⚠️ pattern without value + +t#744 = ???*0* +- *0* t + ⚠️ pattern without value + +t#750 = ???*0* +- *0* t + ⚠️ pattern without value + +t#753 = ???*0* +- *0* t + ⚠️ pattern without value + +t#843 = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +t#883 = (n["child"] | J) + +ta = (...) => undefined + +tb = A( + {"menuitem": !(0)}, + { + "area": !(0), + "base": !(0), + "br": !(0), + "col": !(0), + "embed": !(0), + "hr": !(0), + "img": !(0), + "input": !(0), + "keygen": !(0), + "link": !(0), + "meta": !(0), + "param": !(0), + "source": !(0), + "track": !(0), + "wbr": !(0) + } +) + +tc = (...) => (undefined | 1 | 2 | 4 | 8 | 16 | 32 | ???*0* | 134217728 | 268435456 | 536870912 | 1073741824 | a) +- *0* unsupported expression + ⚠️ This value might have side effects + +td = rd(sd) + +te = (...) => (undefined | a) + +tf = (...) => {"instance": a, "listener": b, "currentTarget": c} + +tg = (...) => undefined + +th = (...) => undefined + +ti = (...) => undefined + +tj = (...) => a + +tk = (null | [f]) + +tl = {"usingClientEntryPoint": !(1), "Events": [Cb, ue, Db, Eb, Fb, Rk]} + +u#292 = (???*0* | w | F | ((null == n) ? h : ue(n)) | t | vf(u) | 0 | ???*1*) +- *0* u + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +u#449 = (g | null | x | q(e, h[w], k) | d(e, u)) + +u#454 = (???*0* | t | n) +- *0* unsupported expression + ⚠️ This value might have side effects + +u#673 = b["stateNode"]["containerInfo"] + +u#843 = f["stateNode"] + +u#883 = g["child"] + +ua = aa["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"] + +ub = (...) => undefined + +uc = (...) => (0 | b | d) + +ud = A({}, sd, {"view": 0, "detail": 0}) + +ue = (...) => (undefined | a["stateNode"]) + +uf = `__reactContainer$${Nf}` + +ug = (...) => undefined + +uh = (...) => b(a["_payload"]) + +ui = (...) => (undefined | FreeVar(undefined)) + +uj = (...) => undefined + +uk = (null | c | a | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +ul = { + "findFiberByHostInstance": Wc, + "bundleType": 0, + "version": "18.2.0", + "rendererPackageName": "react-dom" +} + +v = (...) => undefined + +va = FreeVar(Symbol)["for"]("react.element") + +vb = (...) => (undefined | ("string" === typeof(b["is"])) | !(1) | !(0)) + +vc = (...) => (undefined | (b + 250) | (b + 5000) | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +vd = rd(ud) + +ve = (...) => (undefined | b) + +vf = (...) => (null | (a ? a : null)) + +vg = (...) => undefined + +vh = (...) => J + +vi = (...) => ti(8390656, 8, a, b) + +vj = (...) => undefined + +vk = null + +vl = { + "bundleType": ul["bundleType"], + "version": ul["version"], + "rendererPackageName": ul["rendererPackageName"], + "rendererConfig": ul["rendererConfig"], + "overrideHookState": null, + "overrideHookStateDeletePath": null, + "overrideHookStateRenamePath": null, + "overrideProps": null, + "overridePropsDeletePath": null, + "overridePropsRenamePath": null, + "setErrorHandler": null, + "setSuspenseHandler": null, + "scheduleUpdate": null, + "currentDispatcherRef": ua["ReactCurrentDispatcher"], + "findHostInstanceByFiber": *anonymous function 129223*, + "findFiberByHostInstance": (ul["findFiberByHostInstance"] || kl), + "findHostInstancesForRefresh": null, + "scheduleRefresh": null, + "scheduleRoot": null, + "setRefreshHandler": null, + "getCurrentFiber": null, + "reconcilerVersion": "18.2.0-next-9e3b772b8-20220608" +} + +w#292 = (d | w["return"] | "mouse" | "pointer" | 0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +w#449 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +w#454 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +w#673 = x["getSnapshotBeforeUpdate"]( + ((b["elementType"] === b["type"]) ? t : Lg(b["type"], t)), + J +) + +w#843 = f["type"] + +w#883 = a["current"] + +wa = FreeVar(Symbol)["for"]("react.portal") + +wb = (null | d) + +wc = (...) => undefined + +wd = (???*0* | ???*1* | 0) +- *0* wd + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +we = ( + | !(1) + | (xe && (!(FreeVar(document)["documentMode"]) || ???*0*)) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +wf = (...) => undefined + +wg = (...) => undefined + +wh = (...) => c + +wi = (...) => ui(4, 2, a, b) + +wj = (...) => undefined + +wk = (!(1) | !(0)) + +wl = FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + +x#292 = ((t ? ((null !== h) ? `${h}Capture` : null) : h) | "onMouseEnter" | "onPointerEnter" | n | vf(x)) + +x#449 = (null | u | u["sibling"] | y(u, e, w, h[w], k)) + +x#454 = (null | m | m["sibling"]) + +x#673 = b["stateNode"] + +x#843 = Oi(f, k, b) + +x#883 = f["sibling"] + +xa = (Ce | h["_wrapperState"] | (d ? ue(d) : FreeVar(window)) | oe(d, ba)) + +xb = (...) => ((3 === a["nodeType"]) ? a["parentNode"] : a) + +xc = (...) => ((0 !== a) ? a : (???*0* ? 1073741824 : 0)) +- *0* unsupported expression + ⚠️ This value might have side effects + +xd = (???*0* | ???*1*) +- *0* xd + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +xe = (???*0* | ye | !(1)) +- *0* xe + ⚠️ pattern without value + +xf = /\r\n?/g + +xg = (null | a | a | a | b | b) + +xh = (...) => a + +xi = (...) => ui(4, 4, a, b) + +xj = (...) => undefined + +xk = (null | a) + +y#404 = ( + | h["eventTime"] + | c + | { + "eventTime": y, + "lane": r, + "tag": h["tag"], + "payload": h["payload"], + "callback": h["callback"], + "next": null + } +) + +y#431 = (...) => (???*0* | y(a, b, c, f(d["_payload"]), e) | null) +- *0* h(b, a, ("" + d), e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +y#601 = c["getDerivedStateFromProps"] + +y#673 = (???*0* | q["firstChild"] | q["nextSibling"]) +- *0* y + ⚠️ pattern without value + +y#721 = (f["value"] | r["child"]) + +y#843 = Vi(g) + +y#883 = m["return"] + +ya = FreeVar(Symbol)["for"]("react.fragment") + +yb = (null | *anonymous function 128216*) + +yc = (...) => a + +yd = (???*0* | a) +- *0* yd + ⚠️ pattern without value + +ye = (???*0* | ("function" === typeof(ze["oninput"]))) +- *0* unsupported expression + ⚠️ This value might have side effects + +yf = /\u0000|\uFFFD/g + +yg = ( + | null + | Lf(b["firstChild"]) + | Lf(a["nextSibling"]) + | (xg ? Lf(a["stateNode"]["nextSibling"]) : null) + | ???*0* + | Lf(e["nextSibling"]) + | Lf(b["stateNode"]["containerInfo"]["firstChild"]) +) +- *0* unsupported expression + ⚠️ This value might have side effects + +yh = (...) => (Ah(c["children"], e, f, b) | ???*0* | qj(c, e, f, b) | b) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +yi = (...) => (undefined | ???*0*) +- *0* *anonymous function 69020* + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +yj = (...) => b["child"] + +yk = (0 | e) + +z = {} + +za = FreeVar(Symbol)["for"]("react.strict_mode") + +zb = (null | a) + +zc = (...) => b + +zd = (...) => Pd + +ze = FreeVar(document)["createElement"]("div") + +zf = (...) => (("string" === typeof(a)) ? a : `${a}`)["replace"](xf, "\n")["replace"](yf, "") + +zg = (null | [a]) + +zh = (...) => b + +zi = (...) => ui(4, 4, yi["bind"](null, b, a), c) + +zj = (...) => (???*0* | pj(a, b, c) | ((null !== a) ? a["sibling"] : null) | yj(a, b, c) | null | $i(a, b, c)) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +zk = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/input.js new file mode 100644 index 0000000000000..7bbc786deca6a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/input.js @@ -0,0 +1,323 @@ +/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +/* + Modernizr 3.0.0pre (Custom Build) | MIT +*/ +'use strict';var aa=require("react"),ca=require("scheduler");function p(a){for(var b="https://reactjs.org/docs/error-decoder.html?invariant="+a,c=1;cb}return!1}function v(a,b,c,d,e,f,g){this.acceptsBooleans=2===b||3===b||4===b;this.attributeName=d;this.attributeNamespace=e;this.mustUseProperty=c;this.propertyName=a;this.type=b;this.sanitizeURL=f;this.removeEmptyString=g}var z={}; +"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(a){z[a]=new v(a,0,!1,a,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(a){var b=a[0];z[b]=new v(b,1,!1,a[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(a){z[a]=new v(a,2,!1,a.toLowerCase(),null,!1,!1)}); +["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(a){z[a]=new v(a,2,!1,a,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(a){z[a]=new v(a,3,!1,a.toLowerCase(),null,!1,!1)}); +["checked","multiple","muted","selected"].forEach(function(a){z[a]=new v(a,3,!0,a,null,!1,!1)});["capture","download"].forEach(function(a){z[a]=new v(a,4,!1,a,null,!1,!1)});["cols","rows","size","span"].forEach(function(a){z[a]=new v(a,6,!1,a,null,!1,!1)});["rowSpan","start"].forEach(function(a){z[a]=new v(a,5,!1,a.toLowerCase(),null,!1,!1)});var ra=/[\-:]([a-z])/g;function sa(a){return a[1].toUpperCase()} +"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(a){var b=a.replace(ra, +sa);z[b]=new v(b,1,!1,a,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(a){var b=a.replace(ra,sa);z[b]=new v(b,1,!1,a,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!1,!1)}); +z.xlinkHref=new v("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(a){z[a]=new v(a,1,!1,a.toLowerCase(),null,!0,!0)}); +function ta(a,b,c,d){var e=z.hasOwnProperty(b)?z[b]:null;if(null!==e?0!==e.type:d||!(2h||e[g]!==f[h]){var k="\n"+e[g].replace(" at new "," at ");a.displayName&&k.includes("")&&(k=k.replace("",a.displayName));return k}while(1<=g&&0<=h)}break}}}finally{Na=!1,Error.prepareStackTrace=c}return(a=a?a.displayName||a.name:"")?Ma(a):""} +function Pa(a){switch(a.tag){case 5:return Ma(a.type);case 16:return Ma("Lazy");case 13:return Ma("Suspense");case 19:return Ma("SuspenseList");case 0:case 2:case 15:return a=Oa(a.type,!1),a;case 11:return a=Oa(a.type.render,!1),a;case 1:return a=Oa(a.type,!0),a;default:return""}} +function Qa(a){if(null==a)return null;if("function"===typeof a)return a.displayName||a.name||null;if("string"===typeof a)return a;switch(a){case ya:return"Fragment";case wa:return"Portal";case Aa:return"Profiler";case za:return"StrictMode";case Ea:return"Suspense";case Fa:return"SuspenseList"}if("object"===typeof a)switch(a.$$typeof){case Ca:return(a.displayName||"Context")+".Consumer";case Ba:return(a._context.displayName||"Context")+".Provider";case Da:var b=a.render;a=a.displayName;a||(a=b.displayName|| +b.name||"",a=""!==a?"ForwardRef("+a+")":"ForwardRef");return a;case Ga:return b=a.displayName||null,null!==b?b:Qa(a.type)||"Memo";case Ha:b=a._payload;a=a._init;try{return Qa(a(b))}catch(c){}}return null} +function Ra(a){var b=a.type;switch(a.tag){case 24:return"Cache";case 9:return(b.displayName||"Context")+".Consumer";case 10:return(b._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return a=b.render,a=a.displayName||a.name||"",b.displayName||(""!==a?"ForwardRef("+a+")":"ForwardRef");case 7:return"Fragment";case 5:return b;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return Qa(b);case 8:return b===za?"StrictMode":"Mode";case 22:return"Offscreen"; +case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if("function"===typeof b)return b.displayName||b.name||null;if("string"===typeof b)return b}return null}function Sa(a){switch(typeof a){case "boolean":case "number":case "string":case "undefined":return a;case "object":return a;default:return""}} +function Ta(a){var b=a.type;return(a=a.nodeName)&&"input"===a.toLowerCase()&&("checkbox"===b||"radio"===b)} +function Ua(a){var b=Ta(a)?"checked":"value",c=Object.getOwnPropertyDescriptor(a.constructor.prototype,b),d=""+a[b];if(!a.hasOwnProperty(b)&&"undefined"!==typeof c&&"function"===typeof c.get&&"function"===typeof c.set){var e=c.get,f=c.set;Object.defineProperty(a,b,{configurable:!0,get:function(){return e.call(this)},set:function(a){d=""+a;f.call(this,a)}});Object.defineProperty(a,b,{enumerable:c.enumerable});return{getValue:function(){return d},setValue:function(a){d=""+a},stopTracking:function(){a._valueTracker= +null;delete a[b]}}}}function Va(a){a._valueTracker||(a._valueTracker=Ua(a))}function Wa(a){if(!a)return!1;var b=a._valueTracker;if(!b)return!0;var c=b.getValue();var d="";a&&(d=Ta(a)?a.checked?"true":"false":a.value);a=d;return a!==c?(b.setValue(a),!0):!1}function Xa(a){a=a||("undefined"!==typeof document?document:void 0);if("undefined"===typeof a)return null;try{return a.activeElement||a.body}catch(b){return a.body}} +function Ya(a,b){var c=b.checked;return A({},b,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=c?c:a._wrapperState.initialChecked})}function Za(a,b){var c=null==b.defaultValue?"":b.defaultValue,d=null!=b.checked?b.checked:b.defaultChecked;c=Sa(null!=b.value?b.value:c);a._wrapperState={initialChecked:d,initialValue:c,controlled:"checkbox"===b.type||"radio"===b.type?null!=b.checked:null!=b.value}}function ab(a,b){b=b.checked;null!=b&&ta(a,"checked",b,!1)} +function bb(a,b){ab(a,b);var c=Sa(b.value),d=b.type;if(null!=c)if("number"===d){if(0===c&&""===a.value||a.value!=c)a.value=""+c}else a.value!==""+c&&(a.value=""+c);else if("submit"===d||"reset"===d){a.removeAttribute("value");return}b.hasOwnProperty("value")?cb(a,b.type,c):b.hasOwnProperty("defaultValue")&&cb(a,b.type,Sa(b.defaultValue));null==b.checked&&null!=b.defaultChecked&&(a.defaultChecked=!!b.defaultChecked)} +function db(a,b,c){if(b.hasOwnProperty("value")||b.hasOwnProperty("defaultValue")){var d=b.type;if(!("submit"!==d&&"reset"!==d||void 0!==b.value&&null!==b.value))return;b=""+a._wrapperState.initialValue;c||b===a.value||(a.value=b);a.defaultValue=b}c=a.name;""!==c&&(a.name="");a.defaultChecked=!!a._wrapperState.initialChecked;""!==c&&(a.name=c)} +function cb(a,b,c){if("number"!==b||Xa(a.ownerDocument)!==a)null==c?a.defaultValue=""+a._wrapperState.initialValue:a.defaultValue!==""+c&&(a.defaultValue=""+c)}var eb=Array.isArray; +function fb(a,b,c,d){a=a.options;if(b){b={};for(var e=0;e"+b.valueOf().toString()+"";for(b=mb.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;b.firstChild;)a.appendChild(b.firstChild)}}); +function ob(a,b){if(b){var c=a.firstChild;if(c&&c===a.lastChild&&3===c.nodeType){c.nodeValue=b;return}}a.textContent=b} +var pb={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0, +zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},qb=["Webkit","ms","Moz","O"];Object.keys(pb).forEach(function(a){qb.forEach(function(b){b=b+a.charAt(0).toUpperCase()+a.substring(1);pb[b]=pb[a]})});function rb(a,b,c){return null==b||"boolean"===typeof b||""===b?"":c||"number"!==typeof b||0===b||pb.hasOwnProperty(a)&&pb[a]?(""+b).trim():b+"px"} +function sb(a,b){a=a.style;for(var c in b)if(b.hasOwnProperty(c)){var d=0===c.indexOf("--"),e=rb(c,b[c],d);"float"===c&&(c="cssFloat");d?a.setProperty(c,e):a[c]=e}}var tb=A({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0}); +function ub(a,b){if(b){if(tb[a]&&(null!=b.children||null!=b.dangerouslySetInnerHTML))throw Error(p(137,a));if(null!=b.dangerouslySetInnerHTML){if(null!=b.children)throw Error(p(60));if("object"!==typeof b.dangerouslySetInnerHTML||!("__html"in b.dangerouslySetInnerHTML))throw Error(p(61));}if(null!=b.style&&"object"!==typeof b.style)throw Error(p(62));}} +function vb(a,b){if(-1===a.indexOf("-"))return"string"===typeof b.is;switch(a){case "annotation-xml":case "color-profile":case "font-face":case "font-face-src":case "font-face-uri":case "font-face-format":case "font-face-name":case "missing-glyph":return!1;default:return!0}}var wb=null;function xb(a){a=a.target||a.srcElement||window;a.correspondingUseElement&&(a=a.correspondingUseElement);return 3===a.nodeType?a.parentNode:a}var yb=null,zb=null,Ab=null; +function Bb(a){if(a=Cb(a)){if("function"!==typeof yb)throw Error(p(280));var b=a.stateNode;b&&(b=Db(b),yb(a.stateNode,a.type,b))}}function Eb(a){zb?Ab?Ab.push(a):Ab=[a]:zb=a}function Fb(){if(zb){var a=zb,b=Ab;Ab=zb=null;Bb(a);if(b)for(a=0;a>>=0;return 0===a?32:31-(pc(a)/qc|0)|0}var rc=64,sc=4194304; +function tc(a){switch(a&-a){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return a&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return a&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824; +default:return a}}function uc(a,b){var c=a.pendingLanes;if(0===c)return 0;var d=0,e=a.suspendedLanes,f=a.pingedLanes,g=c&268435455;if(0!==g){var h=g&~e;0!==h?d=tc(h):(f&=g,0!==f&&(d=tc(f)))}else g=c&~e,0!==g?d=tc(g):0!==f&&(d=tc(f));if(0===d)return 0;if(0!==b&&b!==d&&0===(b&e)&&(e=d&-d,f=b&-b,e>=f||16===e&&0!==(f&4194240)))return b;0!==(d&4)&&(d|=c&16);b=a.entangledLanes;if(0!==b)for(a=a.entanglements,b&=d;0c;c++)b.push(a);return b} +function Ac(a,b,c){a.pendingLanes|=b;536870912!==b&&(a.suspendedLanes=0,a.pingedLanes=0);a=a.eventTimes;b=31-oc(b);a[b]=c}function Bc(a,b){var c=a.pendingLanes&~b;a.pendingLanes=b;a.suspendedLanes=0;a.pingedLanes=0;a.expiredLanes&=b;a.mutableReadLanes&=b;a.entangledLanes&=b;b=a.entanglements;var d=a.eventTimes;for(a=a.expirationTimes;0=be),ee=String.fromCharCode(32),fe=!1; +function ge(a,b){switch(a){case "keyup":return-1!==$d.indexOf(b.keyCode);case "keydown":return 229!==b.keyCode;case "keypress":case "mousedown":case "focusout":return!0;default:return!1}}function he(a){a=a.detail;return"object"===typeof a&&"data"in a?a.data:null}var ie=!1;function je(a,b){switch(a){case "compositionend":return he(b);case "keypress":if(32!==b.which)return null;fe=!0;return ee;case "textInput":return a=b.data,a===ee&&fe?null:a;default:return null}} +function ke(a,b){if(ie)return"compositionend"===a||!ae&&ge(a,b)?(a=nd(),md=ld=kd=null,ie=!1,a):null;switch(a){case "paste":return null;case "keypress":if(!(b.ctrlKey||b.altKey||b.metaKey)||b.ctrlKey&&b.altKey){if(b.char&&1=b)return{node:c,offset:b-a};a=d}a:{for(;c;){if(c.nextSibling){c=c.nextSibling;break a}c=c.parentNode}c=void 0}c=Je(c)}}function Le(a,b){return a&&b?a===b?!0:a&&3===a.nodeType?!1:b&&3===b.nodeType?Le(a,b.parentNode):"contains"in a?a.contains(b):a.compareDocumentPosition?!!(a.compareDocumentPosition(b)&16):!1:!1} +function Me(){for(var a=window,b=Xa();b instanceof a.HTMLIFrameElement;){try{var c="string"===typeof b.contentWindow.location.href}catch(d){c=!1}if(c)a=b.contentWindow;else break;b=Xa(a.document)}return b}function Ne(a){var b=a&&a.nodeName&&a.nodeName.toLowerCase();return b&&("input"===b&&("text"===a.type||"search"===a.type||"tel"===a.type||"url"===a.type||"password"===a.type)||"textarea"===b||"true"===a.contentEditable)} +function Oe(a){var b=Me(),c=a.focusedElem,d=a.selectionRange;if(b!==c&&c&&c.ownerDocument&&Le(c.ownerDocument.documentElement,c)){if(null!==d&&Ne(c))if(b=d.start,a=d.end,void 0===a&&(a=b),"selectionStart"in c)c.selectionStart=b,c.selectionEnd=Math.min(a,c.value.length);else if(a=(b=c.ownerDocument||document)&&b.defaultView||window,a.getSelection){a=a.getSelection();var e=c.textContent.length,f=Math.min(d.start,e);d=void 0===d.end?f:Math.min(d.end,e);!a.extend&&f>d&&(e=d,d=f,f=e);e=Ke(c,f);var g=Ke(c, +d);e&&g&&(1!==a.rangeCount||a.anchorNode!==e.node||a.anchorOffset!==e.offset||a.focusNode!==g.node||a.focusOffset!==g.offset)&&(b=b.createRange(),b.setStart(e.node,e.offset),a.removeAllRanges(),f>d?(a.addRange(b),a.extend(g.node,g.offset)):(b.setEnd(g.node,g.offset),a.addRange(b)))}b=[];for(a=c;a=a.parentNode;)1===a.nodeType&&b.push({element:a,left:a.scrollLeft,top:a.scrollTop});"function"===typeof c.focus&&c.focus();for(c=0;c=document.documentMode,Qe=null,Re=null,Se=null,Te=!1; +function Ue(a,b,c){var d=c.window===c?c.document:9===c.nodeType?c:c.ownerDocument;Te||null==Qe||Qe!==Xa(d)||(d=Qe,"selectionStart"in d&&Ne(d)?d={start:d.selectionStart,end:d.selectionEnd}:(d=(d.ownerDocument&&d.ownerDocument.defaultView||window).getSelection(),d={anchorNode:d.anchorNode,anchorOffset:d.anchorOffset,focusNode:d.focusNode,focusOffset:d.focusOffset}),Se&&Ie(Se,d)||(Se=d,d=oe(Re,"onSelect"),0Tf||(a.current=Sf[Tf],Sf[Tf]=null,Tf--)}function G(a,b){Tf++;Sf[Tf]=a.current;a.current=b}var Vf={},H=Uf(Vf),Wf=Uf(!1),Xf=Vf;function Yf(a,b){var c=a.type.contextTypes;if(!c)return Vf;var d=a.stateNode;if(d&&d.__reactInternalMemoizedUnmaskedChildContext===b)return d.__reactInternalMemoizedMaskedChildContext;var e={},f;for(f in c)e[f]=b[f];d&&(a=a.stateNode,a.__reactInternalMemoizedUnmaskedChildContext=b,a.__reactInternalMemoizedMaskedChildContext=e);return e} +function Zf(a){a=a.childContextTypes;return null!==a&&void 0!==a}function $f(){E(Wf);E(H)}function ag(a,b,c){if(H.current!==Vf)throw Error(p(168));G(H,b);G(Wf,c)}function bg(a,b,c){var d=a.stateNode;b=b.childContextTypes;if("function"!==typeof d.getChildContext)return c;d=d.getChildContext();for(var e in d)if(!(e in b))throw Error(p(108,Ra(a)||"Unknown",e));return A({},c,d)} +function cg(a){a=(a=a.stateNode)&&a.__reactInternalMemoizedMergedChildContext||Vf;Xf=H.current;G(H,a);G(Wf,Wf.current);return!0}function dg(a,b,c){var d=a.stateNode;if(!d)throw Error(p(169));c?(a=bg(a,b,Xf),d.__reactInternalMemoizedMergedChildContext=a,E(Wf),E(H),G(H,a)):E(Wf);G(Wf,c)}var eg=null,fg=!1,gg=!1;function hg(a){null===eg?eg=[a]:eg.push(a)}function ig(a){fg=!0;hg(a)} +function jg(){if(!gg&&null!==eg){gg=!0;var a=0,b=C;try{var c=eg;for(C=1;a>=g;e-=g;rg=1<<32-oc(b)+e|c<w?(x=u,u=null):x=u.sibling;var n=r(e,u,h[w],k);if(null===n){null===u&&(u=x);break}a&&u&&null===n.alternate&&b(e,u);g=f(n,g,w);null===m?l=n:m.sibling=n;m=n;u=x}if(w===h.length)return c(e,u),I&&tg(e,w),l;if(null===u){for(;ww?(x=m,m=null):x=m.sibling;var t=r(e,m,n.value,k);if(null===t){null===m&&(m=x);break}a&&m&&null===t.alternate&&b(e,m);g=f(t,g,w);null===u?l=t:u.sibling=t;u=t;m=x}if(n.done)return c(e, +m),I&&tg(e,w),l;if(null===m){for(;!n.done;w++,n=h.next())n=q(e,n.value,k),null!==n&&(g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);I&&tg(e,w);return l}for(m=d(e,m);!n.done;w++,n=h.next())n=y(m,e,w,n.value,k),null!==n&&(a&&null!==n.alternate&&m.delete(null===n.key?w:n.key),g=f(n,g,w),null===u?l=n:u.sibling=n,u=n);a&&m.forEach(function(a){return b(e,a)});I&&tg(e,w);return l}function J(a,d,f,h){"object"===typeof f&&null!==f&&f.type===ya&&null===f.key&&(f=f.props.children);if("object"===typeof f&&null!==f){switch(f.$$typeof){case va:a:{for(var k= +f.key,l=d;null!==l;){if(l.key===k){k=f.type;if(k===ya){if(7===l.tag){c(a,l.sibling);d=e(l,f.props.children);d.return=a;a=d;break a}}else if(l.elementType===k||"object"===typeof k&&null!==k&&k.$$typeof===Ha&&uh(k)===l.type){c(a,l.sibling);d=e(l,f.props);d.ref=sh(a,l,f);d.return=a;a=d;break a}c(a,l);break}else b(a,l);l=l.sibling}f.type===ya?(d=Ah(f.props.children,a.mode,h,f.key),d.return=a,a=d):(h=yh(f.type,f.key,f.props,null,a.mode,h),h.ref=sh(a,d,f),h.return=a,a=h)}return g(a);case wa:a:{for(l=f.key;null!== +d;){if(d.key===l)if(4===d.tag&&d.stateNode.containerInfo===f.containerInfo&&d.stateNode.implementation===f.implementation){c(a,d.sibling);d=e(d,f.children||[]);d.return=a;a=d;break a}else{c(a,d);break}else b(a,d);d=d.sibling}d=zh(f,a.mode,h);d.return=a;a=d}return g(a);case Ha:return l=f._init,J(a,d,l(f._payload),h)}if(eb(f))return n(a,d,f,h);if(Ka(f))return t(a,d,f,h);th(a,f)}return"string"===typeof f&&""!==f||"number"===typeof f?(f=""+f,null!==d&&6===d.tag?(c(a,d.sibling),d=e(d,f),d.return=a,a=d): +(c(a,d),d=xh(f,a.mode,h),d.return=a,a=d),g(a)):c(a,d)}return J}var Bh=vh(!0),Ch=vh(!1),Dh={},Eh=Uf(Dh),Fh=Uf(Dh),Gh=Uf(Dh);function Hh(a){if(a===Dh)throw Error(p(174));return a}function Ih(a,b){G(Gh,b);G(Fh,a);G(Eh,Dh);a=b.nodeType;switch(a){case 9:case 11:b=(b=b.documentElement)?b.namespaceURI:lb(null,"");break;default:a=8===a?b.parentNode:b,b=a.namespaceURI||null,a=a.tagName,b=lb(b,a)}E(Eh);G(Eh,b)}function Jh(){E(Eh);E(Fh);E(Gh)} +function Kh(a){Hh(Gh.current);var b=Hh(Eh.current);var c=lb(b,a.type);b!==c&&(G(Fh,a),G(Eh,c))}function Lh(a){Fh.current===a&&(E(Eh),E(Fh))}var M=Uf(0); +function Mh(a){for(var b=a;null!==b;){if(13===b.tag){var c=b.memoizedState;if(null!==c&&(c=c.dehydrated,null===c||"$?"===c.data||"$!"===c.data))return b}else if(19===b.tag&&void 0!==b.memoizedProps.revealOrder){if(0!==(b.flags&128))return b}else if(null!==b.child){b.child.return=b;b=b.child;continue}if(b===a)break;for(;null===b.sibling;){if(null===b.return||b.return===a)return null;b=b.return}b.sibling.return=b.return;b=b.sibling}return null}var Nh=[]; +function Oh(){for(var a=0;ac?c:4;a(!0);var d=Qh.transition;Qh.transition={};try{a(!1),b()}finally{C=c,Qh.transition=d}}function Fi(){return di().memoizedState} +function Gi(a,b,c){var d=lh(a);c={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(Hi(a))Ii(b,c);else if(c=Yg(a,b,c,d),null!==c){var e=L();mh(c,a,d,e);Ji(c,b,d)}} +function ri(a,b,c){var d=lh(a),e={lane:d,action:c,hasEagerState:!1,eagerState:null,next:null};if(Hi(a))Ii(b,e);else{var f=a.alternate;if(0===a.lanes&&(null===f||0===f.lanes)&&(f=b.lastRenderedReducer,null!==f))try{var g=b.lastRenderedState,h=f(g,c);e.hasEagerState=!0;e.eagerState=h;if(He(h,g)){var k=b.interleaved;null===k?(e.next=e,Xg(b)):(e.next=k.next,k.next=e);b.interleaved=e;return}}catch(l){}finally{}c=Yg(a,b,e,d);null!==c&&(e=L(),mh(c,a,d,e),Ji(c,b,d))}} +function Hi(a){var b=a.alternate;return a===N||null!==b&&b===N}function Ii(a,b){Th=Sh=!0;var c=a.pending;null===c?b.next=b:(b.next=c.next,c.next=b);a.pending=b}function Ji(a,b,c){if(0!==(c&4194240)){var d=b.lanes;d&=a.pendingLanes;c|=d;b.lanes=c;Cc(a,c)}} +var ai={readContext:Vg,useCallback:Q,useContext:Q,useEffect:Q,useImperativeHandle:Q,useInsertionEffect:Q,useLayoutEffect:Q,useMemo:Q,useReducer:Q,useRef:Q,useState:Q,useDebugValue:Q,useDeferredValue:Q,useTransition:Q,useMutableSource:Q,useSyncExternalStore:Q,useId:Q,unstable_isNewReconciler:!1},Yh={readContext:Vg,useCallback:function(a,b){ci().memoizedState=[a,void 0===b?null:b];return a},useContext:Vg,useEffect:vi,useImperativeHandle:function(a,b,c){c=null!==c&&void 0!==c?c.concat([a]):null;return ti(4194308, +4,yi.bind(null,b,a),c)},useLayoutEffect:function(a,b){return ti(4194308,4,a,b)},useInsertionEffect:function(a,b){return ti(4,2,a,b)},useMemo:function(a,b){var c=ci();b=void 0===b?null:b;a=a();c.memoizedState=[a,b];return a},useReducer:function(a,b,c){var d=ci();b=void 0!==c?c(b):b;d.memoizedState=d.baseState=b;a={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:a,lastRenderedState:b};d.queue=a;a=a.dispatch=Gi.bind(null,N,a);return[d.memoizedState,a]},useRef:function(a){var b= +ci();a={current:a};return b.memoizedState=a},useState:qi,useDebugValue:Ai,useDeferredValue:function(a){return ci().memoizedState=a},useTransition:function(){var a=qi(!1),b=a[0];a=Ei.bind(null,a[1]);ci().memoizedState=a;return[b,a]},useMutableSource:function(){},useSyncExternalStore:function(a,b,c){var d=N,e=ci();if(I){if(void 0===c)throw Error(p(407));c=c()}else{c=b();if(null===R)throw Error(p(349));0!==(Rh&30)||ni(d,b,c)}e.memoizedState=c;var f={value:c,getSnapshot:b};e.queue=f;vi(ki.bind(null,d, +f,a),[a]);d.flags|=2048;li(9,mi.bind(null,d,f,c,b),void 0,null);return c},useId:function(){var a=ci(),b=R.identifierPrefix;if(I){var c=sg;var d=rg;c=(d&~(1<<32-oc(d)-1)).toString(32)+c;b=":"+b+"R"+c;c=Uh++;0\x3c/script>",a=a.removeChild(a.firstChild)): +"string"===typeof d.is?a=g.createElement(c,{is:d.is}):(a=g.createElement(c),"select"===c&&(g=a,d.multiple?g.multiple=!0:d.size&&(g.size=d.size))):a=g.createElementNS(a,c);a[Of]=b;a[Pf]=d;Aj(a,b,!1,!1);b.stateNode=a;a:{g=vb(c,d);switch(c){case "dialog":D("cancel",a);D("close",a);e=d;break;case "iframe":case "object":case "embed":D("load",a);e=d;break;case "video":case "audio":for(e=0;eHj&&(b.flags|=128,d=!0,Ej(f,!1),b.lanes=4194304)}else{if(!d)if(a=Mh(g),null!==a){if(b.flags|=128,d=!0,c=a.updateQueue,null!==c&&(b.updateQueue=c,b.flags|=4),Ej(f,!0),null===f.tail&&"hidden"===f.tailMode&&!g.alternate&&!I)return S(b),null}else 2*B()-f.renderingStartTime>Hj&&1073741824!==c&&(b.flags|=128,d=!0,Ej(f,!1),b.lanes=4194304);f.isBackwards?(g.sibling=b.child,b.child=g):(c=f.last,null!==c?c.sibling=g:b.child=g,f.last=g)}if(null!==f.tail)return b=f.tail,f.rendering= +b,f.tail=b.sibling,f.renderingStartTime=B(),b.sibling=null,c=M.current,G(M,d?c&1|2:c&1),b;S(b);return null;case 22:case 23:return Ij(),d=null!==b.memoizedState,null!==a&&null!==a.memoizedState!==d&&(b.flags|=8192),d&&0!==(b.mode&1)?0!==(gj&1073741824)&&(S(b),b.subtreeFlags&6&&(b.flags|=8192)):S(b),null;case 24:return null;case 25:return null}throw Error(p(156,b.tag));} +function Jj(a,b){wg(b);switch(b.tag){case 1:return Zf(b.type)&&$f(),a=b.flags,a&65536?(b.flags=a&-65537|128,b):null;case 3:return Jh(),E(Wf),E(H),Oh(),a=b.flags,0!==(a&65536)&&0===(a&128)?(b.flags=a&-65537|128,b):null;case 5:return Lh(b),null;case 13:E(M);a=b.memoizedState;if(null!==a&&null!==a.dehydrated){if(null===b.alternate)throw Error(p(340));Ig()}a=b.flags;return a&65536?(b.flags=a&-65537|128,b):null;case 19:return E(M),null;case 4:return Jh(),null;case 10:return Rg(b.type._context),null;case 22:case 23:return Ij(), +null;case 24:return null;default:return null}}var Kj=!1,U=!1,Lj="function"===typeof WeakSet?WeakSet:Set,V=null;function Mj(a,b){var c=a.ref;if(null!==c)if("function"===typeof c)try{c(null)}catch(d){W(a,b,d)}else c.current=null}function Nj(a,b,c){try{c()}catch(d){W(a,b,d)}}var Oj=!1; +function Pj(a,b){Cf=dd;a=Me();if(Ne(a)){if("selectionStart"in a)var c={start:a.selectionStart,end:a.selectionEnd};else a:{c=(c=a.ownerDocument)&&c.defaultView||window;var d=c.getSelection&&c.getSelection();if(d&&0!==d.rangeCount){c=d.anchorNode;var e=d.anchorOffset,f=d.focusNode;d=d.focusOffset;try{c.nodeType,f.nodeType}catch(F){c=null;break a}var g=0,h=-1,k=-1,l=0,m=0,q=a,r=null;b:for(;;){for(var y;;){q!==c||0!==e&&3!==q.nodeType||(h=g+e);q!==f||0!==d&&3!==q.nodeType||(k=g+d);3===q.nodeType&&(g+= +q.nodeValue.length);if(null===(y=q.firstChild))break;r=q;q=y}for(;;){if(q===a)break b;r===c&&++l===e&&(h=g);r===f&&++m===d&&(k=g);if(null!==(y=q.nextSibling))break;q=r;r=q.parentNode}q=y}c=-1===h||-1===k?null:{start:h,end:k}}else c=null}c=c||{start:0,end:0}}else c=null;Df={focusedElem:a,selectionRange:c};dd=!1;for(V=b;null!==V;)if(b=V,a=b.child,0!==(b.subtreeFlags&1028)&&null!==a)a.return=b,V=a;else for(;null!==V;){b=V;try{var n=b.alternate;if(0!==(b.flags&1024))switch(b.tag){case 0:case 11:case 15:break; +case 1:if(null!==n){var t=n.memoizedProps,J=n.memoizedState,x=b.stateNode,w=x.getSnapshotBeforeUpdate(b.elementType===b.type?t:Lg(b.type,t),J);x.__reactInternalSnapshotBeforeUpdate=w}break;case 3:var u=b.stateNode.containerInfo;1===u.nodeType?u.textContent="":9===u.nodeType&&u.documentElement&&u.removeChild(u.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(p(163));}}catch(F){W(b,b.return,F)}a=b.sibling;if(null!==a){a.return=b.return;V=a;break}V=b.return}n=Oj;Oj=!1;return n} +function Qj(a,b,c){var d=b.updateQueue;d=null!==d?d.lastEffect:null;if(null!==d){var e=d=d.next;do{if((e.tag&a)===a){var f=e.destroy;e.destroy=void 0;void 0!==f&&Nj(b,c,f)}e=e.next}while(e!==d)}}function Rj(a,b){b=b.updateQueue;b=null!==b?b.lastEffect:null;if(null!==b){var c=b=b.next;do{if((c.tag&a)===a){var d=c.create;c.destroy=d()}c=c.next}while(c!==b)}}function Sj(a){var b=a.ref;if(null!==b){var c=a.stateNode;switch(a.tag){case 5:a=c;break;default:a=c}"function"===typeof b?b(a):b.current=a}} +function Tj(a){var b=a.alternate;null!==b&&(a.alternate=null,Tj(b));a.child=null;a.deletions=null;a.sibling=null;5===a.tag&&(b=a.stateNode,null!==b&&(delete b[Of],delete b[Pf],delete b[of],delete b[Qf],delete b[Rf]));a.stateNode=null;a.return=null;a.dependencies=null;a.memoizedProps=null;a.memoizedState=null;a.pendingProps=null;a.stateNode=null;a.updateQueue=null}function Uj(a){return 5===a.tag||3===a.tag||4===a.tag} +function Vj(a){a:for(;;){for(;null===a.sibling;){if(null===a.return||Uj(a.return))return null;a=a.return}a.sibling.return=a.return;for(a=a.sibling;5!==a.tag&&6!==a.tag&&18!==a.tag;){if(a.flags&2)continue a;if(null===a.child||4===a.tag)continue a;else a.child.return=a,a=a.child}if(!(a.flags&2))return a.stateNode}} +function Wj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?8===c.nodeType?c.parentNode.insertBefore(a,b):c.insertBefore(a,b):(8===c.nodeType?(b=c.parentNode,b.insertBefore(a,c)):(b=c,b.appendChild(a)),c=c._reactRootContainer,null!==c&&void 0!==c||null!==b.onclick||(b.onclick=Bf));else if(4!==d&&(a=a.child,null!==a))for(Wj(a,b,c),a=a.sibling;null!==a;)Wj(a,b,c),a=a.sibling} +function Xj(a,b,c){var d=a.tag;if(5===d||6===d)a=a.stateNode,b?c.insertBefore(a,b):c.appendChild(a);else if(4!==d&&(a=a.child,null!==a))for(Xj(a,b,c),a=a.sibling;null!==a;)Xj(a,b,c),a=a.sibling}var X=null,Yj=!1;function Zj(a,b,c){for(c=c.child;null!==c;)ak(a,b,c),c=c.sibling} +function ak(a,b,c){if(lc&&"function"===typeof lc.onCommitFiberUnmount)try{lc.onCommitFiberUnmount(kc,c)}catch(h){}switch(c.tag){case 5:U||Mj(c,b);case 6:var d=X,e=Yj;X=null;Zj(a,b,c);X=d;Yj=e;null!==X&&(Yj?(a=X,c=c.stateNode,8===a.nodeType?a.parentNode.removeChild(c):a.removeChild(c)):X.removeChild(c.stateNode));break;case 18:null!==X&&(Yj?(a=X,c=c.stateNode,8===a.nodeType?Kf(a.parentNode,c):1===a.nodeType&&Kf(a,c),bd(a)):Kf(X,c.stateNode));break;case 4:d=X;e=Yj;X=c.stateNode.containerInfo;Yj=!0; +Zj(a,b,c);X=d;Yj=e;break;case 0:case 11:case 14:case 15:if(!U&&(d=c.updateQueue,null!==d&&(d=d.lastEffect,null!==d))){e=d=d.next;do{var f=e,g=f.destroy;f=f.tag;void 0!==g&&(0!==(f&2)?Nj(c,b,g):0!==(f&4)&&Nj(c,b,g));e=e.next}while(e!==d)}Zj(a,b,c);break;case 1:if(!U&&(Mj(c,b),d=c.stateNode,"function"===typeof d.componentWillUnmount))try{d.props=c.memoizedProps,d.state=c.memoizedState,d.componentWillUnmount()}catch(h){W(c,b,h)}Zj(a,b,c);break;case 21:Zj(a,b,c);break;case 22:c.mode&1?(U=(d=U)||null!== +c.memoizedState,Zj(a,b,c),U=d):Zj(a,b,c);break;default:Zj(a,b,c)}}function bk(a){var b=a.updateQueue;if(null!==b){a.updateQueue=null;var c=a.stateNode;null===c&&(c=a.stateNode=new Lj);b.forEach(function(b){var d=ck.bind(null,a,b);c.has(b)||(c.add(b),b.then(d,d))})}} +function dk(a,b){var c=b.deletions;if(null!==c)for(var d=0;de&&(e=g);d&=~f}d=e;d=B()-d;d=(120>d?120:480>d?480:1080>d?1080:1920>d?1920:3E3>d?3E3:4320>d?4320:1960*mk(d/1960))-d;if(10a?16:a;if(null===xk)var d=!1;else{a=xk;xk=null;yk=0;if(0!==(K&6))throw Error(p(331));var e=K;K|=4;for(V=a.current;null!==V;){var f=V,g=f.child;if(0!==(V.flags&16)){var h=f.deletions;if(null!==h){for(var k=0;kB()-gk?Lk(a,0):sk|=c);Ek(a,b)}function Zk(a,b){0===b&&(0===(a.mode&1)?b=1:(b=sc,sc<<=1,0===(sc&130023424)&&(sc=4194304)));var c=L();a=Zg(a,b);null!==a&&(Ac(a,b,c),Ek(a,c))}function vj(a){var b=a.memoizedState,c=0;null!==b&&(c=b.retryLane);Zk(a,c)} +function ck(a,b){var c=0;switch(a.tag){case 13:var d=a.stateNode;var e=a.memoizedState;null!==e&&(c=e.retryLane);break;case 19:d=a.stateNode;break;default:throw Error(p(314));}null!==d&&d.delete(b);Zk(a,c)}var Wk; +Wk=function(a,b,c){if(null!==a)if(a.memoizedProps!==b.pendingProps||Wf.current)Ug=!0;else{if(0===(a.lanes&c)&&0===(b.flags&128))return Ug=!1,zj(a,b,c);Ug=0!==(a.flags&131072)?!0:!1}else Ug=!1,I&&0!==(b.flags&1048576)&&ug(b,ng,b.index);b.lanes=0;switch(b.tag){case 2:var d=b.type;jj(a,b);a=b.pendingProps;var e=Yf(b,H.current);Tg(b,c);e=Xh(null,b,d,a,e,c);var f=bi();b.flags|=1;"object"===typeof e&&null!==e&&"function"===typeof e.render&&void 0===e.$$typeof?(b.tag=1,b.memoizedState=null,b.updateQueue= +null,Zf(d)?(f=!0,cg(b)):f=!1,b.memoizedState=null!==e.state&&void 0!==e.state?e.state:null,ah(b),e.updater=nh,b.stateNode=e,e._reactInternals=b,rh(b,d,a,c),b=kj(null,b,d,!0,f,c)):(b.tag=0,I&&f&&vg(b),Yi(null,b,e,c),b=b.child);return b;case 16:d=b.elementType;a:{jj(a,b);a=b.pendingProps;e=d._init;d=e(d._payload);b.type=d;e=b.tag=$k(d);a=Lg(d,a);switch(e){case 0:b=dj(null,b,d,a,c);break a;case 1:b=ij(null,b,d,a,c);break a;case 11:b=Zi(null,b,d,a,c);break a;case 14:b=aj(null,b,d,Lg(d.type,a),c);break a}throw Error(p(306, +d,""));}return b;case 0:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),dj(a,b,d,e,c);case 1:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),ij(a,b,d,e,c);case 3:a:{lj(b);if(null===a)throw Error(p(387));d=b.pendingProps;f=b.memoizedState;e=f.element;bh(a,b);gh(b,d,null,c);var g=b.memoizedState;d=g.element;if(f.isDehydrated)if(f={element:d,isDehydrated:!1,cache:g.cache,pendingSuspenseBoundaries:g.pendingSuspenseBoundaries,transitions:g.transitions},b.updateQueue.baseState= +f,b.memoizedState=f,b.flags&256){e=Ki(Error(p(423)),b);b=mj(a,b,d,c,e);break a}else if(d!==e){e=Ki(Error(p(424)),b);b=mj(a,b,d,c,e);break a}else for(yg=Lf(b.stateNode.containerInfo.firstChild),xg=b,I=!0,zg=null,c=Ch(b,null,d,c),b.child=c;c;)c.flags=c.flags&-3|4096,c=c.sibling;else{Ig();if(d===e){b=$i(a,b,c);break a}Yi(a,b,d,c)}b=b.child}return b;case 5:return Kh(b),null===a&&Eg(b),d=b.type,e=b.pendingProps,f=null!==a?a.memoizedProps:null,g=e.children,Ef(d,e)?g=null:null!==f&&Ef(d,f)&&(b.flags|=32), +hj(a,b),Yi(a,b,g,c),b.child;case 6:return null===a&&Eg(b),null;case 13:return pj(a,b,c);case 4:return Ih(b,b.stateNode.containerInfo),d=b.pendingProps,null===a?b.child=Bh(b,null,d,c):Yi(a,b,d,c),b.child;case 11:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),Zi(a,b,d,e,c);case 7:return Yi(a,b,b.pendingProps,c),b.child;case 8:return Yi(a,b,b.pendingProps.children,c),b.child;case 12:return Yi(a,b,b.pendingProps.children,c),b.child;case 10:a:{d=b.type._context;e=b.pendingProps;f=b.memoizedProps; +g=e.value;G(Mg,d._currentValue);d._currentValue=g;if(null!==f)if(He(f.value,g)){if(f.children===e.children&&!Wf.current){b=$i(a,b,c);break a}}else for(f=b.child,null!==f&&(f.return=b);null!==f;){var h=f.dependencies;if(null!==h){g=f.child;for(var k=h.firstContext;null!==k;){if(k.context===d){if(1===f.tag){k=ch(-1,c&-c);k.tag=2;var l=f.updateQueue;if(null!==l){l=l.shared;var m=l.pending;null===m?k.next=k:(k.next=m.next,m.next=k);l.pending=k}}f.lanes|=c;k=f.alternate;null!==k&&(k.lanes|=c);Sg(f.return, +c,b);h.lanes|=c;break}k=k.next}}else if(10===f.tag)g=f.type===b.type?null:f.child;else if(18===f.tag){g=f.return;if(null===g)throw Error(p(341));g.lanes|=c;h=g.alternate;null!==h&&(h.lanes|=c);Sg(g,c,b);g=f.sibling}else g=f.child;if(null!==g)g.return=f;else for(g=f;null!==g;){if(g===b){g=null;break}f=g.sibling;if(null!==f){f.return=g.return;g=f;break}g=g.return}f=g}Yi(a,b,e.children,c);b=b.child}return b;case 9:return e=b.type,d=b.pendingProps.children,Tg(b,c),e=Vg(e),d=d(e),b.flags|=1,Yi(a,b,d,c), +b.child;case 14:return d=b.type,e=Lg(d,b.pendingProps),e=Lg(d.type,e),aj(a,b,d,e,c);case 15:return cj(a,b,b.type,b.pendingProps,c);case 17:return d=b.type,e=b.pendingProps,e=b.elementType===d?e:Lg(d,e),jj(a,b),b.tag=1,Zf(d)?(a=!0,cg(b)):a=!1,Tg(b,c),ph(b,d,e),rh(b,d,e,c),kj(null,b,d,!0,a,c);case 19:return yj(a,b,c);case 22:return ej(a,b,c)}throw Error(p(156,b.tag));};function Gk(a,b){return ac(a,b)} +function al(a,b,c,d){this.tag=a;this.key=c;this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null;this.index=0;this.ref=null;this.pendingProps=b;this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null;this.mode=d;this.subtreeFlags=this.flags=0;this.deletions=null;this.childLanes=this.lanes=0;this.alternate=null}function Bg(a,b,c,d){return new al(a,b,c,d)}function bj(a){a=a.prototype;return!(!a||!a.isReactComponent)} +function $k(a){if("function"===typeof a)return bj(a)?1:0;if(void 0!==a&&null!==a){a=a.$$typeof;if(a===Da)return 11;if(a===Ga)return 14}return 2} +function wh(a,b){var c=a.alternate;null===c?(c=Bg(a.tag,b,a.key,a.mode),c.elementType=a.elementType,c.type=a.type,c.stateNode=a.stateNode,c.alternate=a,a.alternate=c):(c.pendingProps=b,c.type=a.type,c.flags=0,c.subtreeFlags=0,c.deletions=null);c.flags=a.flags&14680064;c.childLanes=a.childLanes;c.lanes=a.lanes;c.child=a.child;c.memoizedProps=a.memoizedProps;c.memoizedState=a.memoizedState;c.updateQueue=a.updateQueue;b=a.dependencies;c.dependencies=null===b?null:{lanes:b.lanes,firstContext:b.firstContext}; +c.sibling=a.sibling;c.index=a.index;c.ref=a.ref;return c} +function yh(a,b,c,d,e,f){var g=2;d=a;if("function"===typeof a)bj(a)&&(g=1);else if("string"===typeof a)g=5;else a:switch(a){case ya:return Ah(c.children,e,f,b);case za:g=8;e|=8;break;case Aa:return a=Bg(12,c,b,e|2),a.elementType=Aa,a.lanes=f,a;case Ea:return a=Bg(13,c,b,e),a.elementType=Ea,a.lanes=f,a;case Fa:return a=Bg(19,c,b,e),a.elementType=Fa,a.lanes=f,a;case Ia:return qj(c,e,f,b);default:if("object"===typeof a&&null!==a)switch(a.$$typeof){case Ba:g=10;break a;case Ca:g=9;break a;case Da:g=11; +break a;case Ga:g=14;break a;case Ha:g=16;d=null;break a}throw Error(p(130,null==a?a:typeof a,""));}b=Bg(g,c,b,e);b.elementType=a;b.type=d;b.lanes=f;return b}function Ah(a,b,c,d){a=Bg(7,a,d,b);a.lanes=c;return a}function qj(a,b,c,d){a=Bg(22,a,d,b);a.elementType=Ia;a.lanes=c;a.stateNode={isHidden:!1};return a}function xh(a,b,c){a=Bg(6,a,null,b);a.lanes=c;return a} +function zh(a,b,c){b=Bg(4,null!==a.children?a.children:[],a.key,b);b.lanes=c;b.stateNode={containerInfo:a.containerInfo,pendingChildren:null,implementation:a.implementation};return b} +function bl(a,b,c,d,e){this.tag=b;this.containerInfo=a;this.finishedWork=this.pingCache=this.current=this.pendingChildren=null;this.timeoutHandle=-1;this.callbackNode=this.pendingContext=this.context=null;this.callbackPriority=0;this.eventTimes=zc(0);this.expirationTimes=zc(-1);this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0;this.entanglements=zc(0);this.identifierPrefix=d;this.onRecoverableError=e;this.mutableSourceEagerHydrationData= +null}function cl(a,b,c,d,e,f,g,h,k){a=new bl(a,b,c,h,k);1===b?(b=1,!0===f&&(b|=8)):b=0;f=Bg(3,null,null,b);a.current=f;f.stateNode=a;f.memoizedState={element:d,isDehydrated:c,cache:null,transitions:null,pendingSuspenseBoundaries:null};ah(f);return a}function dl(a,b,c){var d=3 1 free var = FreeVar(require) + +0 -> 2 call = require*0*("react") +- *0* require: The require method from CommonJS + +0 -> 3 free var = FreeVar(require) + +0 -> 4 call = require*0*("scheduler") +- *0* require: The require method from CommonJS + +0 -> 6 free var = FreeVar(arguments) + +0 -> 7 free var = FreeVar(encodeURIComponent) + +0 -> 9 free var = FreeVar(arguments) + +0 -> 10 call = ???*0*(???*1*) +- *0* FreeVar(encodeURIComponent) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*[c] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 11 free var = FreeVar(Set) + +0 -> 12 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 13 call = (...) => undefined(`${???*0*}Capture`, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 18 member call = ???*0*["add"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*[a] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 19 free var = FreeVar(window) + +0 -> 21 free var = FreeVar(window) + +0 -> 24 free var = FreeVar(window) + +0 -> 27 free var = FreeVar(Object) + +0 -> 29 member call = ???*0*["call"]({}, ???*3*) +- *0* ???*1*["hasOwnProperty"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 31 member call = ???*0*["call"]({}, ???*3*) +- *0* ???*1*["hasOwnProperty"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 33 member call = /^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/["test"](???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 34 conditional = /^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/["test"](???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 38 conditional = (null !== ???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 42 member call = (???*0* | ???*1*)["toLowerCase"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*(0, 5) + ⚠️ unknown callee +- *2* ???*3*["slice"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???*5*["toLowerCase"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference + +0 -> 43 member call = ???*0*()["slice"](0, 5) +- *0* ???*1*["toLowerCase"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 44 call = (...) => (undefined | !(1) | !(0) | !(c["acceptsBooleans"]) | (("data-" !== a) && ("aria-" !== a)))(???*0*, ???*1*, ???*2*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 45 conditional = (null !== ???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +45 -> 47 free var = FreeVar(isNaN) + +45 -> 48 call = ???*0*(???*1*) +- *0* FreeVar(isNaN) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +45 -> 49 free var = FreeVar(isNaN) + +45 -> 50 call = ???*0*(???*1*) +- *0* FreeVar(isNaN) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 61 member call = "children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style"["split"](" ") + +0 -> 62 member call = "children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style"["split"](" ")["forEach"]((...) => undefined) + +0 -> 65 member call = [ + ["acceptCharset", "accept-charset"], + ["className", "class"], + ["htmlFor", "for"], + ["httpEquiv", "http-equiv"] +]["forEach"]((...) => undefined) + +0 -> 70 member call = ["contentEditable", "draggable", "spellCheck", "value"]["forEach"]((...) => undefined) + +70 -> 73 member call = ???*0*["toLowerCase"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 75 member call = ["autoReverse", "externalResourcesRequired", "focusable", "preserveAlpha"]["forEach"]((...) => undefined) + +0 -> 79 member call = "allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope"["split"](" ") + +0 -> 80 member call = "allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope"["split"](" ")["forEach"]((...) => undefined) + +80 -> 83 member call = ???*0*["toLowerCase"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 85 member call = ["checked", "multiple", "muted", "selected"]["forEach"]((...) => undefined) + +0 -> 88 member call = ["capture", "download"]["forEach"]((...) => undefined) + +0 -> 91 member call = ["cols", "rows", "size", "span"]["forEach"]((...) => undefined) + +0 -> 94 member call = ["rowSpan", "start"]["forEach"]((...) => undefined) + +94 -> 97 member call = ???*0*["toLowerCase"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 100 member call = ???*0*["toUpperCase"]() +- *0* ???*1*[1] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 103 member call = "accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height"["split"](" ") + +0 -> 104 member call = "accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height"["split"](" ")["forEach"]((...) => undefined) + +104 -> 106 member call = ???*0*["replace"](/[\-:]([a-z])/g, (...) => a[1]["toUpperCase"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 110 member call = "xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type"["split"](" ") + +0 -> 111 member call = "xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type"["split"](" ")["forEach"]((...) => undefined) + +111 -> 113 member call = ???*0*["replace"](/[\-:]([a-z])/g, (...) => a[1]["toUpperCase"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 116 member call = ["xml:base", "xml:lang", "xml:space"]["forEach"]((...) => undefined) + +116 -> 118 member call = ???*0*["replace"](/[\-:]([a-z])/g, (...) => a[1]["toUpperCase"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 121 member call = ["tabIndex", "crossOrigin"]["forEach"]((...) => undefined) + +121 -> 124 member call = ???*0*["toLowerCase"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 127 member call = ["src", "href", "action", "formAction"]["forEach"]((...) => undefined) + +127 -> 130 member call = ???*0*["toLowerCase"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 132 member call = {}["hasOwnProperty"]( + (???*0* | (???*1* ? ???*5* : null)["attributeName"] | ???*7*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* | ???*3*)(???*4*) + ⚠️ non-function callee +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* b + ⚠️ circular variable reference +- *5* {}[???*6*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *6* b + ⚠️ circular variable reference +- *7* ???*8*["attributeName"] + ⚠️ unknown object +- *8* ???*9*["type"] + ⚠️ unknown object +- *9* e + ⚠️ circular variable reference + +0 -> 133 conditional = ???*0* +- *0* (???*1* | ???*2*)( + (???*3* | (???*4* ? ???*8* : null)["attributeName"] | ???*10*) + ) + ⚠️ non-function callee + ⚠️ This value might have side effects +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* (???*5* | ???*6*)(???*7*) + ⚠️ non-function callee +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* {}[???*9*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *9* b + ⚠️ circular variable reference +- *10* ???*11*["attributeName"] + ⚠️ unknown object +- *11* ???*12*["type"] + ⚠️ unknown object +- *12* e + ⚠️ circular variable reference + +0 -> 135 conditional = (null !== (???*0* | ???*9*)) +- *0* (???*1* ? ???*7* : null) + ⚠️ nested operation +- *1* (???*2* | ???*3*)((???*4* | ???*5*)) + ⚠️ non-function callee +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["attributeName"] + ⚠️ unknown object +- *6* e + ⚠️ circular variable reference +- *7* {}[???*8*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference + +0 -> 142 conditional = (???*0* ? ???*12* : (???*22* | ???*23* | ???*33*)) +- *0* (null !== (???*1* | ???*10*)) + ⚠️ nested operation +- *1* (???*2* ? ???*8* : null) + ⚠️ nested operation +- *2* (???*3* | ???*4*)((???*5* | ???*6*)) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["attributeName"] + ⚠️ unknown object +- *7* e + ⚠️ circular variable reference +- *8* {}[???*9*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["type"] + ⚠️ unknown object +- *11* e + ⚠️ circular variable reference +- *12* (0 !== ???*13*) + ⚠️ nested operation +- *13* ???*14*["type"] + ⚠️ unknown object +- *14* (???*15* ? ???*20* : null) + ⚠️ nested operation +- *15* (???*16* | ???*17*)((???*18* | ???*19*)) + ⚠️ non-function callee +- *16* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* unknown mutation + ⚠️ This value might have side effects +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* ???["attributeName"] + ⚠️ unknown object +- *20* {}[???*21*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* arguments[3] + ⚠️ function calls are not analysed yet +- *23* ???*24*["attributeNamespace"] + ⚠️ unknown object +- *24* (???*25* ? ???*31* : null) + ⚠️ nested operation +- *25* (???*26* | ???*27*)((???*28* | ???*29*)) + ⚠️ non-function callee +- *26* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *27* unknown mutation + ⚠️ This value might have side effects +- *28* arguments[1] + ⚠️ function calls are not analysed yet +- *29* ???*30*["attributeName"] + ⚠️ unknown object +- *30* e + ⚠️ circular variable reference +- *31* {}[???*32*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *32* arguments[1] + ⚠️ function calls are not analysed yet +- *33* !(???*34*) + ⚠️ nested operation +- *34* unsupported expression + ⚠️ This value might have side effects + +142 -> 143 call = (...) => (!(0) | !(1) | !(b) | (!(1) === b) | FreeVar(isNaN)(b) | (FreeVar(isNaN)(b) || ???*0*))( + (???*1* | (???*2* ? ???*6* : null)["attributeName"] | ???*8*), + (???*11* | null | (???*12* ? "" : ???*24*)), + ((???*25* ? ???*31* : null) | ???*33*), + (???*35* | (???*36* ? ???*42* : null)["attributeNamespace"] | ???*44*) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* | ???*4*)(???*5*) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* {}[???*7*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* ???*9*["attributeName"] + ⚠️ unknown object +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* (3 === (???*13* | ???*22*)) + ⚠️ nested operation +- *13* (???*14* ? ???*20* : null) + ⚠️ nested operation +- *14* (???*15* | ???*16*)((???*17* | ???*18*)) + ⚠️ non-function callee +- *15* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* unknown mutation + ⚠️ This value might have side effects +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* ???*19*["attributeName"] + ⚠️ unknown object +- *19* e + ⚠️ circular variable reference +- *20* {}[???*21*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* ???*23*["type"] + ⚠️ unknown object +- *23* e + ⚠️ circular variable reference +- *24* c + ⚠️ circular variable reference +- *25* (???*26* | ???*27*)((???*28* | ???*29*)) + ⚠️ non-function callee +- *26* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *27* unknown mutation + ⚠️ This value might have side effects +- *28* arguments[1] + ⚠️ function calls are not analysed yet +- *29* ???*30*["attributeName"] + ⚠️ unknown object +- *30* e + ⚠️ circular variable reference +- *31* {}[???*32*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *32* arguments[1] + ⚠️ function calls are not analysed yet +- *33* ???*34*["type"] + ⚠️ unknown object +- *34* e + ⚠️ circular variable reference +- *35* arguments[3] + ⚠️ function calls are not analysed yet +- *36* (???*37* | ???*38*)((???*39* | ???*40*)) + ⚠️ non-function callee +- *37* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *38* unknown mutation + ⚠️ This value might have side effects +- *39* arguments[1] + ⚠️ function calls are not analysed yet +- *40* ???*41*["attributeName"] + ⚠️ unknown object +- *41* e + ⚠️ circular variable reference +- *42* {}[???*43*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *43* arguments[1] + ⚠️ function calls are not analysed yet +- *44* ???*45*["attributeNamespace"] + ⚠️ unknown object +- *45* ???*46*["type"] + ⚠️ unknown object +- *46* e + ⚠️ circular variable reference + +142 -> 144 conditional = (???*0* | (???*1* ? ???*7* : null)["attributeNamespace"] | ???*9* | (null === (???*12* | ???*21*))) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (???*2* | ???*3*)((???*4* | ???*5*)) + ⚠️ non-function callee +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["attributeName"] + ⚠️ unknown object +- *6* e + ⚠️ circular variable reference +- *7* {}[???*8*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["attributeNamespace"] + ⚠️ unknown object +- *10* ???*11*["type"] + ⚠️ unknown object +- *11* e + ⚠️ circular variable reference +- *12* (???*13* ? ???*19* : null) + ⚠️ nested operation +- *13* (???*14* | ???*15*)((???*16* | ???*17*)) + ⚠️ non-function callee +- *14* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *15* unknown mutation + ⚠️ This value might have side effects +- *16* arguments[1] + ⚠️ function calls are not analysed yet +- *17* ???*18*["attributeName"] + ⚠️ unknown object +- *18* e + ⚠️ circular variable reference +- *19* {}[???*20*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*["type"] + ⚠️ unknown object +- *22* e + ⚠️ circular variable reference + +144 -> 145 call = (...) => (!(0) | !(1) | ???*0*)( + (???*1* | (???*2* ? ???*6* : null)["attributeName"] | ???*8*) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* | ???*4*)(???*5*) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* {}[???*7*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* ???*9*["attributeName"] + ⚠️ unknown object +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference + +144 -> 146 conditional = (null === (???*0* | null | ???*1*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? "" : ???*13*) + ⚠️ nested operation +- *2* (3 === (???*3* | ???*11*)) + ⚠️ nested operation +- *3* (???*4* ? ???*9* : null) + ⚠️ nested operation +- *4* (???*5* | ???*6*)((???*7* | ???*8*)) + ⚠️ non-function callee +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???["attributeName"] + ⚠️ unknown object +- *9* {}[???*10*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["type"] + ⚠️ unknown object +- *12* e + ⚠️ circular variable reference +- *13* c + ⚠️ circular variable reference + +146 -> 148 member call = ???*0*["removeAttribute"]( + (???*1* | (???*2* ? ???*6* : null)["attributeName"] | ???*8*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* | ???*4*)(???*5*) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* {}[???*7*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* ???*9*["attributeName"] + ⚠️ unknown object +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference + +146 -> 150 member call = ???*0*["setAttribute"]( + (???*1* | (???*2* ? ???*6* : null)["attributeName"] | ???*8*), + (???*11* | null | (???*12* ? "" : ???*24*)) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* | ???*4*)(???*5*) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* {}[???*7*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* ???*9*["attributeName"] + ⚠️ unknown object +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* (3 === (???*13* | ???*22*)) + ⚠️ nested operation +- *13* (???*14* ? ???*20* : null) + ⚠️ nested operation +- *14* (???*15* | ???*16*)((???*17* | ???*18*)) + ⚠️ non-function callee +- *15* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* unknown mutation + ⚠️ This value might have side effects +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* ???*19*["attributeName"] + ⚠️ unknown object +- *19* e + ⚠️ circular variable reference +- *20* {}[???*21*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* ???*23*["type"] + ⚠️ unknown object +- *23* e + ⚠️ circular variable reference +- *24* c + ⚠️ circular variable reference + +144 -> 152 conditional = ((???*0* ? ???*6* : null)["mustUseProperty"] | ???*8*) +- *0* (???*1* | ???*2*)((???*3* | ???*4*)) + ⚠️ non-function callee +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["attributeName"] + ⚠️ unknown object +- *5* e + ⚠️ circular variable reference +- *6* {}[???*7*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???*9*["mustUseProperty"] + ⚠️ unknown object +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference + +152 -> 155 conditional = (null === (???*0* | null | ???*1*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? "" : ???*13*) + ⚠️ nested operation +- *2* (3 === (???*3* | ???*11*)) + ⚠️ nested operation +- *3* (???*4* ? ???*9* : null) + ⚠️ nested operation +- *4* (???*5* | ???*6*)((???*7* | ???*8*)) + ⚠️ non-function callee +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???["attributeName"] + ⚠️ unknown object +- *9* {}[???*10*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["type"] + ⚠️ unknown object +- *12* e + ⚠️ circular variable reference +- *13* c + ⚠️ circular variable reference + +155 -> 157 conditional = (3 === ???*0*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* (???*2* ? ???*8* : null) + ⚠️ nested operation +- *2* (???*3* | ???*4*)((???*5* | ???*6*)) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["attributeName"] + ⚠️ unknown object +- *7* e + ⚠️ circular variable reference +- *8* {}[???*9*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *9* arguments[1] + ⚠️ function calls are not analysed yet + +152 -> 160 conditional = (null === (???*0* | null | ???*1*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? "" : ???*13*) + ⚠️ nested operation +- *2* (3 === (???*3* | ???*11*)) + ⚠️ nested operation +- *3* (???*4* ? ???*9* : null) + ⚠️ nested operation +- *4* (???*5* | ???*6*)((???*7* | ???*8*)) + ⚠️ non-function callee +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???["attributeName"] + ⚠️ unknown object +- *9* {}[???*10*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["type"] + ⚠️ unknown object +- *12* e + ⚠️ circular variable reference +- *13* c + ⚠️ circular variable reference + +160 -> 162 member call = ???*0*["removeAttribute"]( + (???*1* | (???*2* ? ???*6* : null)["attributeName"] | ???*8*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* | ???*4*)(???*5*) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* {}[???*7*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* ???*9*["attributeName"] + ⚠️ unknown object +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference + +160 -> 164 conditional = ((3 === (???*0* | ???*9*)) | (4 === (???*11* | ???*20*)) | (true === (???*22* | null | ???*23*))) +- *0* (???*1* ? ???*7* : null) + ⚠️ nested operation +- *1* (???*2* | ???*3*)((???*4* | ???*5*)) + ⚠️ non-function callee +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["attributeName"] + ⚠️ unknown object +- *6* e + ⚠️ circular variable reference +- *7* {}[???*8*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference +- *11* (???*12* ? ???*18* : null) + ⚠️ nested operation +- *12* (???*13* | ???*14*)((???*15* | ???*16*)) + ⚠️ non-function callee +- *13* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *14* unknown mutation + ⚠️ This value might have side effects +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* ???*17*["attributeName"] + ⚠️ unknown object +- *17* e + ⚠️ circular variable reference +- *18* {}[???*19*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["type"] + ⚠️ unknown object +- *21* e + ⚠️ circular variable reference +- *22* arguments[2] + ⚠️ function calls are not analysed yet +- *23* (???*24* ? "" : ???*35*) + ⚠️ nested operation +- *24* (3 === (???*25* | ???*33*)) + ⚠️ nested operation +- *25* (???*26* ? ???*31* : null) + ⚠️ nested operation +- *26* (???*27* | ???*28*)((???*29* | ???*30*)) + ⚠️ non-function callee +- *27* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *28* unknown mutation + ⚠️ This value might have side effects +- *29* arguments[1] + ⚠️ function calls are not analysed yet +- *30* ???["attributeName"] + ⚠️ unknown object +- *31* {}[???*32*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *32* arguments[1] + ⚠️ function calls are not analysed yet +- *33* ???*34*["type"] + ⚠️ unknown object +- *34* e + ⚠️ circular variable reference +- *35* c + ⚠️ circular variable reference + +160 -> 165 conditional = (???*0* | (???*1* ? ???*7* : null)["attributeNamespace"] | ???*9*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (???*2* | ???*3*)((???*4* | ???*5*)) + ⚠️ non-function callee +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["attributeName"] + ⚠️ unknown object +- *6* e + ⚠️ circular variable reference +- *7* {}[???*8*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["attributeNamespace"] + ⚠️ unknown object +- *10* ???*11*["type"] + ⚠️ unknown object +- *11* e + ⚠️ circular variable reference + +165 -> 167 member call = ???*0*["setAttributeNS"]( + (???*1* | (???*2* ? ???*8* : null)["attributeNamespace"] | ???*10*), + (???*13* | (???*14* ? ???*18* : null)["attributeName"] | ???*20*), + (???*23* | null | (???*24* ? "" : ???*36*)) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* (???*3* | ???*4*)((???*5* | ???*6*)) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["attributeName"] + ⚠️ unknown object +- *7* e + ⚠️ circular variable reference +- *8* {}[???*9*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["attributeNamespace"] + ⚠️ unknown object +- *11* ???*12*["type"] + ⚠️ unknown object +- *12* e + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* (???*15* | ???*16*)(???*17*) + ⚠️ non-function callee +- *15* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* unknown mutation + ⚠️ This value might have side effects +- *17* b + ⚠️ circular variable reference +- *18* {}[???*19*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *19* b + ⚠️ circular variable reference +- *20* ???*21*["attributeName"] + ⚠️ unknown object +- *21* ???*22*["type"] + ⚠️ unknown object +- *22* e + ⚠️ circular variable reference +- *23* arguments[2] + ⚠️ function calls are not analysed yet +- *24* (3 === (???*25* | ???*34*)) + ⚠️ nested operation +- *25* (???*26* ? ???*32* : null) + ⚠️ nested operation +- *26* (???*27* | ???*28*)((???*29* | ???*30*)) + ⚠️ non-function callee +- *27* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *28* unknown mutation + ⚠️ This value might have side effects +- *29* arguments[1] + ⚠️ function calls are not analysed yet +- *30* ???*31*["attributeName"] + ⚠️ unknown object +- *31* e + ⚠️ circular variable reference +- *32* {}[???*33*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *33* arguments[1] + ⚠️ function calls are not analysed yet +- *34* ???*35*["type"] + ⚠️ unknown object +- *35* e + ⚠️ circular variable reference +- *36* c + ⚠️ circular variable reference + +165 -> 169 member call = ???*0*["setAttribute"]( + (???*1* | (???*2* ? ???*6* : null)["attributeName"] | ???*8*), + (???*11* | null | (???*12* ? "" : ???*24*)) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* | ???*4*)(???*5*) + ⚠️ non-function callee +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* {}[???*7*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* ???*9*["attributeName"] + ⚠️ unknown object +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* e + ⚠️ circular variable reference +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* (3 === (???*13* | ???*22*)) + ⚠️ nested operation +- *13* (???*14* ? ???*20* : null) + ⚠️ nested operation +- *14* (???*15* | ???*16*)((???*17* | ???*18*)) + ⚠️ non-function callee +- *15* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* unknown mutation + ⚠️ This value might have side effects +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* ???*19*["attributeName"] + ⚠️ unknown object +- *19* e + ⚠️ circular variable reference +- *20* {}[???*21*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* ???*23*["type"] + ⚠️ unknown object +- *23* e + ⚠️ circular variable reference +- *24* c + ⚠️ circular variable reference + +0 -> 172 free var = FreeVar(Symbol) + +0 -> 173 member call = ???*0*["for"]("react.element") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 175 free var = FreeVar(Symbol) + +0 -> 176 member call = ???*0*["for"]("react.portal") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 178 free var = FreeVar(Symbol) + +0 -> 179 member call = ???*0*["for"]("react.fragment") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 181 free var = FreeVar(Symbol) + +0 -> 182 member call = ???*0*["for"]("react.strict_mode") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 184 free var = FreeVar(Symbol) + +0 -> 185 member call = ???*0*["for"]("react.profiler") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 187 free var = FreeVar(Symbol) + +0 -> 188 member call = ???*0*["for"]("react.provider") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 190 free var = FreeVar(Symbol) + +0 -> 191 member call = ???*0*["for"]("react.context") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 193 free var = FreeVar(Symbol) + +0 -> 194 member call = ???*0*["for"]("react.forward_ref") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 196 free var = FreeVar(Symbol) + +0 -> 197 member call = ???*0*["for"]("react.suspense") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 199 free var = FreeVar(Symbol) + +0 -> 200 member call = ???*0*["for"]("react.suspense_list") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 202 free var = FreeVar(Symbol) + +0 -> 203 member call = ???*0*["for"]("react.memo") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 205 free var = FreeVar(Symbol) + +0 -> 206 member call = ???*0*["for"]("react.lazy") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 208 free var = FreeVar(Symbol) + +0 -> 209 member call = ???*0*["for"]("react.scope") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 211 free var = FreeVar(Symbol) + +0 -> 212 member call = ???*0*["for"]("react.debug_trace_mode") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 214 free var = FreeVar(Symbol) + +0 -> 215 member call = ???*0*["for"]("react.offscreen") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 217 free var = FreeVar(Symbol) + +0 -> 218 member call = ???*0*["for"]("react.legacy_hidden") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 220 free var = FreeVar(Symbol) + +0 -> 221 member call = ???*0*["for"]("react.cache") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 223 free var = FreeVar(Symbol) + +0 -> 224 member call = ???*0*["for"]("react.tracing_marker") +- *0* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 226 free var = FreeVar(Symbol) + +0 -> 229 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | ???*2* | ???*4*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*[Ja] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference + +0 -> 231 free var = FreeVar(Object) + +0 -> 232 conditional = (???*0* === (???*1* | ???*2* | ???*7* | "")) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* La + ⚠️ pattern without value +- *2* ???*3*(/\n( *(at )?)/) + ⚠️ unknown callee +- *3* ???*4*["match"] + ⚠️ unknown object +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["trim"] + ⚠️ unknown object +- *6* ???["stack"] + ⚠️ unknown object +- *7* ???*8*[1] + ⚠️ unknown object +- *8* ???*9*(/\n( *(at )?)/) + ⚠️ unknown callee +- *9* ???*10*["match"] + ⚠️ unknown object +- *10* ???*11*() + ⚠️ nested operation +- *11* ???["trim"] + ⚠️ unknown object + +232 -> 233 free var = FreeVar(Error) + +232 -> 234 call = ???*0*() +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +232 -> 238 member call = ???*0*["trim"]() +- *0* ???*1*["stack"] + ⚠️ unknown object +- *1* c + ⚠️ pattern without value + +232 -> 239 member call = ???*0*()["match"](/\n( *(at )?)/) +- *0* ???*1*["trim"] + ⚠️ unknown object +- *1* ???*2*["stack"] + ⚠️ unknown object +- *2* c + ⚠️ pattern without value + +0 -> 242 free var = FreeVar(Error) + +0 -> 244 free var = FreeVar(Error) + +0 -> 245 conditional = (???*0* | (...) => undefined) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +245 -> 246 free var = FreeVar(Error) + +245 -> 247 call = ???*0*() +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +245 -> 249 free var = FreeVar(Object) + +245 -> 251 free var = FreeVar(Error) + +245 -> 252 call = ???*0*() +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +245 -> 253 member call = ???*0*["defineProperty"]((???*1* | (...) => undefined["prototype"]), "props", {"set": (...) => undefined}) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +245 -> 254 free var = FreeVar(Reflect) + +245 -> 256 free var = FreeVar(Reflect) + +245 -> 258 free var = FreeVar(Reflect) + +245 -> 259 member call = ???*0*["construct"]((???*1* | (...) => undefined), []) +- *0* FreeVar(Reflect) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +245 -> 261 free var = FreeVar(Reflect) + +245 -> 262 member call = ???*0*["construct"]((???*1* | (???*2* ? ???*3* : "")), [], (???*5* | (...) => undefined)) +- *0* FreeVar(Reflect) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["displayName"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* arguments[1] + ⚠️ function calls are not analysed yet + +245 -> 264 member call = (???*0* | (...) => undefined)["call"]() +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +245 -> 267 member call = (???*0* | (???*1* ? ???*2* : ""))["call"]((???*4* | (...) => undefined["prototype"])) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["displayName"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* ???*5*["prototype"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet + +245 -> 268 free var = FreeVar(Error) + +245 -> 269 call = ???*0*() +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +245 -> 270 call = (???*0* | (???*1* ? ???*2* : ""))() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["displayName"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +0 -> 272 conditional = (???*0* | ("string" === ???*1*)) +- *0* l + ⚠️ pattern without value +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["stack"] + ⚠️ unknown object +- *3* l + ⚠️ pattern without value + +272 -> 275 member call = ???*0*["split"]("\n") +- *0* ???*1*["stack"] + ⚠️ unknown object +- *1* l + ⚠️ pattern without value + +272 -> 278 member call = ???*0*["split"]("\n") +- *0* ???*1*["stack"] + ⚠️ unknown object +- *1* l + ⚠️ pattern without value + +272 -> 285 conditional = (???*0* !== ???*4*) +- *0* ???*1*[g] + ⚠️ unknown object +- *1* ???*2*["split"]("\n") + ⚠️ unknown callee object +- *2* ???*3*["stack"] + ⚠️ unknown object +- *3* l + ⚠️ pattern without value +- *4* ???*5*[h] + ⚠️ unknown object +- *5* ???*6*["split"]("\n") + ⚠️ unknown callee object +- *6* ???*7*["stack"] + ⚠️ unknown object +- *7* l + ⚠️ pattern without value + +285 -> 286 conditional = (1 !== (???*0* | ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +286 -> 291 member call = ???*0*["replace"](" at new ", " at ") +- *0* ???*1*[g] + ⚠️ unknown object +- *1* ???*2*["split"]("\n") + ⚠️ unknown callee object +- *2* ???*3*["stack"] + ⚠️ unknown object +- *3* l + ⚠️ pattern without value + +286 -> 294 member call = ( + | ` +${???*0*}` + | ???*5* +)["includes"]("") +- *0* ???*1*["replace"](" at new ", " at ") + ⚠️ unknown callee object +- *1* ???*2*[g] + ⚠️ unknown object +- *2* ???*3*["split"]("\n") + ⚠️ unknown callee object +- *3* ???*4*["stack"] + ⚠️ unknown object +- *4* l + ⚠️ pattern without value +- *5* ???*6*["replace"]("", a["displayName"]) + ⚠️ unknown callee object +- *6* k + ⚠️ circular variable reference + +286 -> 297 member call = ( + | ` +${???*0*}` + | ???*5* +)["replace"]("", (???*7* | (???*9* ? ???*10* : "")["displayName"])) +- *0* ???*1*["replace"](" at new ", " at ") + ⚠️ unknown callee object +- *1* ???*2*[g] + ⚠️ unknown object +- *2* ???*3*["split"]("\n") + ⚠️ unknown callee object +- *3* ???*4*["stack"] + ⚠️ unknown object +- *4* l + ⚠️ pattern without value +- *5* ???*6*["replace"]("", a["displayName"]) + ⚠️ unknown callee object +- *6* k + ⚠️ circular variable reference +- *7* ???*8*["displayName"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["displayName"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference + +0 -> 299 free var = FreeVar(Error) + +0 -> 300 conditional = (???*0* | (???*1* ? ???*2* : "")) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["displayName"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +0 -> 303 call = (...) => ` +${La}${a}`((???*0* | (???*1* ? ???*2* : ""))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["displayName"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +0 -> 306 call = (...) => ` +${La}${a}`( + ( + | ???*0* + | ""["type"] + | ` +${???*2*}`["type"] + | (???*7* ? ???*8* : "")["type"] + | (???*24* ? ???*25* : "")["type"] + | (???*42* ? ???*43* : "")["type"] + ) +) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["replace"](" at new ", " at ") + ⚠️ unknown callee object +- *3* ???*4*[g] + ⚠️ unknown object +- *4* ???*5*["split"]("\n") + ⚠️ unknown callee object +- *5* ???*6*["stack"] + ⚠️ unknown object +- *6* l + ⚠️ pattern without value +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* ` +${(???*9* | ???*10* | ???*14* | "")}${(???*18* | ???*20*)}` + ⚠️ nested operation +- *9* La + ⚠️ pattern without value +- *10* ???*11*(/\n( *(at )?)/) + ⚠️ unknown callee +- *11* ???*12*["match"] + ⚠️ unknown object +- *12* ???*13*() + ⚠️ nested operation +- *13* ???["trim"] + ⚠️ unknown object +- *14* ???*15*[1] + ⚠️ unknown object +- *15* ???*16*(/\n( *(at )?)/) + ⚠️ unknown callee +- *16* ???*17*["match"] + ⚠️ unknown object +- *17* ???() + ⚠️ nested operation +- *18* ???*19*["type"] + ⚠️ unknown object +- *19* a + ⚠️ circular variable reference +- *20* (???*21* ? ???*22* : "") + ⚠️ nested operation +- *21* a + ⚠️ circular variable reference +- *22* ???*23*["displayName"] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* ` +${(???*26* | ???*27* | ???*31* | "")}${(???*35* | ???*38*)}` + ⚠️ nested operation +- *26* La + ⚠️ pattern without value +- *27* ???*28*(/\n( *(at )?)/) + ⚠️ unknown callee +- *28* ???*29*["match"] + ⚠️ unknown object +- *29* ???*30*() + ⚠️ nested operation +- *30* ???["trim"] + ⚠️ unknown object +- *31* ???*32*[1] + ⚠️ unknown object +- *32* ???*33*(/\n( *(at )?)/) + ⚠️ unknown callee +- *33* ???*34*["match"] + ⚠️ unknown object +- *34* ???() + ⚠️ nested operation +- *35* ???*36*["render"] + ⚠️ unknown object +- *36* ???*37*["type"] + ⚠️ unknown object +- *37* a + ⚠️ circular variable reference +- *38* (???*39* ? ???*40* : "") + ⚠️ nested operation +- *39* a + ⚠️ circular variable reference +- *40* ???*41*["displayName"] + ⚠️ unknown object +- *41* a + ⚠️ circular variable reference +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* ` +${(???*44* | ???*45* | ???*49* | "")}${(???*53* | ???*55*)}` + ⚠️ nested operation +- *44* La + ⚠️ pattern without value +- *45* ???*46*(/\n( *(at )?)/) + ⚠️ unknown callee +- *46* ???*47*["match"] + ⚠️ unknown object +- *47* ???*48*() + ⚠️ nested operation +- *48* ???["trim"] + ⚠️ unknown object +- *49* ???*50*[1] + ⚠️ unknown object +- *50* ???*51*(/\n( *(at )?)/) + ⚠️ unknown callee +- *51* ???*52*["match"] + ⚠️ unknown object +- *52* ???() + ⚠️ nested operation +- *53* ???*54*["type"] + ⚠️ unknown object +- *54* a + ⚠️ circular variable reference +- *55* (???*56* ? ???*57* : "") + ⚠️ nested operation +- *56* a + ⚠️ circular variable reference +- *57* ???*58*["displayName"] + ⚠️ unknown object +- *58* a + ⚠️ circular variable reference + +0 -> 307 call = (...) => ` +${La}${a}`("Lazy") + +0 -> 308 call = (...) => ` +${La}${a}`("Suspense") + +0 -> 309 call = (...) => ` +${La}${a}`("SuspenseList") + +0 -> 311 call = (...) => ("" | k | (???*0* ? Ma(a) : ""))( + ( + | ???*1* + | ""["type"] + | ` +${???*3*}`["type"] + | (???*8* ? ???*9* : "")["type"] + | (???*25* ? ???*26* : "")["type"] + | (???*43* ? ???*44* : "")["type"] + ), + false +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["replace"](" at new ", " at ") + ⚠️ unknown callee object +- *4* ???*5*[g] + ⚠️ unknown object +- *5* ???*6*["split"]("\n") + ⚠️ unknown callee object +- *6* ???*7*["stack"] + ⚠️ unknown object +- *7* l + ⚠️ pattern without value +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ` +${(???*10* | ???*11* | ???*15* | "")}${(???*19* | ???*21*)}` + ⚠️ nested operation +- *10* La + ⚠️ pattern without value +- *11* ???*12*(/\n( *(at )?)/) + ⚠️ unknown callee +- *12* ???*13*["match"] + ⚠️ unknown object +- *13* ???*14*() + ⚠️ nested operation +- *14* ???["trim"] + ⚠️ unknown object +- *15* ???*16*[1] + ⚠️ unknown object +- *16* ???*17*(/\n( *(at )?)/) + ⚠️ unknown callee +- *17* ???*18*["match"] + ⚠️ unknown object +- *18* ???() + ⚠️ nested operation +- *19* ???*20*["type"] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* (???*22* ? ???*23* : "") + ⚠️ nested operation +- *22* a + ⚠️ circular variable reference +- *23* ???*24*["displayName"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* ` +${(???*27* | ???*28* | ???*32* | "")}${(???*36* | ???*39*)}` + ⚠️ nested operation +- *27* La + ⚠️ pattern without value +- *28* ???*29*(/\n( *(at )?)/) + ⚠️ unknown callee +- *29* ???*30*["match"] + ⚠️ unknown object +- *30* ???*31*() + ⚠️ nested operation +- *31* ???["trim"] + ⚠️ unknown object +- *32* ???*33*[1] + ⚠️ unknown object +- *33* ???*34*(/\n( *(at )?)/) + ⚠️ unknown callee +- *34* ???*35*["match"] + ⚠️ unknown object +- *35* ???() + ⚠️ nested operation +- *36* ???*37*["render"] + ⚠️ unknown object +- *37* ???*38*["type"] + ⚠️ unknown object +- *38* a + ⚠️ circular variable reference +- *39* (???*40* ? ???*41* : "") + ⚠️ nested operation +- *40* a + ⚠️ circular variable reference +- *41* ???*42*["displayName"] + ⚠️ unknown object +- *42* a + ⚠️ circular variable reference +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* ` +${(???*45* | ???*46* | ???*50* | "")}${(???*54* | ???*56*)}` + ⚠️ nested operation +- *45* La + ⚠️ pattern without value +- *46* ???*47*(/\n( *(at )?)/) + ⚠️ unknown callee +- *47* ???*48*["match"] + ⚠️ unknown object +- *48* ???*49*() + ⚠️ nested operation +- *49* ???["trim"] + ⚠️ unknown object +- *50* ???*51*[1] + ⚠️ unknown object +- *51* ???*52*(/\n( *(at )?)/) + ⚠️ unknown callee +- *52* ???*53*["match"] + ⚠️ unknown object +- *53* ???() + ⚠️ nested operation +- *54* ???*55*["type"] + ⚠️ unknown object +- *55* a + ⚠️ circular variable reference +- *56* (???*57* ? ???*58* : "") + ⚠️ nested operation +- *57* a + ⚠️ circular variable reference +- *58* ???*59*["displayName"] + ⚠️ unknown object +- *59* a + ⚠️ circular variable reference + +0 -> 314 call = (...) => ("" | k | (???*0* ? Ma(a) : ""))( + ( + | ???*1* + | ""["type"]["render"] + | ` +${???*4*}`["type"]["render"] + | (???*9* ? ???*10* : "")["type"]["render"] + | (???*26* ? ???*27* : "")["type"]["render"] + | (???*44* ? ???*45* : "")["type"]["render"] + ), + false +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["render"] + ⚠️ unknown object +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["replace"](" at new ", " at ") + ⚠️ unknown callee object +- *5* ???*6*[g] + ⚠️ unknown object +- *6* ???*7*["split"]("\n") + ⚠️ unknown callee object +- *7* ???*8*["stack"] + ⚠️ unknown object +- *8* l + ⚠️ pattern without value +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* ` +${(???*11* | ???*12* | ???*16* | "")}${(???*20* | ???*22*)}` + ⚠️ nested operation +- *11* La + ⚠️ pattern without value +- *12* ???*13*(/\n( *(at )?)/) + ⚠️ unknown callee +- *13* ???*14*["match"] + ⚠️ unknown object +- *14* ???*15*() + ⚠️ nested operation +- *15* ...[...] + ⚠️ unknown object +- *16* ???*17*[1] + ⚠️ unknown object +- *17* ???*18*(/\n( *(at )?)/) + ⚠️ unknown callee +- *18* ???*19*["match"] + ⚠️ unknown object +- *19* ...() + ⚠️ nested operation +- *20* ???*21*["type"] + ⚠️ unknown object +- *21* a + ⚠️ circular variable reference +- *22* (???*23* ? ???*24* : "") + ⚠️ nested operation +- *23* a + ⚠️ circular variable reference +- *24* ???*25*["displayName"] + ⚠️ unknown object +- *25* a + ⚠️ circular variable reference +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ` +${(???*28* | ???*29* | ???*33* | "")}${(???*37* | ???*40*)}` + ⚠️ nested operation +- *28* La + ⚠️ pattern without value +- *29* ???*30*(/\n( *(at )?)/) + ⚠️ unknown callee +- *30* ???*31*["match"] + ⚠️ unknown object +- *31* ???*32*() + ⚠️ nested operation +- *32* ...[...] + ⚠️ unknown object +- *33* ???*34*[1] + ⚠️ unknown object +- *34* ???*35*(/\n( *(at )?)/) + ⚠️ unknown callee +- *35* ???*36*["match"] + ⚠️ unknown object +- *36* ...() + ⚠️ nested operation +- *37* ???*38*["render"] + ⚠️ unknown object +- *38* ???*39*["type"] + ⚠️ unknown object +- *39* a + ⚠️ circular variable reference +- *40* (???*41* ? ???*42* : "") + ⚠️ nested operation +- *41* a + ⚠️ circular variable reference +- *42* ???*43*["displayName"] + ⚠️ unknown object +- *43* a + ⚠️ circular variable reference +- *44* unsupported expression + ⚠️ This value might have side effects +- *45* ` +${(???*46* | ???*47* | ???*51* | "")}${(???*55* | ???*57*)}` + ⚠️ nested operation +- *46* La + ⚠️ pattern without value +- *47* ???*48*(/\n( *(at )?)/) + ⚠️ unknown callee +- *48* ???*49*["match"] + ⚠️ unknown object +- *49* ???*50*() + ⚠️ nested operation +- *50* ...[...] + ⚠️ unknown object +- *51* ???*52*[1] + ⚠️ unknown object +- *52* ???*53*(/\n( *(at )?)/) + ⚠️ unknown callee +- *53* ???*54*["match"] + ⚠️ unknown object +- *54* ...() + ⚠️ nested operation +- *55* ???*56*["type"] + ⚠️ unknown object +- *56* a + ⚠️ circular variable reference +- *57* (???*58* ? ???*59* : "") + ⚠️ nested operation +- *58* a + ⚠️ circular variable reference +- *59* ???*60*["displayName"] + ⚠️ unknown object +- *60* a + ⚠️ circular variable reference + +0 -> 316 call = (...) => ("" | k | (???*0* ? Ma(a) : ""))( + ( + | ???*1* + | ""["type"] + | ` +${???*3*}`["type"] + | (???*8* ? ???*9* : "")["type"] + | (???*25* ? ???*26* : "")["type"] + | (???*43* ? ???*44* : "")["type"] + ), + true +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["replace"](" at new ", " at ") + ⚠️ unknown callee object +- *4* ???*5*[g] + ⚠️ unknown object +- *5* ???*6*["split"]("\n") + ⚠️ unknown callee object +- *6* ???*7*["stack"] + ⚠️ unknown object +- *7* l + ⚠️ pattern without value +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ` +${(???*10* | ???*11* | ???*15* | "")}${(???*19* | ???*21*)}` + ⚠️ nested operation +- *10* La + ⚠️ pattern without value +- *11* ???*12*(/\n( *(at )?)/) + ⚠️ unknown callee +- *12* ???*13*["match"] + ⚠️ unknown object +- *13* ???*14*() + ⚠️ nested operation +- *14* ???["trim"] + ⚠️ unknown object +- *15* ???*16*[1] + ⚠️ unknown object +- *16* ???*17*(/\n( *(at )?)/) + ⚠️ unknown callee +- *17* ???*18*["match"] + ⚠️ unknown object +- *18* ???() + ⚠️ nested operation +- *19* ???*20*["type"] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* (???*22* ? ???*23* : "") + ⚠️ nested operation +- *22* a + ⚠️ circular variable reference +- *23* ???*24*["displayName"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* ` +${(???*27* | ???*28* | ???*32* | "")}${(???*36* | ???*39*)}` + ⚠️ nested operation +- *27* La + ⚠️ pattern without value +- *28* ???*29*(/\n( *(at )?)/) + ⚠️ unknown callee +- *29* ???*30*["match"] + ⚠️ unknown object +- *30* ???*31*() + ⚠️ nested operation +- *31* ???["trim"] + ⚠️ unknown object +- *32* ???*33*[1] + ⚠️ unknown object +- *33* ???*34*(/\n( *(at )?)/) + ⚠️ unknown callee +- *34* ???*35*["match"] + ⚠️ unknown object +- *35* ???() + ⚠️ nested operation +- *36* ???*37*["render"] + ⚠️ unknown object +- *37* ???*38*["type"] + ⚠️ unknown object +- *38* a + ⚠️ circular variable reference +- *39* (???*40* ? ???*41* : "") + ⚠️ nested operation +- *40* a + ⚠️ circular variable reference +- *41* ???*42*["displayName"] + ⚠️ unknown object +- *42* a + ⚠️ circular variable reference +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* ` +${(???*45* | ???*46* | ???*50* | "")}${(???*54* | ???*56*)}` + ⚠️ nested operation +- *45* La + ⚠️ pattern without value +- *46* ???*47*(/\n( *(at )?)/) + ⚠️ unknown callee +- *47* ???*48*["match"] + ⚠️ unknown object +- *48* ???*49*() + ⚠️ nested operation +- *49* ???["trim"] + ⚠️ unknown object +- *50* ???*51*[1] + ⚠️ unknown object +- *51* ???*52*(/\n( *(at )?)/) + ⚠️ unknown callee +- *52* ???*53*["match"] + ⚠️ unknown object +- *53* ???() + ⚠️ nested operation +- *54* ???*55*["type"] + ⚠️ unknown object +- *55* a + ⚠️ circular variable reference +- *56* (???*57* ? ???*58* : "") + ⚠️ nested operation +- *57* a + ⚠️ circular variable reference +- *58* ???*59*["displayName"] + ⚠️ unknown object +- *59* a + ⚠️ circular variable reference + +0 -> 317 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | ???*2* | null["displayName"] | null["name"] | "" | ???*4*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["displayName"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : "ForwardRef") + ⚠️ nested operation +- *5* ("" !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* `ForwardRef(${???*8*})` + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference + +0 -> 320 conditional = ("object" === ???*0*) +- *0* typeof((???*1* | ???*2* | null["displayName"] | null["name"] | "" | ???*4*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["displayName"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : "ForwardRef") + ⚠️ nested operation +- *5* ("" !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* `ForwardRef(${???*8*})` + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference + +320 -> 329 conditional = ("" !== (???*0* | ???*1* | null["displayName"] | null["name"] | "" | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["displayName"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (???*4* ? ???*6* : "ForwardRef") + ⚠️ nested operation +- *4* ("" !== ???*5*) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* `ForwardRef(${???*7*})` + ⚠️ nested operation +- *7* a + ⚠️ circular variable reference + +320 -> 331 conditional = (null !== (???*0* | ""["render"] | ""["displayName"] | null | ""["_payload"])) +- *0* ???*1*["render"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +331 -> 333 call = (...) => ( + | null + | (a["displayName"] || a["name"] || null) + | a + | "Fragment" + | "Portal" + | "Profiler" + | "StrictMode" + | "Suspense" + | "SuspenseList" + | `${(a["displayName"] || "Context")}.Consumer` + | `${(a["_context"]["displayName"] || "Context")}.Provider` + | ???*0* + | Qa(a(b)) +)( + ( + | ???*1* + | null["displayName"]["type"] + | null["name"]["type"] + | ""["type"] + | (???*3* ? ???*5* : "ForwardRef")["type"] + ) +) +- *0* ((null !== b) ? b : (Qa(a["type"]) || "Memo")) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ("" !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* `ForwardRef(${???*6*})` + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference + +320 -> 336 call = (???*0* | ???*1* | null["displayName"] | null["name"] | "" | (???*3* ? ???*5* : "ForwardRef"))( + ( + | ???*7* + | ""["render"] + | (???*9* ? ???*11* : "ForwardRef")["render"] + | ""["displayName"] + | (???*13* ? ???*15* : "ForwardRef")["displayName"] + | null + | ""["_payload"] + | (???*17* ? ???*19* : "ForwardRef")["_payload"] + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["displayName"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* ("" !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* `ForwardRef(${???*6*})` + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["render"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ("" !== ???*10*) + ⚠️ nested operation +- *10* a + ⚠️ circular variable reference +- *11* `ForwardRef(${???*12*})` + ⚠️ nested operation +- *12* a + ⚠️ circular variable reference +- *13* ("" !== ???*14*) + ⚠️ nested operation +- *14* a + ⚠️ circular variable reference +- *15* `ForwardRef(${???*16*})` + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ("" !== ???*18*) + ⚠️ nested operation +- *18* a + ⚠️ circular variable reference +- *19* `ForwardRef(${???*20*})` + ⚠️ nested operation +- *20* a + ⚠️ circular variable reference + +320 -> 337 call = (...) => ( + | null + | (a["displayName"] || a["name"] || null) + | a + | "Fragment" + | "Portal" + | "Profiler" + | "StrictMode" + | "Suspense" + | "SuspenseList" + | `${(a["displayName"] || "Context")}.Consumer` + | `${(a["_context"]["displayName"] || "Context")}.Provider` + | ???*0* + | Qa(a(b)) +)(???*1*) +- *0* ((null !== b) ? b : (Qa(a["type"]) || "Memo")) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* (???*2* | ???*3* | null["displayName"] | null["name"] | "" | (???*5* ? ???*7* : "ForwardRef"))(b) + ⚠️ non-function callee +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["displayName"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* ("" !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* `ForwardRef(${???*8*})` + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference + +0 -> 347 conditional = ("" !== (???*0* | ???*1* | "")) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["render"] + ⚠️ unknown object +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +0 -> 348 call = (...) => ( + | null + | (a["displayName"] || a["name"] || null) + | a + | "Fragment" + | "Portal" + | "Profiler" + | "StrictMode" + | "Suspense" + | "SuspenseList" + | `${(a["displayName"] || "Context")}.Consumer` + | `${(a["_context"]["displayName"] || "Context")}.Provider` + | ???*0* + | Qa(a(b)) +)((???*1* | ""["type"])) +- *0* ((null !== b) ? b : (Qa(a["type"]) || "Memo")) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 349 conditional = ((???*0* | ""["type"]) === ???*2*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["for"]("react.strict_mode") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *3* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 350 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | ""["type"])) + ⚠️ nested operation +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 356 member call = (???*0* | ???*1*)["toLowerCase"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeName"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +0 -> 357 call = (...) => (???*0* && ("input" === a["toLowerCase"]()) && (("checkbox" === b) || ("radio" === b)))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 358 conditional = (???*0* | ("input" === ???*1*) | ("checkbox" === ???*4*) | ("radio" === ???*6*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*() + ⚠️ nested operation +- *2* ???*3*["toLowerCase"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["type"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["type"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 360 free var = FreeVar(Object) + +0 -> 363 member call = ???*0*["getOwnPropertyDescriptor"](???*1*, ((???*4* | ???*5*) ? "checked" : "value")) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object +- *2* ???*3*["constructor"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* ("input" === ???*6*) + ⚠️ nested operation +- *6* ???*7*() + ⚠️ nested operation +- *7* ???*8*["toLowerCase"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 366 member call = ???*0*["hasOwnProperty"](((???*1* | ???*2*) ? "checked" : "value")) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ("input" === ???*3*) + ⚠️ nested operation +- *3* ???*4*() + ⚠️ nested operation +- *4* ???*5*["toLowerCase"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 369 conditional = (!(???*0*) | ("undefined" !== ???*2*) | ("function" === ???*5*)) +- *0* ???*1*["hasOwnProperty"](b) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* typeof(???*3*) + ⚠️ nested operation +- *3* ???*4*["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* typeof(???*6*) + ⚠️ nested operation +- *6* ???*7*["get"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +369 -> 373 free var = FreeVar(Object) + +369 -> 375 member call = ???*0*["call"](???*3*) +- *0* ???*1*["get"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +369 -> 377 member call = ???*0*["call"](???*3*, ???*4*) +- *0* ???*1*["set"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +369 -> 378 member call = ???*0*["defineProperty"]( + ???*1*, + ((???*2* | ???*3*) ? "checked" : "value"), + {"configurable": true, "get": (...) => e["call"](???*7*), "set": (...) => undefined} +) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ("input" === ???*4*) + ⚠️ nested operation +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toLowerCase"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +369 -> 380 free var = FreeVar(Object) + +369 -> 382 member call = ???*0*["defineProperty"](???*1*, ((???*2* | ???*3*) ? "checked" : "value"), {"enumerable": ???*7*}) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ("input" === ???*4*) + ⚠️ nested operation +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toLowerCase"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*["enumerable"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???*9*["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *9* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 387 call = (...) => ( + | undefined + | { + "getValue": *anonymous function 10089*, + "setValue": *anonymous function 10119*, + "stopTracking": *anonymous function 10152* + } +)(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 390 member call = ( + | ???*0* + | ""["_valueTracker"] + | ((???*2* | ???*3*) ? ???*7* : ???*10*)["_valueTracker"] +)["getValue"]() +- *0* ???*1*["_valueTracker"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ("input" === ???*4*) + ⚠️ nested operation +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toLowerCase"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* (???*8* ? "true" : "false") + ⚠️ nested operation +- *8* ???*9*["checked"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["value"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference + +0 -> 391 call = (...) => (???*0* && ("input" === a["toLowerCase"]()) && (("checkbox" === b) || ("radio" === b)))( + (???*1* | "" | ((???*2* | ???*3*) ? ???*7* : ???*10*)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ("input" === ???*4*) + ⚠️ nested operation +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toLowerCase"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* (???*8* ? "true" : "false") + ⚠️ nested operation +- *8* ???*9*["checked"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["value"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference + +0 -> 392 conditional = ( + | ???*0* + | ("input" === ???*1*) + | ("checkbox" === (???*4* | ""["type"])) + | ("radio" === (???*6* | ""["type"])) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*() + ⚠️ nested operation +- *2* ???*3*["toLowerCase"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["type"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["type"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +392 -> 394 conditional = (???*0* | ""["checked"] | ((???*2* | ???*3*) ? ???*7* : ???*10*)["checked"]) +- *0* ???*1*["checked"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ("input" === ???*4*) + ⚠️ nested operation +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toLowerCase"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* (???*8* ? "true" : "false") + ⚠️ nested operation +- *8* ???*9*["checked"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["value"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference + +0 -> 396 conditional = ((???*0* | "" | ???*1*) !== ???*12*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ((???*2* | ???*3*) ? ???*7* : ???*10*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ("input" === ???*4*) + ⚠️ nested operation +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toLowerCase"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* (???*8* ? "true" : "false") + ⚠️ nested operation +- *8* ???*9*["checked"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["value"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* ???*13*() + ⚠️ nested operation +- *13* ???*14*["getValue"] + ⚠️ unknown object +- *14* ???*15*["_valueTracker"] + ⚠️ unknown object +- *15* arguments[0] + ⚠️ function calls are not analysed yet + +396 -> 398 member call = ( + | ???*0* + | ""["_valueTracker"] + | ((???*2* | ???*3*) ? ???*7* : ???*10*)["_valueTracker"] +)["setValue"]( + (???*12* | "" | ((???*13* | ???*14*) ? ???*18* : ???*21*)) +) +- *0* ???*1*["_valueTracker"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ("input" === ???*4*) + ⚠️ nested operation +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toLowerCase"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* (???*8* ? "true" : "false") + ⚠️ nested operation +- *8* ???*9*["checked"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["value"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* ("input" === ???*15*) + ⚠️ nested operation +- *15* ???*16*() + ⚠️ nested operation +- *16* ???*17*["toLowerCase"] + ⚠️ unknown object +- *17* a + ⚠️ circular variable reference +- *18* (???*19* ? "true" : "false") + ⚠️ nested operation +- *19* ???*20*["checked"] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* ???*22*["value"] + ⚠️ unknown object +- *22* a + ⚠️ circular variable reference + +0 -> 399 free var = FreeVar(document) + +0 -> 400 conditional = ("undefined" !== ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +400 -> 401 free var = FreeVar(document) + +0 -> 406 conditional = (null != ???*0*) +- *0* ???*1*["checked"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 409 call = ???*0*( + {}, + ???*2*, + { + "defaultChecked": ???*3*, + "defaultValue": ???*4*, + "value": ???*5*, + "checked": (???*6* ? ???*9* : ???*11*) + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (null != ???*7*) + ⚠️ nested operation +- *7* ???*8*["checked"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["checked"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["initialChecked"] + ⚠️ unknown object +- *12* ???*13*["_wrapperState"] + ⚠️ unknown object +- *13* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 411 conditional = (null == ???*0*) +- *0* ???*1*["defaultValue"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 414 conditional = (null != ???*0*) +- *0* ???*1*["checked"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 418 conditional = (null != ???*0*) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 420 call = (...) => (undefined | a | "")((???*0* ? ???*3* : (???*5* | undefined | ""))) +- *0* (null != ???*1*) + ⚠️ nested operation +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["value"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* (???*6* ? "" : ???*9*) + ⚠️ nested operation +- *6* (null == ???*7*) + ⚠️ nested operation +- *7* ???*8*["defaultValue"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["defaultValue"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 424 conditional = (("checkbox" === ???*0*) | ("radio" === ???*2*)) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 428 call = (...) => undefined(???*0*, "checked", (???*1* | ???*2*), false) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["checked"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference + +0 -> 429 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 431 call = (...) => (undefined | a | "")(???*0*) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 433 conditional = (null != (undefined | ???*0* | "")) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +433 -> 434 conditional = ("number" === ???*0*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +434 -> 437 conditional = ((0 === (undefined | ???*0* | "")) | ("" === ???*2*) | (???*4* != (undefined | ???*6* | ""))) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["value"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["value"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["value"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet + +433 -> 441 conditional = (("submit" === ???*0*) | ("reset" === ???*2*)) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +441 -> 443 member call = ???*0*["removeAttribute"]("value") +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 445 member call = ???*0*["hasOwnProperty"]("value") +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 446 conditional = ???*0* +- *0* ???*1*["hasOwnProperty"]("value") + ⚠️ unknown callee object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +446 -> 448 call = (...) => undefined(???*0*, ???*1*, (undefined | ???*3* | "")) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["value"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +446 -> 450 member call = ???*0*["hasOwnProperty"]("defaultValue") +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +446 -> 453 call = (...) => (undefined | a | "")(???*0*) +- *0* ???*1*["defaultValue"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +446 -> 454 call = (...) => undefined(???*0*, ???*1*, (undefined | ???*3* | "")) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["defaultValue"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 460 member call = (???*0* | ???*1*)["hasOwnProperty"]("value") +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["initialValue"] + ⚠️ unknown object +- *2* ???*3*["_wrapperState"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 462 member call = (???*0* | ???*1*)["hasOwnProperty"]("defaultValue") +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["initialValue"] + ⚠️ unknown object +- *2* ???*3*["_wrapperState"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 463 conditional = ???*0* +- *0* ???*1*["hasOwnProperty"]("value") + ⚠️ unknown callee object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 479 call = (...) => (undefined | null | (a["activeElement"] || a["body"]) | a["body"])(???*0*) +- *0* ???*1*["ownerDocument"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 480 conditional = (("number" !== ???*0*) | ((undefined | null | ???*1*) !== ???*4*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["activeElement"] + ⚠️ unknown object +- *2* ???*3*["ownerDocument"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +480 -> 481 conditional = (null == ???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 488 free var = FreeVar(Array) + +0 -> 490 conditional = (???*0* | {} | null | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*[(0 | ???*3* | ???*4*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* ???*5*["hasOwnProperty"](`$${a[c]["value"]}`) + ⚠️ unknown callee object +- *5* b + ⚠️ circular variable reference + +490 -> 498 member call = (???*0* | {} | null | ???*1*)["hasOwnProperty"](`$${???*6*}`) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*[(0 | ???*3* | ???*4*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* ???*5*["hasOwnProperty"](`$${a[c]["value"]}`) + ⚠️ unknown callee object +- *5* b + ⚠️ circular variable reference +- *6* ???*7*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*[(???*9* | 0 | ???*10* | undefined | ???*11* | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* updated with update expression + ⚠️ This value might have side effects +- *11* c + ⚠️ circular variable reference + +490 -> 505 call = (...) => (undefined | a | "")((???*0* | 0 | ???*1* | undefined | ???*2* | "")) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects +- *2* c + ⚠️ circular variable reference + +490 -> 509 conditional = (???*0* === (???*16* | 0 | ???*17* | undefined | ???*18* | "")) +- *0* ???*1*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3* | ???*4* | ???*8* | null["hasOwnProperty"](???*13*))] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* ???*5*["hasOwnProperty"](`$${???*6*}`) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???[(??? | 0 | ??? | undefined | ??? | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* (???*9* | ???*10*)(`$${???*11*}`) + ⚠️ non-function callee + ⚠️ This value might have side effects +- *9* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unknown mutation + ⚠️ This value might have side effects +- *11* ???*12*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* ???[(??? | 0 | ??? | undefined | ??? | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* `$${???*14*}` + ⚠️ nested operation +- *14* ???*15*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *15* ???[(??? | 0 | ??? | undefined | ??? | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* arguments[2] + ⚠️ function calls are not analysed yet +- *17* updated with update expression + ⚠️ This value might have side effects +- *18* c + ⚠️ circular variable reference + +0 -> 519 conditional = (null != ???*0*) +- *0* ???*1*["dangerouslySetInnerHTML"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +519 -> 520 free var = FreeVar(Error) + +519 -> 521 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(91) + +519 -> 522 call = ???*0*( + `Minified React error #${91}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${91}` + ⚠️ nested operation + +0 -> 525 call = ???*0*( + {}, + ???*2*, + {"value": ???*3*, "defaultValue": ???*4*, "children": ???*5*} +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* ???*6*["initialValue"] + ⚠️ unknown object +- *6* ???*7*["_wrapperState"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 527 conditional = (null == (???*0* | ""["value"] | ""["children"] | ???*2* | ???*3* | "")) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* c + ⚠️ circular variable reference + +527 -> 530 conditional = (null != (???*0* | ""["value"] | ""["children"] | ???*2* | ???*3* | "")) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* c + ⚠️ circular variable reference + +530 -> 531 conditional = (null != (???*0* | ???*1* | ???*3* | "")) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["defaultValue"] + ⚠️ unknown object +- *2* b + ⚠️ circular variable reference +- *3* b + ⚠️ circular variable reference + +531 -> 532 free var = FreeVar(Error) + +531 -> 533 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(92) + +531 -> 534 call = ???*0*( + `Minified React error #${92}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${92}` + ⚠️ nested operation + +530 -> 535 call = ???*0*( + (???*2* | ""["value"] | ""["children"] | ???*4* | ???*5* | "") +) +- *0* ???*1*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["value"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* c + ⚠️ circular variable reference + +530 -> 536 conditional = ???*0* +- *0* ???*1*(c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +536 -> 538 free var = FreeVar(Error) + +536 -> 539 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(93) + +536 -> 540 call = ???*0*( + `Minified React error #${93}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${93}` + ⚠️ nested operation + +0 -> 543 call = (...) => (undefined | a | "")( + (???*0* | ""["value"] | ""["children"] | ???*2* | ???*3* | "") +) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* c + ⚠️ circular variable reference + +0 -> 545 call = (...) => (undefined | a | "")(???*0*) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 547 call = (...) => (undefined | a | "")(???*0*) +- *0* ???*1*["defaultValue"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 558 conditional = ((null == ???*0*) | ("http://www.w3.org/1999/xhtml" === ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +558 -> 559 call = (...) => ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" +)(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +558 -> 560 conditional = (("http://www.w3.org/2000/svg" === ???*0*) | ("foreignObject" === ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 561 free var = FreeVar(MSApp) + +0 -> 563 free var = FreeVar(MSApp) + +0 -> 564 conditional = (("undefined" !== ???*0*) | ???*2*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(MSApp) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["execUnsafeLocalFunction"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(MSApp) + ⚠️ unknown global + ⚠️ This value might have side effects + +564 -> 566 free var = FreeVar(MSApp) + +564 -> 567 member call = ???*0*["execUnsafeLocalFunction"]((...) => a(b, c, d, e)) +- *0* FreeVar(MSApp) + ⚠️ unknown global + ⚠️ This value might have side effects + +567 -> 568 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 570 conditional = (("http://www.w3.org/2000/svg" !== ???*0*) | ???*2*) +- *0* ???*1*["namespaceURI"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +570 -> 573 free var = FreeVar(document) + +570 -> 574 member call = ???*0*["createElement"]("div") +- *0* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +570 -> 578 member call = (???*0* | ???*1* | ???*3*)["valueOf"]() +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["firstChild"] + ⚠️ unknown object +- *2* mb + ⚠️ pattern without value +- *3* ???*4*["firstChild"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +570 -> 579 member call = (???*0*() | ???*2*())["toString"]() +- *0* ???*1*["valueOf"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["valueOf"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["firstChild"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +570 -> 584 member call = ???*0*["removeChild"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["firstChild"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +570 -> 588 member call = ???*0*["appendChild"]((???*1* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["firstChild"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["firstChild"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["firstChild"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *6* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 589 conditional = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +589 -> 593 conditional = (???*0* | (???*2* === ???*4*) | (3 === ???*6*)) +- *0* ???*1*["firstChild"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["firstChild"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["lastChild"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["nodeType"] + ⚠️ unknown object +- *7* ???*8*["firstChild"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 598 free var = FreeVar(Object) + +0 -> 599 member call = ???*0*["keys"]( + { + "animationIterationCount": true, + "aspectRatio": true, + "borderImageOutset": true, + "borderImageSlice": true, + "borderImageWidth": true, + "boxFlex": true, + "boxFlexGroup": true, + "boxOrdinalGroup": true, + "columnCount": true, + "columns": true, + "flex": true, + "flexGrow": true, + "flexPositive": true, + "flexShrink": true, + "flexNegative": true, + "flexOrder": true, + "gridArea": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowSpan": true, + "gridRowStart": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnSpan": true, + "gridColumnStart": true, + "fontWeight": true, + "lineClamp": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "tabSize": true, + "widows": true, + "zIndex": true, + "zoom": true, + "fillOpacity": true, + "floodOpacity": true, + "stopOpacity": true, + "strokeDasharray": true, + "strokeDashoffset": true, + "strokeMiterlimit": true, + "strokeOpacity": true, + "strokeWidth": true + } +) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 600 member call = ???*0*["forEach"]((...) => undefined) +- *0* ???*1*["keys"](pb) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +600 -> 602 member call = ["Webkit", "ms", "Moz", "O"]["forEach"]((...) => undefined) + +602 -> 605 member call = ???*0*["charAt"](0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +602 -> 606 member call = ???*0*["toUpperCase"]() +- *0* ???*1*["charAt"](0) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +602 -> 608 member call = ???*0*["substring"](1) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 611 conditional = ((null == ???*0*) | ("boolean" === ???*1*) | ("" === ???*3*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +611 -> 613 member call = { + "animationIterationCount": true, + "aspectRatio": true, + "borderImageOutset": true, + "borderImageSlice": true, + "borderImageWidth": true, + "boxFlex": true, + "boxFlexGroup": true, + "boxOrdinalGroup": true, + "columnCount": true, + "columns": true, + "flex": true, + "flexGrow": true, + "flexPositive": true, + "flexShrink": true, + "flexNegative": true, + "flexOrder": true, + "gridArea": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowSpan": true, + "gridRowStart": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnSpan": true, + "gridColumnStart": true, + "fontWeight": true, + "lineClamp": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "tabSize": true, + "widows": true, + "zIndex": true, + "zoom": true, + "fillOpacity": true, + "floodOpacity": true, + "stopOpacity": true, + "strokeDasharray": true, + "strokeDashoffset": true, + "strokeMiterlimit": true, + "strokeOpacity": true, + "strokeWidth": true +}["hasOwnProperty"](???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +611 -> 615 conditional = (???*0* | ("number" !== ???*1*) | (0 === ???*3*) | ???*4* | true | ???*8*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* (???*5* | ???*6*)(???*7*) + ⚠️ non-function callee +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* {}[???*9*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *9* arguments[0] + ⚠️ function calls are not analysed yet + +615 -> 617 member call = ???*0*["trim"]() +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 620 member call = ???*0*["hasOwnProperty"]((???*1* | "cssFloat")) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* c + ⚠️ pattern without value + +0 -> 621 conditional = ???*0* +- *0* ???*1*["hasOwnProperty"](c) + ⚠️ unknown callee object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +621 -> 623 member call = (???*0* | "cssFloat")["indexOf"]("--") +- *0* c + ⚠️ pattern without value + +621 -> 625 call = (...) => (((null == b) || ("boolean" === typeof(b)) || ("" === b)) ? "" : ((c || ("number" !== typeof(b)) || (0 === b) || (pb["hasOwnProperty"](a) && pb[a])) ? `${b}`["trim"]() : `${b}px`))((???*0* | "cssFloat"), ???*1*, (0 === (???*3* | ???*5*))) +- *0* c + ⚠️ pattern without value +- *1* ???*2*[c] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["indexOf"]("--") + ⚠️ unknown callee object +- *4* c + ⚠️ pattern without value +- *5* "cssFloat"["indexOf"]("--") + ⚠️ nested operation + +621 -> 626 conditional = (0 === (???*0* | ???*2*)) +- *0* ???*1*["indexOf"]("--") + ⚠️ unknown callee object +- *1* c + ⚠️ pattern without value +- *2* "cssFloat"["indexOf"]("--") + ⚠️ nested operation + +626 -> 628 member call = (???*0* | ???*1*)["setProperty"]((???*3* | "cssFloat"), ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["style"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* c + ⚠️ pattern without value +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 630 call = ???*0*( + {"menuitem": true}, + { + "area": true, + "base": true, + "br": true, + "col": true, + "embed": true, + "hr": true, + "img": true, + "input": true, + "keygen": true, + "link": true, + "meta": true, + "param": true, + "source": true, + "track": true, + "wbr": true + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 631 conditional = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +631 -> 635 conditional = (???*0* | (null != ???*4*)) +- *0* ???*1*[a] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*( + {"menuitem": !(0)}, + { + "area": !(0), + "base": !(0), + "br": !(0), + "col": !(0), + "embed": !(0), + "hr": !(0), + "img": !(0), + "input": !(0), + "keygen": !(0), + "link": !(0), + "meta": !(0), + "param": !(0), + "source": !(0), + "track": !(0), + "wbr": !(0) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* ???*3*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["children"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet + +635 -> 636 free var = FreeVar(Error) + +635 -> 637 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(137, ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +635 -> 638 call = ???*0*( + `Minified React error #${137}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${137}` + ⚠️ nested operation + +631 -> 640 conditional = (null != ???*0*) +- *0* ???*1*["dangerouslySetInnerHTML"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +640 -> 642 conditional = (null != ???*0*) +- *0* ???*1*["children"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +642 -> 643 free var = FreeVar(Error) + +642 -> 644 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(60) + +642 -> 645 call = ???*0*( + `Minified React error #${60}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${60}` + ⚠️ nested operation + +640 -> 648 conditional = (("object" !== ???*0*) | !(???*3*)) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* ???*2*["dangerouslySetInnerHTML"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects + +648 -> 649 free var = FreeVar(Error) + +648 -> 650 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(61) + +648 -> 651 call = ???*0*( + `Minified React error #${61}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${61}` + ⚠️ nested operation + +631 -> 654 conditional = ((null != ???*0*) | ("object" !== ???*2*)) +- *0* ???*1*["style"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* typeof(???*3*) + ⚠️ nested operation +- *3* ???*4*["style"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +654 -> 655 free var = FreeVar(Error) + +654 -> 656 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(62) + +654 -> 657 call = ???*0*( + `Minified React error #${62}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${62}` + ⚠️ nested operation + +0 -> 659 member call = ???*0*["indexOf"]("-") +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 660 conditional = (???*0* === ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["indexOf"]("-") + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 664 free var = FreeVar(window) + +0 -> 668 conditional = (3 === (???*0* | ???*2*)) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 670 call = (...) => (( + || !(a) + || ((5 !== a["tag"]) && (6 !== a["tag"]) && (13 !== a["tag"]) && (3 !== a["tag"])) +) ? null : a)((???*0* | (???*1* ? null : (???*5* | ???*6*)))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* !((???*2* | ???*3*)) + ⚠️ nested operation +- *2* a + ⚠️ circular variable reference +- *3* ???*4*[Of] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* a + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference + +0 -> 671 conditional = ("function" !== ???*0*) +- *0* typeof((null | (...) => undefined)) + ⚠️ nested operation + +671 -> 672 free var = FreeVar(Error) + +671 -> 673 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(280) + +671 -> 674 call = ???*0*( + `Minified React error #${280}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${280}` + ⚠️ nested operation + +0 -> 676 call = (...) => (a[Pf] || null)( + (???*0* | (???*2* ? null : (???*6* | ???*7*))["stateNode"] | null) +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* !((???*3* | ???*4*)) + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* ???*5*[Of] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* a + ⚠️ circular variable reference +- *7* ???*8*[Of] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference + +0 -> 679 call = (null | (...) => undefined)( + (???*0* | (???*2* ? null : (???*6* | ???*7*))["stateNode"]), + (???*9* | (???*11* ? null : (???*15* | ???*16*))["type"]), + ( + | ???*18* + | (???*20* ? null : (???*24* | ???*25*))["stateNode"] + | null + ) +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* !((???*3* | ???*4*)) + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* ???*5*[Of] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* a + ⚠️ circular variable reference +- *7* ???*8*[Of] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* !((???*12* | ???*13*)) + ⚠️ nested operation +- *12* a + ⚠️ circular variable reference +- *13* ???*14*[Of] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* a + ⚠️ circular variable reference +- *16* ???*17*[Of] + ⚠️ unknown object +- *17* a + ⚠️ circular variable reference +- *18* ???*19*["stateNode"] + ⚠️ unknown object +- *19* arguments[0] + ⚠️ function calls are not analysed yet +- *20* !((???*21* | ???*22*)) + ⚠️ nested operation +- *21* a + ⚠️ circular variable reference +- *22* ???*23*[Of] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference +- *24* a + ⚠️ circular variable reference +- *25* ???*26*[Of] + ⚠️ unknown object +- *26* a + ⚠️ circular variable reference + +0 -> 680 conditional = (null | ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +680 -> 681 conditional = (null | [???*0*] | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +681 -> 683 member call = (null | [???*0*] | ???*1*)["push"](???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 684 conditional = (null | ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +684 -> 685 call = (...) => undefined((null | ???*0* | 0 | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +684 -> 686 conditional = (null | [???*0*] | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +686 -> 689 call = (...) => undefined( + (null[(null | ???*0* | 0 | ???*1*)] | ???*2* | ???*4* | ???*5* | ???*7* | ???*8*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects +- *2* [???*3*][null] + ⚠️ non-num constant property on array +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* [][???*6*] + ⚠️ unknown array prototype methods or values +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unknown mutation + ⚠️ This value might have side effects +- *8* ???*9*[(null | ???*10* | 0 | ???*11*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* updated with update expression + ⚠️ This value might have side effects + +0 -> 690 call = ???*0*(???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 691 conditional = (false | true) + +691 -> 692 call = ???*0*(???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 693 call = ((...) => a(b) | (...) => (undefined | a(b)))(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 694 call = ((...) => undefined | (...) => (undefined | a()))() + +0 -> 695 call = (...) => undefined() + +0 -> 697 call = (...) => (a[Pf] || null)( + ( + | ???*0* + | !((???*2* | null | ???*4*))["stateNode"] + | false["stateNode"] + | null[???*7*] + | !(???*8*)[???*10*] + | !(???*11*)[???*17*] + ) +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*[Pf] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference +- *4* !(???*5*) + ⚠️ nested operation +- *5* ???*6*["disabled"] + ⚠️ unknown object +- *6* d + ⚠️ circular variable reference +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???*9*["disabled"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ("button" === (???*12* | ???*13* | ???*15* | false)) + ⚠️ nested operation +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* ???*14*["type"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* !(???*16*) + ⚠️ nested operation +- *16* d + ⚠️ circular variable reference +- *17* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 701 conditional = ( + | ???*0* + | !((???*2* | null | ???*4*))["stateNode"] + | false["stateNode"] + | null[???*7*] + | !(???*8*)[???*10*] + | !(???*11*)[???*17*] + | ("function" !== ???*18*) +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*[Pf] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference +- *4* !(???*5*) + ⚠️ nested operation +- *5* ???*6*["disabled"] + ⚠️ unknown object +- *6* d + ⚠️ circular variable reference +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???*9*["disabled"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ("button" === (???*12* | ???*13* | ???*15* | false)) + ⚠️ nested operation +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* ???*14*["type"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* !(???*16*) + ⚠️ nested operation +- *16* d + ⚠️ circular variable reference +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* typeof((???*19* | false["stateNode"] | null[???*21*])) + ⚠️ nested operation +- *19* ???*20*["stateNode"] + ⚠️ unknown object +- *20* arguments[0] + ⚠️ function calls are not analysed yet +- *21* arguments[1] + ⚠️ function calls are not analysed yet + +701 -> 702 free var = FreeVar(Error) + +701 -> 703 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`( + 231, + ???*0*, + typeof((???*1* | false["stateNode"] | null[???*3*])) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +701 -> 704 call = ???*0*( + `Minified React error #${231}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${231}` + ⚠️ nested operation + +0 -> 705 conditional = !(???*0*) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +705 -> 707 free var = FreeVar(Object) + +705 -> 708 member call = ???*0*["defineProperty"]({}, "passive", {"get": (...) => undefined}) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +705 -> 710 free var = FreeVar(window) + +705 -> 711 member call = ???*0*["addEventListener"]("test", {}, {}) +- *0* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +705 -> 713 free var = FreeVar(window) + +705 -> 714 member call = ???*0*["removeEventListener"]("test", {}, {}) +- *0* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 718 free var = FreeVar(Array) + +0 -> 719 free var = FreeVar(arguments) + +0 -> 720 member call = ???*0*["call"](???*3*, 3) +- *0* ???*1*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 722 member call = ???*0*["apply"](???*1*, ???*2*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["call"](FreeVar(arguments), 3) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *3* ???*4*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 724 member call = ???*0*["onError"](???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* m + ⚠️ pattern without value + +0 -> 726 free var = FreeVar(arguments) + +0 -> 727 member call = (...) => undefined["apply"]({"onError": (...) => undefined}, ???*0*) +- *0* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 729 free var = FreeVar(arguments) + +0 -> 730 member call = (...) => undefined["apply"](???*0*, ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 731 conditional = (false | true) + +731 -> 732 conditional = (false | true) + +732 -> 733 free var = FreeVar(Error) + +732 -> 734 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(198) + +732 -> 735 call = ???*0*( + `Minified React error #${198}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${198}` + ⚠️ nested operation + +0 -> 737 conditional = ???*0* +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 744 conditional = (3 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 746 conditional = (13 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +746 -> 750 conditional = (null !== ???*0*) +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 752 call = (...) => ((3 === b["tag"]) ? c : null)(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 753 conditional = (???*0* !== ???*8*) +- *0* (???*1* ? (???*4* | ???*5* | ???*6*) : null) + ⚠️ nested operation +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["return"] + ⚠️ unknown object +- *7* b + ⚠️ circular variable reference +- *8* arguments[0] + ⚠️ function calls are not analysed yet + +753 -> 754 free var = FreeVar(Error) + +753 -> 755 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(188) + +753 -> 756 call = ???*0*( + `Minified React error #${188}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${188}` + ⚠️ nested operation + +0 -> 758 conditional = !((???*0* | ???*2*)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? (???*6* | ???*7* | ???*8*) : null) + ⚠️ nested operation +- *3* (3 === ???*4*) + ⚠️ nested operation +- *4* ???*5*["tag"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["return"] + ⚠️ unknown object +- *9* b + ⚠️ circular variable reference + +758 -> 759 call = (...) => ((3 === b["tag"]) ? c : null)(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +758 -> 760 conditional = (null === (???*0* | ???*2*)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? (???*6* | ???*7* | ???*8*) : null) + ⚠️ nested operation +- *3* (3 === ???*4*) + ⚠️ nested operation +- *4* ???*5*["tag"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["return"] + ⚠️ unknown object +- *9* b + ⚠️ circular variable reference + +760 -> 761 free var = FreeVar(Error) + +760 -> 762 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(188) + +760 -> 763 call = ???*0*( + `Minified React error #${188}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${188}` + ⚠️ nested operation + +758 -> 764 conditional = ((???*0* | ???*2*) !== ???*10*) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? (???*6* | ???*7* | ???*8*) : null) + ⚠️ nested operation +- *3* (3 === ???*4*) + ⚠️ nested operation +- *4* ???*5*["tag"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["return"] + ⚠️ unknown object +- *9* b + ⚠️ circular variable reference +- *10* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 767 conditional = (null === ???*0*) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 771 conditional = (???*0* === ???*3*) +- *0* ???*1*["child"] + ⚠️ unknown object +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["child"] + ⚠️ unknown object +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* ???*6*["return"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +771 -> 773 conditional = (???*0* === (???*3* | ???*4* | ???*6*)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* (???*7* ? (???*10* | ???*11* | ???*12*) : null) + ⚠️ nested operation +- *7* (3 === ???*8*) + ⚠️ nested operation +- *8* ???*9*["tag"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* a + ⚠️ circular variable reference +- *12* ???*13*["return"] + ⚠️ unknown object +- *13* b + ⚠️ circular variable reference + +773 -> 774 call = (...) => undefined( + ( + | ???*0* + | (???*2* ? (???*5* | ???*6* | ???*7*) : null)["return"] + ) +) +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (3 === ???*3*) + ⚠️ nested operation +- *3* ???*4*["tag"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["return"] + ⚠️ unknown object +- *8* b + ⚠️ circular variable reference + +771 -> 775 conditional = (???*0* === (???*3* | ???*5*)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* (???*6* ? (???*9* | ???*10* | ???*11*) : null) + ⚠️ nested operation +- *6* (3 === ???*7*) + ⚠️ nested operation +- *7* ???*8*["tag"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["return"] + ⚠️ unknown object +- *12* b + ⚠️ circular variable reference + +775 -> 776 call = (...) => undefined( + ( + | ???*0* + | (???*2* ? (???*5* | ???*6* | ???*7*) : null)["return"] + ) +) +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (3 === ???*3*) + ⚠️ nested operation +- *3* ???*4*["tag"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["return"] + ⚠️ unknown object +- *8* b + ⚠️ circular variable reference + +771 -> 778 free var = FreeVar(Error) + +771 -> 779 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(188) + +771 -> 780 call = ???*0*( + `Minified React error #${188}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${188}` + ⚠️ nested operation + +0 -> 783 conditional = (???*0* !== ???*2*) +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["return"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +783 -> 786 conditional = !((false | true)) + +786 -> 789 conditional = !((false | true)) + +789 -> 790 free var = FreeVar(Error) + +789 -> 791 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(189) + +789 -> 792 call = ???*0*( + `Minified React error #${189}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${189}` + ⚠️ nested operation + +0 -> 794 conditional = (???*0* !== (???*2* | ???*4*)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* (???*5* ? (???*8* | ???*9* | ???*10*) : null) + ⚠️ nested operation +- *5* (3 === ???*6*) + ⚠️ nested operation +- *6* ???*7*["tag"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["return"] + ⚠️ unknown object +- *11* b + ⚠️ circular variable reference + +794 -> 795 free var = FreeVar(Error) + +794 -> 796 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(190) + +794 -> 797 call = ???*0*( + `Minified React error #${190}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${190}` + ⚠️ nested operation + +0 -> 799 conditional = (3 !== ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +799 -> 800 free var = FreeVar(Error) + +799 -> 801 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(188) + +799 -> 802 call = ???*0*( + `Minified React error #${188}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${188}` + ⚠️ nested operation + +0 -> 805 conditional = (???*0* === (???*3* | ???*4* | ???*6*)) +- *0* ???*1*["current"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* (???*7* ? (???*10* | ???*11* | ???*12*) : null) + ⚠️ nested operation +- *7* (3 === ???*8*) + ⚠️ nested operation +- *8* ???*9*["tag"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* a + ⚠️ circular variable reference +- *12* ???*13*["return"] + ⚠️ unknown object +- *13* b + ⚠️ circular variable reference + +0 -> 806 call = (...) => (((b !== a) ? null : a) | a | b | ((c["stateNode"]["current"] === c) ? a : b))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 807 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +807 -> 808 call = (...) => (a | b | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 812 call = (...) => (a | b | null)((???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +0 -> 826 conditional = (null | ???*0* | ("function" === ???*1*)) +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* typeof((null["onCommitFiberRoot"] | ???*2*)) + ⚠️ nested operation +- *2* ???*3*["onCommitFiberRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects + +826 -> 830 member call = (null | ???*0*)["onCommitFiberRoot"]((null | ???*1*), ???*3*, ???*4*, (128 === ???*5*)) +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["inject"](vl) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +0 -> 832 free var = FreeVar(Math) + +0 -> 833 conditional = ???*0* +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +833 -> 835 free var = FreeVar(Math) + +0 -> 837 free var = FreeVar(Math) + +0 -> 839 free var = FreeVar(Math) + +0 -> 840 conditional = (0 === (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +840 -> 841 call = ???*0*((???*2* | ???*3*)) +- *0* ???*1*["log"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 845 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +845 -> 846 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +846 -> 847 call = (...) => (undefined | 1 | 2 | 4 | 8 | 16 | 32 | ???*0* | 134217728 | 268435456 | 536870912 | 1073741824 | a)(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +846 -> 848 call = (...) => (undefined | 1 | 2 | 4 | 8 | 16 | 32 | ???*0* | 134217728 | 268435456 | 536870912 | 1073741824 | a)((???*1* | ???*3* | ???*4*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["pingedLanes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +845 -> 849 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +849 -> 850 call = (...) => (undefined | 1 | 2 | 4 | 8 | 16 | 32 | ???*0* | 134217728 | 268435456 | 536870912 | 1073741824 | a)(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +849 -> 851 call = (...) => (undefined | 1 | 2 | 4 | 8 | 16 | 32 | ???*0* | 134217728 | 268435456 | 536870912 | 1073741824 | a)((???*1* | ???*3* | ???*4*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["pingedLanes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +0 -> 853 conditional = (0 !== (???*0* | ???*1* | ???*3*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["entangledLanes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects + +853 -> 855 call = (???*0* ? ???*2* : (...) => ???*4*)((???*6* | ???*7* | ???*9*)) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["entangledLanes"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 861 call = (???*0* ? ???*2* : (...) => ???*4*)((???*6* | ???*8*)) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*["pendingLanes"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 863 conditional = (???*0* === ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*[g] + ⚠️ unknown object +- *2* ???*3*["expirationTimes"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +863 -> 864 conditional = ((0 === ???*0*) | (0 !== ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +864 -> 866 call = (...) => (undefined | (b + 250) | (b + 5000) | ???*0*)(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 869 conditional = (0 !== (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 871 member call = []["push"](???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 876 call = (???*0* ? ???*2* : (...) => ???*4*)((???*6* | ???*7*)) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 888 call = (???*0* ? ???*2* : (...) => ???*4*)((???*6* | ???*7*)) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 894 call = (???*0* ? ???*2* : (...) => ???*4*)((???*6* | ???*7*)) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 897 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 898 free var = FreeVar(Map) + +0 -> 899 free var = FreeVar(Map) + +0 -> 901 member call = "mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit"["split"](" ") + +0 -> 904 member call = ???*0*["delete"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["pointerId"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 907 member call = ???*0*["delete"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["pointerId"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 909 conditional = ( + | (null === ( + | ???*0* + | { + "blockedOn": (???*1* | ???*2* | ???*10*), + "domEventName": ???*12*, + "eventSystemFlags": ???*13*, + "nativeEvent": ???*14*, + "targetContainers": [???*15*] + } + )) + | ((???*16* | ???*18* | ???*19*) !== ???*20*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? null : (???*7* | ???*8*)) + ⚠️ nested operation +- *3* !((???*4* | ???*5*)) + ⚠️ nested operation +- *4* b + ⚠️ circular variable reference +- *5* ???*6*[Of] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* b + ⚠️ circular variable reference +- *8* ???*9*[Of] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["targetContainers"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* arguments[3] + ⚠️ function calls are not analysed yet +- *14* arguments[5] + ⚠️ function calls are not analysed yet +- *15* arguments[4] + ⚠️ function calls are not analysed yet +- *16* ???*17*["nativeEvent"] + ⚠️ unknown object +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* arguments[5] + ⚠️ function calls are not analysed yet +- *19* unknown mutation + ⚠️ This value might have side effects +- *20* arguments[5] + ⚠️ function calls are not analysed yet + +909 -> 910 call = (...) => (( + || !(a) + || ((5 !== a["tag"]) && (6 !== a["tag"]) && (13 !== a["tag"]) && (3 !== a["tag"])) +) ? null : a)( + (???*0* | (???*1* ? null : (???*5* | ???*6*)) | ???*8* | [???*10*] | ???*11*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* !((???*2* | ???*3*)) + ⚠️ nested operation +- *2* b + ⚠️ circular variable reference +- *3* ???*4*[Of] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["targetContainers"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* arguments[4] + ⚠️ function calls are not analysed yet +- *11* unknown mutation + ⚠️ This value might have side effects + +909 -> 911 call = (???*0* | (...) => undefined)( + (???*1* | (???*2* ? null : (???*6* | ???*7*)) | ???*9* | [???*11*] | ???*12*) +) +- *0* Fc + ⚠️ pattern without value +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* !((???*3* | ???*4*)) + ⚠️ nested operation +- *3* b + ⚠️ circular variable reference +- *4* ???*5*[Of] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* b + ⚠️ circular variable reference +- *7* ???*8*[Of] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["targetContainers"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[4] + ⚠️ function calls are not analysed yet +- *12* unknown mutation + ⚠️ This value might have side effects + +0 -> 915 member call = (???*0* | (???*1* ? null : (???*5* | ???*6*)) | ???*8* | [???*10*] | ???*11*)["indexOf"](???*12*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* !((???*2* | ???*3*)) + ⚠️ nested operation +- *2* b + ⚠️ circular variable reference +- *3* ???*4*[Of] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["targetContainers"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* arguments[4] + ⚠️ function calls are not analysed yet +- *11* unknown mutation + ⚠️ This value might have side effects +- *12* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 917 member call = (???*0* | (???*1* ? null : (???*5* | ???*6*)) | ???*8* | [???*10*] | ???*11*)["push"](???*12*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* !((???*2* | ???*3*)) + ⚠️ nested operation +- *2* b + ⚠️ circular variable reference +- *3* ???*4*[Of] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["targetContainers"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* arguments[4] + ⚠️ function calls are not analysed yet +- *11* unknown mutation + ⚠️ This value might have side effects +- *12* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 918 call = (...) => (???*0* | a)( + ( + | null + | ???*1* + | ???*2* + | { + "blockedOn": (???*3* | (???*4* ? null : (???*8* | ???*9*)) | ???*11*), + "domEventName": ???*13*, + "eventSystemFlags": ???*14*, + "nativeEvent": ???*15*, + "targetContainers": [???*16*] + } + ), + ???*17*, + ???*18*, + ???*19*, + ???*20*, + ???*21* +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* Lc + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* !((???*5* | ???*6*)) + ⚠️ nested operation +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["targetContainers"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* arguments[4] + ⚠️ function calls are not analysed yet +- *16* arguments[3] + ⚠️ function calls are not analysed yet +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* arguments[2] + ⚠️ function calls are not analysed yet +- *20* arguments[3] + ⚠️ function calls are not analysed yet +- *21* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 919 call = (...) => (???*0* | a)( + ( + | null + | ???*1* + | ???*2* + | { + "blockedOn": (???*3* | (???*4* ? null : (???*8* | ???*9*)) | ???*11*), + "domEventName": ???*13*, + "eventSystemFlags": ???*14*, + "nativeEvent": ???*15*, + "targetContainers": [???*16*] + } + ), + ???*17*, + ???*18*, + ???*19*, + ???*20*, + ???*21* +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* Mc + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* !((???*5* | ???*6*)) + ⚠️ nested operation +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["targetContainers"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* arguments[4] + ⚠️ function calls are not analysed yet +- *16* arguments[3] + ⚠️ function calls are not analysed yet +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* arguments[2] + ⚠️ function calls are not analysed yet +- *20* arguments[3] + ⚠️ function calls are not analysed yet +- *21* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 920 call = (...) => (???*0* | a)( + ( + | null + | ???*1* + | ???*2* + | { + "blockedOn": (???*3* | (???*4* ? null : (???*8* | ???*9*)) | ???*11*), + "domEventName": ???*13*, + "eventSystemFlags": ???*14*, + "nativeEvent": ???*15*, + "targetContainers": [???*16*] + } + ), + ???*17*, + ???*18*, + ???*19*, + ???*20*, + ???*21* +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* Nc + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* !((???*5* | ???*6*)) + ⚠️ nested operation +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["targetContainers"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* arguments[4] + ⚠️ function calls are not analysed yet +- *16* arguments[3] + ⚠️ function calls are not analysed yet +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* arguments[2] + ⚠️ function calls are not analysed yet +- *20* arguments[3] + ⚠️ function calls are not analysed yet +- *21* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 924 member call = ???*0*["get"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["pointerId"] + ⚠️ unknown object +- *2* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 925 call = (...) => (???*0* | a)((???*1* | null), ???*3*, ???*4*, ???*5*, ???*6*, ???*7*) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ???*2*["get"](f) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* arguments[3] + ⚠️ function calls are not analysed yet +- *7* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 926 member call = ???*0*["set"]( + ???*1*, + ( + | ???*3* + | ???*4* + | null + | { + "blockedOn": (???*6* | (???*7* ? null : (???*11* | ???*12*)) | ???*14*), + "domEventName": ???*16*, + "eventSystemFlags": ???*17*, + "nativeEvent": ???*18*, + "targetContainers": [???*19*] + } + ) +) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["pointerId"] + ⚠️ unknown object +- *2* arguments[4] + ⚠️ function calls are not analysed yet +- *3* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *4* ???*5*["get"](f) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* unknown new expression + ⚠️ This value might have side effects +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* !((???*8* | ???*9*)) + ⚠️ nested operation +- *8* b + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* b + ⚠️ circular variable reference +- *12* ???*13*[Of] + ⚠️ unknown object +- *13* a + ⚠️ circular variable reference +- *14* ???*15*["targetContainers"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* arguments[1] + ⚠️ function calls are not analysed yet +- *17* arguments[2] + ⚠️ function calls are not analysed yet +- *18* arguments[4] + ⚠️ function calls are not analysed yet +- *19* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 930 member call = ???*0*["get"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["pointerId"] + ⚠️ unknown object +- *2* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 931 call = (...) => (???*0* | a)((???*1* | null), ???*3*, ???*4*, ???*5*, ???*6*, ???*7*) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ???*2*["get"](f) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* arguments[3] + ⚠️ function calls are not analysed yet +- *7* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 932 member call = ???*0*["set"]( + ???*1*, + ( + | ???*3* + | ???*4* + | null + | { + "blockedOn": (???*6* | (???*7* ? null : (???*11* | ???*12*)) | ???*14*), + "domEventName": ???*16*, + "eventSystemFlags": ???*17*, + "nativeEvent": ???*18*, + "targetContainers": [???*19*] + } + ) +) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["pointerId"] + ⚠️ unknown object +- *2* arguments[4] + ⚠️ function calls are not analysed yet +- *3* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *4* ???*5*["get"](f) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* unknown new expression + ⚠️ This value might have side effects +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* !((???*8* | ???*9*)) + ⚠️ nested operation +- *8* b + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* b + ⚠️ circular variable reference +- *12* ???*13*[Of] + ⚠️ unknown object +- *13* a + ⚠️ circular variable reference +- *14* ???*15*["targetContainers"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* arguments[1] + ⚠️ function calls are not analysed yet +- *17* arguments[2] + ⚠️ function calls are not analysed yet +- *18* arguments[4] + ⚠️ function calls are not analysed yet +- *19* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 934 call = (...) => (b | c | null)(???*0*) +- *0* ???*1*["target"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 935 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +935 -> 936 call = (...) => ((3 === b["tag"]) ? c : null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +935 -> 937 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +937 -> 939 call = (...) => (b["dehydrated"] | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +937 -> 942 call = (???*0* | (...) => (undefined | ???*1*))(???*2*, (...) => undefined) +- *0* Ic + ⚠️ pattern without value +- *1* b() + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* ???*3*["priority"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +942 -> 943 call = (???*0* | (...) => undefined)(???*1*) +- *0* Gc + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +937 -> 948 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +948 -> 951 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 962 call = (...) => ( + | a + | ((3 === b["tag"]) ? b["stateNode"]["containerInfo"] : null) + | null +)(???*0*, ???*2*, ???*4*, ???*5*) +- *0* ???*1*["domEventName"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["eventSystemFlags"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*["nativeEvent"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 963 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +963 -> 969 member call = ???*0*["dispatchEvent"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* unknown new expression + ⚠️ This value might have side effects + +963 -> 970 call = (...) => (( + || !(a) + || ((5 !== a["tag"]) && (6 !== a["tag"]) && (13 !== a["tag"]) && (3 !== a["tag"])) +) ? null : a)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +963 -> 971 call = (???*0* | (...) => undefined)(???*1*) +- *0* Fc + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 974 member call = ???*0*["shift"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 975 call = (...) => (!(1) | ???*0* | !(0))(???*1*) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 977 member call = ???*0*["delete"](???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 978 call = (...) => (!(1) | ???*0* | !(0))( + ( + | null + | ???*1* + | ???*2* + | { + "blockedOn": (???*3* | (???*4* ? null : (???*8* | ???*9*)) | ???*11*), + "domEventName": ???*13*, + "eventSystemFlags": ???*14*, + "nativeEvent": ???*15*, + "targetContainers": [???*16*] + } + ) +) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* Lc + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* !((???*5* | ???*6*)) + ⚠️ nested operation +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["targetContainers"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* arguments[4] + ⚠️ function calls are not analysed yet +- *16* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 979 call = (...) => (!(1) | ???*0* | !(0))( + ( + | null + | ???*1* + | ???*2* + | { + "blockedOn": (???*3* | (???*4* ? null : (???*8* | ???*9*)) | ???*11*), + "domEventName": ???*13*, + "eventSystemFlags": ???*14*, + "nativeEvent": ???*15*, + "targetContainers": [???*16*] + } + ) +) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* Mc + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* !((???*5* | ???*6*)) + ⚠️ nested operation +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["targetContainers"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* arguments[4] + ⚠️ function calls are not analysed yet +- *16* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 980 call = (...) => (!(1) | ???*0* | !(0))( + ( + | null + | ???*1* + | ???*2* + | { + "blockedOn": (???*3* | (???*4* ? null : (???*8* | ???*9*)) | ???*11*), + "domEventName": ???*13*, + "eventSystemFlags": ???*14*, + "nativeEvent": ???*15*, + "targetContainers": [???*16*] + } + ) +) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* Nc + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* !((???*5* | ???*6*)) + ⚠️ nested operation +- *5* b + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["targetContainers"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* arguments[4] + ⚠️ function calls are not analysed yet +- *16* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 982 member call = ???*0*["forEach"]((...) => undefined) +- *0* unknown new expression + ⚠️ This value might have side effects + +0 -> 984 member call = ???*0*["forEach"]((...) => undefined) +- *0* unknown new expression + ⚠️ This value might have side effects + +0 -> 989 member call = module["unstable_scheduleCallback"](module["unstable_NormalPriority"], (...) => undefined) + +0 -> 990 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 993 call = (...) => undefined(???*0*, ???*1*) +- *0* [][0] + ⚠️ invalid index +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 998 call = (...) => undefined( + ( + | null + | ???*0* + | ???*1* + | { + "blockedOn": (???*2* | (???*3* ? null : (???*7* | ???*8*)) | ???*10*), + "domEventName": ???*12*, + "eventSystemFlags": ???*13*, + "nativeEvent": ???*14*, + "targetContainers": [???*15*] + } + ), + ???*16* +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* Lc + ⚠️ circular variable reference +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* !((???*4* | ???*5*)) + ⚠️ nested operation +- *4* b + ⚠️ circular variable reference +- *5* ???*6*[Of] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* b + ⚠️ circular variable reference +- *8* ???*9*[Of] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["targetContainers"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* arguments[4] + ⚠️ function calls are not analysed yet +- *15* arguments[3] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 999 call = (...) => undefined( + ( + | null + | ???*0* + | ???*1* + | { + "blockedOn": (???*2* | (???*3* ? null : (???*7* | ???*8*)) | ???*10*), + "domEventName": ???*12*, + "eventSystemFlags": ???*13*, + "nativeEvent": ???*14*, + "targetContainers": [???*15*] + } + ), + ???*16* +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* Mc + ⚠️ circular variable reference +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* !((???*4* | ???*5*)) + ⚠️ nested operation +- *4* b + ⚠️ circular variable reference +- *5* ???*6*[Of] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* b + ⚠️ circular variable reference +- *8* ???*9*[Of] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["targetContainers"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* arguments[4] + ⚠️ function calls are not analysed yet +- *15* arguments[3] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1000 call = (...) => undefined( + ( + | null + | ???*0* + | ???*1* + | { + "blockedOn": (???*2* | (???*3* ? null : (???*7* | ???*8*)) | ???*10*), + "domEventName": ???*12*, + "eventSystemFlags": ???*13*, + "nativeEvent": ???*14*, + "targetContainers": [???*15*] + } + ), + ???*16* +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* Nc + ⚠️ circular variable reference +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* !((???*4* | ???*5*)) + ⚠️ nested operation +- *4* b + ⚠️ circular variable reference +- *5* ???*6*[Of] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* b + ⚠️ circular variable reference +- *8* ???*9*[Of] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["targetContainers"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* arguments[4] + ⚠️ function calls are not analysed yet +- *15* arguments[3] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1002 member call = ???*0*["forEach"]((...) => ad(b, a)) +- *0* unknown new expression + ⚠️ This value might have side effects + +0 -> 1004 member call = ???*0*["forEach"]((...) => ad(b, a)) +- *0* unknown new expression + ⚠️ This value might have side effects + +0 -> 1012 call = (...) => (undefined | FreeVar(undefined))((1 | ???*0* | 0 | ???*1*)) +- *0* updated with update expression + ⚠️ This value might have side effects +- *1* [][0] + ⚠️ invalid index + +0 -> 1015 member call = []["shift"]() + +0 -> 1019 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 1023 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 1025 conditional = (true | false | !(???*0*)) +- *0* !((null | ???*1*)) + ⚠️ nested operation +- *1* dd + ⚠️ circular variable reference + +1025 -> 1026 call = (...) => ( + | a + | ((3 === b["tag"]) ? b["stateNode"]["containerInfo"] : null) + | null +)(???*0*, ???*1*, ???*2*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +1025 -> 1027 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1027 -> 1028 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +1027 -> 1029 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +1027 -> 1030 call = (...) => (???*0* | !(0) | !(1))(???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* arguments[3] + ⚠️ function calls are not analysed yet + +1027 -> 1031 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1031 -> 1033 member call = ???*0*["stopPropagation"]() +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +1031 -> 1034 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +1031 -> 1036 member call = "mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit"["split"](" ")["indexOf"](???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +1031 -> 1037 conditional = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +1037 -> 1038 call = (...) => (( + || !(a) + || ((5 !== a["tag"]) && (6 !== a["tag"]) && (13 !== a["tag"]) && (3 !== a["tag"])) +) ? null : a)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1037 -> 1039 call = (???*0* | (...) => undefined)(???*1*) +- *0* Ec + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1037 -> 1040 call = (...) => ( + | a + | ((3 === b["tag"]) ? b["stateNode"]["containerInfo"] : null) + | null +)(???*0*, ???*1*, ???*2*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +1037 -> 1041 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +1037 -> 1043 member call = ???*0*["stopPropagation"]() +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +1037 -> 1044 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*, ???*2*, null, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 1045 call = (...) => ((3 === a["nodeType"]) ? a["parentNode"] : a)(???*0*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 1046 call = (...) => (b | c | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1047 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1047 -> 1048 call = (...) => ((3 === b["tag"]) ? c : null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1047 -> 1050 call = (...) => (b["dehydrated"] | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1047 -> 1051 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1051 -> 1056 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1056 -> 1058 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1061 call = module["unstable_getCurrentPriorityLevel"]() + +0 -> 1071 member call = (???*0* ? (null["value"] | ???*1* | ???*16*) : (null["textContent"] | ???*18* | ???*33*))["slice"]((???*35* | 0 | ???*36*), (???*37* ? ???*38* : ???*39*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* (???*3* ? (???*8* | ???*10*) : (???*12* | ???*13* | ???*15*)) + ⚠️ nested operation +- *3* (3 === (???*4* | ???*6*)) + ⚠️ nested operation +- *4* ???*5*["nodeType"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* ???*7*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* ???*9*["parentNode"] + ⚠️ unknown object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*["target"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* ???*17*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* unknown new expression + ⚠️ This value might have side effects +- *18* ???*19*["textContent"] + ⚠️ unknown object +- *19* (???*20* ? (???*25* | ???*27*) : (???*29* | ???*30* | ???*32*)) + ⚠️ nested operation +- *20* (3 === (???*21* | ???*23*)) + ⚠️ nested operation +- *21* ???*22*["nodeType"] + ⚠️ unknown object +- *22* arguments[2] + ⚠️ function calls are not analysed yet +- *23* ???*24*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *25* ???*26*["parentNode"] + ⚠️ unknown object +- *26* arguments[2] + ⚠️ function calls are not analysed yet +- *27* ???*28*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *28* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *29* arguments[2] + ⚠️ function calls are not analysed yet +- *30* ???*31*["target"] + ⚠️ unknown object +- *31* a + ⚠️ circular variable reference +- *32* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *33* ???*34*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unknown new expression + ⚠️ This value might have side effects +- *35* a + ⚠️ pattern without value +- *36* updated with update expression + ⚠️ This value might have side effects +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* unsupported expression + ⚠️ This value might have side effects + +0 -> 1074 conditional = (???*0* | (13 === (???*1* | ???*2* | 13))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["charCode"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +0 -> 1082 member call = ???*0*["hasOwnProperty"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* c + ⚠️ pattern without value + +0 -> 1085 conditional = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*[c] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1085 -> 1086 call = (???*0* | ???*1*)(???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*[c] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 1090 conditional = (null != ???*0*) +- *0* ???*1*["defaultPrevented"] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 1093 conditional = (???*0* ? ???*3* : ???*5*) +- *0* (null != ???*1*) + ⚠️ nested operation +- *1* ???*2*["defaultPrevented"] + ⚠️ unknown object +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* ???*4*["defaultPrevented"] + ⚠️ unknown object +- *4* arguments[3] + ⚠️ function calls are not analysed yet +- *5* (false === ???*6*) + ⚠️ nested operation +- *6* ???*7*["returnValue"] + ⚠️ unknown object +- *7* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 1099 conditional = ???*0* +- *0* ???*1*["preventDefault"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +1099 -> 1101 member call = ???*0*["preventDefault"]() +- *0* ???*1*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 1107 conditional = ???*0* +- *0* ???*1*["stopPropagation"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +1107 -> 1109 member call = ???*0*["stopPropagation"]() +- *0* ???*1*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 1113 call = ???*0*( + (...) => ???*2*["prototype"], + { + "preventDefault": (...) => undefined, + "stopPropagation": (...) => undefined, + "persist": (...) => undefined, + "isPersistent": (...) => !(0) + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 1116 free var = FreeVar(Date) + +0 -> 1117 member call = ???*0*["now"]() +- *0* FreeVar(Date) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1118 call = (...) => b( + { + "eventPhase": 0, + "bubbles": 0, + "cancelable": 0, + "timeStamp": (...) => (a["timeStamp"] || FreeVar(Date)["now"]()), + "defaultPrevented": 0, + "isTrusted": 0 + } +) + +0 -> 1119 call = ???*0*( + {}, + { + "eventPhase": 0, + "bubbles": 0, + "cancelable": 0, + "timeStamp": (...) => (a["timeStamp"] || FreeVar(Date)["now"]()), + "defaultPrevented": 0, + "isTrusted": 0 + }, + {"view": 0, "detail": 0} +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1120 call = (...) => b(???*0*) +- *0* ???*1*({}, sd, {"view": 0, "detail": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1122 conditional = (???*0* === ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["relatedTarget"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1122 -> 1125 conditional = (???*0* === ???*2*) +- *0* ???*1*["fromElement"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["srcElement"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1131 conditional = (???*0* | ???*1* | ("mousemove" === ???*2*)) +- *0* yd + ⚠️ pattern without value +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1137 call = ???*0*( + {}, + ???*2*, + { + "screenX": 0, + "screenY": 0, + "clientX": 0, + "clientY": 0, + "pageX": 0, + "pageY": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "getModifierState": (...) => Pd, + "button": 0, + "buttons": 0, + "relatedTarget": (...) => ((???*5* === a["relatedTarget"]) ? ((a["fromElement"] === a["srcElement"]) ? a["toElement"] : a["fromElement"]) : a["relatedTarget"]), + "movementX": (...) => (a["movementX"] | wd), + "movementY": (...) => (???*6* ? a["movementY"] : xd) + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*({}, sd, {"view": 0, "detail": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects + +0 -> 1138 call = (...) => b(???*0*) +- *0* ???*1*( + {}, + ud, + { + "screenX": 0, + "screenY": 0, + "clientX": 0, + "clientY": 0, + "pageX": 0, + "pageY": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "getModifierState": zd, + "button": 0, + "buttons": 0, + "relatedTarget": *anonymous function 28404*, + "movementX": *anonymous function 28530*, + "movementY": *anonymous function 28699* + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1139 call = ???*0*({}, ???*2*, {"dataTransfer": 0}) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*( + {}, + ud, + { + "screenX": 0, + "screenY": 0, + "clientX": 0, + "clientY": 0, + "pageX": 0, + "pageY": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "getModifierState": zd, + "button": 0, + "buttons": 0, + "relatedTarget": *anonymous function 28404*, + "movementX": *anonymous function 28530*, + "movementY": *anonymous function 28699* + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1140 call = (...) => b(???*0*) +- *0* ???*1*({}, Ad, {"dataTransfer": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1141 call = ???*0*({}, ???*2*, {"relatedTarget": 0}) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*({}, sd, {"view": 0, "detail": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1142 call = (...) => b(???*0*) +- *0* ???*1*({}, ud, {"relatedTarget": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1143 call = ???*0*( + {}, + { + "eventPhase": 0, + "bubbles": 0, + "cancelable": 0, + "timeStamp": (...) => (a["timeStamp"] || FreeVar(Date)["now"]()), + "defaultPrevented": 0, + "isTrusted": 0 + }, + {"animationName": 0, "elapsedTime": 0, "pseudoElement": 0} +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1144 call = (...) => b(???*0*) +- *0* ???*1*( + {}, + sd, + {"animationName": 0, "elapsedTime": 0, "pseudoElement": 0} + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1147 free var = FreeVar(window) + +0 -> 1148 call = ???*0*( + {}, + { + "eventPhase": 0, + "bubbles": 0, + "cancelable": 0, + "timeStamp": (...) => (a["timeStamp"] || FreeVar(Date)["now"]()), + "defaultPrevented": 0, + "isTrusted": 0 + }, + { + "clipboardData": (...) => (???*2* ? a["clipboardData"] : FreeVar(window)["clipboardData"]) + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 1149 call = (...) => b(???*0*) +- *0* ???*1*({}, sd, {"clipboardData": *anonymous function 28936*}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1150 call = ???*0*( + {}, + { + "eventPhase": 0, + "bubbles": 0, + "cancelable": 0, + "timeStamp": (...) => (a["timeStamp"] || FreeVar(Date)["now"]()), + "defaultPrevented": 0, + "isTrusted": 0 + }, + {"data": 0} +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1151 call = (...) => b(???*0*) +- *0* ???*1*({}, sd, {"data": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1154 conditional = ???*0* +- *0* ???*1*["getModifierState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +1154 -> 1156 member call = ???*0*["getModifierState"]( + (???*2* | "altKey" | "ctrlKey" | "metaKey" | "shiftKey" | ???*3*) +) +- *0* ???*1*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* {}[???*4*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *4* a + ⚠️ circular variable reference + +0 -> 1160 conditional = ( + | ???*0* + | ((???*2* | ???*3*) ? (???*7* | ???*8* | 13) : 0)["key"] +) +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (13 === (???*4* | ???*5* | 13)) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["charCode"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["charCode"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference + +0 -> 1165 conditional = ("keypress" === ???*0*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1165 -> 1166 call = (...) => ((???*0* || (13 === a)) ? a : 0)( + (???*1* | ((???*2* | ???*3*) ? (???*7* | ???*8* | 13) : 0)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (13 === (???*4* | ???*5* | 13)) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["charCode"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["charCode"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference + +1165 -> 1167 conditional = (13 === (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ((???*2* | ???*3*) ? (???*7* | ???*8* | 13) : 0) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (13 === (???*4* | ???*5* | 13)) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["charCode"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["charCode"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference + +1167 -> 1169 free var = FreeVar(String) + +1167 -> 1170 member call = ???*0*["fromCharCode"]( + (???*1* | ((???*2* | ???*3*) ? (???*7* | ???*8* | 13) : 0)) +) +- *0* FreeVar(String) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (13 === (???*4* | ???*5* | 13)) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["charCode"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["charCode"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference + +1165 -> 1173 conditional = (("keydown" === ???*0*) | ("keyup" === ???*2*)) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1177 conditional = ("keypress" === ???*0*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1177 -> 1178 call = (...) => ((???*0* || (13 === a)) ? a : 0)(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1181 conditional = (("keydown" === ???*0*) | ("keyup" === ???*2*)) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1184 conditional = ("keypress" === ???*0*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1184 -> 1185 call = (...) => ((???*0* || (13 === a)) ? a : 0)(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1184 -> 1188 conditional = (("keydown" === ???*0*) | ("keyup" === ???*2*)) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1190 call = ???*0*( + {}, + ???*2*, + { + "key": (...) => ( + | b + | (("keypress" === a["type"]) ? ???*5* : ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? (Nd[a["keyCode"]] || "Unidentified") : "")) + ), + "code": 0, + "location": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "repeat": 0, + "locale": 0, + "getModifierState": (...) => Pd, + "charCode": (...) => (("keypress" === a["type"]) ? od(a) : 0), + "keyCode": (...) => ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? a["keyCode"] : 0), + "which": (...) => (("keypress" === a["type"]) ? od(a) : ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? a["keyCode"] : 0)) + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*({}, sd, {"view": 0, "detail": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* ((13 === a) ? "Enter" : FreeVar(String)["fromCharCode"](a)) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +0 -> 1191 call = (...) => b(???*0*) +- *0* ???*1*( + {}, + ud, + { + "key": *anonymous function 29891*, + "code": 0, + "location": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "repeat": 0, + "locale": 0, + "getModifierState": zd, + "charCode": *anonymous function 30217*, + "keyCode": *anonymous function 30272*, + "which": *anonymous function 30346* + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1192 call = ???*0*( + {}, + ???*2*, + { + "pointerId": 0, + "width": 0, + "height": 0, + "pressure": 0, + "tangentialPressure": 0, + "tiltX": 0, + "tiltY": 0, + "twist": 0, + "pointerType": 0, + "isPrimary": 0 + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*( + {}, + ud, + { + "screenX": 0, + "screenY": 0, + "clientX": 0, + "clientY": 0, + "pageX": 0, + "pageY": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "getModifierState": zd, + "button": 0, + "buttons": 0, + "relatedTarget": *anonymous function 28404*, + "movementX": *anonymous function 28530*, + "movementY": *anonymous function 28699* + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1193 call = (...) => b(???*0*) +- *0* ???*1*( + {}, + Ad, + { + "pointerId": 0, + "width": 0, + "height": 0, + "pressure": 0, + "tangentialPressure": 0, + "tiltX": 0, + "tiltY": 0, + "twist": 0, + "pointerType": 0, + "isPrimary": 0 + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1194 call = ???*0*( + {}, + ???*2*, + { + "touches": 0, + "targetTouches": 0, + "changedTouches": 0, + "altKey": 0, + "metaKey": 0, + "ctrlKey": 0, + "shiftKey": 0, + "getModifierState": (...) => Pd + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*({}, sd, {"view": 0, "detail": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1195 call = (...) => b(???*0*) +- *0* ???*1*( + {}, + ud, + { + "touches": 0, + "targetTouches": 0, + "changedTouches": 0, + "altKey": 0, + "metaKey": 0, + "ctrlKey": 0, + "shiftKey": 0, + "getModifierState": zd + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1196 call = ???*0*( + {}, + { + "eventPhase": 0, + "bubbles": 0, + "cancelable": 0, + "timeStamp": (...) => (a["timeStamp"] || FreeVar(Date)["now"]()), + "defaultPrevented": 0, + "isTrusted": 0 + }, + {"propertyName": 0, "elapsedTime": 0, "pseudoElement": 0} +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1197 call = (...) => b(???*0*) +- *0* ???*1*( + {}, + sd, + {"propertyName": 0, "elapsedTime": 0, "pseudoElement": 0} + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1203 call = ???*0*( + {}, + ???*2*, + { + "deltaX": (...) => (???*5* ? a["deltaX"] : (???*6* ? ???*7* : 0)), + "deltaY": (...) => (???*8* ? a["deltaY"] : (???*9* ? ???*10* : (???*11* ? ???*12* : 0))), + "deltaZ": 0, + "deltaMode": 0 + } +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*( + {}, + ud, + { + "screenX": 0, + "screenY": 0, + "clientX": 0, + "clientY": 0, + "pageX": 0, + "pageY": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "getModifierState": zd, + "button": 0, + "buttons": 0, + "relatedTarget": *anonymous function 28404*, + "movementX": *anonymous function 28530*, + "movementY": *anonymous function 28699* + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects + +0 -> 1204 call = (...) => b(???*0*) +- *0* ???*1*( + {}, + Ad, + { + "deltaX": *anonymous function 30803*, + "deltaY": *anonymous function 30887*, + "deltaZ": 0, + "deltaMode": 0 + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1205 free var = FreeVar(window) + +0 -> 1206 free var = FreeVar(document) + +0 -> 1208 free var = FreeVar(document) + +0 -> 1209 free var = FreeVar(window) + +0 -> 1211 free var = FreeVar(String) + +0 -> 1212 member call = ???*0*["fromCharCode"](32) +- *0* FreeVar(String) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1215 member call = [9, 13, 27, 32]["indexOf"](???*0*) +- *0* ???*1*["keyCode"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1218 conditional = (("object" === ???*0*) | ???*4*) +- *0* typeof((???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["detail"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* unsupported expression + ⚠️ This value might have side effects + +0 -> 1220 call = (...) => ((("object" === typeof(a)) && ???*0*) ? a["data"] : null)(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1223 conditional = (((???*0* | ???*1*) === ???*3*) | false | true) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["data"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["fromCharCode"](32) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* FreeVar(String) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1224 conditional = (false | true) + +1224 -> 1225 call = (...) => (undefined | (???*0* !== $d["indexOf"](b["keyCode"])) | (229 !== b["keyCode"]) | !(0) | !(1))((???*1* | null | ???*2* | ???*20*), ???*21*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*((???*14* | 0 | ???*15*), ???*16*) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["slice"] + ⚠️ unknown object +- *4* (???*5* ? (null["value"] | ???*6* | ???*8*) : (null["textContent"] | ???*10* | ???*12*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*["value"] + ⚠️ unknown object +- *7* (??? ? (??? | ???) : (??? | ??? | ???)) + ⚠️ nested operation +- *8* ???*9*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* unknown new expression + ⚠️ This value might have side effects +- *10* ???*11*["textContent"] + ⚠️ unknown object +- *11* (??? ? (??? | ???) : (??? | ??? | ???)) + ⚠️ nested operation +- *12* ???*13*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* unknown new expression + ⚠️ This value might have side effects +- *14* a + ⚠️ pattern without value +- *15* updated with update expression + ⚠️ This value might have side effects +- *16* (???*17* ? ???*18* : ???*19*) + ⚠️ nested operation +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* arguments[1] + ⚠️ function calls are not analysed yet + +1224 -> 1226 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1226 -> 1227 call = (...) => (md | ???*0*)() +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 1233 conditional = (!(???*0*) | ???*2*) +- *0* ???*1*["ctrlKey"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["ctrlKey"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +1233 -> 1237 conditional = (???*0* | ???*2*) +- *0* ???*1*["char"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +1233 -> 1240 conditional = ???*0* +- *0* ???*1*["which"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +1240 -> 1242 free var = FreeVar(String) + +1240 -> 1244 member call = ???*0*["fromCharCode"](???*1*) +- *0* FreeVar(String) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["which"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1246 conditional = (!(???*0*) | !((???*3* | ???*7*)) | null | ???*8* | ???*10* | ("ko" !== ???*11*)) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* !(???*4*) + ⚠️ nested operation +- *4* ("undefined" === ???*5*) + ⚠️ nested operation +- *5* typeof(???*6*) + ⚠️ nested operation +- *6* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* ???*9*["documentMode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["locale"] + ⚠️ unknown object +- *12* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1251 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["nodeName"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1252 conditional = ("input" === (???*0* | ???*1* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeName"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*() + ⚠️ nested operation +- *4* ???*5*["toLowerCase"] + ⚠️ unknown object +- *5* ???*6*["nodeName"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +1252 -> 1255 conditional = ("textarea" === (???*0* | ???*1* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeName"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*() + ⚠️ nested operation +- *4* ???*5*["toLowerCase"] + ⚠️ unknown object +- *5* ???*6*["nodeName"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1256 call = (...) => undefined(???*0*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 1257 call = (...) => d((???*0* | []), "onChange") +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1260 member call = ???*0*["push"]( + {"event": (???*1* | ???*2*), "listeners": (???*3* | [])} +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1261 call = (...) => undefined(???*0*, 0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1262 call = (...) => (undefined | a["stateNode"])(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1263 call = (...) => (!(1) | !(0) | ((a !== c) ? !(0) : !(1)))((undefined | ???*0*)) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1264 conditional = !(???*0*) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +1264 -> 1265 conditional = !(???*0*) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +1265 -> 1266 free var = FreeVar(document) + +1265 -> 1267 conditional = !((???*0* | ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ("function" === ???*2*) + ⚠️ nested operation +- *2* typeof(???*3*) + ⚠️ nested operation +- *3* ???*4*["oninput"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +1267 -> 1269 free var = FreeVar(document) + +1267 -> 1270 member call = ???*0*["createElement"]("div") +- *0* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +1267 -> 1272 member call = ???*0*["setAttribute"]("oninput", "return;") +- *0* ???*1*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +1264 -> 1275 free var = FreeVar(document) + +1264 -> 1277 free var = FreeVar(document) + +0 -> 1279 member call = (null | ???*0*)["detachEvent"]("onpropertychange", (...) => undefined) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1281 call = (...) => (undefined | a)((null | ???*0* | ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 1282 conditional = (("value" === ???*0*) | undefined | null | ???*2* | ???*3*) +- *0* ???*1*["propertyName"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +1282 -> 1283 call = (...) => ((3 === a["nodeType"]) ? a["parentNode"] : a)(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +1282 -> 1284 call = (...) => undefined( + [], + (null | ???*0* | ???*1*), + ???*2*, + (???*3* ? (???*8* | ???*10*) : (???*12* | ???*13* | ???*15*)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* (3 === (???*4* | ???*6*)) + ⚠️ nested operation +- *4* ???*5*["nodeType"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* ???*9*["parentNode"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* ???*14*["target"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +1282 -> 1285 call = (...) => (undefined | a(b, c) | Gb(a, b, c))((...) => undefined, []) + +0 -> 1286 conditional = ("focusin" === ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +1286 -> 1287 call = (...) => undefined() + +1286 -> 1289 member call = (null | ???*0*)["attachEvent"]("onpropertychange", (...) => undefined) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +1286 -> 1290 call = (...) => undefined() + +0 -> 1291 conditional = (("selectionchange" === ???*0*) | ("keyup" === ???*1*) | ("keydown" === ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1291 -> 1292 call = (...) => (undefined | a)((null | ???*0* | ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 1293 conditional = ("click" === ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +1293 -> 1294 call = (...) => (undefined | a)(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1295 conditional = (("input" === ???*0*) | ("change" === ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1295 -> 1296 call = (...) => (undefined | a)(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1298 free var = FreeVar(Object) + +0 -> 1299 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* ???*2*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +1299 -> 1301 free var = FreeVar(Object) + +0 -> 1302 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*, ???*10*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1304 free var = FreeVar(Object) + +0 -> 1305 member call = ???*0*["keys"](???*1*) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1307 free var = FreeVar(Object) + +0 -> 1308 member call = ???*0*["keys"](???*1*) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1314 member call = ???*0*["call"](???*3*, ???*4*) +- *0* ???*1*["hasOwnProperty"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*[d] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["keys"](a) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *6* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1317 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*, ???*11*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*[e] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* ???*12*[e] + ⚠️ unknown object +- *12* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1320 call = (...) => a( + (???*0* | 0 | ???*1* | (???*2* + (???*3* | ???*6*))) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* d + ⚠️ pattern without value +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["length"] + ⚠️ unknown object +- *4* ???*5*["textContent"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["length"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects + +0 -> 1322 conditional = (3 === (???*0* | 0["nodeType"] | ???*2*)) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +0 -> 1326 conditional = (???*0* | 0["nextSibling"] | (???*2* + ???*3*)["nextSibling"] | ???*6*) +- *0* ???*1*["nextSibling"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["length"] + ⚠️ unknown object +- *4* ???*5*["textContent"] + ⚠️ unknown object +- *5* c + ⚠️ circular variable reference +- *6* ???*7*["nextSibling"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 1329 call = (...) => a( + (???*0* | 0 | ???*1* | (???*2* + ???*3*) | ???*6* | ???*8* | ???*9*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* d + ⚠️ pattern without value +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["length"] + ⚠️ unknown object +- *4* ???*5*["textContent"] + ⚠️ unknown object +- *5* c + ⚠️ circular variable reference +- *6* ???*7*["firstChild"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* c + ⚠️ circular variable reference + +0 -> 1330 conditional = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +1330 -> 1331 conditional = (???*0* === ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +1331 -> 1333 conditional = (???*0* | (3 === ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1333 -> 1335 conditional = (???*0* | (3 === ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +1335 -> 1337 call = (...) => ((a && b) ? ((a === b) ? !(0) : ((a && (3 === a["nodeType"])) ? !(1) : ((b && (3 === b["nodeType"])) ? Le(a, b["parentNode"]) : (???*0* ? a["contains"](b) : (a["compareDocumentPosition"] ? !(!(???*1*)) : !(1)))))) : !(1))(???*2*, ???*3*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["parentNode"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +1335 -> 1339 member call = ???*0*["contains"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +1335 -> 1341 conditional = ???*0* +- *0* ???*1*["compareDocumentPosition"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1341 -> 1343 member call = ???*0*["compareDocumentPosition"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1344 free var = FreeVar(window) + +0 -> 1345 call = (...) => (undefined | null | (a["activeElement"] || a["body"]) | a["body"])() + +0 -> 1350 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1353 call = (...) => (undefined | null | (a["activeElement"] || a["body"]) | a["body"])( + ( + | ???*0* + | undefined["contentWindow"]["document"] + | null["contentWindow"]["document"] + | ???*2* + | (???*6* ? ???*9* : ???*10*)["activeElement"]["contentWindow"]["document"] + | (???*11* ? ???*14* : ???*15*)["body"]["contentWindow"]["document"] + | (???*16* ? ???*19* : ???*20*)["body"]["contentWindow"]["document"] + | (???*21* ? ???*24* : ???*25*)["activeElement"]["contentWindow"]["document"] + | (???*26* ? ???*29* : ???*30*)["body"]["contentWindow"]["document"] + | (???*31* ? ???*34* : ???*35*)["body"]["contentWindow"]["document"] + ) +) +- *0* ???*1*["document"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["document"] + ⚠️ unknown object +- *3* ???*4*["contentWindow"] + ⚠️ unknown object +- *4* ???*5*["activeElement"] + ⚠️ unknown object +- *5* unknown function argument (out of bounds) +- *6* ("undefined" !== ???*7*) + ⚠️ nested operation +- *7* typeof(???*8*) + ⚠️ nested operation +- *8* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ("undefined" !== ???*12*) + ⚠️ nested operation +- *12* typeof(???*13*) + ⚠️ nested operation +- *13* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *14* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* ("undefined" !== ???*17*) + ⚠️ nested operation +- *17* typeof(???*18*) + ⚠️ nested operation +- *18* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *19* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ("undefined" !== ???*22*) + ⚠️ nested operation +- *22* typeof(???*23*) + ⚠️ nested operation +- *23* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *24* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* ("undefined" !== ???*27*) + ⚠️ nested operation +- *27* typeof(???*28*) + ⚠️ nested operation +- *28* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *29* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ("undefined" !== ???*32*) + ⚠️ nested operation +- *32* typeof(???*33*) + ⚠️ nested operation +- *33* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *35* unsupported expression + ⚠️ This value might have side effects + +0 -> 1357 member call = ???*0*["toLowerCase"]() +- *0* ???*1*["nodeName"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1364 call = (...) => b() + +0 -> 1370 call = (...) => ((a && b) ? ((a === b) ? !(0) : ((a && (3 === a["nodeType"])) ? !(1) : ((b && (3 === b["nodeType"])) ? Le(a, b["parentNode"]) : (???*0* ? a["contains"](b) : (a["compareDocumentPosition"] ? !(!(???*1*)) : !(1)))))) : !(1))(???*2*, ???*3*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1371 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1371 -> 1372 call = (...) => ( + && b + && ( + || ( + && ("input" === b) + && ( + || ("text" === a["type"]) + || ("search" === a["type"]) + || ("tel" === a["type"]) + || ("url" === a["type"]) + || ("password" === a["type"]) + ) + ) + || ("textarea" === b) + || ("true" === a["contentEditable"]) + ) +)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1371 -> 1373 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1379 free var = FreeVar(Math) + +1373 -> 1382 member call = ???*0*["min"](???*1*, ???*2*) +- *0* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1384 free var = FreeVar(document) + +1373 -> 1386 free var = FreeVar(window) + +1373 -> 1389 member call = ???*0*["getSelection"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1393 free var = FreeVar(Math) + +1373 -> 1395 member call = ???*0*["min"](???*1*, ???*2*) +- *0* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1397 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1397 -> 1399 free var = FreeVar(Math) + +1397 -> 1401 member call = ???*0*["min"](???*1*, ???*2*) +- *0* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1403 call = (...) => (undefined | {"node": c, "offset": ???*0*})(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1404 call = (...) => (undefined | {"node": c, "offset": ???*0*})(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1415 member call = ???*0*["createRange"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1419 member call = ???*0*["setStart"](???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1421 member call = ???*0*["removeAllRanges"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1423 member call = ???*0*["addRange"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1427 member call = ???*0*["extend"](???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1431 member call = ???*0*["setEnd"](???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1373 -> 1433 member call = ???*0*["addRange"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1371 -> 1439 member call = ???*0*["push"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1371 -> 1442 member call = ???*0*["focus"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1451 free var = FreeVar(document) + +0 -> 1453 free var = FreeVar(document) + +0 -> 1455 conditional = (???*0* === ???*2*) +- *0* ???*1*["window"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +1455 -> 1458 conditional = (9 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 1460 call = (...) => (undefined | null | (a["activeElement"] || a["body"]) | a["body"])(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1461 call = (...) => ( + && b + && ( + || ( + && ("input" === b) + && ( + || ("text" === a["type"]) + || ("search" === a["type"]) + || ("tel" === a["type"]) + || ("url" === a["type"]) + || ("password" === a["type"]) + ) + ) + || ("textarea" === b) + || ("true" === a["contentEditable"]) + ) +)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1462 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1462 -> 1469 free var = FreeVar(window) + +1462 -> 1470 member call = ???*0*["getSelection"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1475 call = (...) => (!(0) | !(1))(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1476 call = (...) => d(???*0*, "onSelect") +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1479 member call = ???*0*["push"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1483 member call = ???*0*["toLowerCase"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1485 member call = ???*0*["toLowerCase"]() +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1488 call = (...) => c("Animation", "AnimationEnd") + +0 -> 1489 call = (...) => c("Animation", "AnimationIteration") + +0 -> 1490 call = (...) => c("Animation", "AnimationStart") + +0 -> 1491 call = (...) => c("Transition", "TransitionEnd") + +0 -> 1494 free var = FreeVar(document) + +0 -> 1495 member call = ???*0*["createElement"]("div") +- *0* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1496 free var = FreeVar(window) + +0 -> 1503 free var = FreeVar(window) + +0 -> 1507 conditional = ???*0* +- *0* {}[???*1*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1512 member call = ({} | ???*0*)["hasOwnProperty"](???*2*) +- *0* {}[???*1*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ pattern without value + +0 -> 1513 conditional = (???*0* | ???*4* | ???*8*) +- *0* (???*1* | ???*2*)(???*3*) + ⚠️ non-function callee +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* c + ⚠️ pattern without value +- *4* ???*5*["hasOwnProperty"](???*7*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* {}[???*6*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* c + ⚠️ pattern without value +- *8* unsupported expression + ⚠️ This value might have side effects + +0 -> 1516 call = (...) => (Xe[a] | a | ???*0*)("animationend") +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 1517 call = (...) => (Xe[a] | a | ???*0*)("animationiteration") +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 1518 call = (...) => (Xe[a] | a | ???*0*)("animationstart") +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 1519 call = (...) => (Xe[a] | a | ???*0*)("transitionend") +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 1520 free var = FreeVar(Map) + +0 -> 1522 member call = "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ") + +0 -> 1524 member call = ???*0*["set"](???*1*, ???*2*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1525 call = (...) => undefined(???*0*, [???*1*]) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1529 member call = "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ")[(0 | ???*0*)]["toLowerCase"]() +- *0* updated with update expression + ⚠️ This value might have side effects + +0 -> 1532 member call = "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ")[(0 | ???*0*)][0]["toUpperCase"]() +- *0* updated with update expression + ⚠️ This value might have side effects + +0 -> 1534 member call = "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ")[(0 | ???*0*)]["slice"](1) +- *0* updated with update expression + ⚠️ This value might have side effects + +0 -> 1535 call = (...) => undefined(???*0*(), `on${???*4*}`) +- *0* ???*1*["toLowerCase"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ") + ⚠️ nested operation +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* (???*5* + ???*9*) + ⚠️ nested operation +- *5* ???*6*() + ⚠️ nested operation +- *6* ???*7*["toUpperCase"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*[0] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???[(0 | ???)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*(1) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *10* ???*11*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* ???*12*[(0 | ???*13*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ") + ⚠️ nested operation +- *13* updated with update expression + ⚠️ This value might have side effects + +0 -> 1536 call = (...) => undefined((???*0* | ???*1* | "animationend" | ???*2*), "onAnimationEnd") +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 1537 call = (...) => undefined((???*0* | ???*1* | "animationiteration" | ???*2*), "onAnimationIteration") +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 1538 call = (...) => undefined((???*0* | ???*1* | "animationstart" | ???*2*), "onAnimationStart") +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 1539 call = (...) => undefined("dblclick", "onDoubleClick") + +0 -> 1540 call = (...) => undefined("focusin", "onFocus") + +0 -> 1541 call = (...) => undefined("focusout", "onBlur") + +0 -> 1542 call = (...) => undefined((???*0* | ???*1* | "transitionend" | ???*2*), "onTransitionEnd") +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 1543 call = (...) => undefined("onMouseEnter", ["mouseout", "mouseover"]) + +0 -> 1544 call = (...) => undefined("onMouseLeave", ["mouseout", "mouseover"]) + +0 -> 1545 call = (...) => undefined("onPointerEnter", ["pointerout", "pointerover"]) + +0 -> 1546 call = (...) => undefined("onPointerLeave", ["pointerout", "pointerover"]) + +0 -> 1548 member call = "change click focusin focusout input keydown keyup selectionchange"["split"](" ") + +0 -> 1549 call = (...) => undefined( + "onChange", + "change click focusin focusout input keydown keyup selectionchange"["split"](" ") +) + +0 -> 1551 member call = "focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange"["split"](" ") + +0 -> 1552 call = (...) => undefined( + "onSelect", + "focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange"["split"](" ") +) + +0 -> 1553 call = (...) => undefined( + "onBeforeInput", + ["compositionend", "keypress", "textInput", "paste"] +) + +0 -> 1555 member call = "compositionend focusout keydown keypress keyup mousedown"["split"](" ") + +0 -> 1556 call = (...) => undefined( + "onCompositionEnd", + "compositionend focusout keydown keypress keyup mousedown"["split"](" ") +) + +0 -> 1558 member call = "compositionstart focusout keydown keypress keyup mousedown"["split"](" ") + +0 -> 1559 call = (...) => undefined( + "onCompositionStart", + "compositionstart focusout keydown keypress keyup mousedown"["split"](" ") +) + +0 -> 1561 member call = "compositionupdate focusout keydown keypress keyup mousedown"["split"](" ") + +0 -> 1562 call = (...) => undefined( + "onCompositionUpdate", + "compositionupdate focusout keydown keypress keyup mousedown"["split"](" ") +) + +0 -> 1564 member call = "abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting"["split"](" ") + +0 -> 1565 free var = FreeVar(Set) + +0 -> 1568 member call = "cancel close invalid load scroll toggle"["split"](" ") + +0 -> 1569 member call = "cancel close invalid load scroll toggle"["split"](" ")["concat"]( + "abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting"["split"](" ") +) + +0 -> 1572 call = (...) => undefined((???*0* | "unknown-event"), ???*2*, ???*3*, ???*4*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1578 conditional = (???*0* | (0 !== ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +1578 -> 1585 member call = (???*0* | null[(0 | ???*4*)]["event"] | ???*5*)["isPropagationStopped"]() +- *0* ???*1*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["event"] + ⚠️ unknown object +- *6* ???*7*["listeners"] + ⚠️ unknown object +- *7* d + ⚠️ circular variable reference + +1578 -> 1586 call = (...) => undefined( + (???*0* | null[(0 | ???*4*)]["event"] | ???*5*), + (???*8* | null[(0 | ???*14*)][(???*15* | ???*16* | 0)] | ???*17*), + ( + | ???*19* + | null[(0 | ???*26*)][(???*27* | ???*28* | 0)]["currentTarget"] + | ???*29* + ) +) +- *0* ???*1*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["event"] + ⚠️ unknown object +- *6* ???*7*["listeners"] + ⚠️ unknown object +- *7* d + ⚠️ circular variable reference +- *8* ???*9*[(???*12* | ???*13* | 0)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*[(0 | ???*11*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* updated with update expression + ⚠️ This value might have side effects +- *14* updated with update expression + ⚠️ This value might have side effects +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* updated with update expression + ⚠️ This value might have side effects +- *17* ???*18*["listener"] + ⚠️ unknown object +- *18* h + ⚠️ circular variable reference +- *19* ???*20*["currentTarget"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* ???*21*[(???*24* | ???*25* | 0)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* ???*22*[(0 | ???*23*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* updated with update expression + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* updated with update expression + ⚠️ This value might have side effects +- *26* updated with update expression + ⚠️ This value might have side effects +- *27* unsupported expression + ⚠️ This value might have side effects +- *28* updated with update expression + ⚠️ This value might have side effects +- *29* ???*30*["currentTarget"] + ⚠️ unknown object +- *30* ???*31*["listener"] + ⚠️ unknown object +- *31* h + ⚠️ circular variable reference + +1578 -> 1593 member call = (???*0* | null[(0 | ???*4*)]["event"] | ???*5*)["isPropagationStopped"]() +- *0* ???*1*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["event"] + ⚠️ unknown object +- *6* ???*7*["listeners"] + ⚠️ unknown object +- *7* d + ⚠️ circular variable reference + +1578 -> 1594 call = (...) => undefined( + (???*0* | null[(0 | ???*4*)]["event"] | ???*5*), + (???*8* | null[(0 | ???*14*)][(???*15* | ???*16* | 0)] | ???*17*), + ( + | ???*19* + | null[(0 | ???*26*)][(???*27* | ???*28* | 0)]["currentTarget"] + | ???*29* + ) +) +- *0* ???*1*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["event"] + ⚠️ unknown object +- *6* ???*7*["listeners"] + ⚠️ unknown object +- *7* d + ⚠️ circular variable reference +- *8* ???*9*[(???*12* | ???*13* | 0)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*[(0 | ???*11*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* updated with update expression + ⚠️ This value might have side effects +- *14* updated with update expression + ⚠️ This value might have side effects +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* updated with update expression + ⚠️ This value might have side effects +- *17* ???*18*["listener"] + ⚠️ unknown object +- *18* h + ⚠️ circular variable reference +- *19* ???*20*["currentTarget"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* ???*21*[(???*24* | ???*25* | 0)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* ???*22*[(0 | ???*23*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* updated with update expression + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* updated with update expression + ⚠️ This value might have side effects +- *26* updated with update expression + ⚠️ This value might have side effects +- *27* unsupported expression + ⚠️ This value might have side effects +- *28* updated with update expression + ⚠️ This value might have side effects +- *29* ???*30*["currentTarget"] + ⚠️ unknown object +- *30* ???*31*["listener"] + ⚠️ unknown object +- *31* h + ⚠️ circular variable reference + +0 -> 1597 free var = FreeVar(Set) + +0 -> 1599 member call = (???*0* | ???*2*)["has"](`${???*3*}__bubble`) +- *0* ???*1*[of] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1600 call = (...) => undefined(???*0*, ???*1*, 2, false) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1602 member call = (???*0* | ???*2*)["add"](`${???*3*}__bubble`) +- *0* ???*1*[of] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1603 call = (...) => undefined(???*0*, ???*1*, (0 | ???*2*), ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1607 free var = FreeVar(Math) + +0 -> 1608 member call = ???*0*["random"]() +- *0* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1609 member call = ???*0*()["toString"](36) +- *0* ???*1*["random"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1610 member call = ???*0*["slice"](2) +- *0* ???*1*(36) + ⚠️ unknown callee +- *1* ???*2*["toString"] + ⚠️ unknown object +- *2* ???*3*() + ⚠️ nested operation +- *3* ???*4*["random"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1612 conditional = !(???*0*) +- *0* ???*1*[rf] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1612 -> 1615 member call = ???*0*["forEach"]((...) => undefined) +- *0* unknown new expression + ⚠️ This value might have side effects + +1615 -> 1617 member call = ???*0*["has"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1615 -> 1618 call = (...) => undefined(???*0*, false, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1615 -> 1619 call = (...) => undefined(???*0*, true, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1612 -> 1621 conditional = (9 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1612 -> 1625 call = (...) => undefined("selectionchange", false, (???*0* ? ???*3* : ???*4*)) +- *0* (9 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["ownerDocument"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1626 call = (...) => (undefined | 1 | 4 | 16 | 536870912)(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1628 member call = ((...) => undefined | ???*0* | true)["bind"]( + null, + ???*1*, + ( + | ???*2* + | (...) => undefined["bind"](null, ???*3*, ???*4*, ???*5*) + | ???*6* + | true["bind"](null, ???*11*, ???*12*, ???*13*) + ), + ???*14* +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* c + ⚠️ circular variable reference +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["bind"](null, ???*8*, ???*9*, ???*10*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* c + ⚠️ circular variable reference +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* c + ⚠️ circular variable reference +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1629 conditional = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +1629 -> 1630 conditional = (???*0* !== ((...) => undefined | ???*1* | true)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +1630 -> 1632 member call = ???*0*["addEventListener"]( + ???*1*, + ( + | ???*2* + | (...) => undefined["bind"](null, ???*3*, ???*4*, ???*5*) + | ???*6* + | true["bind"](null, ???*11*, ???*12*, ???*13*) + ), + {"capture": true, "passive": ((...) => undefined | ???*14* | true)} +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* c + ⚠️ circular variable reference +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["bind"](null, ???*8*, ???*9*, ???*10*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* c + ⚠️ circular variable reference +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* c + ⚠️ circular variable reference +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* unsupported expression + ⚠️ This value might have side effects + +1630 -> 1634 member call = ???*0*["addEventListener"]( + ???*1*, + ( + | ???*2* + | (...) => undefined["bind"](null, ???*3*, ???*4*, ???*5*) + | ???*6* + | true["bind"](null, ???*11*, ???*12*, ???*13*) + ), + true +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* c + ⚠️ circular variable reference +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["bind"](null, ???*8*, ???*9*, ???*10*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* c + ⚠️ circular variable reference +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* c + ⚠️ circular variable reference +- *13* arguments[0] + ⚠️ function calls are not analysed yet + +1629 -> 1635 conditional = (???*0* !== ((...) => undefined | ???*1* | true)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +1635 -> 1637 member call = ???*0*["addEventListener"]( + ???*1*, + ( + | ???*2* + | (...) => undefined["bind"](null, ???*3*, ???*4*, ???*5*) + | ???*6* + | true["bind"](null, ???*11*, ???*12*, ???*13*) + ), + {"passive": ((...) => undefined | ???*14* | true)} +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* c + ⚠️ circular variable reference +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["bind"](null, ???*8*, ???*9*, ???*10*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* c + ⚠️ circular variable reference +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* c + ⚠️ circular variable reference +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* unsupported expression + ⚠️ This value might have side effects + +1635 -> 1639 member call = ???*0*["addEventListener"]( + ???*1*, + ( + | ???*2* + | (...) => undefined["bind"](null, ???*3*, ???*4*, ???*5*) + | ???*6* + | true["bind"](null, ???*11*, ???*12*, ???*13*) + ), + false +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* c + ⚠️ circular variable reference +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["bind"](null, ???*8*, ???*9*, ???*10*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* c + ⚠️ circular variable reference +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* c + ⚠️ circular variable reference +- *13* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1640 conditional = ((0 === ???*0*) | (null !== (???*1* | ???*2* | ???*3*))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["return"] + ⚠️ unknown object +- *4* d + ⚠️ circular variable reference + +1640 -> 1642 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1642 -> 1647 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1647 -> 1650 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1642 -> 1656 call = (...) => (b | c | null)((???*0* | ???*3*)) +- *0* ???*1*["containerInfo"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* ???*4*["containerInfo"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +0 -> 1660 call = (...) => (undefined | a(b, c) | Gb(a, b, c))((...) => undefined) + +1660 -> 1661 call = (...) => ((3 === a["nodeType"]) ? a["parentNode"] : a)(???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +1660 -> 1663 member call = ???*0*["get"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1660 -> 1664 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1664 -> 1665 call = (...) => ((???*0* || (13 === a)) ? a : 0)(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +1664 -> 1667 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1667 -> 1668 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1664 -> 1671 call = (...) => (null | c)(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1664 -> 1673 call = (...) => {"instance": a, "listener": b, "currentTarget": c}(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1664 -> 1674 member call = ???*0*["push"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1664 -> 1678 member call = []["push"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1660 -> 1679 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +1679 -> 1682 call = (...) => (b | c | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1684 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1684 -> 1686 conditional = ((???*0* | ???*15*) === (???*17* | ???*31*)) +- *0* ???*1*["window"] + ⚠️ unknown object +- *1* (???*2* ? (???*7* | ???*9*) : (???*11* | ???*12* | ???*14*)) + ⚠️ nested operation +- *2* (3 === (???*3* | ???*5*)) + ⚠️ nested operation +- *3* ???*4*["nodeType"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* ???*8*["parentNode"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* ???*10*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* ???*13*["target"] + ⚠️ unknown object +- *13* a + ⚠️ circular variable reference +- *14* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *15* ???*16*["window"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* unknown new expression + ⚠️ This value might have side effects +- *17* (???*18* ? (???*23* | ???*25*) : (???*27* | ???*28* | ???*30*)) + ⚠️ nested operation +- *18* (3 === (???*19* | ???*21*)) + ⚠️ nested operation +- *19* ???*20*["nodeType"] + ⚠️ unknown object +- *20* arguments[2] + ⚠️ function calls are not analysed yet +- *21* ???*22*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *23* ???*24*["parentNode"] + ⚠️ unknown object +- *24* arguments[2] + ⚠️ function calls are not analysed yet +- *25* ???*26*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *27* arguments[2] + ⚠️ function calls are not analysed yet +- *28* ???*29*["target"] + ⚠️ unknown object +- *29* a + ⚠️ circular variable reference +- *30* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *31* unknown new expression + ⚠️ This value might have side effects + +1686 -> 1690 free var = FreeVar(window) + +1684 -> 1691 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1691 -> 1694 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1694 -> 1695 call = (...) => (b | c | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1691 -> 1696 call = (...) => ((3 === b["tag"]) ? c : null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1684 -> 1699 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1699 -> 1700 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1700 -> 1701 call = (...) => (undefined | a["stateNode"])(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1699 -> 1702 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1702 -> 1703 call = (...) => (undefined | a["stateNode"])(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1699 -> 1706 call = (...) => (b | c | null)( + ( + | (???*0* ? (???*5* | ???*7*) : (???*9* | ???*10* | ???*12*)) + | ???*13* + ) +) +- *0* (3 === (???*1* | ???*3*)) + ⚠️ nested operation +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* ???*6*["parentNode"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["target"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* unknown new expression + ⚠️ This value might have side effects + +1699 -> 1709 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1709 -> 1710 call = (...) => (null | (a ? a : null))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1709 -> 1711 call = (...) => (null | (a ? a : null))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1709 -> 1712 call = (...) => (null | (a ? a : null))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1709 -> 1713 call = (...) => (null | (a ? a : null))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1709 -> 1715 call = (...) => (null | (a ? a : null))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1709 -> 1716 call = (...) => (null | (a ? a : null))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1699 -> 1717 call = (...) => undefined([], ???*0*, ???*1*, ???*2*, false) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1699 -> 1718 call = (...) => undefined([], ???*0*, ???*1*, ???*2*, true) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1719 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1719 -> 1720 call = (...) => (undefined | a["stateNode"])(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1719 -> 1721 free var = FreeVar(window) + +1679 -> 1725 member call = ???*0*["toLowerCase"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1727 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1727 -> 1728 call = (...) => (("input" === b) ? !(!(le[a["type"]])) : (("textarea" === b) ? !(0) : !(1)))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1727 -> 1729 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1729 -> 1732 member call = ???*0*["toLowerCase"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1735 call = ( + | (...) => (undefined | b) + | (...) => (undefined | te(b)) + | (...) => (undefined | te(qe)) + | (...) => (undefined | te(b)) + | ???*0* +)(???*2*, ???*3*) +- *0* ???*1*(a, d) + ⚠️ unknown callee +- *1* na + ⚠️ circular variable reference +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1736 conditional = ( + | (...) => (undefined | b) + | (...) => (undefined | te(b)) + | (...) => (undefined | te(qe)) + | (...) => (undefined | te(b)) + | ???*0* + | ???*2* +) +- *0* ???*1*(a, d) + ⚠️ unknown callee +- *1* na + ⚠️ circular variable reference +- *2* unsupported expression + ⚠️ This value might have side effects + +1736 -> 1737 call = (...) => undefined( + [], + ( + | (...) => (undefined | b) + | (...) => (undefined | te(b)) + | (...) => (undefined | te(qe)) + | (...) => (undefined | te(b)) + | ???*0* + ), + ???*2*, + ( + | (???*3* ? (???*8* | ???*10*) : (???*12* | ???*13* | ???*15*)) + | ???*16* + ) +) +- *0* ???*1*(a, d) + ⚠️ unknown callee +- *1* na + ⚠️ circular variable reference +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* (3 === (???*4* | ???*6*)) + ⚠️ nested operation +- *4* ???*5*["nodeType"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* ???*7*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* ???*9*["parentNode"] + ⚠️ unknown object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*["target"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* unknown new expression + ⚠️ This value might have side effects + +1679 -> 1738 call = ???*0*(???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1743 call = (...) => undefined(???*0*, "number", ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1744 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1744 -> 1745 call = (...) => (undefined | a["stateNode"])(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1744 -> 1746 free var = FreeVar(window) + +1679 -> 1747 call = (...) => (("input" === b) ? !(!(le[a["type"]])) : (("textarea" === b) ? !(0) : !(1)))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1749 call = (...) => undefined( + [], + ???*0*, + ( + | (???*1* ? (???*6* | ???*8*) : (???*10* | ???*11* | ???*13*)) + | ???*14* + ) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (3 === (???*2* | ???*4*)) + ⚠️ nested operation +- *2* ???*3*["nodeType"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* ???*5*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* ???*7*["parentNode"] + ⚠️ unknown object +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* ???*12*["target"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *14* unknown new expression + ⚠️ This value might have side effects + +1679 -> 1750 call = (...) => undefined( + [], + ???*0*, + ( + | (???*1* ? (???*6* | ???*8*) : (???*10* | ???*11* | ???*13*)) + | ???*14* + ) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (3 === (???*2* | ???*4*)) + ⚠️ nested operation +- *2* ???*3*["nodeType"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* ???*5*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* ???*7*["parentNode"] + ⚠️ unknown object +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* ???*12*["target"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *14* unknown new expression + ⚠️ This value might have side effects + +1679 -> 1751 conditional = (!(???*0*) | ???*3*) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +1751 -> 1752 conditional = (false | true) + +1752 -> 1753 call = (...) => (undefined | (???*0* !== $d["indexOf"](b["keyCode"])) | (229 !== b["keyCode"]) | !(0) | !(1))(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +1679 -> 1756 conditional = ( + | false + | true + | ("onCompositionStart" !== ("onCompositionStart" | "onCompositionEnd" | "onCompositionUpdate" | ???*0* | ???*1*)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unknown new expression + ⚠️ This value might have side effects + +1756 -> 1757 call = (...) => (md | ???*0*)() +- *0* unsupported expression + ⚠️ This value might have side effects + +1679 -> 1760 call = (...) => d( + ???*0*, + ("onCompositionStart" | "onCompositionEnd" | "onCompositionUpdate" | ???*1* | ???*2*) +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unknown new expression + ⚠️ This value might have side effects + +1679 -> 1763 member call = []["push"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1764 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1764 -> 1766 call = (...) => ((("object" === typeof(a)) && ???*0*) ? a["data"] : null)(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +1679 -> 1768 conditional = (!(???*0*) | ???*3* | !((null | ???*4*))) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["documentMode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +1768 -> 1769 call = (...) => (undefined | he(b) | null | ee | ???*0*)(???*1*, ???*2*) +- *0* (((a === ee) && fe) ? null : a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +1768 -> 1770 call = (...) => ( + | undefined + | ((("compositionend" === a) || (!(ae) && ge(a, b))) ? ???*0* : null) + | null + | b["char"] + | FreeVar(String)["fromCharCode"](b["which"]) + | ((de && ("ko" !== b["locale"])) ? null : b["data"]) +)(???*1*, ???*2*) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +1679 -> 1771 call = (...) => d(???*0*, "onBeforeInput") +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1679 -> 1774 member call = []["push"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1660 -> 1776 call = (...) => undefined([], ???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1779 call = (...) => (null | c)((???*0* | ???*1*), `${???*3*}Capture`) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1781 call = (...) => {"instance": a, "listener": b, "currentTarget": c}( + (???*0* | ???*1*), + ( + | ???*3* + | null + | !((???*5* | null | ???*7*))["stateNode"] + | false["stateNode"] + | null[`${???*10*}Capture`] + | !(???*11*)[`${???*13*}Capture`] + | !(???*14*)[`${???*20*}Capture`] + | !((???*21* | null | ???*23*))["stateNode"] + | null[???*26*] + | !(???*27*)[???*29*] + | !(???*30*)[???*36*] + ), + ( + | ???*37* + | ???*38* + | null + | !((???*40* | null | ???*42*))["stateNode"] + | false["stateNode"] + | null[`${???*45*}Capture`] + | !(???*46*)[`${???*48*}Capture`] + | !(???*49*)[`${???*55*}Capture`] + | !((???*56* | null | ???*58*))["stateNode"] + | null[???*61*] + | !(???*62*)[???*64*] + | !(???*65*)[???*71*] + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*[Pf] + ⚠️ unknown object +- *6* c + ⚠️ circular variable reference +- *7* !(???*8*) + ⚠️ nested operation +- *8* ???*9*["disabled"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["disabled"] + ⚠️ unknown object +- *12* d + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* ("button" === (???*15* | ???*16* | ???*18* | false)) + ⚠️ nested operation +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* ???*17*["return"] + ⚠️ unknown object +- *17* a + ⚠️ circular variable reference +- *18* !(???*19*) + ⚠️ nested operation +- *19* d + ⚠️ circular variable reference +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*[Pf] + ⚠️ unknown object +- *22* c + ⚠️ circular variable reference +- *23* !(???*24*) + ⚠️ nested operation +- *24* ???*25*["disabled"] + ⚠️ unknown object +- *25* d + ⚠️ circular variable reference +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* ???*28*["disabled"] + ⚠️ unknown object +- *28* d + ⚠️ circular variable reference +- *29* arguments[1] + ⚠️ function calls are not analysed yet +- *30* ("button" === (???*31* | ???*32* | ???*34* | false)) + ⚠️ nested operation +- *31* arguments[0] + ⚠️ function calls are not analysed yet +- *32* ???*33*["return"] + ⚠️ unknown object +- *33* a + ⚠️ circular variable reference +- *34* !(???*35*) + ⚠️ nested operation +- *35* d + ⚠️ circular variable reference +- *36* arguments[1] + ⚠️ function calls are not analysed yet +- *37* arguments[0] + ⚠️ function calls are not analysed yet +- *38* ???*39*["return"] + ⚠️ unknown object +- *39* a + ⚠️ circular variable reference +- *40* ???*41*[Pf] + ⚠️ unknown object +- *41* c + ⚠️ circular variable reference +- *42* !(???*43*) + ⚠️ nested operation +- *43* ???*44*["disabled"] + ⚠️ unknown object +- *44* d + ⚠️ circular variable reference +- *45* arguments[1] + ⚠️ function calls are not analysed yet +- *46* ???*47*["disabled"] + ⚠️ unknown object +- *47* d + ⚠️ circular variable reference +- *48* arguments[1] + ⚠️ function calls are not analysed yet +- *49* ("button" === (???*50* | ???*51* | ???*53* | false)) + ⚠️ nested operation +- *50* arguments[0] + ⚠️ function calls are not analysed yet +- *51* ???*52*["return"] + ⚠️ unknown object +- *52* a + ⚠️ circular variable reference +- *53* !(???*54*) + ⚠️ nested operation +- *54* d + ⚠️ circular variable reference +- *55* arguments[1] + ⚠️ function calls are not analysed yet +- *56* ???*57*[Pf] + ⚠️ unknown object +- *57* c + ⚠️ circular variable reference +- *58* !(???*59*) + ⚠️ nested operation +- *59* ???*60*["disabled"] + ⚠️ unknown object +- *60* d + ⚠️ circular variable reference +- *61* arguments[1] + ⚠️ function calls are not analysed yet +- *62* ???*63*["disabled"] + ⚠️ unknown object +- *63* d + ⚠️ circular variable reference +- *64* arguments[1] + ⚠️ function calls are not analysed yet +- *65* ("button" === (???*66* | ???*67* | ???*69* | false)) + ⚠️ nested operation +- *66* arguments[0] + ⚠️ function calls are not analysed yet +- *67* ???*68*["return"] + ⚠️ unknown object +- *68* a + ⚠️ circular variable reference +- *69* !(???*70*) + ⚠️ nested operation +- *70* d + ⚠️ circular variable reference +- *71* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1782 member call = []["unshift"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1783 call = (...) => (null | c)((???*0* | ???*1*), ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1785 call = (...) => {"instance": a, "listener": b, "currentTarget": c}( + (???*0* | ???*1*), + ( + | ???*3* + | null + | !((???*5* | null | ???*7*))["stateNode"] + | false["stateNode"] + | null[`${???*10*}Capture`] + | !(???*11*)[`${???*13*}Capture`] + | !(???*14*)[`${???*20*}Capture`] + | !((???*21* | null | ???*23*))["stateNode"] + | null[???*26*] + | !(???*27*)[???*29*] + | !(???*30*)[???*36*] + ), + ( + | ???*37* + | ???*38* + | null + | !((???*40* | null | ???*42*))["stateNode"] + | false["stateNode"] + | null[`${???*45*}Capture`] + | !(???*46*)[`${???*48*}Capture`] + | !(???*49*)[`${???*55*}Capture`] + | !((???*56* | null | ???*58*))["stateNode"] + | null[???*61*] + | !(???*62*)[???*64*] + | !(???*65*)[???*71*] + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*[Pf] + ⚠️ unknown object +- *6* c + ⚠️ circular variable reference +- *7* !(???*8*) + ⚠️ nested operation +- *8* ???*9*["disabled"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["disabled"] + ⚠️ unknown object +- *12* d + ⚠️ circular variable reference +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* ("button" === (???*15* | ???*16* | ???*18* | false)) + ⚠️ nested operation +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* ???*17*["return"] + ⚠️ unknown object +- *17* a + ⚠️ circular variable reference +- *18* !(???*19*) + ⚠️ nested operation +- *19* d + ⚠️ circular variable reference +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*[Pf] + ⚠️ unknown object +- *22* c + ⚠️ circular variable reference +- *23* !(???*24*) + ⚠️ nested operation +- *24* ???*25*["disabled"] + ⚠️ unknown object +- *25* d + ⚠️ circular variable reference +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* ???*28*["disabled"] + ⚠️ unknown object +- *28* d + ⚠️ circular variable reference +- *29* arguments[1] + ⚠️ function calls are not analysed yet +- *30* ("button" === (???*31* | ???*32* | ???*34* | false)) + ⚠️ nested operation +- *31* arguments[0] + ⚠️ function calls are not analysed yet +- *32* ???*33*["return"] + ⚠️ unknown object +- *33* a + ⚠️ circular variable reference +- *34* !(???*35*) + ⚠️ nested operation +- *35* d + ⚠️ circular variable reference +- *36* arguments[1] + ⚠️ function calls are not analysed yet +- *37* arguments[0] + ⚠️ function calls are not analysed yet +- *38* ???*39*["return"] + ⚠️ unknown object +- *39* a + ⚠️ circular variable reference +- *40* ???*41*[Pf] + ⚠️ unknown object +- *41* c + ⚠️ circular variable reference +- *42* !(???*43*) + ⚠️ nested operation +- *43* ???*44*["disabled"] + ⚠️ unknown object +- *44* d + ⚠️ circular variable reference +- *45* arguments[1] + ⚠️ function calls are not analysed yet +- *46* ???*47*["disabled"] + ⚠️ unknown object +- *47* d + ⚠️ circular variable reference +- *48* arguments[1] + ⚠️ function calls are not analysed yet +- *49* ("button" === (???*50* | ???*51* | ???*53* | false)) + ⚠️ nested operation +- *50* arguments[0] + ⚠️ function calls are not analysed yet +- *51* ???*52*["return"] + ⚠️ unknown object +- *52* a + ⚠️ circular variable reference +- *53* !(???*54*) + ⚠️ nested operation +- *54* d + ⚠️ circular variable reference +- *55* arguments[1] + ⚠️ function calls are not analysed yet +- *56* ???*57*[Pf] + ⚠️ unknown object +- *57* c + ⚠️ circular variable reference +- *58* !(???*59*) + ⚠️ nested operation +- *59* ???*60*["disabled"] + ⚠️ unknown object +- *60* d + ⚠️ circular variable reference +- *61* arguments[1] + ⚠️ function calls are not analysed yet +- *62* ???*63*["disabled"] + ⚠️ unknown object +- *63* d + ⚠️ circular variable reference +- *64* arguments[1] + ⚠️ function calls are not analysed yet +- *65* ("button" === (???*66* | ???*67* | ???*69* | false)) + ⚠️ nested operation +- *66* arguments[0] + ⚠️ function calls are not analysed yet +- *67* ???*68*["return"] + ⚠️ unknown object +- *68* a + ⚠️ circular variable reference +- *69* !(???*70*) + ⚠️ nested operation +- *70* d + ⚠️ circular variable reference +- *71* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1786 member call = []["push"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1790 conditional = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +0 -> 1795 conditional = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +1795 -> 1796 call = (...) => (null | c)((???*0* | ???*1*), ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["_reactName"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +1795 -> 1798 call = (...) => {"instance": a, "listener": b, "currentTarget": c}( + (???*0* | ???*1*), + ( + | ???*3* + | null + | !((???*5* | null | ???*7*))["stateNode"] + | false["stateNode"] + | null[???*10*] + | !(???*12*)[???*14*] + | !(???*16*)[???*22*] + ), + (???*24* | ???*25*) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*[Pf] + ⚠️ unknown object +- *6* c + ⚠️ circular variable reference +- *7* !(???*8*) + ⚠️ nested operation +- *8* ???*9*["disabled"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* ???*11*["_reactName"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ???*13*["disabled"] + ⚠️ unknown object +- *13* d + ⚠️ circular variable reference +- *14* ???*15*["_reactName"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* ("button" === (???*17* | ???*18* | ???*20* | false)) + ⚠️ nested operation +- *17* arguments[2] + ⚠️ function calls are not analysed yet +- *18* ???*19*["return"] + ⚠️ unknown object +- *19* c + ⚠️ circular variable reference +- *20* !(???*21*) + ⚠️ nested operation +- *21* d + ⚠️ circular variable reference +- *22* ???*23*["_reactName"] + ⚠️ unknown object +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* arguments[2] + ⚠️ function calls are not analysed yet +- *25* ???*26*["return"] + ⚠️ unknown object +- *26* c + ⚠️ circular variable reference + +1795 -> 1799 member call = []["unshift"]( + { + "instance": (???*0* | ???*1*), + "listener": ( + | ???*3* + | null + | !((???*5* | null | ???*7*))["stateNode"] + | false["stateNode"] + | null[???*10*] + | !(???*12*)[???*14*] + | !(???*16*)[???*22*] + ), + "currentTarget": (???*24* | ???*25*) + } +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*[Pf] + ⚠️ unknown object +- *6* c + ⚠️ circular variable reference +- *7* !(???*8*) + ⚠️ nested operation +- *8* ???*9*["disabled"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* ???*11*["_reactName"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ???*13*["disabled"] + ⚠️ unknown object +- *13* d + ⚠️ circular variable reference +- *14* ???*15*["_reactName"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* ("button" === (???*17* | ???*18* | ???*20* | false)) + ⚠️ nested operation +- *17* arguments[2] + ⚠️ function calls are not analysed yet +- *18* ???*19*["return"] + ⚠️ unknown object +- *19* c + ⚠️ circular variable reference +- *20* !(???*21*) + ⚠️ nested operation +- *21* d + ⚠️ circular variable reference +- *22* ???*23*["_reactName"] + ⚠️ unknown object +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* arguments[2] + ⚠️ function calls are not analysed yet +- *25* ???*26*["return"] + ⚠️ unknown object +- *26* c + ⚠️ circular variable reference + +1795 -> 1800 call = (...) => (null | c)((???*0* | ???*1*), ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["_reactName"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +1795 -> 1802 call = (...) => {"instance": a, "listener": b, "currentTarget": c}( + (???*0* | ???*1*), + ( + | ???*3* + | null + | !((???*5* | null | ???*7*))["stateNode"] + | false["stateNode"] + | null[???*10*] + | !(???*12*)[???*14*] + | !(???*16*)[???*22*] + ), + (???*24* | ???*25*) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*[Pf] + ⚠️ unknown object +- *6* c + ⚠️ circular variable reference +- *7* !(???*8*) + ⚠️ nested operation +- *8* ???*9*["disabled"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* ???*11*["_reactName"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ???*13*["disabled"] + ⚠️ unknown object +- *13* d + ⚠️ circular variable reference +- *14* ???*15*["_reactName"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* ("button" === (???*17* | ???*18* | ???*20* | false)) + ⚠️ nested operation +- *17* arguments[2] + ⚠️ function calls are not analysed yet +- *18* ???*19*["return"] + ⚠️ unknown object +- *19* c + ⚠️ circular variable reference +- *20* !(???*21*) + ⚠️ nested operation +- *21* d + ⚠️ circular variable reference +- *22* ???*23*["_reactName"] + ⚠️ unknown object +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* arguments[2] + ⚠️ function calls are not analysed yet +- *25* ???*26*["return"] + ⚠️ unknown object +- *26* c + ⚠️ circular variable reference + +1795 -> 1803 member call = []["push"]( + { + "instance": (???*0* | ???*1*), + "listener": ( + | ???*3* + | null + | !((???*5* | null | ???*7*))["stateNode"] + | false["stateNode"] + | null[???*10*] + | !(???*12*)[???*14*] + | !(???*16*)[???*22*] + ), + "currentTarget": (???*24* | ???*25*) + } +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*[Pf] + ⚠️ unknown object +- *6* c + ⚠️ circular variable reference +- *7* !(???*8*) + ⚠️ nested operation +- *8* ???*9*["disabled"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* ???*11*["_reactName"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ???*13*["disabled"] + ⚠️ unknown object +- *13* d + ⚠️ circular variable reference +- *14* ???*15*["_reactName"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* ("button" === (???*17* | ???*18* | ???*20* | false)) + ⚠️ nested operation +- *17* arguments[2] + ⚠️ function calls are not analysed yet +- *18* ???*19*["return"] + ⚠️ unknown object +- *19* c + ⚠️ circular variable reference +- *20* !(???*21*) + ⚠️ nested operation +- *21* d + ⚠️ circular variable reference +- *22* ???*23*["_reactName"] + ⚠️ unknown object +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* arguments[2] + ⚠️ function calls are not analysed yet +- *25* ???*26*["return"] + ⚠️ unknown object +- *26* c + ⚠️ circular variable reference + +0 -> 1807 member call = ???*0*["push"]({"event": ???*1*, "listeners": []}) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1810 conditional = ("string" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1811 member call = (???*0* ? ???*3* : ???*4*)["replace"](/\r\n?/g, "\n") +- *0* ("string" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1812 member call = ???*0*["replace"](/\u0000|\uFFFD/g, "") +- *0* ???*1*(/\r\n?/g, "\n") + ⚠️ unknown callee +- *1* ???*2*["replace"] + ⚠️ unknown object +- *2* (???*3* ? ???*5* : ???*6*) + ⚠️ nested operation +- *3* ("string" === ???*4*) + ⚠️ nested operation +- *4* typeof(???) + ⚠️ nested operation +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1813 call = (...) => (("string" === typeof(a)) ? a : `${a}`)["replace"](xf, "\n")["replace"](yf, "")((???*0* | ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["replace"](yf, "") + ⚠️ unknown callee object +- *2* ???*3*(/\r\n?/g, "\n") + ⚠️ unknown callee +- *3* ???*4*["replace"] + ⚠️ unknown object +- *4* (???*5* ? ???*6* : ???*7*) + ⚠️ nested operation +- *5* ("string" === ???) + ⚠️ nested operation +- *6* b + ⚠️ circular variable reference +- *7* b + ⚠️ circular variable reference + +0 -> 1814 call = (...) => (("string" === typeof(a)) ? a : `${a}`)["replace"](xf, "\n")["replace"](yf, "")(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1815 conditional = ((???*0* !== (???*7* | ???*8*)) | ???*15*) +- *0* ???*1*["replace"](yf, "") + ⚠️ unknown callee object +- *1* ???*2*(/\r\n?/g, "\n") + ⚠️ unknown callee +- *2* ???*3*["replace"] + ⚠️ unknown object +- *3* (???*4* ? ???*5* : ???*6*) + ⚠️ nested operation +- *4* ("string" === ???) + ⚠️ nested operation +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???*9*["replace"](yf, "") + ⚠️ unknown callee object +- *9* ???*10*(/\r\n?/g, "\n") + ⚠️ unknown callee +- *10* ???*11*["replace"] + ⚠️ unknown object +- *11* (???*12* ? ???*13* : ???*14*) + ⚠️ nested operation +- *12* ("string" === ???) + ⚠️ nested operation +- *13* b + ⚠️ circular variable reference +- *14* b + ⚠️ circular variable reference +- *15* arguments[2] + ⚠️ function calls are not analysed yet + +1815 -> 1816 free var = FreeVar(Error) + +1815 -> 1817 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(425) + +1815 -> 1818 call = ???*0*( + `Minified React error #${425}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${425}` + ⚠️ nested operation + +0 -> 1825 free var = FreeVar(setTimeout) + +0 -> 1826 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects + +1826 -> 1827 free var = FreeVar(setTimeout) + +0 -> 1828 free var = FreeVar(clearTimeout) + +0 -> 1829 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(clearTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects + +1829 -> 1830 free var = FreeVar(clearTimeout) + +0 -> 1831 free var = FreeVar(Promise) + +0 -> 1832 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects + +1832 -> 1833 free var = FreeVar(Promise) + +0 -> 1834 free var = FreeVar(queueMicrotask) + +0 -> 1835 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(queueMicrotask) + ⚠️ unknown global + ⚠️ This value might have side effects + +1835 -> 1836 free var = FreeVar(queueMicrotask) + +1835 -> 1837 conditional = ("undefined" !== ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* (???*2* ? ???*5* : ???*6*) + ⚠️ nested operation +- *2* ("function" === ???*3*) + ⚠️ nested operation +- *3* typeof(???*4*) + ⚠️ nested operation +- *4* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects + +1837 -> 1841 member call = (???*0* ? ???*3* : ???*4*)["resolve"](null) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +1837 -> 1842 member call = ???*0*["then"](???*7*) +- *0* ???*1*(null) + ⚠️ unknown callee +- *1* ???*2*["resolve"] + ⚠️ unknown object +- *2* (???*3* ? ???*5* : ???*6*) + ⚠️ nested operation +- *3* ("function" === ???*4*) + ⚠️ nested operation +- *4* typeof(???) + ⚠️ nested operation +- *5* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +1837 -> 1843 member call = ???*0*["catch"]((...) => undefined) +- *0* ???*1*["then"](a) + ⚠️ unknown callee object +- *1* ???*2*(null) + ⚠️ unknown callee +- *2* ???*3*["resolve"] + ⚠️ unknown object +- *3* (???*4* ? ???*5* : ???*6*) + ⚠️ nested operation +- *4* ("function" === ???) + ⚠️ nested operation +- *5* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects + +0 -> 1844 free var = FreeVar(setTimeout) + +0 -> 1845 call = ???*0*((...) => undefined) +- *0* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1848 member call = ???*0*["removeChild"]((???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["data"] + ⚠️ unknown object +- *3* ???*4*["nextSibling"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 1850 conditional = (???*0* | (8 === ???*2*)) +- *0* ???*1*["nextSibling"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["nodeType"] + ⚠️ unknown object +- *3* ???*4*["nextSibling"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +1850 -> 1852 conditional = (0 === (0 | ???*0*)) +- *0* updated with update expression + ⚠️ This value might have side effects + +1852 -> 1854 member call = ???*0*["removeChild"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nextSibling"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +1852 -> 1855 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1856 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1859 conditional = (8 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1863 conditional = (8 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1869 free var = FreeVar(Math) + +0 -> 1870 member call = ???*0*["random"]() +- *0* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1871 member call = ???*0*()["toString"](36) +- *0* ???*1*["random"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1872 member call = ???*0*["slice"](2) +- *0* ???*1*(36) + ⚠️ unknown callee +- *1* ???*2*["toString"] + ⚠️ unknown object +- *2* ???*3*() + ⚠️ nested operation +- *3* ???*4*["random"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 1880 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +1880 -> 1881 call = (...) => (a | null)((???*0* | ???*1* | ???*2* | null)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["previousSibling"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +1880 -> 1883 call = (...) => (a | null)((???*0* | ???*1* | ???*2* | null)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["previousSibling"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +0 -> 1891 conditional = (!((???*0* | ???*1*)) | (5 !== ???*3*) | (6 !== ???*5*) | (13 !== ???*7*) | (3 !== ???*9*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*[Of] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["tag"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["tag"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*["tag"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["tag"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1894 conditional = ((5 === ???*0*) | (6 === ???*2*)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1896 free var = FreeVar(Error) + +0 -> 1897 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(33) + +0 -> 1898 call = ???*0*( + `Minified React error #${33}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${33}` + ⚠️ nested operation + +0 -> 1906 call = (...) => {"current": a}({}) + +0 -> 1907 call = (...) => {"current": a}(false) + +0 -> 1912 conditional = (???*0* | (???*2* === ???*5*)) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["__reactInternalMemoizedUnmaskedChildContext"] + ⚠️ unknown object +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1920 call = (...) => undefined({"current": false}) + +0 -> 1921 call = (...) => undefined({"current": {}}) + +0 -> 1923 conditional = (({} | ???*0*) !== {}) +- *0* unknown mutation + ⚠️ This value might have side effects + +1923 -> 1924 free var = FreeVar(Error) + +1923 -> 1925 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(168) + +1923 -> 1926 call = ???*0*( + `Minified React error #${168}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${168}` + ⚠️ nested operation + +0 -> 1927 call = (...) => undefined({"current": {}}, ???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1928 call = (...) => undefined({"current": false}, ???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 1933 member call = (???*0* | ???*2*())["getChildContext"]() +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["getChildContext"] + ⚠️ unknown object +- *3* d + ⚠️ circular variable reference + +0 -> 1934 conditional = !(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +1934 -> 1935 free var = FreeVar(Error) + +1934 -> 1936 call = (...) => ( + | "Cache" + | `${(b["displayName"] || "Context")}.Consumer` + | `${(b["_context"]["displayName"] || "Context")}.Provider` + | "DehydratedFragment" + | ???*0* + | "Fragment" + | b + | "Portal" + | "Root" + | "Text" + | Qa(b) + | ((b === za) ? "StrictMode" : "Mode") + | "Offscreen" + | "Profiler" + | "Scope" + | "Suspense" + | "SuspenseList" + | "TracingMarker" + | (b["displayName"] || b["name"] || null) + | null +)(???*1*) +- *0* ( + || b["displayName"] + || (("" !== a) ? ("ForwardRef(" + a + ")") : "ForwardRef") + ) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +1934 -> 1937 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(108, ???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* e + ⚠️ pattern without value + +1934 -> 1938 call = ???*0*(???*1*) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1939 call = ???*0*({}, ???*2*, (???*3* | ???*5*())) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["getChildContext"] + ⚠️ unknown object +- *6* d + ⚠️ circular variable reference + +0 -> 1943 call = (...) => undefined({"current": {}}, (???*0* | ???*1* | ???*2* | {})) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["__reactInternalMemoizedMergedChildContext"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +0 -> 1945 call = (...) => undefined({"current": false}, (false | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +0 -> 1947 conditional = !((???*0* | ???*2* | ???*3* | ???*4*)) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* ???*5*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +1947 -> 1948 free var = FreeVar(Error) + +1947 -> 1949 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(169) + +1947 -> 1950 call = ???*0*( + `Minified React error #${169}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${169}` + ⚠️ nested operation + +0 -> 1951 conditional = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +1951 -> 1952 call = (...) => (c | A({}, c, d))((???*0* | {} | ???*1* | ???*2*), ???*5*, ({} | ???*6*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* ???*3*({}, c, d) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* unknown mutation + ⚠️ This value might have side effects + +1951 -> 1954 call = (...) => undefined({"current": false}) + +1951 -> 1955 call = (...) => undefined({"current": {}}) + +1951 -> 1956 call = (...) => undefined({"current": {}}, (???*0* | {} | ???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* ???*3*({}, c, d) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +1951 -> 1957 call = (...) => undefined({"current": false}) + +0 -> 1958 call = (...) => undefined({"current": false}, ???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 1959 conditional = (null === (null | [???*0*] | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["slice"]((a + 1)) + ⚠️ unknown callee object +- *2* eg + ⚠️ circular variable reference + +1959 -> 1961 member call = (null | [???*0*] | ???*1*)["push"](???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["slice"]((a + 1)) + ⚠️ unknown callee object +- *2* eg + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1962 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1963 conditional = (!((false | true)) | (null !== (null | [???*0*] | ???*1*))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["slice"]((a + 1)) + ⚠️ unknown callee object +- *2* eg + ⚠️ circular variable reference + +1963 -> 1966 call = (null[(0 | ???*0*)] | ???*1* | ???*2* | ???*3* | ???*5* | ???*9*)(true) +- *0* updated with update expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* [][???*4*] + ⚠️ unknown array prototype methods or values +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*[(0 | ???*8*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["slice"]((a + 1)) + ⚠️ unknown callee object +- *7* eg + ⚠️ circular variable reference +- *8* updated with update expression + ⚠️ This value might have side effects +- *9* ???*10*(!(0)) + ⚠️ unknown callee +- *10* d + ⚠️ circular variable reference + +1963 -> 1968 member call = (null | [???*0*] | ???*1*)["slice"](((0 | ???*3*) + 1)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["slice"]((a + 1)) + ⚠️ unknown callee object +- *2* eg + ⚠️ circular variable reference +- *3* updated with update expression + ⚠️ This value might have side effects + +1963 -> 1969 call = module["unstable_scheduleCallback"]( + module["unstable_ImmediatePriority"], + (...) => null +) + +0 -> 1975 call = (???*0* ? ???*2* : (...) => ???*4*)(???*6*) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 1976 call = (???*0* ? ???*2* : (...) => ???*4*)(???*6*) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1978 member call = ???*0*["toString"](32) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 1979 call = (???*0* ? ???*2* : (...) => ???*4*)(???*6*) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 1981 call = (...) => undefined(???*0*, 1) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1982 call = (...) => undefined(???*0*, 1, 0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 1993 call = (...) => ???*0*(5, null, null, 0) +- *0* unknown new expression + ⚠️ This value might have side effects + +0 -> 1998 conditional = (null === (???*0* | ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +1998 -> 2002 member call = (???*0* | ???*1*)["push"](???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects + +0 -> 2007 member call = ???*0*["toLowerCase"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2010 member call = ???*0*["toLowerCase"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2011 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2012 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2012 -> 2015 call = (...) => (null | a)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2018 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2019 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2022 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2023 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2023 -> 2024 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2023 -> 2026 call = (...) => ???*0*(18, null, null, 0) +- *0* unknown new expression + ⚠️ This value might have side effects + +0 -> 2032 conditional = (false | true) + +2032 -> 2033 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2033 -> 2034 call = (...) => (undefined | ((null !== b) ? ???*0* : !(1)) | ???*1* | !(1))(???*3*, ???*4*) +- *0* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ((null !== b) ? ???*2* : !(1)) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +2033 -> 2035 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2035 -> 2036 call = (...) => ((0 !== ???*0*) && (0 === ???*1*))(???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +2035 -> 2037 conditional = ((0 !== ???*0*) | (0 === ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +2037 -> 2038 free var = FreeVar(Error) + +2037 -> 2039 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(418) + +2037 -> 2040 call = ???*0*( + `Minified React error #${418}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${418}` + ⚠️ nested operation + +2035 -> 2042 call = (...) => (null | a)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2035 -> 2043 call = (...) => (undefined | ((null !== b) ? ???*0* : !(1)) | ???*1* | !(1))(???*3*, ???*4*) +- *0* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ((null !== b) ? ???*2* : !(1)) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +2035 -> 2044 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2044 -> 2045 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2033 -> 2048 call = (...) => ((0 !== ???*0*) && (0 === ???*1*))(???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +2033 -> 2049 conditional = ((0 !== ???*0*) | (0 === ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +2049 -> 2050 free var = FreeVar(Error) + +2049 -> 2051 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(418) + +2049 -> 2052 call = ???*0*( + `Minified React error #${418}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${418}` + ⚠️ nested operation + +0 -> 2060 conditional = !((false | true)) + +2060 -> 2061 call = (...) => undefined((???*0* | ???*1* | (???*3* ? ???*5* : null))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["dehydrated"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference + +0 -> 2067 call = (...) => ( + || ("textarea" === a) + || ("noscript" === a) + || ("string" === typeof(b["children"])) + || ("number" === typeof(b["children"])) + || ( + && ("object" === typeof(b["dangerouslySetInnerHTML"])) + && (null !== b["dangerouslySetInnerHTML"]) + && (null != b["dangerouslySetInnerHTML"]["__html"]) + ) +)( + (???*0* | (???*2* ? ???*4* : null)["type"]), + (???*6* | (???*8* ? ???*10* : null)["memoizedProps"]) +) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* ???*5*["dehydrated"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["memoizedProps"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* (null !== ???*9*) + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["dehydrated"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference + +0 -> 2068 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2068 -> 2069 call = (...) => ((0 !== ???*0*) && (0 === ???*1*))((???*2* | ???*3* | (???*5* ? ???*7* : null))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["dehydrated"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference + +2068 -> 2070 conditional = ((0 !== ???*0*) | (0 === ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +2070 -> 2071 call = (...) => undefined() + +2070 -> 2072 free var = FreeVar(Error) + +2070 -> 2073 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(418) + +2070 -> 2074 call = ???*0*( + `Minified React error #${418}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${418}` + ⚠️ nested operation + +2068 -> 2075 call = (...) => undefined((???*0* | ???*1* | (???*3* ? ???*5* : null)), ???*7*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["dehydrated"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* max number of linking steps reached + ⚠️ This value might have side effects + +2068 -> 2077 call = (...) => (null | a)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2078 call = (...) => undefined((???*0* | ???*1* | (???*3* ? ???*5* : null))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["dehydrated"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference + +0 -> 2080 conditional = (13 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2080 -> 2082 conditional = (null !== (???*0* | ???*1* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["dehydrated"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference + +2080 -> 2084 conditional = !((???*0* | ???*1* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["dehydrated"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference + +2084 -> 2085 free var = FreeVar(Error) + +2084 -> 2086 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(317) + +2084 -> 2087 call = ???*0*( + `Minified React error #${317}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${317}` + ⚠️ nested operation + +2080 -> 2090 conditional = (8 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2090 -> 2092 conditional = ("/$" === ???*0*) +- *0* ???*1*["data"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2092 -> 2093 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2093 -> 2095 call = (...) => (null | a)((???*0* | (???*2* ? ???*4* : null)["nextSibling"])) +- *0* ???*1*["nextSibling"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* ???*5*["dehydrated"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference + +2080 -> 2097 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2097 -> 2100 call = (...) => (null | a)( + ( + | ???*0* + | (???*3* ? ???*5* : null)["stateNode"]["nextSibling"] + ) +) +- *0* ???*1*["nextSibling"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["dehydrated"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference + +0 -> 2102 call = (...) => (null | a)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2103 conditional = (null === (null | [???*0*])) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +2103 -> 2105 member call = (null | [???*0*])["push"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2108 conditional = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["defaultProps"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +2108 -> 2109 call = ???*0*({}, (???*2* | ???*3*)) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*({}, b) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *4* ???*5*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 2114 call = (...) => {"current": a}(null) + +0 -> 2116 call = (...) => undefined({"current": null}) + +0 -> 2120 conditional = (???*0* !== ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2131 conditional = ((null | ???*0*) !== ( + | ???*1* + | {"context": ???*2*, "memoizedValue": ???*3*, "next": null} +)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["_currentValue"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference + +2131 -> 2132 conditional = (null === (null | ???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["dependencies"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +2132 -> 2133 free var = FreeVar(Error) + +2132 -> 2134 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(308) + +2132 -> 2135 call = ???*0*( + `Minified React error #${308}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${308}` + ⚠️ nested operation + +0 -> 2138 conditional = (null === (null | [???*0*])) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +2138 -> 2140 member call = (null | [???*0*])["push"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2142 conditional = (null === ???*0*) +- *0* ???*1*["interleaved"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +2142 -> 2144 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2149 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2159 conditional = (3 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2173 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +2173 -> 2175 conditional = (null === ???*0*) +- *0* ???*1*["pending"] + ⚠️ unknown object +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +2173 -> 2181 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2183 conditional = (null === ???*0*) +- *0* ???*1*["pending"] + ⚠️ unknown object +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +2183 -> 2185 call = (...) => undefined(???*0*) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2190 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2193 conditional = ((null !== (???*0* | ???*1*)) | ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* b + ⚠️ circular variable reference +- *3* (0 !== ???*4*) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +2193 -> 2197 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 2201 conditional = ( + | (null !== (???*0* | null["alternate"] | ???*2* | ???*3* | ???*4*)) + | ???*6* +) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (c === d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +2201 -> 2203 conditional = (null !== ( + | ???*0* + | { + "baseState": ???*2*, + "firstBaseUpdate": (null | ???*5*), + "lastBaseUpdate": ( + | null + | { + "eventTime": ???*6*, + "lane": ???*8*, + "tag": ???*10*, + "payload": ???*12*, + "callback": ???*14*, + "next": null + } + | ???*16* + | ???*17* + ), + "shared": ???*18*, + "effects": ???*21* + } +)) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["baseState"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*["eventTime"] + ⚠️ unknown object +- *7* c + ⚠️ circular variable reference +- *8* ???*9*["lane"] + ⚠️ unknown object +- *9* c + ⚠️ circular variable reference +- *10* ???*11*["tag"] + ⚠️ unknown object +- *11* c + ⚠️ circular variable reference +- *12* ???*13*["payload"] + ⚠️ unknown object +- *13* c + ⚠️ circular variable reference +- *14* ???*15*["callback"] + ⚠️ unknown object +- *15* c + ⚠️ circular variable reference +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* ???*19*["shared"] + ⚠️ unknown object +- *19* ???*20*["alternate"] + ⚠️ unknown object +- *20* arguments[0] + ⚠️ function calls are not analysed yet +- *21* ???*22*["effects"] + ⚠️ unknown object +- *22* ???*23*["alternate"] + ⚠️ unknown object +- *23* arguments[0] + ⚠️ function calls are not analysed yet + +2203 -> 2209 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2203 -> 2212 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2219 conditional = (null === ( + | ???*0* + | ???*1* + | null + | { + "eventTime": ???*4*, + "lane": ???*6*, + "tag": ???*8*, + "payload": ???*10*, + "callback": ???*12*, + "next": null + } + | ???*14* + | ???*15* +)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["lastBaseUpdate"] + ⚠️ unknown object +- *2* ???*3*["updateQueue"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* ???*5*["eventTime"] + ⚠️ unknown object +- *5* c + ⚠️ circular variable reference +- *6* ???*7*["lane"] + ⚠️ unknown object +- *7* c + ⚠️ circular variable reference +- *8* ???*9*["tag"] + ⚠️ unknown object +- *9* c + ⚠️ circular variable reference +- *10* ???*11*["payload"] + ⚠️ unknown object +- *11* c + ⚠️ circular variable reference +- *12* ???*13*["callback"] + ⚠️ unknown object +- *13* c + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* unknown mutation + ⚠️ This value might have side effects + +0 -> 2228 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2228 -> 2233 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2228 -> 2238 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2242 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2242 -> 2246 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2246 -> 2253 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | ???*2* | ???*6* | null["next"]["payload"])) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["payload"] + ⚠️ unknown object +- *3* ???*4*["pending"] + ⚠️ unknown object +- *4* ???*5*["shared"] + ⚠️ unknown object +- *5* ???["updateQueue"] + ⚠️ unknown object +- *6* ???*7*["payload"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["lastBaseUpdate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects + +2253 -> 2255 member call = ( + | ???*0* + | ???*1* + | ???*6* + | null["next"]["payload"] + | (???*9* ? ???*12* : ???*14*)["next"]["payload"] +)["call"](???*15*, ???*16*, ???*17*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["payload"] + ⚠️ unknown object +- *2* ???*3*["pending"] + ⚠️ unknown object +- *3* ???*4*["shared"] + ⚠️ unknown object +- *4* ???*5*["updateQueue"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["payload"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["lastBaseUpdate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ("function" === ???*10*) + ⚠️ nested operation +- *10* typeof(???*11*) + ⚠️ nested operation +- *11* n + ⚠️ circular variable reference +- *12* ???*13*["call"](y, q, r) + ⚠️ unknown callee object +- *13* n + ⚠️ circular variable reference +- *14* n + ⚠️ circular variable reference +- *15* max number of linking steps reached + ⚠️ This value might have side effects +- *16* max number of linking steps reached + ⚠️ This value might have side effects +- *17* max number of linking steps reached + ⚠️ This value might have side effects + +2246 -> 2259 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | ???*2* | ???*6* | null["next"]["payload"])) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["payload"] + ⚠️ unknown object +- *3* ???*4*["pending"] + ⚠️ unknown object +- *4* ???*5*["shared"] + ⚠️ unknown object +- *5* ???["updateQueue"] + ⚠️ unknown object +- *6* ???*7*["payload"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["lastBaseUpdate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects + +2259 -> 2261 member call = ( + | ???*0* + | ???*1* + | ???*6* + | null["next"]["payload"] + | (???*9* ? ???*12* : ???*14*)["next"]["payload"] +)["call"](???*15*, ???*16*, ???*17*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["payload"] + ⚠️ unknown object +- *2* ???*3*["pending"] + ⚠️ unknown object +- *3* ???*4*["shared"] + ⚠️ unknown object +- *4* ???*5*["updateQueue"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["payload"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["lastBaseUpdate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ("function" === ???*10*) + ⚠️ nested operation +- *10* typeof(???*11*) + ⚠️ nested operation +- *11* n + ⚠️ circular variable reference +- *12* ???*13*["call"](y, q, r) + ⚠️ unknown callee object +- *13* n + ⚠️ circular variable reference +- *14* n + ⚠️ circular variable reference +- *15* max number of linking steps reached + ⚠️ This value might have side effects +- *16* max number of linking steps reached + ⚠️ This value might have side effects +- *17* max number of linking steps reached + ⚠️ This value might have side effects + +2246 -> 2262 call = ???*0*({}, ???*2*, ???*3*) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +2246 -> 2267 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2267 -> 2270 member call = ???*0*["push"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2246 -> 2274 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2242 -> 2277 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2242 -> 2290 conditional = (null !== (???*0* | ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["interleaved"] + ⚠️ unknown object +- *2* ???*3*["shared"] + ⚠️ unknown object +- *3* ???*4*["updateQueue"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2299 conditional = (null !== (???*0* | ???*1* | 0["effects"] | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["effects"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["effects"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +2299 -> 2303 conditional = (null !== (???*0* | 0["effects"][(???*5* | 0 | ???*6*)]["callback"] | ???*7*)) +- *0* ???*1*["callback"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(???*3* | 0 | ???*4*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* ???*8*["callback"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet + +2303 -> 2305 conditional = ("function" !== ???*0*) +- *0* typeof((???*1* | 0["effects"][(???*6* | 0 | ???*7*)]["callback"] | ???*8*)) + ⚠️ nested operation +- *1* ???*2*["callback"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* ???*3*[(???*4* | 0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* updated with update expression + ⚠️ This value might have side effects +- *8* ???*9*["callback"] + ⚠️ unknown object +- *9* arguments[2] + ⚠️ function calls are not analysed yet + +2305 -> 2306 free var = FreeVar(Error) + +2305 -> 2307 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`( + 191, + (???*0* | 0["effects"][(???*5* | 0 | ???*6*)]["callback"] | ???*7*) +) +- *0* ???*1*["callback"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(???*3* | 0 | ???*4*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* ???*8*["callback"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet + +2305 -> 2308 call = ???*0*( + `Minified React error #${191}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${191}` + ⚠️ nested operation + +2303 -> 2310 member call = (???*0* | 0["effects"][(???*5* | 0 | ???*6*)]["callback"] | ???*7*)["call"]( + (???*9* | 0["effects"][(???*13* | 0 | ???*14*)] | ???*15*) +) +- *0* ???*1*["callback"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(???*3* | 0 | ???*4*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* ???*8*["callback"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* ???*10*[(???*11* | 0 | ???*12*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* updated with update expression + ⚠️ This value might have side effects +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* updated with update expression + ⚠️ This value might have side effects +- *15* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2314 call = (???*0* | ???*1* | (???*3* ? (???*5* | ???*6*) : ???*8*))(???*11*, (???*12* | ???*13*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*(d, b) + ⚠️ unknown callee +- *2* c + ⚠️ circular variable reference +- *3* (null === ???*4*) + ⚠️ nested operation +- *4* c + ⚠️ circular variable reference +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* ???*9*({}, b, c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *9* ???*10*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* arguments[3] + ⚠️ function calls are not analysed yet +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* ???*14*["memoizedState"] + ⚠️ unknown object +- *14* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2315 conditional = ((null === (???*0* | ???*1* | ???*3*)) | (???*12* === (???*13* | ???*14* | ???*16*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*(d, b) + ⚠️ unknown callee +- *2* c + ⚠️ circular variable reference +- *3* (???*4* ? (???*6* | ???*7*) : ???*9*) + ⚠️ nested operation +- *4* (null === ???*5*) + ⚠️ nested operation +- *5* c + ⚠️ circular variable reference +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*({}, b, c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *10* ???*11*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* ???*15*(d, b) + ⚠️ unknown callee +- *15* c + ⚠️ circular variable reference +- *16* (???*17* ? (???*19* | ???*20*) : ???*22*) + ⚠️ nested operation +- *17* (null === ???*18*) + ⚠️ nested operation +- *18* c + ⚠️ circular variable reference +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["memoizedState"] + ⚠️ unknown object +- *21* arguments[0] + ⚠️ function calls are not analysed yet +- *22* ???*23*({}, b, c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *23* ???*24*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +2315 -> 2316 call = ???*0*( + {}, + (???*2* | ???*3*), + (???*5* | ???*6* | (???*8* ? (???*10* | ???*11*) : ???*13*)) +) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* ???*7*(d, b) + ⚠️ unknown callee +- *7* c + ⚠️ circular variable reference +- *8* (null === ???*9*) + ⚠️ nested operation +- *9* c + ⚠️ circular variable reference +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* ???*14*({}, b, c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *14* ???*15*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *15* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 2322 call = (...) => ((3 === b["tag"]) ? c : null)((???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +0 -> 2324 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 2325 call = (...) => (1 | ???*0* | ???*1* | a)((???*2* | ???*3*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["_reactInternals"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference + +0 -> 2326 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}( + (???*0* ? ???*2* : ???*3*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +0 -> 2329 call = (...) => (null | Zg(a, c))( + (???*0* | ???*1*), + { + "eventTime": (???*3* ? ???*5* : ???*6*), + "lane": ( + | 1 + | ???*14* + | ???*15* + | ???*16* + | ???*17* + | 0 + | ???*19* + | 4 + | ((???*20* | ???*22*) ? ???*23* : 4) + | (???*24* ? 16 : (???*25* | null | ???*32* | ???*33*)) + | ???*35* + | (???*37* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + }, + ( + | 1 + | ???*40* + | ???*41* + | ???*42* + | ???*43* + | 0 + | ???*45* + | 4 + | ((???*46* | ???*48*) ? ???*49* : 4) + | (???*50* ? 16 : (???*51* | null | ???*58* | ???*59*)) + | ???*61* + | (???*63* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (0 !== ???*4*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* module["unstable_now"]() + ⚠️ nested operation +- *6* (???*7* ? (???*11* | ???*12*) : ???*13*) + ⚠️ nested operation +- *7* (???*8* !== (???*9* | ???*10*)) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* module["unstable_now"]() + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["_reactInternals"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* C + ⚠️ circular variable reference +- *20* (0 !== ???*21*) + ⚠️ nested operation +- *21* C + ⚠️ circular variable reference +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* C + ⚠️ circular variable reference +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* (???*26* ? ???*27* : 1) + ⚠️ nested operation +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* (???*28* ? ???*29* : 4) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* (???*30* ? 16 : 536870912) + ⚠️ nested operation +- *30* (0 !== ???*31*) + ⚠️ nested operation +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* arguments[0] + ⚠️ function calls are not analysed yet +- *33* ???*34*["value"] + ⚠️ unknown object +- *34* arguments[1] + ⚠️ function calls are not analysed yet +- *35* ???*36*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *36* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *37* (???*38* === ???*39*) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* a + ⚠️ circular variable reference +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *42* arguments[0] + ⚠️ function calls are not analysed yet +- *43* ???*44*["_reactInternals"] + ⚠️ unknown object +- *44* a + ⚠️ circular variable reference +- *45* C + ⚠️ circular variable reference +- *46* (0 !== ???*47*) + ⚠️ nested operation +- *47* C + ⚠️ circular variable reference +- *48* unsupported expression + ⚠️ This value might have side effects +- *49* C + ⚠️ circular variable reference +- *50* unsupported expression + ⚠️ This value might have side effects +- *51* (???*52* ? ???*53* : 1) + ⚠️ nested operation +- *52* unsupported expression + ⚠️ This value might have side effects +- *53* (???*54* ? ???*55* : 4) + ⚠️ nested operation +- *54* unsupported expression + ⚠️ This value might have side effects +- *55* (???*56* ? 16 : 536870912) + ⚠️ nested operation +- *56* (0 !== ???*57*) + ⚠️ nested operation +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* arguments[0] + ⚠️ function calls are not analysed yet +- *59* ???*60*["value"] + ⚠️ unknown object +- *60* arguments[1] + ⚠️ function calls are not analysed yet +- *61* ???*62*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *62* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *63* (???*64* === ???*65*) + ⚠️ nested operation +- *64* unsupported expression + ⚠️ This value might have side effects +- *65* a + ⚠️ circular variable reference + +0 -> 2330 call = (...) => undefined( + (???*0* | null | (???*1* ? ???*5* : null)), + (???*8* | ???*9*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + (???*37* ? ???*39* : ???*40*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["_reactInternals"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference +- *37* (0 !== ???*38*) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* module["unstable_now"]() + ⚠️ nested operation +- *40* (???*41* ? (???*45* | ???*46*) : ???*47*) + ⚠️ nested operation +- *41* (???*42* !== (???*43* | ???*44*)) + ⚠️ nested operation +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* module["unstable_now"]() + ⚠️ nested operation +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* module["unstable_now"]() + ⚠️ nested operation +- *47* unsupported expression + ⚠️ This value might have side effects + +0 -> 2331 call = (...) => undefined( + (???*0* | null | (???*1* ? ???*5* : null)), + (???*8* | ???*9*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["_reactInternals"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +0 -> 2333 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 2334 call = (...) => (1 | ???*0* | ???*1* | a)((???*2* | ???*3*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["_reactInternals"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference + +0 -> 2335 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}( + (???*0* ? ???*2* : ???*3*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +0 -> 2339 call = (...) => (null | Zg(a, c))( + (???*0* | ???*1*), + { + "eventTime": (???*3* ? ???*5* : ???*6*), + "lane": ( + | 1 + | ???*14* + | ???*15* + | ???*16* + | ???*17* + | 0 + | ???*19* + | 4 + | ((???*20* | ???*22*) ? ???*23* : 4) + | (???*24* ? 16 : (???*25* | null | ???*32* | ???*33*)) + | ???*35* + | (???*37* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + }, + ( + | 1 + | ???*40* + | ???*41* + | ???*42* + | ???*43* + | 0 + | ???*45* + | 4 + | ((???*46* | ???*48*) ? ???*49* : 4) + | (???*50* ? 16 : (???*51* | null | ???*58* | ???*59*)) + | ???*61* + | (???*63* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (0 !== ???*4*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* module["unstable_now"]() + ⚠️ nested operation +- *6* (???*7* ? (???*11* | ???*12*) : ???*13*) + ⚠️ nested operation +- *7* (???*8* !== (???*9* | ???*10*)) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* module["unstable_now"]() + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["_reactInternals"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* C + ⚠️ circular variable reference +- *20* (0 !== ???*21*) + ⚠️ nested operation +- *21* C + ⚠️ circular variable reference +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* C + ⚠️ circular variable reference +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* (???*26* ? ???*27* : 1) + ⚠️ nested operation +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* (???*28* ? ???*29* : 4) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* (???*30* ? 16 : 536870912) + ⚠️ nested operation +- *30* (0 !== ???*31*) + ⚠️ nested operation +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* arguments[0] + ⚠️ function calls are not analysed yet +- *33* ???*34*["value"] + ⚠️ unknown object +- *34* arguments[1] + ⚠️ function calls are not analysed yet +- *35* ???*36*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *36* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *37* (???*38* === ???*39*) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* a + ⚠️ circular variable reference +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *42* arguments[0] + ⚠️ function calls are not analysed yet +- *43* ???*44*["_reactInternals"] + ⚠️ unknown object +- *44* a + ⚠️ circular variable reference +- *45* C + ⚠️ circular variable reference +- *46* (0 !== ???*47*) + ⚠️ nested operation +- *47* C + ⚠️ circular variable reference +- *48* unsupported expression + ⚠️ This value might have side effects +- *49* C + ⚠️ circular variable reference +- *50* unsupported expression + ⚠️ This value might have side effects +- *51* (???*52* ? ???*53* : 1) + ⚠️ nested operation +- *52* unsupported expression + ⚠️ This value might have side effects +- *53* (???*54* ? ???*55* : 4) + ⚠️ nested operation +- *54* unsupported expression + ⚠️ This value might have side effects +- *55* (???*56* ? 16 : 536870912) + ⚠️ nested operation +- *56* (0 !== ???*57*) + ⚠️ nested operation +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* arguments[0] + ⚠️ function calls are not analysed yet +- *59* ???*60*["value"] + ⚠️ unknown object +- *60* arguments[1] + ⚠️ function calls are not analysed yet +- *61* ???*62*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *62* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *63* (???*64* === ???*65*) + ⚠️ nested operation +- *64* unsupported expression + ⚠️ This value might have side effects +- *65* a + ⚠️ circular variable reference + +0 -> 2340 call = (...) => undefined( + (???*0* | null | (???*1* ? ???*5* : null)), + (???*8* | ???*9*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + (???*37* ? ???*39* : ???*40*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["_reactInternals"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference +- *37* (0 !== ???*38*) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* module["unstable_now"]() + ⚠️ nested operation +- *40* (???*41* ? (???*45* | ???*46*) : ???*47*) + ⚠️ nested operation +- *41* (???*42* !== (???*43* | ???*44*)) + ⚠️ nested operation +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* module["unstable_now"]() + ⚠️ nested operation +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* module["unstable_now"]() + ⚠️ nested operation +- *47* unsupported expression + ⚠️ This value might have side effects + +0 -> 2341 call = (...) => undefined( + (???*0* | null | (???*1* ? ???*5* : null)), + (???*8* | ???*9*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["_reactInternals"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +0 -> 2343 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 2344 call = (...) => (1 | ???*0* | ???*1* | a)((???*2* | ???*3*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["_reactInternals"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference + +0 -> 2345 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}( + (???*0* ? ???*2* : ???*3*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +0 -> 2348 call = (...) => (null | Zg(a, c))( + (???*0* | ???*1*), + { + "eventTime": (???*3* ? ???*5* : ???*6*), + "lane": ( + | 1 + | ???*14* + | ???*15* + | ???*16* + | ???*17* + | 0 + | ???*19* + | 4 + | ((???*20* | ???*22*) ? ???*23* : 4) + | (???*24* ? 16 : (???*25* | null | ???*32* | ???*33*)) + | ???*35* + | (???*37* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + }, + ( + | 1 + | ???*40* + | ???*41* + | ???*42* + | ???*43* + | 0 + | ???*45* + | 4 + | ((???*46* | ???*48*) ? ???*49* : 4) + | (???*50* ? 16 : (???*51* | null | ???*58* | ???*59*)) + | ???*61* + | (???*63* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (0 !== ???*4*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* module["unstable_now"]() + ⚠️ nested operation +- *6* (???*7* ? (???*11* | ???*12*) : ???*13*) + ⚠️ nested operation +- *7* (???*8* !== (???*9* | ???*10*)) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* module["unstable_now"]() + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["_reactInternals"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* C + ⚠️ circular variable reference +- *20* (0 !== ???*21*) + ⚠️ nested operation +- *21* C + ⚠️ circular variable reference +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* C + ⚠️ circular variable reference +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* (???*26* ? ???*27* : 1) + ⚠️ nested operation +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* (???*28* ? ???*29* : 4) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* (???*30* ? 16 : 536870912) + ⚠️ nested operation +- *30* (0 !== ???*31*) + ⚠️ nested operation +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* arguments[0] + ⚠️ function calls are not analysed yet +- *33* ???*34*["value"] + ⚠️ unknown object +- *34* arguments[1] + ⚠️ function calls are not analysed yet +- *35* ???*36*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *36* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *37* (???*38* === ???*39*) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* a + ⚠️ circular variable reference +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *42* arguments[0] + ⚠️ function calls are not analysed yet +- *43* ???*44*["_reactInternals"] + ⚠️ unknown object +- *44* a + ⚠️ circular variable reference +- *45* C + ⚠️ circular variable reference +- *46* (0 !== ???*47*) + ⚠️ nested operation +- *47* C + ⚠️ circular variable reference +- *48* unsupported expression + ⚠️ This value might have side effects +- *49* C + ⚠️ circular variable reference +- *50* unsupported expression + ⚠️ This value might have side effects +- *51* (???*52* ? ???*53* : 1) + ⚠️ nested operation +- *52* unsupported expression + ⚠️ This value might have side effects +- *53* (???*54* ? ???*55* : 4) + ⚠️ nested operation +- *54* unsupported expression + ⚠️ This value might have side effects +- *55* (???*56* ? 16 : 536870912) + ⚠️ nested operation +- *56* (0 !== ???*57*) + ⚠️ nested operation +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* arguments[0] + ⚠️ function calls are not analysed yet +- *59* ???*60*["value"] + ⚠️ unknown object +- *60* arguments[1] + ⚠️ function calls are not analysed yet +- *61* ???*62*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *62* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *63* (???*64* === ???*65*) + ⚠️ nested operation +- *64* unsupported expression + ⚠️ This value might have side effects +- *65* a + ⚠️ circular variable reference + +0 -> 2349 call = (...) => undefined( + (???*0* | null | (???*1* ? ???*5* : null)), + (???*8* | ???*9*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + (???*37* ? ???*39* : ???*40*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["_reactInternals"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference +- *37* (0 !== ???*38*) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* module["unstable_now"]() + ⚠️ nested operation +- *40* (???*41* ? (???*45* | ???*46*) : ???*47*) + ⚠️ nested operation +- *41* (???*42* !== (???*43* | ???*44*)) + ⚠️ nested operation +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* module["unstable_now"]() + ⚠️ nested operation +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* module["unstable_now"]() + ⚠️ nested operation +- *47* unsupported expression + ⚠️ This value might have side effects + +0 -> 2350 call = (...) => undefined( + (???*0* | null | (???*1* ? ???*5* : null)), + (???*8* | ???*9*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["_reactInternals"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +0 -> 2353 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* ???*2*["shouldComponentUpdate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +2353 -> 2355 member call = (???*0* | ???*1*)["shouldComponentUpdate"](???*3*, ???*4*, ???*5*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* arguments[5] + ⚠️ function calls are not analysed yet +- *5* arguments[6] + ⚠️ function calls are not analysed yet + +2353 -> 2359 conditional = ???*0* +- *0* ???*1*["prototype"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +2359 -> 2360 call = (...) => (!(0) | !(1))(???*0*, ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +2359 -> 2361 call = (...) => (!(0) | !(1))(???*0*, ???*1*) +- *0* arguments[4] + ⚠️ function calls are not analysed yet +- *1* arguments[5] + ⚠️ function calls are not analysed yet + +0 -> 2363 conditional = ( + | ("object" === ???*0*) + | (null !== (???*12* | ???*14* | ???*16* | ???*17* | ???*18*)) +) +- *0* typeof((???*1* | ???*3* | ???*5* | ???*6* | ???*7*)) + ⚠️ nested operation +- *1* ???*2*["contextType"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["contextType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* (???*8* ? ({} | ???*9*) : {}) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*["__reactInternalMemoizedMaskedChildContext"] + ⚠️ unknown object +- *10* ???*11*["stateNode"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* ???*13*["contextType"] + ⚠️ unknown object +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* ???*15*["contextType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *15* unknown new expression + ⚠️ This value might have side effects +- *16* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* unknown mutation + ⚠️ This value might have side effects +- *18* (???*19* ? ({} | ???*20*) : {}) + ⚠️ nested operation +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* ???*21*["__reactInternalMemoizedMaskedChildContext"] + ⚠️ unknown object +- *21* ???*22*["stateNode"] + ⚠️ unknown object +- *22* arguments[0] + ⚠️ function calls are not analysed yet + +2363 -> 2364 call = (...) => b( + (???*0* | ???*2* | ???*4* | ???*5* | (???*6* ? ({} | ???*7*) : {})) +) +- *0* ???*1*["contextType"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["contextType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* ???*8*["__reactInternalMemoizedMaskedChildContext"] + ⚠️ unknown object +- *8* ???*9*["stateNode"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet + +2363 -> 2365 call = (...) => ((null !== a) && (???*0* !== a))((???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects + +2363 -> 2366 conditional = ((null !== (???*0* | ???*1* | ???*2*)) | (???*4* !== (???*5* | ???*6* | ???*7*))) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* ???*3*["childContextTypes"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* unknown new expression + ⚠️ This value might have side effects +- *7* ???*8*["childContextTypes"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference + +2363 -> 2369 call = (...) => (Vf | d["__reactInternalMemoizedMaskedChildContext"] | e)((???*0* | ???*1*), ({} | (???*3* ? ({} | ???*8*) : ({} | ???*9*)))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (null !== (???*4* | ???*5* | ???*6*)) + ⚠️ nested operation +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* unknown new expression + ⚠️ This value might have side effects +- *6* ???*7*["childContextTypes"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* unknown mutation + ⚠️ This value might have side effects +- *9* unknown mutation + ⚠️ This value might have side effects + +0 -> 2373 conditional = ((null !== (???*0* | ???*2*)) | (???*4* !== (???*5* | ???*7*))) +- *0* ???*1*["state"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["state"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* ???*6*["state"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["state"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects + +0 -> 2384 member call = ???*0*["componentWillReceiveProps"](???*1*, ???*2*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2387 member call = ???*0*["UNSAFE_componentWillReceiveProps"](???*1*, ???*2*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2391 member call = { + "isMounted": (...) => (???*0* ? (Vb(a) === a) : !(1)), + "enqueueSetState": (...) => undefined, + "enqueueReplaceState": (...) => undefined, + "enqueueForceUpdate": (...) => undefined +}["enqueueReplaceState"](???*1*, ???*2*, null) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["state"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2397 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2399 conditional = (("object" === ???*0*) | (null !== (???*10* | ???*12*))) +- *0* typeof((???*1* | ???*3*)) + ⚠️ nested operation +- *1* ???*2*["contextType"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ({} | ???*8*) : ({} | ???*9*)) + ⚠️ nested operation +- *4* (null !== (???*5* | ???*6*)) + ⚠️ nested operation +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["state"] + ⚠️ unknown object +- *7* ???["stateNode"] + ⚠️ unknown object +- *8* unknown mutation + ⚠️ This value might have side effects +- *9* unknown mutation + ⚠️ This value might have side effects +- *10* ???*11*["contextType"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* (???*13* ? ({} | ???*18*) : ({} | ???*19*)) + ⚠️ nested operation +- *13* (null !== (???*14* | ???*15*)) + ⚠️ nested operation +- *14* arguments[1] + ⚠️ function calls are not analysed yet +- *15* ???*16*["state"] + ⚠️ unknown object +- *16* ???*17*["stateNode"] + ⚠️ unknown object +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* unknown mutation + ⚠️ This value might have side effects +- *19* unknown mutation + ⚠️ This value might have side effects + +2399 -> 2401 call = (...) => b( + (???*0* | (???*2* ? ({} | ???*7*) : ({} | ???*8*))) +) +- *0* ???*1*["contextType"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (null !== (???*3* | ???*4*)) + ⚠️ nested operation +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["state"] + ⚠️ unknown object +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unknown mutation + ⚠️ This value might have side effects +- *8* unknown mutation + ⚠️ This value might have side effects + +2399 -> 2402 call = (...) => ((null !== a) && (???*0* !== a))((???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["state"] + ⚠️ unknown object +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +2399 -> 2403 conditional = ((null !== (???*0* | ???*1*)) | (???*4* !== (???*5* | ???*6*))) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["state"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["state"] + ⚠️ unknown object +- *7* ???*8*["stateNode"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet + +2399 -> 2406 call = (...) => (Vf | d["__reactInternalMemoizedMaskedChildContext"] | e)( + ???*0*, + (???*1* | (???*3* ? ({} | ???*8*) : ({} | ???*9*))) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["contextType"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (null !== (???*4* | ???*5*)) + ⚠️ nested operation +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["state"] + ⚠️ unknown object +- *6* ???*7*["stateNode"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* unknown mutation + ⚠️ This value might have side effects +- *9* unknown mutation + ⚠️ This value might have side effects + +0 -> 2410 call = (...) => undefined( + ???*0*, + (???*1* | ???*2*), + (???*5* | (???*7* ? ({} | ???*12*) : ({} | ???*13*))), + ???*14* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["state"] + ⚠️ unknown object +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["contextType"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* (null !== (???*8* | ???*9*)) + ⚠️ nested operation +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["state"] + ⚠️ unknown object +- *10* ???*11*["stateNode"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* unknown mutation + ⚠️ This value might have side effects +- *13* unknown mutation + ⚠️ This value might have side effects +- *14* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2420 member call = ???*0*["componentWillMount"]() +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2423 member call = ???*0*["UNSAFE_componentWillMount"]() +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2427 member call = { + "isMounted": (...) => (???*0* ? (Vb(a) === a) : !(1)), + "enqueueSetState": (...) => undefined, + "enqueueReplaceState": (...) => undefined, + "enqueueForceUpdate": (...) => undefined +}["enqueueReplaceState"](???*1*, ???*3*, null) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["state"] + ⚠️ unknown object +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2428 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2434 conditional = ((null !== (???*0* | ???*1*)) | ("function" !== ???*3*) | ("object" !== ???*7*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* typeof((???*4* | ???*5*)) + ⚠️ nested operation +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["ref"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* typeof((???*8* | ???*9*)) + ⚠️ nested operation +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["ref"] + ⚠️ unknown object +- *10* arguments[2] + ⚠️ function calls are not analysed yet + +2434 -> 2436 conditional = ???*0* +- *0* ???*1*["_owner"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +2436 -> 2438 conditional = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_owner"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference + +2438 -> 2440 conditional = (1 !== ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +2440 -> 2441 free var = FreeVar(Error) + +2440 -> 2442 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(309) + +2440 -> 2443 call = ???*0*( + `Minified React error #${309}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${309}` + ⚠️ nested operation + +2436 -> 2445 conditional = !(???*0*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +2445 -> 2446 free var = FreeVar(Error) + +2445 -> 2447 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(147, (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +2445 -> 2448 call = ???*0*( + `Minified React error #${147}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${147}` + ⚠️ nested operation + +2436 -> 2453 conditional = ( + | (null !== (???*0* | (...) => undefined)) + | (null !== (???*1* | (...) => undefined["ref"])) + | ("function" === ???*3*) + | ((???*6* | (...) => undefined["ref"]["_stringRef"]) === (???*9* | ???*10*)) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* typeof((???*4* | (...) => undefined["ref"])) + ⚠️ nested operation +- *4* ???*5*["ref"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["_stringRef"] + ⚠️ unknown object +- *7* ???*8*["ref"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*["ref"] + ⚠️ unknown object +- *11* arguments[2] + ⚠️ function calls are not analysed yet + +2436 -> 2457 conditional = (null === ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +2434 -> 2461 conditional = ("string" !== ???*0*) +- *0* typeof((???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["ref"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +2461 -> 2462 free var = FreeVar(Error) + +2461 -> 2463 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(284) + +2461 -> 2464 call = ???*0*( + `Minified React error #${284}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${284}` + ⚠️ nested operation + +2434 -> 2466 conditional = !(???*0*) +- *0* ???*1*["_owner"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +2466 -> 2467 free var = FreeVar(Error) + +2466 -> 2468 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(290, (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +2466 -> 2469 call = ???*0*( + `Minified React error #${290}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${290}` + ⚠️ nested operation + +0 -> 2473 free var = FreeVar(Object) + +0 -> 2474 member call = ???*0*["call"](???*3*) +- *0* ???*1*["toString"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2475 free var = FreeVar(Error) + +0 -> 2476 conditional = ("[object Object]" === (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["call"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* ???*3*["toString"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +2476 -> 2479 free var = FreeVar(Object) + +2476 -> 2480 member call = ???*0*["keys"](???*1*) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +2476 -> 2481 member call = ???*0*["join"](", ") +- *0* ???*1*["keys"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 2482 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(31, (???*0* ? ???*6* : (???*10* | ???*11*))) +- *0* ("[object Object]" === (???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["call"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *3* ???*4*["toString"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* `object with keys {${???*7*}}` + ⚠️ nested operation +- *7* ???*8*["join"](", ") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["keys"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *9* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* ???*12*["call"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *12* ???*13*["toString"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* ???*14*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 2483 call = ???*0*( + `Minified React error #${31}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${31}` + ⚠️ nested operation + +0 -> 2486 call = ???*0*(???*2*) +- *0* ???*1*["_init"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["_payload"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2487 conditional = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +2487 -> 2489 conditional = (null === ???*0*) +- *0* ???*1*["deletions"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2489 -> 2493 member call = ???*0*["push"](???*2*) +- *0* ???*1*["deletions"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2494 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["sibling"] + ⚠️ unknown object +- *3* d + ⚠️ circular variable reference + +0 -> 2496 free var = FreeVar(Map) + +0 -> 2498 conditional = (null !== ???*0*) +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +2498 -> 2501 member call = (???*0* | ???*1*)["set"](???*2*, (???*4* | ???*5*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* ???*3*["key"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["sibling"] + ⚠️ unknown object +- *6* b + ⚠️ circular variable reference + +2498 -> 2504 member call = (???*0* | ???*1*)["set"](???*2*, (???*4* | ???*5*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* ???*3*["index"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["sibling"] + ⚠️ unknown object +- *6* b + ⚠️ circular variable reference + +0 -> 2506 call = (...) => c((???*0* | ???*1* | ???*3*), ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2510 conditional = !(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2513 conditional = (null !== (???*0* | ???*1*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2520 conditional = ((null === (???*0* | ???*1* | ???*2* | ???*3*)) | (6 !== (???*5* | ???*7*))) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* b + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["tag"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects + +2520 -> 2522 call = (...) => a(???*0*, ???*1*, ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["mode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2524 call = (...) => a((???*0* | ???*1* | ???*2* | ???*3*), ???*5*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* b + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2527 conditional = (???*0* === ???*2*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["for"]("react.fragment") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *3* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +2527 -> 2531 call = (...) => (???*0* | b)(???*1*, ???*2*, ???*3*, (???*6* | ???*7* | ???*9* | ???*10*), ???*11*) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["children"] + ⚠️ unknown object +- *4* ???*5*["props"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* arguments[3] + ⚠️ function calls are not analysed yet +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* unknown new expression + ⚠️ This value might have side effects +- *10* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *11* ???*12*["key"] + ⚠️ unknown object +- *12* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2534 call = (...) => b(a["_payload"])(???*0*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2536 conditional = ( + | (null !== ???*0*) + | (???*1* === ???*3*) + | ("object" === ???*5*) + | (null !== ???*8*) + | (???*10* === ???*13*) + | (???*15* === ???*19*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["elementType"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["type"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* typeof(???*6*) + ⚠️ nested operation +- *6* ???*7*["type"] + ⚠️ unknown object +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["type"] + ⚠️ unknown object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["$$typeof"] + ⚠️ unknown object +- *11* ???*12*["type"] + ⚠️ unknown object +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*["for"]("react.lazy") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *14* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *15* ???*16*(a["_payload"]) + ⚠️ unknown callee +- *16* ???*17*["_init"] + ⚠️ unknown object +- *17* ???*18*["type"] + ⚠️ unknown object +- *18* arguments[2] + ⚠️ function calls are not analysed yet +- *19* ???*20*["type"] + ⚠️ unknown object +- *20* arguments[1] + ⚠️ function calls are not analysed yet + +2536 -> 2538 call = (...) => a(???*0*, ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["props"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +2536 -> 2540 call = (...) => (b["ref"] | b | a)(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2546 call = (...) => (Ah(c["children"], e, f, b) | ???*0* | qj(c, e, f, b) | b)(???*1*, ???*3*, ???*5*, null, ???*7*, (???*9* | ???*10* | ???*12* | ???*13*)) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["key"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*["props"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["mode"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* arguments[3] + ⚠️ function calls are not analysed yet +- *10* ???*11*["alternate"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* unknown new expression + ⚠️ This value might have side effects +- *13* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +0 -> 2548 call = (...) => (b["ref"] | b | a)(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2557 conditional = ( + | (null === (???*0* | ???*1* | ???*3* | ???*4*)) + | (4 !== (???*5* | ???*7*)) + | ((???*9* | ???*12*) !== ???*15*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["mode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* b + ⚠️ circular variable reference +- *5* ???*6*["tag"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects +- *9* ???*10*["containerInfo"] + ⚠️ unknown object +- *10* ???*11*["stateNode"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ???*13*["containerInfo"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* ???*14*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unknown new expression + ⚠️ This value might have side effects +- *15* ???*16*["containerInfo"] + ⚠️ unknown object +- *16* arguments[2] + ⚠️ function calls are not analysed yet + +2557 -> 2559 call = (...) => b(???*0*, ???*1*, ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["mode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2562 call = (...) => a((???*0* | ???*1* | ???*3* | ???*4*), (???*5* | [])) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["mode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* b + ⚠️ circular variable reference +- *5* ???*6*["children"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2565 conditional = ((null === (???*0* | ???*1* | ???*2* | ???*3*)) | (7 !== (???*5* | ???*7*))) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* b + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["tag"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects + +2565 -> 2567 call = (...) => a(???*0*, ???*1*, ???*3*, ???*4*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["mode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 2569 call = (...) => a((???*0* | ???*1* | ???*2* | ???*3*), ???*5*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* b + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2571 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2571 -> 2573 call = (...) => a((???*0* | ???*1* | ???*2* | ???*3*), ???*5*, (???*7* | ???*8* | ???*11* | ???*14* | ???*15*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* b + ⚠️ circular variable reference +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* ???*4*["mode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["mode"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["children"] + ⚠️ unknown object +- *9* ???*10*["props"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["children"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* ???*13*["props"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* unknown new expression + ⚠️ This value might have side effects +- *14* unknown new expression + ⚠️ This value might have side effects +- *15* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +0 -> 2575 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2575 -> 2581 call = (...) => (Ah(c["children"], e, f, b) | ???*0* | qj(c, e, f, b) | b)( + (???*1* | ???*3*), + (???*5* | ???*7*), + (???*9* | ???*11*), + null, + ???*13*, + (???*15* | ???*16* | ???*19* | ???*22* | ???*23*) +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["type"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* ???*6*["key"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["key"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects +- *9* ???*10*["props"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["props"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unknown new expression + ⚠️ This value might have side effects +- *13* ???*14*["mode"] + ⚠️ unknown object +- *14* arguments[0] + ⚠️ function calls are not analysed yet +- *15* arguments[2] + ⚠️ function calls are not analysed yet +- *16* ???*17*["children"] + ⚠️ unknown object +- *17* ???*18*["props"] + ⚠️ unknown object +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* ???*20*["children"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* ???*21*["props"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* unknown new expression + ⚠️ This value might have side effects +- *22* unknown new expression + ⚠️ This value might have side effects +- *23* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +2575 -> 2583 call = (...) => (b["ref"] | b | a)(???*0*, null, (???*1* | ???*2* | ???*3* | ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* b + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* ???*5*["mode"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +2575 -> 2586 call = (...) => b((???*0* | ???*1* | ???*2* | ???*3*), ???*5*, (???*7* | ???*8* | ???*11* | ???*14* | ???*15*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* b + ⚠️ circular variable reference +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* ???*4*["mode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["mode"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["children"] + ⚠️ unknown object +- *9* ???*10*["props"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["children"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* ???*13*["props"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* unknown new expression + ⚠️ This value might have side effects +- *14* unknown new expression + ⚠️ This value might have side effects +- *15* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +2575 -> 2590 call = (???*0* | ???*2*)((???*4* | ???*6*)) +- *0* ???*1*["_init"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["_init"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* ???*5*["_payload"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["_payload"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unknown new expression + ⚠️ This value might have side effects + +2575 -> 2591 call = (...) => (???*0* | q(a, d(b["_payload"]), c) | null)(???*1*, ???*2*, (???*7* | ???*8* | ???*11* | ???*14* | ???*15*)) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (???*3* | ???*5*)(b["_payload"]) + ⚠️ non-function callee +- *3* ???*4*["_init"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["_init"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* unknown new expression + ⚠️ This value might have side effects +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["children"] + ⚠️ unknown object +- *9* ???*10*["props"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["children"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* ???*13*["props"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* unknown new expression + ⚠️ This value might have side effects +- *14* unknown new expression + ⚠️ This value might have side effects +- *15* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +2575 -> 2592 call = ???*0*((???*2* | ???*3* | ???*4* | ???*5*)) +- *0* ???*1*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* b + ⚠️ circular variable reference +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* ???*6*["mode"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +2575 -> 2593 call = (...) => (null | (("function" === typeof(a)) ? a : null))((???*0* | ???*1* | ???*2* | ???*3*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* b + ⚠️ circular variable reference +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* ???*4*["mode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +2575 -> 2594 conditional = ( + | ???*0* + | null + | (???*3* ? (???*12* | ???*13* | ???*14* | ???*15* | ???*17*) : null) +) +- *0* ???*1*(b) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* ("function" === ???*4*) + ⚠️ nested operation +- *4* typeof((???*5* | ???*6* | ???*7* | ???*8* | ???*10*)) + ⚠️ nested operation +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* b + ⚠️ circular variable reference +- *7* unknown new expression + ⚠️ This value might have side effects +- *8* ???*9*["mode"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* b + ⚠️ circular variable reference +- *14* unknown new expression + ⚠️ This value might have side effects +- *15* ???*16*["mode"] + ⚠️ unknown object +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +2594 -> 2596 call = (...) => a((???*0* | ???*1* | ???*2* | ???*3*), ???*5*, (???*7* | ???*8* | ???*11* | ???*14* | ???*15*), null) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* b + ⚠️ circular variable reference +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* ???*4*["mode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["mode"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["children"] + ⚠️ unknown object +- *9* ???*10*["props"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["children"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* ???*13*["props"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* unknown new expression + ⚠️ This value might have side effects +- *14* unknown new expression + ⚠️ This value might have side effects +- *15* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +2575 -> 2598 call = (...) => undefined(???*0*, (???*1* | ???*2* | ???*3* | ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* b + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* ???*5*["mode"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2599 conditional = (null !== ???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2601 conditional = (("string" === ???*0*) | ("" !== ???*2*) | ("number" === ???*3*)) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* typeof(???*4*) + ⚠️ nested operation +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +2601 -> 2602 conditional = (null !== (???*0* | ???*5*)) +- *0* (???*1* ? ???*3* : null) + ⚠️ nested operation +- *1* (null !== ???*2*) + ⚠️ nested operation +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["key"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["_init"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet + +2602 -> 2603 call = (...) => (???*0* | b)(???*1*, ???*2*, ???*3*, ???*4*) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2604 conditional = (("object" === ???*0*) | (null !== ???*2*)) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +2604 -> 2607 conditional = (???*0* === (???*2* | ???*7*)) +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? ???*5* : null) + ⚠️ nested operation +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["key"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["_init"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet + +2607 -> 2608 call = (...) => (m(a, b, c["props"]["children"], d, c["key"]) | ???*0* | d)(???*1*, ???*2*, ???*3*, ???*4*) +- *0* d + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +2604 -> 2610 conditional = (???*0* === (???*2* | ???*7*)) +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? ???*5* : null) + ⚠️ nested operation +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["key"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["_init"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet + +2610 -> 2611 call = (...) => (???*0* | b)(???*1*, ???*2*, ???*3*, ???*4*) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +2604 -> 2614 call = ((???*0* ? ???*2* : null) | ???*4*)(???*6*) +- *0* (null !== ???*1*) + ⚠️ nested operation +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["key"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["_init"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* ???*7*["_payload"] + ⚠️ unknown object +- *7* arguments[2] + ⚠️ function calls are not analysed yet + +2604 -> 2615 call = (...) => ( + | ((null !== e) ? null : h(a, b, `${c}`, d)) + | ((c["key"] === e) ? k(a, b, c, d) : null) + | ((c["key"] === e) ? l(a, b, c, d) : null) + | ???*0* + | ((null !== e) ? null : m(a, b, c, d, null)) + | null +)(???*1*, ???*2*, ???*3*, ???*10*) +- *0* r(a, b, e(c["_payload"]), d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ((???*4* ? ???*6* : null) | ???*8*)(c["_payload"]) + ⚠️ non-function callee +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["key"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???*9*["_init"] + ⚠️ unknown object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* arguments[3] + ⚠️ function calls are not analysed yet + +2604 -> 2616 call = ???*0*(???*2*) +- *0* ???*1*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +2604 -> 2617 call = (...) => (null | (("function" === typeof(a)) ? a : null))(???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +2604 -> 2618 conditional = (???*0* | null | (???*3* ? (???*10* | ???*11* | ???*13*) : null)) +- *0* ???*1*(c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* ("function" === ???*4*) + ⚠️ nested operation +- *4* typeof((???*5* | ???*6* | ???*8*)) + ⚠️ nested operation +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* ???*7*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* ???*9*[Ja] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* ???*12*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* ???*14*[Ja] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference + +2618 -> 2619 conditional = (null !== (???*0* | ???*5*)) +- *0* (???*1* ? ???*3* : null) + ⚠️ nested operation +- *1* (null !== ???*2*) + ⚠️ nested operation +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["key"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["_init"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet + +2619 -> 2620 call = (...) => (???*0* | b)(???*1*, ???*2*, ???*3*, ???*4*, null) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +2604 -> 2621 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 2622 conditional = (("string" === ???*0*) | ("" !== ???*2*) | ("number" === ???*3*)) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* typeof(???*4*) + ⚠️ nested operation +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +2622 -> 2624 member call = (???*0* | ???*1* | null)["get"](???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["get"](c) + ⚠️ unknown callee object +- *2* a + ⚠️ circular variable reference +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +2622 -> 2625 call = (...) => (???*0* | b)(???*1*, (???*2* | ???*3* | null), ???*5*, ???*6*) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["get"](c) + ⚠️ unknown callee object +- *4* a + ⚠️ circular variable reference +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 2626 conditional = (("object" === ???*0*) | (null !== ???*2*)) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet + +2626 -> 2630 conditional = (null === ???*0*) +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +2626 -> 2632 member call = (???*0* | ???*1* | null)["get"]((???*3* ? ???*6* : ???*7*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["get"](c) + ⚠️ unknown callee object +- *2* a + ⚠️ circular variable reference +- *3* (null === ???*4*) + ⚠️ nested operation +- *4* ???*5*["key"] + ⚠️ unknown object +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["key"] + ⚠️ unknown object +- *8* arguments[3] + ⚠️ function calls are not analysed yet + +2626 -> 2633 call = (...) => (m(a, b, c["props"]["children"], d, c["key"]) | ???*0* | d)(???*1*, (???*2* | ???*3* | null), ???*5*, ???*6*) +- *0* d + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["get"](c) + ⚠️ unknown callee object +- *4* a + ⚠️ circular variable reference +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* arguments[4] + ⚠️ function calls are not analysed yet + +2626 -> 2636 conditional = (null === ???*0*) +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +2626 -> 2638 member call = (???*0* | ???*1* | null)["get"]((???*3* ? ???*6* : ???*7*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["get"](c) + ⚠️ unknown callee object +- *2* a + ⚠️ circular variable reference +- *3* (null === ???*4*) + ⚠️ nested operation +- *4* ???*5*["key"] + ⚠️ unknown object +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["key"] + ⚠️ unknown object +- *8* arguments[3] + ⚠️ function calls are not analysed yet + +2626 -> 2639 call = (...) => (???*0* | b)(???*1*, (???*2* | ???*3* | null), ???*5*, ???*6*) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["get"](c) + ⚠️ unknown callee object +- *4* a + ⚠️ circular variable reference +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* arguments[4] + ⚠️ function calls are not analysed yet + +2626 -> 2642 call = ???*0*(???*2*) +- *0* ???*1*["_init"] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* ???*3*["_payload"] + ⚠️ unknown object +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +2626 -> 2643 call = (...) => (???*0* | y(a, b, c, f(d["_payload"]), e) | null)((???*1* | ???*2* | null), ???*4*, ???*5*, ???*6*, ???*9*) +- *0* h(b, a, ("" + d), e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["get"](c) + ⚠️ unknown callee object +- *3* a + ⚠️ circular variable reference +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* ???*7*(d["_payload"]) + ⚠️ unknown callee +- *7* ???*8*["_init"] + ⚠️ unknown object +- *8* arguments[3] + ⚠️ function calls are not analysed yet +- *9* arguments[4] + ⚠️ function calls are not analysed yet + +2626 -> 2644 call = ???*0*(???*2*) +- *0* ???*1*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[3] + ⚠️ function calls are not analysed yet + +2626 -> 2645 call = (...) => (null | (("function" === typeof(a)) ? a : null))(???*0*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +2626 -> 2646 conditional = (???*0* | null | (???*3* ? (???*10* | ???*11* | ???*13*) : null)) +- *0* ???*1*(d) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* ("function" === ???*4*) + ⚠️ nested operation +- *4* typeof((???*5* | ???*6* | ???*8*)) + ⚠️ nested operation +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* ???*7*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* ???*9*[Ja] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* arguments[3] + ⚠️ function calls are not analysed yet +- *11* ???*12*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* ???*14*[Ja] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference + +2646 -> 2648 member call = (???*0* | ???*1* | null)["get"](???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["get"](c) + ⚠️ unknown callee object +- *2* a + ⚠️ circular variable reference +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +2646 -> 2649 call = (...) => (???*0* | b)(???*1*, (???*2* | ???*3* | null), ???*5*, ???*6*, null) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["get"](c) + ⚠️ unknown callee object +- *4* a + ⚠️ circular variable reference +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* arguments[4] + ⚠️ function calls are not analysed yet + +2626 -> 2650 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2655 call = (...) => ( + | ((null !== e) ? null : h(a, b, `${c}`, d)) + | ((c["key"] === e) ? k(a, b, c, d) : null) + | ((c["key"] === e) ? l(a, b, c, d) : null) + | ???*0* + | ((null !== e) ? null : m(a, b, c, d, null)) + | null +)(???*1*, ???*2*, ???*3*, ???*5*) +- *0* r(a, b, e(c["_payload"]), d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* ???*4*[w] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2657 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2658 call = (...) => (???*0* | c)(???*1*, ???*2*, (???*3* | ???*4*)) +- *0* c + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +0 -> 2659 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2662 conditional = ((???*0* | ???*1*) === ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects +- *2* ???*3*["length"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +2662 -> 2663 call = (...) => null(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2662 -> 2664 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +0 -> 2665 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2665 -> 2668 call = (...) => (???*0* | q(a, d(b["_payload"]), c) | null)(???*1*, ???*2*, ???*4*) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*[w] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +2665 -> 2669 call = (...) => (???*0* | c)(???*1*, ???*2*, (???*3* | ???*4*)) +- *0* c + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +2665 -> 2670 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2665 -> 2672 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +0 -> 2673 call = (...) => a(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2676 call = (...) => (???*0* | y(a, b, c, f(d["_payload"]), e) | null)(???*1*, ???*2*, (???*3* | ???*4*), ???*5*, ???*7*) +- *0* h(b, a, ("" + d), e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*[w] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2680 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2682 member call = ???*0*["delete"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2683 call = (...) => (???*0* | c)(???*1*, ???*2*, (???*3* | ???*4*)) +- *0* c + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +0 -> 2684 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2687 member call = ???*0*["forEach"]((...) => b(e, a)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2687 -> 2688 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2689 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +0 -> 2690 call = (...) => (null | (("function" === typeof(a)) ? a : null))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2691 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2691 -> 2692 free var = FreeVar(Error) + +2691 -> 2693 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(150) + +2691 -> 2694 call = ???*0*( + `Minified React error #${150}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${150}` + ⚠️ nested operation + +0 -> 2696 member call = ???*0*["call"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2697 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2697 -> 2698 free var = FreeVar(Error) + +2697 -> 2699 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(151) + +2697 -> 2700 call = ???*0*( + `Minified React error #${151}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${151}` + ⚠️ nested operation + +0 -> 2702 member call = ???*0*["next"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2705 member call = ???*0*["next"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2709 call = (...) => ( + | ((null !== e) ? null : h(a, b, `${c}`, d)) + | ((c["key"] === e) ? k(a, b, c, d) : null) + | ((c["key"] === e) ? l(a, b, c, d) : null) + | ???*0* + | ((null !== e) ? null : m(a, b, c, d, null)) + | null +)(???*1*, ???*2*, ???*3*, ???*4*) +- *0* r(a, b, e(c["_payload"]), d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2711 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2712 call = (...) => (???*0* | c)(???*1*, ???*2*, (???*3* | ???*4*)) +- *0* c + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +0 -> 2713 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2716 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2716 -> 2717 call = (...) => null(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2716 -> 2718 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +0 -> 2719 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2719 -> 2722 member call = ???*0*["next"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2719 -> 2724 call = (...) => (???*0* | q(a, d(b["_payload"]), c) | null)(???*1*, ???*2*, ???*3*) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +2719 -> 2725 call = (...) => (???*0* | c)(???*1*, ???*2*, (???*3* | ???*4*)) +- *0* c + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +2719 -> 2726 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2719 -> 2728 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +0 -> 2729 call = (...) => a(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2732 member call = ???*0*["next"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2734 call = (...) => (???*0* | y(a, b, c, f(d["_payload"]), e) | null)(???*1*, ???*2*, (???*3* | ???*4*), ???*5*, ???*6*) +- *0* h(b, a, ("" + d), e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects +- *6* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 2738 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2740 member call = ???*0*["delete"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2741 call = (...) => (???*0* | c)(???*1*, ???*2*, (???*3* | ???*4*)) +- *0* c + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +0 -> 2742 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2745 member call = ???*0*["forEach"]((...) => b(e, a)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2745 -> 2746 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2747 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +0 -> 2752 conditional = (("object" === ???*0*) | (null !== (???*6* | ???*7* | ???*10*))) +- *0* typeof((???*1* | ???*2* | ???*5*)) + ⚠️ nested operation +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["children"] + ⚠️ unknown object +- *3* ???*4*["props"] + ⚠️ unknown object +- *4* f + ⚠️ circular variable reference +- *5* f + ⚠️ circular variable reference +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["children"] + ⚠️ unknown object +- *8* ???*9*["props"] + ⚠️ unknown object +- *9* f + ⚠️ circular variable reference +- *10* f + ⚠️ circular variable reference + +2752 -> 2756 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2756 -> 2758 conditional = (???*0* === ???*2*) +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["for"]("react.fragment") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *3* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +2758 -> 2760 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2760 -> 2762 call = (...) => null(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2760 -> 2765 call = (...) => a(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* ???*3*["props"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +2758 -> 2769 call = (...) => b(a["_payload"])(???*0*) +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +2758 -> 2771 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2771 -> 2773 call = (...) => null(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2771 -> 2775 call = (...) => a(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* ???*2*["props"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +2771 -> 2777 call = (...) => (b["ref"] | b | a)(???*0*, ???*1*, (???*2* | ???*3* | ???*6*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["children"] + ⚠️ unknown object +- *4* ???*5*["props"] + ⚠️ unknown object +- *5* f + ⚠️ circular variable reference +- *6* f + ⚠️ circular variable reference + +2756 -> 2779 call = (...) => null(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2756 -> 2780 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2752 -> 2783 conditional = (???*0* === ???*2*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["for"]("react.fragment") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *3* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +2783 -> 2788 call = (...) => a(???*0*, ???*3*, ???*4*, ???*5*) +- *0* ???*1*["children"] + ⚠️ unknown object +- *1* ???*2*["props"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*["key"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet + +2783 -> 2794 call = (...) => (Ah(c["children"], e, f, b) | ???*0* | qj(c, e, f, b) | b)(???*1*, ???*3*, ???*5*, null, ???*7*, ???*8*) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["key"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*["props"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* max number of linking steps reached + ⚠️ This value might have side effects +- *8* max number of linking steps reached + ⚠️ This value might have side effects + +2783 -> 2796 call = (...) => (b["ref"] | b | a)(???*0*, ???*1*, (???*2* | ???*3* | ???*6*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["children"] + ⚠️ unknown object +- *4* ???*5*["props"] + ⚠️ unknown object +- *5* f + ⚠️ circular variable reference +- *6* f + ⚠️ circular variable reference + +2752 -> 2798 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2752 -> 2801 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2801 -> 2809 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2809 -> 2811 call = (...) => null(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2809 -> 2813 call = (...) => a(???*0*, (???*1* | [])) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +2809 -> 2815 call = (...) => null(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2801 -> 2816 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2752 -> 2819 call = (...) => b((???*0* | ???*1* | ???*4*), ???*5*, ???*6*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* ???*3*["props"] + ⚠️ unknown object +- *3* f + ⚠️ circular variable reference +- *4* f + ⚠️ circular variable reference +- *5* max number of linking steps reached + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects + +2752 -> 2821 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2752 -> 2824 call = ???*0*(???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* ???*2*["_payload"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +2752 -> 2825 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, ???*3*, ???*4*, ???*5*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +2752 -> 2826 call = ???*0*((???*2* | ???*3* | ???*6*)) +- *0* ???*1*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["children"] + ⚠️ unknown object +- *4* ???*5*["props"] + ⚠️ unknown object +- *5* f + ⚠️ circular variable reference +- *6* f + ⚠️ circular variable reference + +2752 -> 2827 conditional = ???*0* +- *0* ???*1*(f) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +2827 -> 2828 call = (...) => l(???*0*, ???*1*, (???*2* | ???*3* | ???*6*), ???*7*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["children"] + ⚠️ unknown object +- *4* ???*5*["props"] + ⚠️ unknown object +- *5* f + ⚠️ circular variable reference +- *6* f + ⚠️ circular variable reference +- *7* max number of linking steps reached + ⚠️ This value might have side effects + +2752 -> 2829 call = (...) => (null | (("function" === typeof(a)) ? a : null))((???*0* | ???*1* | ???*4*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* ???*3*["props"] + ⚠️ unknown object +- *3* f + ⚠️ circular variable reference +- *4* f + ⚠️ circular variable reference + +2752 -> 2830 conditional = ( + | null + | (???*0* ? (???*9* | ???*10* | ???*13* | ???*14*) : null) +) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof((???*2* | ???*3* | ???*6* | ???*7*)) + ⚠️ nested operation +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["children"] + ⚠️ unknown object +- *4* ???*5*["props"] + ⚠️ unknown object +- *5* f + ⚠️ circular variable reference +- *6* f + ⚠️ circular variable reference +- *7* ???*8*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["children"] + ⚠️ unknown object +- *11* ???*12*["props"] + ⚠️ unknown object +- *12* f + ⚠️ circular variable reference +- *13* f + ⚠️ circular variable reference +- *14* ???*15*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *15* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +2830 -> 2831 call = (...) => l(???*0*, ???*1*, (???*2* | ???*3* | ???*6*), ???*7*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["children"] + ⚠️ unknown object +- *4* ???*5*["props"] + ⚠️ unknown object +- *5* f + ⚠️ circular variable reference +- *6* f + ⚠️ circular variable reference +- *7* max number of linking steps reached + ⚠️ This value might have side effects + +2752 -> 2832 call = (...) => undefined(???*0*, (???*1* | ???*2* | ???*5*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["children"] + ⚠️ unknown object +- *3* ???*4*["props"] + ⚠️ unknown object +- *4* f + ⚠️ circular variable reference +- *5* f + ⚠️ circular variable reference + +0 -> 2833 conditional = (("string" === ???*0*) | ("" !== (???*6* | ???*7* | ???*10*)) | ("number" === ???*11*)) +- *0* typeof((???*1* | ???*2* | ???*5*)) + ⚠️ nested operation +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["children"] + ⚠️ unknown object +- *3* ???*4*["props"] + ⚠️ unknown object +- *4* f + ⚠️ circular variable reference +- *5* f + ⚠️ circular variable reference +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["children"] + ⚠️ unknown object +- *8* ???*9*["props"] + ⚠️ unknown object +- *9* f + ⚠️ circular variable reference +- *10* f + ⚠️ circular variable reference +- *11* typeof((???*12* | ???*13* | ???*16*)) + ⚠️ nested operation +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*["children"] + ⚠️ unknown object +- *14* ???*15*["props"] + ⚠️ unknown object +- *15* f + ⚠️ circular variable reference +- *16* f + ⚠️ circular variable reference + +2833 -> 2835 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2835 -> 2837 call = (...) => null(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2835 -> 2838 call = (...) => a(???*0*, (???*1* | ???*2* | ???*5*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["children"] + ⚠️ unknown object +- *3* ???*4*["props"] + ⚠️ unknown object +- *4* f + ⚠️ circular variable reference +- *5* f + ⚠️ circular variable reference + +2835 -> 2840 call = (...) => null(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +2835 -> 2842 call = (...) => a((???*0* | ???*1* | ???*4*), ???*5*, ???*6*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* ???*3*["props"] + ⚠️ unknown object +- *3* f + ⚠️ circular variable reference +- *4* f + ⚠️ circular variable reference +- *5* max number of linking steps reached + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects + +2833 -> 2844 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2833 -> 2845 call = (...) => null(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2846 call = (...) => J(true) + +0 -> 2847 call = (...) => J(false) + +0 -> 2848 call = (...) => {"current": a}({}) + +0 -> 2849 call = (...) => {"current": a}({}) + +0 -> 2850 call = (...) => {"current": a}({}) + +0 -> 2851 conditional = (???*0* === {}) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +2851 -> 2852 free var = FreeVar(Error) + +2851 -> 2853 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(174) + +2851 -> 2854 call = ???*0*( + `Minified React error #${174}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${174}` + ⚠️ nested operation + +0 -> 2855 call = (...) => undefined( + {"current": {}}, + ( + | ???*0* + | (???*1* ? ???*2* : ???*4*) + | ???*6* + | (???*8* ? ???*10* : ???*12*)["namespaceURI"] + | null + | (???*13* ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : ???*15*) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["namespaceURI"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference +- *4* ((???*5* | false) ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : null) + ⚠️ nested operation +- *5* (null == null) + ⚠️ nested operation +- *6* ???*7*["documentElement"] + ⚠️ unknown object +- *7* b + ⚠️ circular variable reference +- *8* (8 === ???*9*) + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["parentNode"] + ⚠️ unknown object +- *11* b + ⚠️ circular variable reference +- *12* b + ⚠️ circular variable reference +- *13* (null == ???*14*) + ⚠️ nested operation +- *14* b + ⚠️ circular variable reference +- *15* (???*16* ? "http://www.w3.org/1999/xhtml" : ???*18*) + ⚠️ nested operation +- *16* ("http://www.w3.org/2000/svg" === ???*17*) + ⚠️ nested operation +- *17* b + ⚠️ circular variable reference +- *18* b + ⚠️ circular variable reference + +0 -> 2856 call = (...) => undefined( + {"current": {}}, + ( + | ???*0* + | ???*1* + | (???*3* ? ???*4* : ???*6*)["nodeType"] + | null["nodeType"] + | (???*8* ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : ???*10*)["nodeType"] + | (???*14* ? (???*16* | null["parentNode"]) : (???*18* | ???*19* | ???*25* | null)) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["namespaceURI"] + ⚠️ unknown object +- *5* b + ⚠️ circular variable reference +- *6* ((???*7* | false) ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : null) + ⚠️ nested operation +- *7* (null == null) + ⚠️ nested operation +- *8* (null == ???*9*) + ⚠️ nested operation +- *9* b + ⚠️ circular variable reference +- *10* (???*11* ? "http://www.w3.org/1999/xhtml" : ???*13*) + ⚠️ nested operation +- *11* ("http://www.w3.org/2000/svg" === ???*12*) + ⚠️ nested operation +- *12* b + ⚠️ circular variable reference +- *13* b + ⚠️ circular variable reference +- *14* (8 === ???*15*) + ⚠️ nested operation +- *15* a + ⚠️ circular variable reference +- *16* ???*17*["parentNode"] + ⚠️ unknown object +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* (???*20* ? ???*21* : ???*23*) + ⚠️ nested operation +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["namespaceURI"] + ⚠️ unknown object +- *22* b + ⚠️ circular variable reference +- *23* ((???*24* | false) ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : null) + ⚠️ nested operation +- *24* (null == null) + ⚠️ nested operation +- *25* ???*26*["documentElement"] + ⚠️ unknown object +- *26* b + ⚠️ circular variable reference + +0 -> 2857 call = (...) => undefined({"current": {}}, {}) + +0 -> 2861 call = (...) => (((null == a) || ("http://www.w3.org/1999/xhtml" === a)) ? kb(b) : ((("http://www.w3.org/2000/svg" === a) && ("foreignObject" === b)) ? "http://www.w3.org/1999/xhtml" : a))(null, "") + +0 -> 2862 conditional = (8 === (???*0* | ???*1* | null["nodeType"] | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? (???*6* | null["parentNode"]) : (???*8* | ???*9* | ???*15* | null)) + ⚠️ nested operation +- *4* (8 === ???*5*) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["parentNode"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* (???*10* ? ???*11* : ???*13*) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["namespaceURI"] + ⚠️ unknown object +- *12* b + ⚠️ circular variable reference +- *13* ((???*14* | false) ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : null) + ⚠️ nested operation +- *14* (null == null) + ⚠️ nested operation +- *15* ???*16*["documentElement"] + ⚠️ unknown object +- *16* b + ⚠️ circular variable reference + +0 -> 2866 call = (...) => (((null == a) || ("http://www.w3.org/1999/xhtml" === a)) ? kb(b) : ((("http://www.w3.org/2000/svg" === a) && ("foreignObject" === b)) ? "http://www.w3.org/1999/xhtml" : a))( + ( + | ???*0* + | (???*1* ? ???*2* : ???*4*) + | ???*6* + | (???*8* ? ???*10* : ???*12*)["namespaceURI"] + | null + | (???*13* ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : ???*15*) + ), + ( + | ???*19* + | ???*20* + | (???*22* ? ???*23* : ???*25*)["nodeType"] + | null["nodeType"] + | (???*27* ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : ???*29*)["nodeType"] + | (???*33* ? (???*35* | null["parentNode"]) : (???*37* | ???*38* | ???*44* | null)) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["namespaceURI"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference +- *4* ((???*5* | false) ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : null) + ⚠️ nested operation +- *5* (null == null) + ⚠️ nested operation +- *6* ???*7*["documentElement"] + ⚠️ unknown object +- *7* b + ⚠️ circular variable reference +- *8* (8 === ???*9*) + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["parentNode"] + ⚠️ unknown object +- *11* b + ⚠️ circular variable reference +- *12* b + ⚠️ circular variable reference +- *13* (null == ???*14*) + ⚠️ nested operation +- *14* b + ⚠️ circular variable reference +- *15* (???*16* ? "http://www.w3.org/1999/xhtml" : ???*18*) + ⚠️ nested operation +- *16* ("http://www.w3.org/2000/svg" === ???*17*) + ⚠️ nested operation +- *17* b + ⚠️ circular variable reference +- *18* b + ⚠️ circular variable reference +- *19* arguments[0] + ⚠️ function calls are not analysed yet +- *20* ???*21*["nodeType"] + ⚠️ unknown object +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["namespaceURI"] + ⚠️ unknown object +- *24* b + ⚠️ circular variable reference +- *25* ((???*26* | false) ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : null) + ⚠️ nested operation +- *26* (null == null) + ⚠️ nested operation +- *27* (null == ???*28*) + ⚠️ nested operation +- *28* b + ⚠️ circular variable reference +- *29* (???*30* ? "http://www.w3.org/1999/xhtml" : ???*32*) + ⚠️ nested operation +- *30* ("http://www.w3.org/2000/svg" === ???*31*) + ⚠️ nested operation +- *31* b + ⚠️ circular variable reference +- *32* b + ⚠️ circular variable reference +- *33* (8 === ???*34*) + ⚠️ nested operation +- *34* a + ⚠️ circular variable reference +- *35* ???*36*["parentNode"] + ⚠️ unknown object +- *36* arguments[1] + ⚠️ function calls are not analysed yet +- *37* arguments[1] + ⚠️ function calls are not analysed yet +- *38* (???*39* ? ???*40* : ???*42*) + ⚠️ nested operation +- *39* unsupported expression + ⚠️ This value might have side effects +- *40* ???*41*["namespaceURI"] + ⚠️ unknown object +- *41* b + ⚠️ circular variable reference +- *42* ((???*43* | false) ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : null) + ⚠️ nested operation +- *43* (null == null) + ⚠️ nested operation +- *44* ???*45*["documentElement"] + ⚠️ unknown object +- *45* b + ⚠️ circular variable reference + +0 -> 2867 call = (...) => undefined({"current": {}}) + +0 -> 2868 call = (...) => undefined( + {"current": {}}, + ( + | ???*0* + | (???*1* ? ???*2* : ???*4*) + | ???*6* + | (???*8* ? ???*10* : ???*12*)["namespaceURI"] + | null + | (???*13* ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : ???*15*) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["namespaceURI"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference +- *4* ((???*5* | false) ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : null) + ⚠️ nested operation +- *5* (null == null) + ⚠️ nested operation +- *6* ???*7*["documentElement"] + ⚠️ unknown object +- *7* b + ⚠️ circular variable reference +- *8* (8 === ???*9*) + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["parentNode"] + ⚠️ unknown object +- *11* b + ⚠️ circular variable reference +- *12* b + ⚠️ circular variable reference +- *13* (null == ???*14*) + ⚠️ nested operation +- *14* b + ⚠️ circular variable reference +- *15* (???*16* ? "http://www.w3.org/1999/xhtml" : ???*18*) + ⚠️ nested operation +- *16* ("http://www.w3.org/2000/svg" === ???*17*) + ⚠️ nested operation +- *17* b + ⚠️ circular variable reference +- *18* b + ⚠️ circular variable reference + +0 -> 2869 call = (...) => undefined({"current": {}}) + +0 -> 2870 call = (...) => undefined({"current": {}}) + +0 -> 2871 call = (...) => undefined({"current": {}}) + +0 -> 2873 call = (...) => a(({} | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +0 -> 2875 call = (...) => a(({} | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +0 -> 2877 call = (...) => (((null == a) || ("http://www.w3.org/1999/xhtml" === a)) ? kb(b) : ((("http://www.w3.org/2000/svg" === a) && ("foreignObject" === b)) ? "http://www.w3.org/1999/xhtml" : a))(({} | ???*0*), ???*1*) +- *0* unknown mutation + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2878 call = (...) => undefined({"current": {}}, ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2879 call = (...) => undefined( + {"current": {}}, + (???*0* ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" + ) : ???*2*) +) +- *0* (null == ({} | ???*1*)) + ⚠️ nested operation +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* (???*3* ? "http://www.w3.org/1999/xhtml" : ({} | ???*5*)) + ⚠️ nested operation +- *3* ("http://www.w3.org/2000/svg" === ({} | ???*4*)) + ⚠️ nested operation +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +0 -> 2881 call = (...) => undefined({"current": {}}) + +0 -> 2882 call = (...) => undefined({"current": {}}) + +0 -> 2883 call = (...) => {"current": a}(0) + +0 -> 2885 conditional = (13 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +2885 -> 2893 conditional = ((19 === ???*0*) | (???*2* !== ???*3*)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["revealOrder"] + ⚠️ unknown object +- *4* ???*5*["memoizedProps"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +2893 -> 2896 conditional = (null !== ???*0*) +- *0* ???*1*["child"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2914 free var = FreeVar(Error) + +0 -> 2915 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(321) + +0 -> 2916 call = ???*0*( + `Minified React error #${321}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${321}` + ⚠️ nested operation + +0 -> 2921 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*, ???*11*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*[c] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* ???*12*[c] + ⚠️ unknown object +- *12* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 2927 conditional = ((null === (???*0* | ???*1*)) | (null === ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*(d, e) + ⚠️ unknown callee +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2928 call = ???*0*(???*1*, ???*2*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 2929 conditional = (false | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +2929 -> 2930 free var = FreeVar(Error) + +2929 -> 2931 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(301) + +2929 -> 2932 call = ???*0*( + `Minified React error #${301}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${301}` + ⚠️ nested operation + +2929 -> 2935 call = ???*0*(???*1*, ???*2*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 2938 conditional = ( + | ???*0* + | (null !== ( + | null + | ???*1* + | null["alternate"] + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | null["alternate"]["next"] | ???*19* | null | ???*22*)) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* b + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects + +2938 -> 2939 free var = FreeVar(Error) + +2938 -> 2940 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(300) + +2938 -> 2941 call = ???*0*( + `Minified React error #${300}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${300}` + ⚠️ nested operation + +0 -> 2942 conditional = (null === ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | ???*1* + | null["alternate"] + | ???*8* + | null["next"] + | ???*10* + | { + "memoizedState": (null["memoizedState"] | ???*12* | ???*14*), + "baseState": (null["baseState"] | ???*16* | ???*18*), + "baseQueue": (null["baseQueue"] | ???*20* | ???*22*), + "queue": (null["queue"] | ???*24* | ???*26*), + "next": null + } +)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (???*2* ? (null["memoizedState"] | ???*4*) : ???*6*) + ⚠️ nested operation +- *2* (null === ???*3*) + ⚠️ nested operation +- *3* P + ⚠️ circular variable reference +- *4* ???*5*["memoizedState"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["next"] + ⚠️ unknown object +- *7* P + ⚠️ circular variable reference +- *8* ???*9*["alternate"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* ???*15*["memoizedState"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* ???*17*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* ???*19*["baseState"] + ⚠️ unknown object +- *19* a + ⚠️ circular variable reference +- *20* ???*21*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* ???*23*["baseQueue"] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference +- *24* ???*25*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* ???*27*["queue"] + ⚠️ unknown object +- *27* a + ⚠️ circular variable reference + +0 -> 2945 conditional = (null === ( + | null + | ???*0* + | null["alternate"] + | ???*1* + | ???*3* + | { + "memoizedState": ???*8*, + "baseState": ???*10*, + "baseQueue": ???*12*, + "queue": ???*14*, + "next": null + } +)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* O + ⚠️ circular variable reference +- *10* ???*11*["baseState"] + ⚠️ unknown object +- *11* O + ⚠️ circular variable reference +- *12* ???*13*["baseQueue"] + ⚠️ unknown object +- *13* O + ⚠️ circular variable reference +- *14* ???*15*["queue"] + ⚠️ unknown object +- *15* O + ⚠️ circular variable reference + +2945 -> 2947 conditional = (null !== ( + | null["alternate"] + | ???*0* + | ???*2* + | null["next"] + | ???*7* + | { + "memoizedState": (null["memoizedState"] | ???*9* | ???*11*), + "baseState": (null["baseState"] | ???*13* | ???*15*), + "baseQueue": (null["baseQueue"] | ???*17* | ???*19*), + "queue": (null["queue"] | ???*21* | ???*23*), + "next": null + } +)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? ???*5* : null) + ⚠️ nested operation +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["memoizedState"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* ???*16*["baseState"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["baseQueue"] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* ???*22*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["queue"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference + +0 -> 2950 conditional = (null === ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | ???*1* + | null["alternate"] + | ???*8* + | null["next"] + | ???*10* + | { + "memoizedState": (null["memoizedState"] | ???*12* | ???*14*), + "baseState": (null["baseState"] | ???*16* | ???*18*), + "baseQueue": (null["baseQueue"] | ???*20* | ???*22*), + "queue": (null["queue"] | ???*24* | ???*26*), + "next": null + } +)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (???*2* ? (null["memoizedState"] | ???*4*) : ???*6*) + ⚠️ nested operation +- *2* (null === ???*3*) + ⚠️ nested operation +- *3* P + ⚠️ circular variable reference +- *4* ???*5*["memoizedState"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["next"] + ⚠️ unknown object +- *7* P + ⚠️ circular variable reference +- *8* ???*9*["alternate"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* ???*15*["memoizedState"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* ???*17*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* ???*19*["baseState"] + ⚠️ unknown object +- *19* a + ⚠️ circular variable reference +- *20* ???*21*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* ???*23*["baseQueue"] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference +- *24* ???*25*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* ???*27*["queue"] + ⚠️ unknown object +- *27* a + ⚠️ circular variable reference + +0 -> 2953 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2953 -> 2954 conditional = (null === ( + | null["alternate"] + | ???*0* + | ???*2* + | null["next"] + | ???*7* + | { + "memoizedState": (null["memoizedState"] | ???*9* | ???*11*), + "baseState": (null["baseState"] | ???*13* | ???*15*), + "baseQueue": (null["baseQueue"] | ???*17* | ???*19*), + "queue": (null["queue"] | ???*21* | ???*23*), + "next": null + } +)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? ???*5* : null) + ⚠️ nested operation +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["memoizedState"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* ???*16*["baseState"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["baseQueue"] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* ???*22*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["queue"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference + +2954 -> 2955 free var = FreeVar(Error) + +2954 -> 2956 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(310) + +2954 -> 2957 call = ???*0*( + `Minified React error #${310}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${310}` + ⚠️ nested operation + +2953 -> 2962 conditional = (null === ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | ???*1* + | null["alternate"] + | ???*8* + | null["next"] + | ???*10* + | { + "memoizedState": (null["memoizedState"] | ???*12* | ???*14*), + "baseState": (null["baseState"] | ???*16* | ???*18*), + "baseQueue": (null["baseQueue"] | ???*20* | ???*22*), + "queue": (null["queue"] | ???*24* | ???*26*), + "next": null + } +)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (???*2* ? (null["memoizedState"] | ???*4*) : ???*6*) + ⚠️ nested operation +- *2* (null === ???*3*) + ⚠️ nested operation +- *3* P + ⚠️ circular variable reference +- *4* ???*5*["memoizedState"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["next"] + ⚠️ unknown object +- *7* P + ⚠️ circular variable reference +- *8* ???*9*["alternate"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* ???*15*["memoizedState"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* ???*17*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* ???*19*["baseState"] + ⚠️ unknown object +- *19* a + ⚠️ circular variable reference +- *20* ???*21*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* ???*23*["baseQueue"] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference +- *24* ???*25*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* ???*27*["queue"] + ⚠️ unknown object +- *27* a + ⚠️ circular variable reference + +0 -> 2965 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +2965 -> 2966 call = ???*0*(???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 2967 call = (...) => P() + +0 -> 2969 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2969 -> 2970 free var = FreeVar(Error) + +2969 -> 2971 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(311) + +2969 -> 2972 call = ???*0*( + `Minified React error #${311}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${311}` + ⚠️ nested operation + +0 -> 2976 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2976 -> 2977 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 2984 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2984 -> 2988 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2988 -> 2994 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2994 -> 2997 call = ???*0*(???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +2988 -> 3001 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2984 -> 3005 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +2984 -> 3008 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*, ???*10*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* max number of linking steps reached + ⚠️ This value might have side effects +- *10* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3014 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3021 call = (...) => P() + +0 -> 3023 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3023 -> 3024 free var = FreeVar(Error) + +3023 -> 3025 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(311) + +3023 -> 3026 call = ???*0*( + `Minified React error #${311}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${311}` + ⚠️ nested operation + +0 -> 3031 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3031 -> 3035 call = ???*0*(???*1*, (???*2* | ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* ???*3*["action"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["action"] + ⚠️ unknown object +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* g + ⚠️ circular variable reference + +3031 -> 3038 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*, ???*10*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* max number of linking steps reached + ⚠️ This value might have side effects +- *10* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3043 call = (...) => P() + +0 -> 3044 call = ???*0*() +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3046 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*, ???*10*()) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* max number of linking steps reached + ⚠️ This value might have side effects +- *10* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3050 member call = (...) => c(*anonymous function 67764*)["bind"]( + null, + ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) + ), + ( + | null + | ???*23* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*24* ? (null["memoizedState"] | ???*26*) : ???*28*) + | null["alternate"] + | ???*30* + | (null !== (null | ???*32* | ???*33*))["alternate"] + | (null !== (null["next"] | ???*34* | ???*36*))["alternate"] + | (???*38* ? ???*40* : null) + | null["next"] + | ???*42* + | { + "memoizedState": (null["memoizedState"] | ???*44* | ???*46*), + "baseState": (null["baseState"] | ???*48* | ???*50*), + "baseQueue": (null["baseQueue"] | ???*52* | ???*54*), + "queue": (null["queue"] | ???*56* | ???*58*), + "next": null + } + ), + ???*60* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (null === ???*25*) + ⚠️ nested operation +- *25* P + ⚠️ circular variable reference +- *26* ???*27*["memoizedState"] + ⚠️ unknown object +- *27* arguments[1] + ⚠️ function calls are not analysed yet +- *28* ???*29*["next"] + ⚠️ unknown object +- *29* P + ⚠️ circular variable reference +- *30* ???*31*["alternate"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* a + ⚠️ circular variable reference +- *34* ???*35*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* ???*37*["next"] + ⚠️ unknown object +- *37* a + ⚠️ circular variable reference +- *38* (null !== ???*39*) + ⚠️ nested operation +- *39* a + ⚠️ circular variable reference +- *40* ???*41*["memoizedState"] + ⚠️ unknown object +- *41* a + ⚠️ circular variable reference +- *42* ???*43*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* ???*45*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* ???*47*["memoizedState"] + ⚠️ unknown object +- *47* a + ⚠️ circular variable reference +- *48* ???*49*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *49* unsupported expression + ⚠️ This value might have side effects +- *50* ???*51*["baseState"] + ⚠️ unknown object +- *51* a + ⚠️ circular variable reference +- *52* ???*53*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *53* unsupported expression + ⚠️ This value might have side effects +- *54* ???*55*["baseQueue"] + ⚠️ unknown object +- *55* a + ⚠️ circular variable reference +- *56* ???*57*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* ???*59*["queue"] + ⚠️ unknown object +- *59* a + ⚠️ circular variable reference +- *60* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3051 call = (...) => ui(2048, 8, a, b)(???*0*, [???*1*]) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3055 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3055 -> 3058 member call = (...) => undefined["bind"]( + null, + ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) + ), + ( + | null + | ???*23* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*24* ? (null["memoizedState"] | ???*26*) : ???*28*) + | null["alternate"] + | ???*30* + | (null !== (null | ???*32* | ???*33*))["alternate"] + | (null !== (null["next"] | ???*34* | ???*36*))["alternate"] + | (???*38* ? ???*40* : null) + | null["next"] + | ???*42* + | { + "memoizedState": (null["memoizedState"] | ???*44* | ???*46*), + "baseState": (null["baseState"] | ???*48* | ???*50*), + "baseQueue": (null["baseQueue"] | ???*52* | ???*54*), + "queue": (null["queue"] | ???*56* | ???*58*), + "next": null + } + ), + ???*60*(), + ???*61* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (null === ???*25*) + ⚠️ nested operation +- *25* P + ⚠️ circular variable reference +- *26* ???*27*["memoizedState"] + ⚠️ unknown object +- *27* arguments[1] + ⚠️ function calls are not analysed yet +- *28* ???*29*["next"] + ⚠️ unknown object +- *29* P + ⚠️ circular variable reference +- *30* ???*31*["alternate"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* a + ⚠️ circular variable reference +- *34* ???*35*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* ???*37*["next"] + ⚠️ unknown object +- *37* a + ⚠️ circular variable reference +- *38* (null !== ???*39*) + ⚠️ nested operation +- *39* a + ⚠️ circular variable reference +- *40* ???*41*["memoizedState"] + ⚠️ unknown object +- *41* a + ⚠️ circular variable reference +- *42* ???*43*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* ???*45*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* ???*47*["memoizedState"] + ⚠️ unknown object +- *47* a + ⚠️ circular variable reference +- *48* ???*49*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *49* unsupported expression + ⚠️ This value might have side effects +- *50* ???*51*["baseState"] + ⚠️ unknown object +- *51* a + ⚠️ circular variable reference +- *52* ???*53*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *53* unsupported expression + ⚠️ This value might have side effects +- *54* ???*55*["baseQueue"] + ⚠️ unknown object +- *55* a + ⚠️ circular variable reference +- *56* ???*57*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* ???*59*["queue"] + ⚠️ unknown object +- *59* a + ⚠️ circular variable reference +- *60* arguments[1] + ⚠️ function calls are not analysed yet +- *61* arguments[1] + ⚠️ function calls are not analysed yet + +3055 -> 3059 call = (...) => a(9, ???*0*, ???*1*, null) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +3055 -> 3060 conditional = (null === (null | ???*0* | ???*1* | ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* unknown new expression + ⚠️ This value might have side effects + +3060 -> 3061 free var = FreeVar(Error) + +3060 -> 3062 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(349) + +3060 -> 3063 call = ???*0*( + `Minified React error #${349}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${349}` + ⚠️ nested operation + +3055 -> 3064 call = (...) => undefined( + ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) + ), + ???*23*, + ???*24*() +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3067 conditional = (null === (???*0* | null["updateQueue"] | ???*1* | {"lastEffect": null, "stores": null})) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +3067 -> 3071 conditional = (null === (???*0* | ???*1* | null["updateQueue"]["stores"] | null | ???*3*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stores"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unknown mutation + ⚠️ This value might have side effects + +3071 -> 3074 member call = ( + | ???*0* + | ???*1* + | null["updateQueue"]["stores"] + | (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + ))["updateQueue"]["stores"] + | (null !== (null["next"] | ???*19* | ???*21* | null | ???*24*))["updateQueue"]["stores"] + | null + | ???*25* +)["push"](???*26*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stores"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["next"] + ⚠️ unknown object +- *22* ???*23*["alternate"] + ⚠️ unknown object +- *23* N + ⚠️ circular variable reference +- *24* unknown mutation + ⚠️ This value might have side effects +- *25* unknown mutation + ⚠️ This value might have side effects +- *26* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3077 call = (...) => (undefined | !(He(a, c)) | !(0))(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3078 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3079 call = ???*0*((...) => undefined) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +3079 -> 3080 call = (...) => (undefined | !(He(a, c)) | !(0))(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +3079 -> 3081 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3084 call = ???*0*() +- *0* ???*1*["getSnapshot"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3085 call = (???*0* ? ???*4* : (...) => ???*6*)((???*9* | ???*10*), ???*12*()) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*["value"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* ???*13*["getSnapshot"] + ⚠️ unknown object +- *13* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3086 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)(???*0*, 1) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3087 call = (...) => undefined((???*0* ? ???*4* : null), ???*7*, 1, ???*8*) +- *0* (3 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["alternate"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* unsupported expression + ⚠️ This value might have side effects + +0 -> 3088 call = (...) => P() + +0 -> 3089 call = ( + | ???*0* + | ???*1*() + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": (...) => (("function" === typeof(b)) ? b(a) : b), + "lastRenderedState": ???*2* + } + | ???*3* +)() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* a + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects + +0 -> 3095 member call = (...) => (undefined | FreeVar(undefined))["bind"]( + null, + ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) + ), + ( + | ???*23* + | ???*24*() + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": (...) => (("function" === typeof(b)) ? b(a) : b), + "lastRenderedState": ???*25* + } + | ???*26* + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects +- *23* arguments[0] + ⚠️ function calls are not analysed yet +- *24* a + ⚠️ circular variable reference +- *25* a + ⚠️ circular variable reference +- *26* unsupported expression + ⚠️ This value might have side effects + +0 -> 3098 conditional = (null === (???*0* | null["updateQueue"] | ???*1* | {"lastEffect": null, "stores": null})) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +3098 -> 3103 conditional = (null === (???*0* | ???*1* | null["updateQueue"]["lastEffect"] | null | ???*3*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["lastEffect"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unknown mutation + ⚠️ This value might have side effects + +0 -> 3111 call = (...) => P() + +0 -> 3112 call = (...) => P() + +0 -> 3115 conditional = (???*0* === ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 3116 call = (...) => a(???*0*, ???*1*, ???*2*, (???*3* ? null : ???*6*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (???*4* === ???*5*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 3117 call = (...) => P() + +0 -> 3118 conditional = (???*0* === (???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? null : ???*6*) + ⚠️ nested operation +- *3* (???*4* === ???*5*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* d + ⚠️ circular variable reference +- *6* d + ⚠️ circular variable reference + +0 -> 3119 conditional = (null !== ( + | null + | ???*0* + | null["alternate"] + | ???*1* + | ???*3* + | { + "memoizedState": ???*8*, + "baseState": ???*10*, + "baseQueue": ???*12*, + "queue": ???*14*, + "next": null + } +)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* O + ⚠️ circular variable reference +- *10* ???*11*["baseState"] + ⚠️ unknown object +- *11* O + ⚠️ circular variable reference +- *12* ???*13*["baseQueue"] + ⚠️ unknown object +- *13* O + ⚠️ circular variable reference +- *14* ???*15*["queue"] + ⚠️ unknown object +- *15* O + ⚠️ circular variable reference + +3119 -> 3123 call = (...) => (!(1) | !(0))( + (???*0* | (???*1* ? null : ???*4*)), + ( + | null["memoizedState"]["deps"] + | ???*5* + | null["alternate"]["memoizedState"]["deps"] + | ???*8* + | (null !== ???*12*)["alternate"]["memoizedState"]["deps"] + | (null !== ???*13*)["alternate"]["memoizedState"]["deps"] + | (???*15* ? ???*17* : null)["memoizedState"]["deps"] + ) +) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (???*2* === ???*3*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* d + ⚠️ circular variable reference +- *4* d + ⚠️ circular variable reference +- *5* ???*6*["deps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* ???*9*["deps"] + ⚠️ unknown object +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* ???*11*["alternate"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference + +3119 -> 3124 conditional = ((null !== (???*0* | ???*1*)) | false | true) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? null : ???*5*) + ⚠️ nested operation +- *2* (???*3* === ???*4*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* d + ⚠️ circular variable reference +- *5* d + ⚠️ circular variable reference + +3124 -> 3126 call = (...) => a( + ???*0*, + ???*1*, + ( + | ???*2* + | null["memoizedState"]["destroy"] + | ???*3* + | null["alternate"]["memoizedState"]["destroy"] + | ???*6* + | (null !== ???*10*)["alternate"]["memoizedState"]["destroy"] + | (null !== ???*11*)["alternate"]["memoizedState"]["destroy"] + | (???*13* ? ???*15* : null)["memoizedState"]["destroy"] + ), + (???*17* | (???*18* ? null : ???*21*)) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["destroy"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*["destroy"] + ⚠️ unknown object +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* ???*9*["alternate"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* (null !== ???*14*) + ⚠️ nested operation +- *14* a + ⚠️ circular variable reference +- *15* ???*16*["memoizedState"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* arguments[3] + ⚠️ function calls are not analysed yet +- *18* (???*19* === ???*20*) + ⚠️ nested operation +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* d + ⚠️ circular variable reference +- *21* d + ⚠️ circular variable reference + +0 -> 3129 call = (...) => a( + ???*0*, + ???*1*, + ( + | ???*2* + | null["memoizedState"]["destroy"] + | ???*3* + | null["alternate"]["memoizedState"]["destroy"] + | ???*6* + | (null !== ???*10*)["alternate"]["memoizedState"]["destroy"] + | (null !== ???*11*)["alternate"]["memoizedState"]["destroy"] + | (???*13* ? ???*15* : null)["memoizedState"]["destroy"] + ), + (???*17* | (???*18* ? null : ???*21*)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["destroy"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*["destroy"] + ⚠️ unknown object +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* ???*9*["alternate"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* (null !== ???*14*) + ⚠️ nested operation +- *14* a + ⚠️ circular variable reference +- *15* ???*16*["memoizedState"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* arguments[3] + ⚠️ function calls are not analysed yet +- *18* (???*19* === ???*20*) + ⚠️ nested operation +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* d + ⚠️ circular variable reference +- *21* d + ⚠️ circular variable reference + +0 -> 3130 call = (...) => undefined(8390656, 8, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3131 call = (...) => (undefined | FreeVar(undefined))(2048, 8, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3132 call = (...) => (undefined | FreeVar(undefined))(4, 2, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3133 call = (...) => (undefined | FreeVar(undefined))(4, 4, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3134 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +3134 -> 3135 call = (???*0* | ???*1*())() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference + +3134 -> 3136 call = ???*0*((???*1* | ???*2*())) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference + +3134 -> 3137 call = ???*0*(null) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3138 conditional = ((null !== ???*0*) | (???*1* !== ???*2*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +3138 -> 3139 call = (???*0* | ???*1*())() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference + +0 -> 3142 conditional = ((null !== (???*0* | ???*1*)) | (???*6* !== (???*7* | ???*8*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? ???*4* : null) + ⚠️ nested operation +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference +- *4* ???*5*["concat"]([a]) + ⚠️ unknown callee object +- *5* c + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* (???*9* ? ???*11* : null) + ⚠️ nested operation +- *9* (null !== ???*10*) + ⚠️ nested operation +- *10* c + ⚠️ circular variable reference +- *11* ???*12*["concat"]([a]) + ⚠️ unknown callee object +- *12* c + ⚠️ circular variable reference + +3142 -> 3144 member call = (???*0* | (???*1* ? ???*3* : null))["concat"]([???*5*]) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (null !== ???*2*) + ⚠️ nested operation +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["concat"]([a]) + ⚠️ unknown callee object +- *4* c + ⚠️ circular variable reference +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3146 member call = (...) => (undefined | ???*0*)["bind"](null, ???*1*, ???*2*) +- *0* *anonymous function 69020* + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3147 call = (...) => (undefined | FreeVar(undefined))( + 4, + 4, + (...) => (undefined | ???*0*)["bind"](null, ???*1*, ???*2*), + (???*3* | (???*4* ? ???*6* : null)) +) +- *0* *anonymous function 69020* + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* c + ⚠️ circular variable reference +- *6* ???*7*["concat"]([a]) + ⚠️ unknown callee object +- *7* c + ⚠️ circular variable reference + +0 -> 3148 call = (...) => P() + +0 -> 3149 conditional = (???*0* === (???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? null : ???*6*) + ⚠️ nested operation +- *3* (???*4* === ???*5*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* b + ⚠️ circular variable reference + +0 -> 3152 call = (...) => (!(1) | !(0))((???*0* | (???*1* ? null : ???*4*)), ???*5*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* === ???*3*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* b + ⚠️ circular variable reference +- *4* b + ⚠️ circular variable reference +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3153 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3156 call = (...) => P() + +0 -> 3157 conditional = (???*0* === (???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? null : ???*6*) + ⚠️ nested operation +- *3* (???*4* === ???*5*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* b + ⚠️ circular variable reference + +0 -> 3160 call = (...) => (!(1) | !(0))((???*0* | (???*1* ? null : ???*4*)), ???*5*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* === ???*3*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* b + ⚠️ circular variable reference +- *4* b + ⚠️ circular variable reference +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3161 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3163 call = (???*0* | ???*1*())() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference + +0 -> 3165 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 3169 call = (???*0* ? ???*4* : (...) => ???*6*)((???*9* | 64 | ???*10*), ???*11*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* unsupported assign operation + ⚠️ This value might have side effects +- *11* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3170 call = (...) => a() + +0 -> 3173 conditional = ((0 !== (0 | 1 | ???*0* | 4 | ???*1* | ???*6*)) | ???*7*) +- *0* C + ⚠️ circular variable reference +- *1* ((???*2* | ???*4*) ? ???*5* : 4) + ⚠️ nested operation +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* c + ⚠️ circular variable reference +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 3174 call = ???*0*(true) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3177 call = ???*0*(false) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3178 call = ???*0*() +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3181 call = (...) => P() + +0 -> 3182 call = (...) => (1 | ???*0* | ???*1* | a)(???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3183 call = (...) => ((a === N) || ((null !== b) && (b === N)))(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3184 conditional = ( + | (???*0* === (null | ???*1* | ???*2*)) + | (null !== ???*19*) + | (???*21* === (null | ???*23* | ???*24*)) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + )) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["alternate"] + ⚠️ unknown object +- *20* arguments[0] + ⚠️ function calls are not analysed yet +- *21* ???*22*["alternate"] + ⚠️ unknown object +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* (null !== ( + | null + | ???*25* + | ???*26* + | ???*28* + | { + "memoizedState": ???*33*, + "baseState": ???*35*, + "baseQueue": ???*37*, + "queue": ???*39*, + "next": null + } + )) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* ???*27*["alternate"] + ⚠️ unknown object +- *27* N + ⚠️ circular variable reference +- *28* (???*29* ? ???*31* : null) + ⚠️ nested operation +- *29* (null !== ???*30*) + ⚠️ nested operation +- *30* a + ⚠️ circular variable reference +- *31* ???*32*["memoizedState"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["memoizedState"] + ⚠️ unknown object +- *34* O + ⚠️ circular variable reference +- *35* ???*36*["baseState"] + ⚠️ unknown object +- *36* O + ⚠️ circular variable reference +- *37* ???*38*["baseQueue"] + ⚠️ unknown object +- *38* O + ⚠️ circular variable reference +- *39* ???*40*["queue"] + ⚠️ unknown object +- *40* O + ⚠️ circular variable reference + +3184 -> 3185 call = (...) => undefined( + ???*0*, + ( + | ???*1* + | { + "lane": ( + | 1 + | ???*2* + | ???*3* + | ???*4* + | 0 + | ???*5* + | 4 + | ((???*6* | ???*8*) ? ???*9* : 4) + | (???*10* ? 16 : (???*11* | null | ???*18* | ???*19*)) + | ???*21* + | (???*23* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "action": ???*26*, + "hasEagerState": false, + "eagerState": null, + "next": null + } + | (???*27* ? ???*31* : null) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* C + ⚠️ circular variable reference +- *6* (0 !== ???*7*) + ⚠️ nested operation +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* C + ⚠️ circular variable reference +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 1) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? ???*15* : 4) + ⚠️ nested operation +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* (???*16* ? 16 : 536870912) + ⚠️ nested operation +- *16* (0 !== ???*17*) + ⚠️ nested operation +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* arguments[0] + ⚠️ function calls are not analysed yet +- *19* ???*20*["value"] + ⚠️ unknown object +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *23* (???*24* === ???*25*) + ⚠️ nested operation +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* a + ⚠️ circular variable reference +- *26* c + ⚠️ circular variable reference +- *27* (3 === ???*28*) + ⚠️ nested operation +- *28* ???*29*["tag"] + ⚠️ unknown object +- *29* ???*30*["alternate"] + ⚠️ unknown object +- *30* arguments[0] + ⚠️ function calls are not analysed yet +- *31* ???*32*["stateNode"] + ⚠️ unknown object +- *32* ???*33*["alternate"] + ⚠️ unknown object +- *33* arguments[0] + ⚠️ function calls are not analysed yet + +3184 -> 3186 call = (...) => Zg(a, d)( + ???*0*, + ???*1*, + ( + | ???*2* + | { + "lane": ( + | 1 + | ???*3* + | ???*4* + | ???*5* + | 0 + | ???*6* + | 4 + | ((???*7* | ???*9*) ? ???*10* : 4) + | (???*11* ? 16 : (???*12* | null | ???*19* | ???*20*)) + | ???*22* + | (???*24* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "action": ???*27*, + "hasEagerState": false, + "eagerState": null, + "next": null + } + | (???*28* ? ???*32* : null) + ), + ( + | 1 + | ???*35* + | ???*36* + | ???*37* + | 0 + | ???*38* + | 4 + | ((???*39* | ???*41*) ? ???*42* : 4) + | (???*43* ? 16 : (???*44* | null | ???*51* | ???*52*)) + | ???*54* + | (???*56* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* C + ⚠️ circular variable reference +- *7* (0 !== ???*8*) + ⚠️ nested operation +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* C + ⚠️ circular variable reference +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 1) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? ???*16* : 4) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* (???*17* ? 16 : 536870912) + ⚠️ nested operation +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* arguments[0] + ⚠️ function calls are not analysed yet +- *20* ???*21*["value"] + ⚠️ unknown object +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* ???*23*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *23* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *24* (???*25* === ???*26*) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* a + ⚠️ circular variable reference +- *27* c + ⚠️ circular variable reference +- *28* (3 === ???*29*) + ⚠️ nested operation +- *29* ???*30*["tag"] + ⚠️ unknown object +- *30* ???*31*["alternate"] + ⚠️ unknown object +- *31* arguments[0] + ⚠️ function calls are not analysed yet +- *32* ???*33*["stateNode"] + ⚠️ unknown object +- *33* ???*34*["alternate"] + ⚠️ unknown object +- *34* arguments[0] + ⚠️ function calls are not analysed yet +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *37* arguments[0] + ⚠️ function calls are not analysed yet +- *38* C + ⚠️ circular variable reference +- *39* (0 !== ???*40*) + ⚠️ nested operation +- *40* C + ⚠️ circular variable reference +- *41* unsupported expression + ⚠️ This value might have side effects +- *42* C + ⚠️ circular variable reference +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* (???*45* ? ???*46* : 1) + ⚠️ nested operation +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* (???*47* ? ???*48* : 4) + ⚠️ nested operation +- *47* unsupported expression + ⚠️ This value might have side effects +- *48* (???*49* ? 16 : 536870912) + ⚠️ nested operation +- *49* (0 !== ???*50*) + ⚠️ nested operation +- *50* unsupported expression + ⚠️ This value might have side effects +- *51* arguments[0] + ⚠️ function calls are not analysed yet +- *52* ???*53*["value"] + ⚠️ unknown object +- *53* arguments[1] + ⚠️ function calls are not analysed yet +- *54* ???*55*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *55* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *56* (???*57* === ???*58*) + ⚠️ nested operation +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* a + ⚠️ circular variable reference + +3184 -> 3187 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +3184 -> 3188 call = (...) => undefined( + ( + | ???*0* + | { + "lane": ( + | 1 + | ???*1* + | ???*2* + | ???*3* + | 0 + | ???*4* + | 4 + | ((???*5* | ???*7*) ? ???*8* : 4) + | (???*9* ? 16 : (???*10* | null | ???*17* | ???*18*)) + | ???*20* + | (???*22* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "action": ???*25*, + "hasEagerState": false, + "eagerState": null, + "next": null + } + | (???*26* ? ???*30* : null) + ), + ???*33*, + ( + | 1 + | ???*34* + | ???*35* + | ???*36* + | 0 + | ???*37* + | 4 + | ((???*38* | ???*40*) ? ???*41* : 4) + | (???*42* ? 16 : (???*43* | null | ???*50* | ???*51*)) + | ???*53* + | (???*55* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + (???*58* ? ???*60* : ???*61*) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* C + ⚠️ circular variable reference +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* C + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? ???*12* : 1) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 4) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? 16 : 536870912) + ⚠️ nested operation +- *15* (0 !== ???*16*) + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["value"] + ⚠️ unknown object +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *22* (???*23* === ???*24*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* a + ⚠️ circular variable reference +- *25* c + ⚠️ circular variable reference +- *26* (3 === ???*27*) + ⚠️ nested operation +- *27* ???*28*["tag"] + ⚠️ unknown object +- *28* ???*29*["alternate"] + ⚠️ unknown object +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["stateNode"] + ⚠️ unknown object +- *31* ???*32*["alternate"] + ⚠️ unknown object +- *32* arguments[0] + ⚠️ function calls are not analysed yet +- *33* arguments[0] + ⚠️ function calls are not analysed yet +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *36* arguments[0] + ⚠️ function calls are not analysed yet +- *37* C + ⚠️ circular variable reference +- *38* (0 !== ???*39*) + ⚠️ nested operation +- *39* C + ⚠️ circular variable reference +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* C + ⚠️ circular variable reference +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* (???*44* ? ???*45* : 1) + ⚠️ nested operation +- *44* unsupported expression + ⚠️ This value might have side effects +- *45* (???*46* ? ???*47* : 4) + ⚠️ nested operation +- *46* unsupported expression + ⚠️ This value might have side effects +- *47* (???*48* ? 16 : 536870912) + ⚠️ nested operation +- *48* (0 !== ???*49*) + ⚠️ nested operation +- *49* unsupported expression + ⚠️ This value might have side effects +- *50* arguments[0] + ⚠️ function calls are not analysed yet +- *51* ???*52*["value"] + ⚠️ unknown object +- *52* arguments[1] + ⚠️ function calls are not analysed yet +- *53* ???*54*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *54* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *55* (???*56* === ???*57*) + ⚠️ nested operation +- *56* unsupported expression + ⚠️ This value might have side effects +- *57* a + ⚠️ circular variable reference +- *58* (0 !== ???*59*) + ⚠️ nested operation +- *59* unsupported expression + ⚠️ This value might have side effects +- *60* module["unstable_now"]() + ⚠️ nested operation +- *61* (???*62* ? (???*66* | ???*67*) : ???*68*) + ⚠️ nested operation +- *62* (???*63* !== (???*64* | ???*65*)) + ⚠️ nested operation +- *63* unsupported expression + ⚠️ This value might have side effects +- *64* unsupported expression + ⚠️ This value might have side effects +- *65* module["unstable_now"]() + ⚠️ nested operation +- *66* unsupported expression + ⚠️ This value might have side effects +- *67* module["unstable_now"]() + ⚠️ nested operation +- *68* unsupported expression + ⚠️ This value might have side effects + +3184 -> 3189 call = (...) => undefined( + ( + | ???*0* + | { + "lane": ( + | 1 + | ???*1* + | ???*2* + | ???*3* + | 0 + | ???*4* + | 4 + | ((???*5* | ???*7*) ? ???*8* : 4) + | (???*9* ? 16 : (???*10* | null | ???*17* | ???*18*)) + | ???*20* + | (???*22* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "action": ???*25*, + "hasEagerState": false, + "eagerState": null, + "next": null + } + | (???*26* ? ???*30* : null) + ), + ???*33*, + ( + | 1 + | ???*34* + | ???*35* + | ???*36* + | 0 + | ???*37* + | 4 + | ((???*38* | ???*40*) ? ???*41* : 4) + | (???*42* ? 16 : (???*43* | null | ???*50* | ???*51*)) + | ???*53* + | (???*55* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* C + ⚠️ circular variable reference +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* C + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? ???*12* : 1) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 4) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? 16 : 536870912) + ⚠️ nested operation +- *15* (0 !== ???*16*) + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["value"] + ⚠️ unknown object +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *22* (???*23* === ???*24*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* a + ⚠️ circular variable reference +- *25* c + ⚠️ circular variable reference +- *26* (3 === ???*27*) + ⚠️ nested operation +- *27* ???*28*["tag"] + ⚠️ unknown object +- *28* ???*29*["alternate"] + ⚠️ unknown object +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["stateNode"] + ⚠️ unknown object +- *31* ???*32*["alternate"] + ⚠️ unknown object +- *32* arguments[0] + ⚠️ function calls are not analysed yet +- *33* arguments[1] + ⚠️ function calls are not analysed yet +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *36* arguments[0] + ⚠️ function calls are not analysed yet +- *37* C + ⚠️ circular variable reference +- *38* (0 !== ???*39*) + ⚠️ nested operation +- *39* C + ⚠️ circular variable reference +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* C + ⚠️ circular variable reference +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* (???*44* ? ???*45* : 1) + ⚠️ nested operation +- *44* unsupported expression + ⚠️ This value might have side effects +- *45* (???*46* ? ???*47* : 4) + ⚠️ nested operation +- *46* unsupported expression + ⚠️ This value might have side effects +- *47* (???*48* ? 16 : 536870912) + ⚠️ nested operation +- *48* (0 !== ???*49*) + ⚠️ nested operation +- *49* unsupported expression + ⚠️ This value might have side effects +- *50* arguments[0] + ⚠️ function calls are not analysed yet +- *51* ???*52*["value"] + ⚠️ unknown object +- *52* arguments[1] + ⚠️ function calls are not analysed yet +- *53* ???*54*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *54* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *55* (???*56* === ???*57*) + ⚠️ nested operation +- *56* unsupported expression + ⚠️ This value might have side effects +- *57* a + ⚠️ circular variable reference + +0 -> 3190 call = (...) => (1 | ???*0* | ???*1* | a)(???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3191 call = (...) => ((a === N) || ((null !== b) && (b === N)))(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3192 conditional = ( + | (???*0* === (null | ???*1* | ???*2*)) + | (null !== ???*19*) + | (???*21* === (null | ???*23* | ???*24*)) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + )) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["alternate"] + ⚠️ unknown object +- *20* arguments[0] + ⚠️ function calls are not analysed yet +- *21* ???*22*["alternate"] + ⚠️ unknown object +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* (null !== ( + | null + | ???*25* + | ???*26* + | ???*28* + | { + "memoizedState": ???*33*, + "baseState": ???*35*, + "baseQueue": ???*37*, + "queue": ???*39*, + "next": null + } + )) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* ???*27*["alternate"] + ⚠️ unknown object +- *27* N + ⚠️ circular variable reference +- *28* (???*29* ? ???*31* : null) + ⚠️ nested operation +- *29* (null !== ???*30*) + ⚠️ nested operation +- *30* a + ⚠️ circular variable reference +- *31* ???*32*["memoizedState"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["memoizedState"] + ⚠️ unknown object +- *34* O + ⚠️ circular variable reference +- *35* ???*36*["baseState"] + ⚠️ unknown object +- *36* O + ⚠️ circular variable reference +- *37* ???*38*["baseQueue"] + ⚠️ unknown object +- *38* O + ⚠️ circular variable reference +- *39* ???*40*["queue"] + ⚠️ unknown object +- *40* O + ⚠️ circular variable reference + +3192 -> 3193 call = (...) => undefined( + ???*0*, + ( + | { + "lane": ( + | 1 + | ???*1* + | ???*2* + | ???*3* + | 0 + | ???*4* + | 4 + | ((???*5* | ???*7*) ? ???*8* : 4) + | (???*9* ? 16 : (???*10* | null | ???*17* | ???*18*)) + | ???*20* + | (???*22* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "action": (???*25* | (???*26* ? ???*30* : null)), + "hasEagerState": false, + "eagerState": null, + "next": null + } + | (???*33* ? ???*35* : ???*36*) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* C + ⚠️ circular variable reference +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* C + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? ???*12* : 1) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 4) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? 16 : 536870912) + ⚠️ nested operation +- *15* (0 !== ???*16*) + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["value"] + ⚠️ unknown object +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *22* (???*23* === ???*24*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* a + ⚠️ circular variable reference +- *25* arguments[2] + ⚠️ function calls are not analysed yet +- *26* (3 === ???*27*) + ⚠️ nested operation +- *27* ???*28*["tag"] + ⚠️ unknown object +- *28* ???*29*["alternate"] + ⚠️ unknown object +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["stateNode"] + ⚠️ unknown object +- *31* ???*32*["alternate"] + ⚠️ unknown object +- *32* arguments[0] + ⚠️ function calls are not analysed yet +- *33* (0 !== ???*34*) + ⚠️ nested operation +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* module["unstable_now"]() + ⚠️ nested operation +- *36* (???*37* ? (???*41* | ???*42*) : ???*43*) + ⚠️ nested operation +- *37* (???*38* !== (???*39* | ???*40*)) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* unsupported expression + ⚠️ This value might have side effects +- *40* module["unstable_now"]() + ⚠️ nested operation +- *41* unsupported expression + ⚠️ This value might have side effects +- *42* module["unstable_now"]() + ⚠️ nested operation +- *43* unsupported expression + ⚠️ This value might have side effects + +3192 -> 3198 conditional = ((0 === ???*0*) | (null === ???*2*) | ???*4*) +- *0* ???*1*["lanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* (null !== f) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +3198 -> 3200 call = ???*0*(???*2*, (???*4* | (???*5* ? ???*9* : null))) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["lastRenderedState"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* (3 === ???*6*) + ⚠️ nested operation +- *6* ???*7*["tag"] + ⚠️ unknown object +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["stateNode"] + ⚠️ unknown object +- *10* ???*11*["alternate"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet + +3198 -> 3203 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*, ???*12*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*(g, c) + ⚠️ unknown callee +- *10* ???*11*["alternate"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* ???*13*["lastRenderedState"] + ⚠️ unknown object +- *13* arguments[1] + ⚠️ function calls are not analysed yet + +3198 -> 3204 conditional = ???*0* +- *0* ???*1*(???*10*, ???*13*) + ⚠️ unknown callee +- *1* (???*2* ? ???*5* : (...) => ???*7*) + ⚠️ nested operation +- *2* ("function" === ???*3*) + ⚠️ nested operation +- *3* typeof(???*4*) + ⚠️ nested operation +- *4* ???["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* (((a === b) && ((0 !== a) || (???*8* === ???*9*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* ???*11*(g, c) + ⚠️ unknown callee +- *11* ???*12*["alternate"] + ⚠️ unknown object +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* ???*14*["lastRenderedState"] + ⚠️ unknown object +- *14* arguments[1] + ⚠️ function calls are not analysed yet + +3204 -> 3206 conditional = (null === ???*0*) +- *0* ???*1*["interleaved"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +3206 -> 3208 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +3192 -> 3213 call = (...) => Zg(a, d)( + ???*0*, + ???*1*, + ( + | { + "lane": ( + | 1 + | ???*2* + | ???*3* + | ???*4* + | 0 + | ???*5* + | 4 + | ((???*6* | ???*8*) ? ???*9* : 4) + | (???*10* ? 16 : (???*11* | null | ???*18* | ???*19*)) + | ???*21* + | (???*23* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "action": (???*26* | (???*27* ? ???*31* : null)), + "hasEagerState": false, + "eagerState": null, + "next": null + } + | (???*34* ? ???*36* : ???*37*) + ), + ( + | 1 + | ???*45* + | ???*46* + | ???*47* + | 0 + | ???*48* + | 4 + | ((???*49* | ???*51*) ? ???*52* : 4) + | (???*53* ? 16 : (???*54* | null | ???*61* | ???*62*)) + | ???*64* + | (???*66* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* C + ⚠️ circular variable reference +- *6* (0 !== ???*7*) + ⚠️ nested operation +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* C + ⚠️ circular variable reference +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 1) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? ???*15* : 4) + ⚠️ nested operation +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* (???*16* ? 16 : 536870912) + ⚠️ nested operation +- *16* (0 !== ???*17*) + ⚠️ nested operation +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* arguments[0] + ⚠️ function calls are not analysed yet +- *19* ???*20*["value"] + ⚠️ unknown object +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *23* (???*24* === ???*25*) + ⚠️ nested operation +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* a + ⚠️ circular variable reference +- *26* arguments[2] + ⚠️ function calls are not analysed yet +- *27* (3 === ???*28*) + ⚠️ nested operation +- *28* ???*29*["tag"] + ⚠️ unknown object +- *29* ???*30*["alternate"] + ⚠️ unknown object +- *30* arguments[0] + ⚠️ function calls are not analysed yet +- *31* ???*32*["stateNode"] + ⚠️ unknown object +- *32* ???*33*["alternate"] + ⚠️ unknown object +- *33* arguments[0] + ⚠️ function calls are not analysed yet +- *34* (0 !== ???*35*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* module["unstable_now"]() + ⚠️ nested operation +- *37* (???*38* ? (???*42* | ???*43*) : ???*44*) + ⚠️ nested operation +- *38* (???*39* !== (???*40* | ???*41*)) + ⚠️ nested operation +- *39* unsupported expression + ⚠️ This value might have side effects +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* module["unstable_now"]() + ⚠️ nested operation +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* module["unstable_now"]() + ⚠️ nested operation +- *44* unsupported expression + ⚠️ This value might have side effects +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *47* arguments[0] + ⚠️ function calls are not analysed yet +- *48* C + ⚠️ circular variable reference +- *49* (0 !== ???*50*) + ⚠️ nested operation +- *50* C + ⚠️ circular variable reference +- *51* unsupported expression + ⚠️ This value might have side effects +- *52* C + ⚠️ circular variable reference +- *53* unsupported expression + ⚠️ This value might have side effects +- *54* (???*55* ? ???*56* : 1) + ⚠️ nested operation +- *55* unsupported expression + ⚠️ This value might have side effects +- *56* (???*57* ? ???*58* : 4) + ⚠️ nested operation +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* (???*59* ? 16 : 536870912) + ⚠️ nested operation +- *59* (0 !== ???*60*) + ⚠️ nested operation +- *60* unsupported expression + ⚠️ This value might have side effects +- *61* arguments[0] + ⚠️ function calls are not analysed yet +- *62* ???*63*["value"] + ⚠️ unknown object +- *63* arguments[1] + ⚠️ function calls are not analysed yet +- *64* ???*65*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *65* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *66* (???*67* === ???*68*) + ⚠️ nested operation +- *67* unsupported expression + ⚠️ This value might have side effects +- *68* a + ⚠️ circular variable reference + +3192 -> 3214 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +3192 -> 3215 call = (...) => undefined( + (???*0* | (???*1* ? ???*5* : null)), + ???*8*, + ( + | 1 + | ???*9* + | ???*10* + | ???*11* + | 0 + | ???*12* + | 4 + | ((???*13* | ???*15*) ? ???*16* : 4) + | (???*17* ? 16 : (???*18* | null | ???*25* | ???*26*)) + | ???*28* + | (???*30* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + ( + | { + "lane": ( + | 1 + | ???*33* + | ???*34* + | ???*35* + | 0 + | ???*36* + | 4 + | ((???*37* | ???*39*) ? ???*40* : 4) + | (???*41* ? 16 : (???*42* | null | ???*49* | ???*50*)) + | ???*52* + | (???*54* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "action": (???*57* | (???*58* ? ???*62* : null)), + "hasEagerState": false, + "eagerState": null, + "next": null + } + | (???*65* ? ???*67* : ???*68*) + ) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* C + ⚠️ circular variable reference +- *13* (0 !== ???*14*) + ⚠️ nested operation +- *14* C + ⚠️ circular variable reference +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* C + ⚠️ circular variable reference +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* (???*19* ? ???*20* : 1) + ⚠️ nested operation +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* (???*21* ? ???*22* : 4) + ⚠️ nested operation +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? 16 : 536870912) + ⚠️ nested operation +- *23* (0 !== ???*24*) + ⚠️ nested operation +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* arguments[0] + ⚠️ function calls are not analysed yet +- *26* ???*27*["value"] + ⚠️ unknown object +- *27* arguments[1] + ⚠️ function calls are not analysed yet +- *28* ???*29*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *30* (???*31* === ???*32*) + ⚠️ nested operation +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* a + ⚠️ circular variable reference +- *33* unsupported expression + ⚠️ This value might have side effects +- *34* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *35* arguments[0] + ⚠️ function calls are not analysed yet +- *36* C + ⚠️ circular variable reference +- *37* (0 !== ???*38*) + ⚠️ nested operation +- *38* C + ⚠️ circular variable reference +- *39* unsupported expression + ⚠️ This value might have side effects +- *40* C + ⚠️ circular variable reference +- *41* unsupported expression + ⚠️ This value might have side effects +- *42* (???*43* ? ???*44* : 1) + ⚠️ nested operation +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* (???*45* ? ???*46* : 4) + ⚠️ nested operation +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* (???*47* ? 16 : 536870912) + ⚠️ nested operation +- *47* (0 !== ???*48*) + ⚠️ nested operation +- *48* unsupported expression + ⚠️ This value might have side effects +- *49* arguments[0] + ⚠️ function calls are not analysed yet +- *50* ???*51*["value"] + ⚠️ unknown object +- *51* arguments[1] + ⚠️ function calls are not analysed yet +- *52* ???*53*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *53* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *54* (???*55* === ???*56*) + ⚠️ nested operation +- *55* unsupported expression + ⚠️ This value might have side effects +- *56* a + ⚠️ circular variable reference +- *57* arguments[2] + ⚠️ function calls are not analysed yet +- *58* (3 === ???*59*) + ⚠️ nested operation +- *59* ???*60*["tag"] + ⚠️ unknown object +- *60* ???*61*["alternate"] + ⚠️ unknown object +- *61* arguments[0] + ⚠️ function calls are not analysed yet +- *62* ???*63*["stateNode"] + ⚠️ unknown object +- *63* ???*64*["alternate"] + ⚠️ unknown object +- *64* arguments[0] + ⚠️ function calls are not analysed yet +- *65* (0 !== ???*66*) + ⚠️ nested operation +- *66* unsupported expression + ⚠️ This value might have side effects +- *67* module["unstable_now"]() + ⚠️ nested operation +- *68* (???*69* ? (???*73* | ???*74*) : ???*75*) + ⚠️ nested operation +- *69* (???*70* !== (???*71* | ???*72*)) + ⚠️ nested operation +- *70* unsupported expression + ⚠️ This value might have side effects +- *71* unsupported expression + ⚠️ This value might have side effects +- *72* module["unstable_now"]() + ⚠️ nested operation +- *73* unsupported expression + ⚠️ This value might have side effects +- *74* module["unstable_now"]() + ⚠️ nested operation +- *75* unsupported expression + ⚠️ This value might have side effects + +3192 -> 3216 call = (...) => undefined( + (???*0* | (???*1* ? ???*5* : null)), + ???*8*, + ( + | 1 + | ???*9* + | ???*10* + | ???*11* + | 0 + | ???*12* + | 4 + | ((???*13* | ???*15*) ? ???*16* : 4) + | (???*17* ? 16 : (???*18* | null | ???*25* | ???*26*)) + | ???*28* + | (???*30* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* C + ⚠️ circular variable reference +- *13* (0 !== ???*14*) + ⚠️ nested operation +- *14* C + ⚠️ circular variable reference +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* C + ⚠️ circular variable reference +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* (???*19* ? ???*20* : 1) + ⚠️ nested operation +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* (???*21* ? ???*22* : 4) + ⚠️ nested operation +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? 16 : 536870912) + ⚠️ nested operation +- *23* (0 !== ???*24*) + ⚠️ nested operation +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* arguments[0] + ⚠️ function calls are not analysed yet +- *26* ???*27*["value"] + ⚠️ unknown object +- *27* arguments[1] + ⚠️ function calls are not analysed yet +- *28* ???*29*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *30* (???*31* === ???*32*) + ⚠️ nested operation +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* a + ⚠️ circular variable reference + +0 -> 3219 conditional = (null === ???*0*) +- *0* ???*1*["pending"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3225 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3225 -> 3229 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 3231 call = (...) => P() + +0 -> 3232 conditional = (???*0* === ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3233 conditional = ((null !== (???*0* | ???*1*)) | (???*6* !== (???*7* | ???*8*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? ???*4* : null) + ⚠️ nested operation +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference +- *4* ???*5*["concat"]([a]) + ⚠️ unknown callee object +- *5* c + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* (???*9* ? ???*11* : null) + ⚠️ nested operation +- *9* (null !== ???*10*) + ⚠️ nested operation +- *10* c + ⚠️ circular variable reference +- *11* ???*12*["concat"]([a]) + ⚠️ unknown callee object +- *12* c + ⚠️ circular variable reference + +3233 -> 3235 member call = (???*0* | (???*1* ? ???*3* : null))["concat"]([???*5*]) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (null !== ???*2*) + ⚠️ nested operation +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["concat"]([a]) + ⚠️ unknown callee object +- *4* c + ⚠️ circular variable reference +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3237 member call = (...) => (undefined | ???*0*)["bind"](null, ???*1*, ???*2*) +- *0* *anonymous function 69020* + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3238 call = (...) => undefined( + 4194308, + 4, + (...) => (undefined | ???*0*)["bind"](null, ???*1*, ???*2*), + (???*3* | (???*4* ? ???*6* : null)) +) +- *0* *anonymous function 69020* + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* c + ⚠️ circular variable reference +- *6* ???*7*["concat"]([a]) + ⚠️ unknown callee object +- *7* c + ⚠️ circular variable reference + +0 -> 3239 call = (...) => undefined(4194308, 4, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3240 call = (...) => undefined(4, 2, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3241 call = (...) => P() + +0 -> 3242 conditional = (???*0* === (???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? null : ???*6*) + ⚠️ nested operation +- *3* (???*4* === ???*5*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* b + ⚠️ circular variable reference +- *6* b + ⚠️ circular variable reference + +0 -> 3243 call = (???*0* | ???*1*())() +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference + +0 -> 3245 call = (...) => P() + +0 -> 3246 conditional = (???*0* !== ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +3246 -> 3247 call = ???*0*((???*1* | (???*2* ? ???*5* : ???*7*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* !== ???*4*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*(b) + ⚠️ unknown callee +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* b + ⚠️ circular variable reference + +0 -> 3253 member call = (...) => undefined["bind"]( + null, + ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) + ), + ( + | ???*23* + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": ???*24*, + "lastRenderedState": (???*25* | (???*26* ? ???*29* : ???*31*)) + } + | ???*32* + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects +- *23* arguments[0] + ⚠️ function calls are not analysed yet +- *24* a + ⚠️ circular variable reference +- *25* arguments[1] + ⚠️ function calls are not analysed yet +- *26* (???*27* !== ???*28*) + ⚠️ nested operation +- *27* unsupported expression + ⚠️ This value might have side effects +- *28* arguments[2] + ⚠️ function calls are not analysed yet +- *29* ???*30*(b) + ⚠️ unknown callee +- *30* arguments[2] + ⚠️ function calls are not analysed yet +- *31* b + ⚠️ circular variable reference +- *32* unsupported expression + ⚠️ This value might have side effects + +0 -> 3255 call = (...) => P() + +0 -> 3258 call = (...) => P() + +0 -> 3259 call = (...) => [b["memoizedState"], a](false) + +0 -> 3263 member call = (...) => undefined["bind"](null, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3265 call = (...) => P() + +0 -> 3266 call = (...) => P() + +0 -> 3267 conditional = (false | true) + +3267 -> 3268 conditional = (???*0* === (???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*() + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference + +3268 -> 3269 free var = FreeVar(Error) + +3268 -> 3270 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(407) + +3268 -> 3271 call = ???*0*( + `Minified React error #${407}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${407}` + ⚠️ nested operation + +3267 -> 3272 call = (???*0* | ???*1*() | ???*2*())() +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* c + ⚠️ circular variable reference +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +3267 -> 3273 call = ???*0*() +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +3267 -> 3274 conditional = (null === (null | ???*0* | ???*1* | ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* unknown new expression + ⚠️ This value might have side effects + +3274 -> 3275 free var = FreeVar(Error) + +3274 -> 3276 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(349) + +3274 -> 3277 call = ???*0*( + `Minified React error #${349}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${349}` + ⚠️ nested operation + +3267 -> 3278 call = (...) => undefined( + ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) + ), + ???*23*, + (???*24* | ???*25*() | ???*26*()) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* arguments[2] + ⚠️ function calls are not analysed yet +- *25* c + ⚠️ circular variable reference +- *26* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3282 member call = (...) => c(*anonymous function 67764*)["bind"]( + null, + ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) + ), + {"value": (???*23* | ???*24*() | ???*25*()), "getSnapshot": ???*26*}, + ???*27* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects +- *23* arguments[2] + ⚠️ function calls are not analysed yet +- *24* c + ⚠️ circular variable reference +- *25* arguments[1] + ⚠️ function calls are not analysed yet +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3283 call = (...) => ti(8390656, 8, a, b)( + (...) => ???*0*["bind"]( + null, + (null | ???*1* | ???*2*), + {"value": (???*19* | ???*20*), "getSnapshot": ???*22*}, + ???*23* + ), + [???*24*] +) +- *0* c(*anonymous function 67764*) + ⚠️ nested operation +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + )) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* arguments[2] + ⚠️ function calls are not analysed yet +- *20* ???*21*() + ⚠️ nested operation +- *21* c + ⚠️ circular variable reference +- *22* arguments[1] + ⚠️ function calls are not analysed yet +- *23* arguments[0] + ⚠️ function calls are not analysed yet +- *24* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3286 member call = (...) => undefined["bind"]( + null, + ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) + ), + {"value": (???*23* | ???*24*() | ???*25*()), "getSnapshot": ???*26*}, + (???*27* | ???*28*() | ???*29*()), + ???*30* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects +- *23* arguments[2] + ⚠️ function calls are not analysed yet +- *24* c + ⚠️ circular variable reference +- *25* arguments[1] + ⚠️ function calls are not analysed yet +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* arguments[2] + ⚠️ function calls are not analysed yet +- *28* c + ⚠️ circular variable reference +- *29* arguments[1] + ⚠️ function calls are not analysed yet +- *30* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3287 call = (...) => a( + 9, + (...) => undefined["bind"]( + null, + (null | ???*0* | ???*1*), + {"value": (???*18* | ???*19*), "getSnapshot": ???*21*}, + (???*22* | ???*23*), + ???*25* + ), + ???*26*, + null +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (null !== ( + | null + | ???*2* + | ???*3* + | ???*5* + | { + "memoizedState": ???*10*, + "baseState": ???*12*, + "baseQueue": ???*14*, + "queue": ???*16*, + "next": null + } + )) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* N + ⚠️ circular variable reference +- *5* (???*6* ? ???*8* : null) + ⚠️ nested operation +- *6* (null !== ???*7*) + ⚠️ nested operation +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["memoizedState"] + ⚠️ unknown object +- *11* O + ⚠️ circular variable reference +- *12* ???*13*["baseState"] + ⚠️ unknown object +- *13* O + ⚠️ circular variable reference +- *14* ???*15*["baseQueue"] + ⚠️ unknown object +- *15* O + ⚠️ circular variable reference +- *16* ???*17*["queue"] + ⚠️ unknown object +- *17* O + ⚠️ circular variable reference +- *18* arguments[2] + ⚠️ function calls are not analysed yet +- *19* ???*20*() + ⚠️ nested operation +- *20* c + ⚠️ circular variable reference +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* arguments[2] + ⚠️ function calls are not analysed yet +- *23* ???*24*() + ⚠️ nested operation +- *24* c + ⚠️ circular variable reference +- *25* arguments[1] + ⚠️ function calls are not analysed yet +- *26* unsupported expression + ⚠️ This value might have side effects + +0 -> 3288 call = (...) => P() + +0 -> 3290 conditional = (false | true) + +3290 -> 3292 call = (???*0* ? ???*2* : (...) => ???*4*)(???*6*) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects + +3290 -> 3293 member call = ???*0*["toString"](32) +- *0* unsupported expression + ⚠️ This value might have side effects + +3290 -> 3295 member call = ???*0*["toString"](32) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3290 -> 3297 member call = ???*0*["toString"](32) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3299 call = (...) => [b["memoizedState"], c["dispatch"]]((...) => (("function" === typeof(b)) ? b(a) : b)) + +0 -> 3300 call = (...) => P() + +0 -> 3302 call = (...) => (???*0* | b)( + ( + | null + | ???*2* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*3* ? (null["memoizedState"] | ???*5*) : ???*7*) + | null["alternate"] + | ???*9* + | (null !== (null | ???*11* | ???*12*))["alternate"] + | (null !== (null["next"] | ???*13* | ???*15*))["alternate"] + | (???*17* ? ???*19* : null) + | null["next"] + | ???*21* + | { + "memoizedState": (null["memoizedState"] | ???*23* | ???*25*), + "baseState": (null["baseState"] | ???*27* | ???*29*), + "baseQueue": (null["baseQueue"] | ???*31* | ???*33*), + "queue": (null["queue"] | ???*35* | ???*37*), + "next": null + } + ), + ( + | null["memoizedState"] + | ???*39* + | null["alternate"]["memoizedState"] + | ???*41* + | (null !== ???*44*)["alternate"]["memoizedState"] + | (null !== ???*45*)["alternate"]["memoizedState"] + | (???*47* ? ???*49* : null)["memoizedState"] + | ???*51* + ), + ???*52* +) +- *0* ???*1* + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (null === ???*4*) + ⚠️ nested operation +- *4* P + ⚠️ circular variable reference +- *5* ???*6*["memoizedState"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["next"] + ⚠️ unknown object +- *8* P + ⚠️ circular variable reference +- *9* ???*10*["alternate"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* a + ⚠️ circular variable reference +- *13* ???*14*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* ???*16*["next"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* (null !== ???*18*) + ⚠️ nested operation +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["memoizedState"] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* ???*22*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* ???*26*["memoizedState"] + ⚠️ unknown object +- *26* a + ⚠️ circular variable reference +- *27* ???*28*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* ???*30*["baseState"] + ⚠️ unknown object +- *30* a + ⚠️ circular variable reference +- *31* ???*32*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* ???*34*["baseQueue"] + ⚠️ unknown object +- *34* a + ⚠️ circular variable reference +- *35* ???*36*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *36* unsupported expression + ⚠️ This value might have side effects +- *37* ???*38*["queue"] + ⚠️ unknown object +- *38* a + ⚠️ circular variable reference +- *39* ???*40*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* ???*42*["memoizedState"] + ⚠️ unknown object +- *42* ???*43*["alternate"] + ⚠️ unknown object +- *43* arguments[1] + ⚠️ function calls are not analysed yet +- *44* O + ⚠️ circular variable reference +- *45* ???*46*["next"] + ⚠️ unknown object +- *46* O + ⚠️ circular variable reference +- *47* (null !== ???*48*) + ⚠️ nested operation +- *48* a + ⚠️ circular variable reference +- *49* ???*50*["memoizedState"] + ⚠️ unknown object +- *50* a + ⚠️ circular variable reference +- *51* unknown mutation + ⚠️ This value might have side effects +- *52* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3304 call = (...) => [b["memoizedState"], c["dispatch"]]((...) => (("function" === typeof(b)) ? b(a) : b)) + +0 -> 3306 call = (...) => P() + +0 -> 3307 call = (...) => [f, d]((...) => (("function" === typeof(b)) ? b(a) : b)) + +0 -> 3308 call = (...) => P() + +0 -> 3309 conditional = (null === ( + | null + | ???*0* + | null["alternate"] + | ???*1* + | ???*3* + | { + "memoizedState": ???*8*, + "baseState": ???*10*, + "baseQueue": ???*12*, + "queue": ???*14*, + "next": null + } +)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* O + ⚠️ circular variable reference +- *10* ???*11*["baseState"] + ⚠️ unknown object +- *11* O + ⚠️ circular variable reference +- *12* ???*13*["baseQueue"] + ⚠️ unknown object +- *13* O + ⚠️ circular variable reference +- *14* ???*15*["queue"] + ⚠️ unknown object +- *15* O + ⚠️ circular variable reference + +3309 -> 3312 call = (...) => (???*0* | b)( + ( + | null + | ???*2* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*3* ? (null["memoizedState"] | ???*5*) : ???*7*) + | null["alternate"] + | ???*9* + | (null !== (null | ???*11* | ???*12*))["alternate"] + | (null !== (null["next"] | ???*13* | ???*15*))["alternate"] + | (???*17* ? ???*19* : null) + | null["next"] + | ???*21* + | { + "memoizedState": (null["memoizedState"] | ???*23* | ???*25*), + "baseState": (null["baseState"] | ???*27* | ???*29*), + "baseQueue": (null["baseQueue"] | ???*31* | ???*33*), + "queue": (null["queue"] | ???*35* | ???*37*), + "next": null + } + ), + ( + | null["memoizedState"] + | ???*39* + | null["alternate"]["memoizedState"] + | ???*41* + | (null !== ???*44*)["alternate"]["memoizedState"] + | (null !== ???*45*)["alternate"]["memoizedState"] + | (???*47* ? ???*49* : null)["memoizedState"] + | ???*51* + ), + ???*52* +) +- *0* ???*1* + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (null === ???*4*) + ⚠️ nested operation +- *4* P + ⚠️ circular variable reference +- *5* ???*6*["memoizedState"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["next"] + ⚠️ unknown object +- *8* P + ⚠️ circular variable reference +- *9* ???*10*["alternate"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* a + ⚠️ circular variable reference +- *13* ???*14*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* ???*16*["next"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* (null !== ???*18*) + ⚠️ nested operation +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["memoizedState"] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* ???*22*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* ???*26*["memoizedState"] + ⚠️ unknown object +- *26* a + ⚠️ circular variable reference +- *27* ???*28*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* ???*30*["baseState"] + ⚠️ unknown object +- *30* a + ⚠️ circular variable reference +- *31* ???*32*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* ???*34*["baseQueue"] + ⚠️ unknown object +- *34* a + ⚠️ circular variable reference +- *35* ???*36*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *36* unsupported expression + ⚠️ This value might have side effects +- *37* ???*38*["queue"] + ⚠️ unknown object +- *38* a + ⚠️ circular variable reference +- *39* ???*40*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* ???*42*["memoizedState"] + ⚠️ unknown object +- *42* ???*43*["alternate"] + ⚠️ unknown object +- *43* arguments[1] + ⚠️ function calls are not analysed yet +- *44* O + ⚠️ circular variable reference +- *45* ???*46*["next"] + ⚠️ unknown object +- *46* O + ⚠️ circular variable reference +- *47* (null !== ???*48*) + ⚠️ nested operation +- *48* a + ⚠️ circular variable reference +- *49* ???*50*["memoizedState"] + ⚠️ unknown object +- *50* a + ⚠️ circular variable reference +- *51* unknown mutation + ⚠️ This value might have side effects +- *52* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3314 call = (...) => [f, d]((...) => (("function" === typeof(b)) ? b(a) : b)) + +0 -> 3316 call = (...) => P() + +0 -> 3317 call = (...) => (undefined | Ma(a["type"]) | Ma("Lazy") | Ma("Suspense") | Ma("SuspenseList") | ???*0* | "")((???*1* | ???*2*)) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["return"] + ⚠️ unknown object +- *3* d + ⚠️ circular variable reference + +0 -> 3321 conditional = (null != ???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3322 conditional = (null != ???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3324 free var = FreeVar(console) + +0 -> 3326 member call = ???*0*["error"](???*1*) +- *0* FreeVar(console) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3327 free var = FreeVar(setTimeout) + +0 -> 3328 call = ???*0*((...) => undefined) +- *0* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 3329 free var = FreeVar(WeakMap) + +0 -> 3330 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(WeakMap) + ⚠️ unknown global + ⚠️ This value might have side effects + +3330 -> 3331 free var = FreeVar(WeakMap) + +3330 -> 3332 free var = FreeVar(Map) + +0 -> 3333 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}( + ???*0*, + ( + | ???*1* + | {"eventTime": ???*2*, "lane": ???*3*, "tag": 0, "payload": null, "callback": null, "next": null} + ) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* c + ⚠️ circular variable reference + +0 -> 3338 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3339 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}( + ???*0*, + ( + | ???*1* + | {"eventTime": ???*2*, "lane": ???*3*, "tag": 0, "payload": null, "callback": null, "next": null} + ) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* c + ⚠️ circular variable reference + +0 -> 3343 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* ???*2*["getDerivedStateFromError"] + ⚠️ unknown object +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +3343 -> 3346 call = ???*0*(???*3*) +- *0* ???*1*["getDerivedStateFromError"] + ⚠️ unknown object +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["value"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +3343 -> 3348 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3352 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3353 conditional = (null === (???*0* | null)) +- *0* unknown new expression + ⚠️ This value might have side effects + +3353 -> 3354 free var = FreeVar(Set) + +3353 -> 3356 member call = (???*0* | null)["add"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 3360 conditional = (null !== ???*0*) +- *0* ???*1*["stack"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3361 member call = ???*0*["componentDidCatch"](???*1*, {"componentStack": (???*3* ? ???*6* : "")}) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* ???*5*["stack"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["stack"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3363 conditional = (null === (???*0* | ???*2*)) +- *0* ???*1*["pingCache"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +3363 -> 3365 free var = FreeVar(Set) + +3363 -> 3367 member call = ( + | ???*0* + | (...) => undefined["bind"](null, ???*2*, ???*3*, ???*4*)["pingCache"] + | ???*5* +)["set"](???*6*, (???*7* | ???*8* | ???*12* | ???*20*)) +- *0* ???*1*["pingCache"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* unknown new expression + ⚠️ This value might have side effects +- *8* ???*9*["get"](???*11*) + ⚠️ unknown callee object +- *9* ???*10*["pingCache"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ???*13*(???*19*) + ⚠️ unknown callee +- *13* ???*14*["get"] + ⚠️ unknown object +- *14* ???*15*["pingCache"] + ⚠️ unknown object +- *15* (...) => undefined["bind"](null, ???*16*, ???*17*, ???*18*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* arguments[2] + ⚠️ function calls are not analysed yet +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["get"](???*22*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* arguments[1] + ⚠️ function calls are not analysed yet + +3363 -> 3369 member call = ( + | ???*0* + | (...) => undefined["bind"](null, ???*2*, ???*3*, ???*4*)["pingCache"] + | ???*5* +)["get"](???*6*) +- *0* ???*1*["pingCache"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet + +3363 -> 3370 free var = FreeVar(Set) + +3363 -> 3372 member call = ( + | ???*0* + | (...) => undefined["bind"](null, ???*2*, ???*3*, ???*4*)["pingCache"] + | ???*5* +)["set"](???*6*, (???*7* | ???*8* | ???*12* | ???*20*)) +- *0* ???*1*["pingCache"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* unknown new expression + ⚠️ This value might have side effects +- *8* ???*9*["get"](???*11*) + ⚠️ unknown callee object +- *9* ???*10*["pingCache"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ???*13*(???*19*) + ⚠️ unknown callee +- *13* ???*14*["get"] + ⚠️ unknown object +- *14* ???*15*["pingCache"] + ⚠️ unknown object +- *15* (...) => undefined["bind"](null, ???*16*, ???*17*, ???*18*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* arguments[2] + ⚠️ function calls are not analysed yet +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["get"](???*22*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3374 member call = (???*0* | ???*1* | ???*5* | ???*13*)["has"](???*16*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["get"](???*4*) + ⚠️ unknown callee object +- *2* ???*3*["pingCache"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*(???*12*) + ⚠️ unknown callee +- *6* ???*7*["get"] + ⚠️ unknown object +- *7* ???*8*["pingCache"] + ⚠️ unknown object +- *8* (...) => undefined["bind"](null, ???*9*, ???*10*, ???*11*) + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* ???*14*["get"](???*15*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3376 member call = (???*0* | ???*1* | ???*5* | ???*13*)["add"](???*16*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["get"](???*4*) + ⚠️ unknown callee object +- *2* ???*3*["pingCache"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*(???*12*) + ⚠️ unknown callee +- *6* ???*7*["get"] + ⚠️ unknown object +- *7* ???*8*["pingCache"] + ⚠️ unknown object +- *8* (...) => undefined["bind"](null, ???*9*, ???*10*, ???*11*) + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* ???*14*["get"](???*15*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3378 member call = (...) => undefined["bind"]( + null, + ( + | ???*0* + | (...) => undefined["bind"](null, ???*1*, ???*2*, ???*3*) + ), + ???*4*, + ???*5* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3380 member call = ???*0*["then"]( + ( + | ???*1* + | (...) => undefined["bind"](null, ???*2*, ???*3*, ???*4*) + ), + ( + | ???*5* + | (...) => undefined["bind"](null, ???*6*, ???*7*, ???*8*) + ) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* a + ⚠️ circular variable reference +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3383 conditional = (null !== (???*0* | ???*1* | ???*4*)) +- *0* b + ⚠️ pattern without value +- *1* (13 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["memoizedState"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +3383 -> 3385 conditional = (null !== ???*0*) +- *0* ???*1*["dehydrated"] + ⚠️ unknown object +- *1* b + ⚠️ pattern without value + +0 -> 3388 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3388 -> 3389 conditional = (???*0* === ( + | ???*1* + | {"eventTime": ???*2*, "lane": 1, "tag": 0, "payload": null, "callback": null, "next": null} +)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +3389 -> 3396 conditional = (null === ???*0*) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +3396 -> 3398 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}(???*0*, 1) +- *0* unsupported expression + ⚠️ This value might have side effects + +3396 -> 3400 call = (...) => (null | Zg(a, c))( + ???*0*, + ( + | ???*1* + | {"eventTime": ???*2*, "lane": 1, "tag": 0, "payload": null, "callback": null, "next": null} + ), + 1 +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 3406 conditional = (null === ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +3406 -> 3407 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, null, ???*3*, ???*4*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +3406 -> 3409 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, ???*3*, ???*5*, ???*6*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["child"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 3412 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3413 call = (...) => a(???*0*, ???*1*, (???*2* | ???*3* | (0 !== (0 | ???*5*))), (???*6* | ???*7*), ???*12*, ???*14*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["render"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* arguments[3] + ⚠️ function calls are not analysed yet +- *7* (???*8* | ???*9* | (0 !== (0 | ???*11*)))(d, e) + ⚠️ non-function callee +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* ???*10*["render"] + ⚠️ unknown object +- *10* c + ⚠️ circular variable reference +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* ???*13*["ref"] + ⚠️ unknown object +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3414 call = (...) => a() + +0 -> 3415 conditional = ((null !== ???*0*) | !((true | false | ???*1*))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? true : false) + ⚠️ nested operation +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects + +3415 -> 3420 call = (...) => (null | b["child"])(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3421 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3423 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*), ???*8*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* (???*4* | ???*5* | (0 !== (0 | ???*7*)))(d, e) + ⚠️ non-function callee +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*["render"] + ⚠️ unknown object +- *6* c + ⚠️ circular variable reference +- *7* updated with update expression + ⚠️ This value might have side effects +- *8* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3425 conditional = (null === (???*0* | ???*1* | ???*3* | ???*4* | null)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +3425 -> 3427 call = (...) => !((!(a) || !(a["isReactComponent"])))( + ( + | ???*0* + | (???*2* ? ???*4* : (...) => (???*5* | ???*6*))["type"] + | ???*7* + | null["child"] + ) +) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference +- *4* c + ⚠️ circular variable reference +- *5* !(0) + ⚠️ nested operation +- *6* !(1) + ⚠️ nested operation +- *7* ???*8*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects + +3425 -> 3431 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3431 -> 3434 call = (...) => (???*0* | dj(a, b, c, d, e))( + ( + | ???*1* + | ???*2* + | ???*4* + | ???*5* + | null + | (???*6* ? ???*8* : (...) => (???*9* | ???*10*))["type"]["alternate"] + ), + ???*11*, + ( + | ???*12* + | (???*14* ? ???*16* : (...) => (???*17* | ???*18*))["type"] + | ???*19* + | null["child"] + ), + ???*21*, + ???*22* +) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["children"] + ⚠️ unknown object +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *6* (null !== ???*7*) + ⚠️ nested operation +- *7* c + ⚠️ circular variable reference +- *8* c + ⚠️ circular variable reference +- *9* !(0) + ⚠️ nested operation +- *10* !(1) + ⚠️ nested operation +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ???*13*["type"] + ⚠️ unknown object +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* (null !== ???*15*) + ⚠️ nested operation +- *15* c + ⚠️ circular variable reference +- *16* c + ⚠️ circular variable reference +- *17* !(0) + ⚠️ nested operation +- *18* !(1) + ⚠️ nested operation +- *19* ???*20*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unknown new expression + ⚠️ This value might have side effects +- *21* arguments[3] + ⚠️ function calls are not analysed yet +- *22* arguments[4] + ⚠️ function calls are not analysed yet + +3425 -> 3437 call = (...) => (Ah(c["children"], e, f, b) | ???*0* | qj(c, e, f, b) | b)( + ( + | ???*1* + | (???*3* ? ???*5* : (...) => (???*6* | ???*7*))["type"] + ), + null, + ???*8*, + ???*9*, + ???*10*, + ???*12* +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* c + ⚠️ circular variable reference +- *5* c + ⚠️ circular variable reference +- *6* !(0) + ⚠️ nested operation +- *7* !(1) + ⚠️ nested operation +- *8* arguments[3] + ⚠️ function calls are not analysed yet +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["mode"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3444 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3444 -> 3447 conditional = (null !== (???*0* | ???*1* | ???*3*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["compare"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* (???*4* ? ???*6* : (...) => (???*7* | ???*8*)) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* c + ⚠️ circular variable reference +- *6* c + ⚠️ circular variable reference +- *7* !(0) + ⚠️ nested operation +- *8* !(1) + ⚠️ nested operation + +3444 -> 3448 call = (???*0* | ???*1* | (???*3* ? ???*5* : (...) => (???*6* | ???*7*)))( + ( + | ???*8* + | (???*11* ? ???*13* : (...) => (???*14* | ???*15*))["type"]["memoizedProps"] + | ???*16* + | null["child"]["memoizedProps"] + ), + ???*19* +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["compare"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* c + ⚠️ circular variable reference +- *5* c + ⚠️ circular variable reference +- *6* !(0) + ⚠️ nested operation +- *7* !(1) + ⚠️ nested operation +- *8* ???*9*["memoizedProps"] + ⚠️ unknown object +- *9* ???*10*["type"] + ⚠️ unknown object +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* (null !== ???*12*) + ⚠️ nested operation +- *12* c + ⚠️ circular variable reference +- *13* c + ⚠️ circular variable reference +- *14* !(0) + ⚠️ nested operation +- *15* !(1) + ⚠️ nested operation +- *16* ???*17*["memoizedProps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* ???*18*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unknown new expression + ⚠️ This value might have side effects +- *19* arguments[3] + ⚠️ function calls are not analysed yet + +3444 -> 3451 conditional = (???*0* | ((???*9* | ???*11* | null["ref"]) === ???*13*)) +- *0* (???*1* | ???*2* | (???*4* ? ???*6* : (...) => (???*7* | ???*8*)))(g, d) + ⚠️ non-function callee +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["compare"] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* c + ⚠️ circular variable reference +- *6* c + ⚠️ circular variable reference +- *7* !(0) + ⚠️ nested operation +- *8* !(1) + ⚠️ nested operation +- *9* ???*10*["ref"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* ???*12*["ref"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unknown new expression + ⚠️ This value might have side effects +- *13* ???*14*["ref"] + ⚠️ unknown object +- *14* arguments[1] + ⚠️ function calls are not analysed yet + +3451 -> 3452 call = (...) => (null | b["child"])( + ( + | ???*0* + | ???*1* + | ???*3* + | ???*4* + | null + | (???*5* ? ???*7* : (...) => (???*8* | ???*9*))["type"]["alternate"] + ), + ???*10*, + ???*11* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* c + ⚠️ circular variable reference +- *7* c + ⚠️ circular variable reference +- *8* !(0) + ⚠️ nested operation +- *9* !(1) + ⚠️ nested operation +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3454 call = (...) => c( + ( + | ???*0* + | (???*2* ? ???*4* : (...) => (???*5* | ???*6*))["type"] + | ???*7* + | null["child"] + ), + ???*9* +) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference +- *4* c + ⚠️ circular variable reference +- *5* !(0) + ⚠️ nested operation +- *6* !(1) + ⚠️ nested operation +- *7* ???*8*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects +- *9* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 3459 conditional = (null !== ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +3459 -> 3461 call = (...) => (!(0) | !(1))(???*0*, (???*2* | ???*3*)) +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* ???*4*["memoizedProps"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +3459 -> 3464 conditional = (true | false | (???*0* === ???*2*)) +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["ref"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +3464 -> 3470 call = (...) => (null | b["child"])(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3471 call = (...) => (???*0* | b["child"])(???*1*, ???*2*, ???*3*, (???*4* | ???*5*), ???*7*) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet +- *5* ???*6*["memoizedProps"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3474 conditional = (null !== (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? ???*8* : ???*9*) + ⚠️ nested operation +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3477 conditional = ("hidden" === (???*0* | ???*3*)) +- *0* ???*1*["mode"] + ⚠️ unknown object +- *1* ???*2*["pendingProps"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["mode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +3477 -> 3479 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3479 -> 3481 call = (...) => undefined({"current": 0}, (???*0* | 0 | ???*1* | ???*2* | ???*3*)) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects + +3479 -> 3482 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3482 -> 3483 conditional = (null !== ???*0*) +- *0* (???*1* ? ???*8* : null) + ⚠️ nested operation +- *1* (null !== (???*2* | ???*3*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*6* : ???*7*) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* f + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet + +3482 -> 3489 call = (...) => undefined({"current": 0}, (???*0* | 0 | ???*1* | ???*2* | ???*3*)) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects + +3479 -> 3491 conditional = (null !== ???*0*) +- *0* (???*1* ? ???*8* : null) + ⚠️ nested operation +- *1* (null !== (???*2* | ???*3*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*6* : ???*7*) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* f + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet + +3479 -> 3493 call = (...) => undefined({"current": 0}, (???*0* | 0 | ???*1* | ???*2* | ???*3*)) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects + +3477 -> 3494 conditional = (null !== ???*0*) +- *0* (???*1* ? ???*8* : null) + ⚠️ nested operation +- *1* (null !== (???*2* | ???*3*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*6* : ???*7*) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* f + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet + +3477 -> 3497 call = (...) => undefined({"current": 0}, (???*0* | 0 | ???*1* | ???*2* | ???*3*)) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects + +0 -> 3498 call = (...) => undefined( + (???*0* | (???*1* ? ???*7* : ???*8*)), + ???*9*, + (???*10* | (???*13* ? ???*23* : ???*33*)["children"] | ???*34*), + ???*36* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (null !== ???*2*) + ⚠️ nested operation +- *2* (???*3* ? ???*5* : null) + ⚠️ nested operation +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["memoizedState"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["children"] + ⚠️ unknown object +- *11* ???*12*["pendingProps"] + ⚠️ unknown object +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* (null !== ???*14*) + ⚠️ nested operation +- *14* (???*15* ? ???*21* : null) + ⚠️ nested operation +- *15* (null !== (???*16* | ???*17*)) + ⚠️ nested operation +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* (???*18* ? ???*19* : ???*20*) + ⚠️ nested operation +- *18* (null !== ???) + ⚠️ nested operation +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* arguments[2] + ⚠️ function calls are not analysed yet +- *21* ???*22*["memoizedState"] + ⚠️ unknown object +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* ???*24*["baseLanes"] + ⚠️ unknown object +- *24* (???*25* ? ???*31* : null) + ⚠️ nested operation +- *25* (null !== (???*26* | ???*27*)) + ⚠️ nested operation +- *26* arguments[0] + ⚠️ function calls are not analysed yet +- *27* (???*28* ? ???*29* : ???*30*) + ⚠️ nested operation +- *28* (null !== ???) + ⚠️ nested operation +- *29* unsupported expression + ⚠️ This value might have side effects +- *30* arguments[2] + ⚠️ function calls are not analysed yet +- *31* ???*32*["memoizedState"] + ⚠️ unknown object +- *32* arguments[0] + ⚠️ function calls are not analysed yet +- *33* arguments[2] + ⚠️ function calls are not analysed yet +- *34* ???*35*["children"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3502 conditional = ((null === ???*0*) | (null !== ???*1*) | (null !== ???*3*) | (???*4* !== ???*6*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["ref"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["ref"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3505 call = (...) => ((null !== a) && (???*0* !== a))((???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*(d, e) + ⚠️ unknown callee +- *3* c + ⚠️ circular variable reference + +0 -> 3506 conditional = ((null !== (???*0* | ???*1* | ???*3*)) | (???*5* !== (???*6* | ???*7* | ???*9*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*(d, e) + ⚠️ unknown callee +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["childContextTypes"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*(d, e) + ⚠️ unknown callee +- *8* c + ⚠️ circular variable reference +- *9* ???*10*["childContextTypes"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference + +0 -> 3508 call = (...) => (Vf | d["__reactInternalMemoizedMaskedChildContext"] | e)( + ???*0*, + ((???*1* ? ({} | ???*7*) : ({} | ???*8*)) | {} | ???*9*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (null !== (???*2* | ???*3* | ???*5*)) + ⚠️ nested operation +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*(d, e) + ⚠️ unknown callee +- *4* c + ⚠️ circular variable reference +- *5* ???*6*["childContextTypes"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* unknown mutation + ⚠️ This value might have side effects +- *8* unknown mutation + ⚠️ This value might have side effects +- *9* ???*10*["__reactInternalMemoizedMaskedChildContext"] + ⚠️ unknown object +- *10* ???*11*["stateNode"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3509 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3510 call = (...) => a( + ???*0*, + ???*1*, + (???*2* | ???*3*), + (???*5* | (0 !== (0 | ???*6*))), + ((???*7* ? ({} | ???*13*) : ({} | ???*14*)) | {} | ???*15*), + ???*18* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*(d, e) + ⚠️ unknown callee +- *4* c + ⚠️ circular variable reference +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* (null !== (???*8* | ???*9* | ???*11*)) + ⚠️ nested operation +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* ???*10*(d, e) + ⚠️ unknown callee +- *10* c + ⚠️ circular variable reference +- *11* ???*12*["childContextTypes"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* unknown mutation + ⚠️ This value might have side effects +- *14* unknown mutation + ⚠️ This value might have side effects +- *15* ???*16*["__reactInternalMemoizedMaskedChildContext"] + ⚠️ unknown object +- *16* ???*17*["stateNode"] + ⚠️ unknown object +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3511 call = (...) => a() + +0 -> 3512 conditional = ((null !== ???*0*) | !((true | false | ???*1*))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (???*2* ? true : false) + ⚠️ nested operation +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects + +3512 -> 3517 call = (...) => (null | b["child"])(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3518 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3520 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*), ???*5*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*(d, e) + ⚠️ unknown callee +- *4* c + ⚠️ circular variable reference +- *5* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3522 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3523 conditional = ((null !== (???*0* | ???*1*)) | (???*3* !== (???*4* | ???*5*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["childContextTypes"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*["childContextTypes"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference + +3523 -> 3524 call = (...) => !(0)(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3525 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3527 conditional = (null === ???*0*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +3527 -> 3528 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +3527 -> 3529 call = (...) => b(???*0*, ???*1*, ???*2*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +3527 -> 3530 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* arguments[4] + ⚠️ function calls are not analysed yet + +3527 -> 3531 conditional = (null === ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +3531 -> 3537 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3537 -> 3538 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3537 -> 3539 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +3537 -> 3540 conditional = ((null !== (???*0* | ???*1*)) | (???*3* !== (???*4* | ???*5*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["childContextTypes"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*["childContextTypes"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference + +3537 -> 3542 call = (...) => (Vf | d["__reactInternalMemoizedMaskedChildContext"] | e)(???*0*, ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +3531 -> 3547 call = (...) => undefined(???*0*, ???*1*, ???*3*, ???*4*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +3531 -> 3550 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*4*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[4] + ⚠️ function calls are not analysed yet + +3531 -> 3553 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3553 -> 3554 call = (...) => undefined(???*0*, ???*1*, (???*2* | ("function" === ???*4*)), ???*7*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["getDerivedStateFromProps"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* typeof(???*5*) + ⚠️ nested operation +- *5* ???*6*["getDerivedStateFromProps"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* max number of linking steps reached + ⚠️ This value might have side effects + +3553 -> 3556 call = (...) => (("function" === typeof(a["shouldComponentUpdate"])) ? a["shouldComponentUpdate"](d, f, g) : ((b["prototype"] && b["prototype"]["isPureReactComponent"]) ? (!(Ie(c, d)) || !(Ie(e, f))) : !(0)))( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + ???*4*, + (???*6* | ???*9* | ???*10* | (???*11* ? ({} | ???*15*) : ({} | ???*16*)) | {}), + ???*17* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* ???*5*["memoizedState"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["context"] + ⚠️ unknown object +- *7* ???*8*["stateNode"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unknown mutation + ⚠️ This value might have side effects +- *11* (null !== (???*12* | ???*13*)) + ⚠️ nested operation +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*["childContextTypes"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* unknown mutation + ⚠️ This value might have side effects +- *16* unknown mutation + ⚠️ This value might have side effects +- *17* max number of linking steps reached + ⚠️ This value might have side effects + +3553 -> 3561 member call = ???*0*["componentWillMount"]() +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +3553 -> 3564 member call = ???*0*["UNSAFE_componentWillMount"]() +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +3531 -> 3577 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +3531 -> 3581 conditional = (???*0* === ???*2*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["elementType"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +3581 -> 3583 call = (...) => b(???*0*, ???*2*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +3531 -> 3588 conditional = ( + | ("object" === ???*0*) + | (null !== (???*13* | ???*16* | ???*17* | ???*18* | {})) +) +- *0* typeof((???*1* | ???*4* | ???*5* | ???*6* | {})) + ⚠️ nested operation +- *1* ???*2*["context"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* (???*7* ? ({} | ???*11*) : ({} | ???*12*)) + ⚠️ nested operation +- *7* (null !== (???*8* | ???*9*)) + ⚠️ nested operation +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* ???*10*["childContextTypes"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* unknown mutation + ⚠️ This value might have side effects +- *12* unknown mutation + ⚠️ This value might have side effects +- *13* ???*14*["context"] + ⚠️ unknown object +- *14* ???*15*["stateNode"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* unknown mutation + ⚠️ This value might have side effects +- *18* (???*19* ? ({} | ???*23*) : ({} | ???*24*)) + ⚠️ nested operation +- *19* (null !== (???*20* | ???*21*)) + ⚠️ nested operation +- *20* arguments[2] + ⚠️ function calls are not analysed yet +- *21* ???*22*["childContextTypes"] + ⚠️ unknown object +- *22* a + ⚠️ circular variable reference +- *23* unknown mutation + ⚠️ This value might have side effects +- *24* unknown mutation + ⚠️ This value might have side effects + +3588 -> 3589 call = (...) => b( + (???*0* | ???*3* | ???*4* | (???*5* ? ({} | ???*9*) : ({} | ???*10*)) | {}) +) +- *0* ???*1*["context"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* (null !== (???*6* | ???*7*)) + ⚠️ nested operation +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["childContextTypes"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* unknown mutation + ⚠️ This value might have side effects +- *10* unknown mutation + ⚠️ This value might have side effects + +3588 -> 3590 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +3588 -> 3591 conditional = ((null !== (???*0* | ???*1*)) | (???*3* !== (???*4* | ???*5*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["childContextTypes"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*["childContextTypes"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference + +3588 -> 3593 call = (...) => (Vf | d["__reactInternalMemoizedMaskedChildContext"] | e)( + ???*0*, + (???*1* | ???*4* | ???*5* | (???*6* ? ({} | ???*10*) : ({} | ???*11*)) | {}) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["context"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* (null !== (???*7* | ???*8*)) + ⚠️ nested operation +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["childContextTypes"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* unknown mutation + ⚠️ This value might have side effects +- *11* unknown mutation + ⚠️ This value might have side effects + +3531 -> 3598 call = (...) => undefined( + ???*0*, + ???*1*, + ???*3*, + (???*4* | ???*7* | ???*8* | (???*9* ? ({} | ???*13*) : ({} | ???*14*)) | {}) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* ???*5*["context"] + ⚠️ unknown object +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* unknown mutation + ⚠️ This value might have side effects +- *9* (null !== (???*10* | ???*11*)) + ⚠️ nested operation +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* ???*12*["childContextTypes"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* unknown mutation + ⚠️ This value might have side effects +- *14* unknown mutation + ⚠️ This value might have side effects + +3531 -> 3601 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*4*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[4] + ⚠️ function calls are not analysed yet + +3531 -> 3604 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3604 -> 3605 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*4*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["getDerivedStateFromProps"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +3604 -> 3607 call = (...) => (("function" === typeof(a["shouldComponentUpdate"])) ? a["shouldComponentUpdate"](d, f, g) : ((b["prototype"] && b["prototype"]["isPureReactComponent"]) ? (!(Ie(c, d)) || !(Ie(e, f))) : !(0)))( + ???*0*, + ???*1*, + ???*2*, + ???*3*, + ???*4*, + ???*6*, + (???*8* | ???*11* | ???*12* | (???*13* ? ({} | ???*17*) : ({} | ???*18*)) | {}) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* ???*5*["memoizedState"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???*9*["context"] + ⚠️ unknown object +- *9* ???*10*["stateNode"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* unknown mutation + ⚠️ This value might have side effects +- *13* (null !== (???*14* | ???*15*)) + ⚠️ nested operation +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* ???*16*["childContextTypes"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* unknown mutation + ⚠️ This value might have side effects +- *18* unknown mutation + ⚠️ This value might have side effects + +3604 -> 3612 member call = ???*0*["componentWillUpdate"]( + ???*2*, + ???*3*, + (???*5* | ???*8* | ???*9* | (???*10* ? ({} | ???*14*) : ({} | ???*15*)) | {}) +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["context"] + ⚠️ unknown object +- *6* ???*7*["stateNode"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unknown mutation + ⚠️ This value might have side effects +- *10* (null !== (???*11* | ???*12*)) + ⚠️ nested operation +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* ???*13*["childContextTypes"] + ⚠️ unknown object +- *13* a + ⚠️ circular variable reference +- *14* unknown mutation + ⚠️ This value might have side effects +- *15* unknown mutation + ⚠️ This value might have side effects + +3604 -> 3615 member call = ???*0*["UNSAFE_componentWillUpdate"]( + ???*2*, + ???*3*, + (???*5* | ???*8* | ???*9* | (???*10* ? ({} | ???*14*) : ({} | ???*15*)) | {}) +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["context"] + ⚠️ unknown object +- *6* ???*7*["stateNode"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unknown mutation + ⚠️ This value might have side effects +- *10* (null !== (???*11* | ???*12*)) + ⚠️ nested operation +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* ???*13*["childContextTypes"] + ⚠️ unknown object +- *13* a + ⚠️ circular variable reference +- *14* unknown mutation + ⚠️ This value might have side effects +- *15* unknown mutation + ⚠️ This value might have side effects + +0 -> 3641 call = (...) => ($i(a, b, f) | b["child"])(???*0*, ???*1*, ???*2*, ???*3*, (true | false), ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3642 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3644 conditional = (!((???*0* | ???*1*)) | !(???*3*)) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (0 !== ???*4*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects + +3644 -> 3645 call = (...) => undefined(???*0*, ???*1*, false) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +3644 -> 3646 call = (...) => (null | b["child"])(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[5] + ⚠️ function calls are not analysed yet + +0 -> 3650 conditional = ((0 !== ???*0*) | ("function" !== ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["getDerivedStateFromError"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +3650 -> 3652 member call = (???*0* | ???*1*)["render"]() +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3654 conditional = ((null !== ???*0*) | (0 !== ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +3654 -> 3657 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, ???*3*, null, ???*5*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["child"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[5] + ⚠️ function calls are not analysed yet + +3654 -> 3659 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, null, (???*3* ? null : ???*5*), ???*8*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (0 !== ???*4*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* ???*6*() + ⚠️ nested operation +- *6* ???*7*["render"] + ⚠️ unknown object +- *7* arguments[3] + ⚠️ function calls are not analysed yet +- *8* arguments[5] + ⚠️ function calls are not analysed yet + +3654 -> 3660 call = (...) => undefined(???*0*, ???*1*, (???*2* ? null : ???*4*), ???*7*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["render"] + ⚠️ unknown object +- *6* arguments[3] + ⚠️ function calls are not analysed yet +- *7* arguments[5] + ⚠️ function calls are not analysed yet + +0 -> 3663 call = (...) => undefined(???*0*, ???*1*, true) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3667 conditional = ???*0* +- *0* ???*1*["pendingContext"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +3667 -> 3671 call = (...) => undefined(???*0*, ???*1*, (???*4* !== ???*7*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["pendingContext"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["pendingContext"] + ⚠️ unknown object +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*["context"] + ⚠️ unknown object +- *8* ???*9*["stateNode"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet + +3667 -> 3674 call = (...) => undefined(???*0*, ???*1*, false) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["context"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3676 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["containerInfo"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3677 call = (...) => undefined() + +0 -> 3678 call = (...) => undefined(???*0*) +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +0 -> 3680 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 3686 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3687 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3690 call = (...) => undefined({"current": 0}, ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 3691 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3691 -> 3692 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +3691 -> 3695 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3695 -> 3697 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3697 -> 3700 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3691 -> 3705 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3705 -> 3708 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3708 -> 3711 call = (...) => a(???*0*, ???*1*, 0, null) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +3705 -> 3712 call = (...) => a(???*0*, ???*1*, (???*2* | ???*3*), null) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["deletions"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +3705 -> 3719 call = (...) => {"baseLanes": a, "cachePool": null, "transitions": null}((???*0* | ???*1*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +3705 -> 3721 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3724 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3724 -> 3725 call = (...) => (???*0* | f | tj(a, b, g, null) | tj(a, b, g, d) | b)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*, ???*6*, (???*7* | ???*8*)) +- *0* tj(a, b, g, d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["deletions"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3726 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3726 -> 3733 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3733 -> 3738 call = (...) => c(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +3726 -> 3741 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3741 -> 3742 call = (...) => c(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +3741 -> 3743 call = (...) => a(???*0*, ???*1*, (???*2* | ???*3*), null) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["deletions"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +3726 -> 3752 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3752 -> 3753 call = (...) => {"baseLanes": a, "cachePool": null, "transitions": null}((???*0* | ???*1*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3763 call = (...) => c(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3769 conditional = (null === (???*0* | ???*1*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +3769 -> 3773 member call = (???*0* | ???*1*)["push"](???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3777 call = (...) => a( + { + "mode": "visible", + "children": (???*0* | {"mode": "visible", "children": ???*1*} | ???*2*) + }, + ???*3*, + 0, + null +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* b + ⚠️ circular variable reference +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* ???*4*["mode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3780 call = (...) => undefined(???*0*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 3782 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, (???*3* | ???*5*), null, ???*7*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["child"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3785 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["children"] + ⚠️ unknown object +- *3* ???*4*["pendingProps"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3788 conditional = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +3788 -> 3791 free var = FreeVar(Error) + +3788 -> 3792 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(422) + +3788 -> 3793 call = ???*0*( + `Minified React error #${422}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${422}` + ⚠️ nested operation + +3788 -> 3794 call = (...) => {"value": a, "source": null, "stack": ((null != c) ? c : null), "digest": ((null != b) ? b : null)}(???*0*) +- *0* ???*1*(p(422)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +3788 -> 3795 call = (...) => a(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[6] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +3788 -> 3797 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3788 -> 3804 call = (...) => a(???*0*, ???*1*, 0, null) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +3788 -> 3805 call = (...) => a(???*0*, ???*1*, ???*2*, null) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[6] + ⚠️ function calls are not analysed yet + +3788 -> 3813 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, ???*3*, null, ???*4*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* arguments[6] + ⚠️ function calls are not analysed yet + +3788 -> 3816 call = (...) => {"baseLanes": a, "cachePool": null, "transitions": null}(???*0*) +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +0 -> 3819 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3819 -> 3820 call = (...) => a(???*0*, ???*1*, ???*2*, null) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[6] + ⚠️ function calls are not analysed yet + +0 -> 3822 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3822 -> 3826 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3822 -> 3828 free var = FreeVar(Error) + +3822 -> 3829 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(419) + +3822 -> 3830 call = ???*0*( + `Minified React error #${419}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${419}` + ⚠️ nested operation + +3822 -> 3831 call = (...) => {"value": a, "source": null, "stack": ((null != c) ? c : null), "digest": ((null != b) ? b : null)}(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +3822 -> 3832 call = (...) => a(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[6] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3834 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3834 -> 3835 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3835 -> 3837 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3835 -> 3840 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +3835 -> 3841 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +3834 -> 3842 call = (...) => undefined() + +3834 -> 3843 free var = FreeVar(Error) + +3834 -> 3844 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(421) + +3834 -> 3845 call = ???*0*( + `Minified React error #${421}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${421}` + ⚠️ nested operation + +3834 -> 3846 call = (...) => {"value": a, "source": null, "stack": ((null != c) ? c : null), "digest": ((null != b) ? b : null)}(???*0*) +- *0* ???*1*(p(421)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +3834 -> 3847 call = (...) => a(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[6] + ⚠️ function calls are not analysed yet +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3849 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3849 -> 3854 member call = (...) => undefined["bind"](null, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3858 call = (...) => (null | a)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3865 call = (...) => ???*0*(???*1*, ???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 3871 call = (...) => undefined(???*0*, ???*2*, ???*3*) +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 3873 conditional = (null === ???*0*) +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3885 call = (...) => undefined( + ( + | ???*0* + | ???*1* + | 0["revealOrder"]["alternate"] + | ???*3* + | null["alternate"] + | null["sibling"]["alternate"] + | 0["revealOrder"]["sibling"] + | null["sibling"] + | null["sibling"]["sibling"] + ), + ???*6*, + (???*7* | 0["children"] | ???*10*), + (???*12* | ???*13* | 0["revealOrder"] | ???*15* | null | ???*17*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["children"] + ⚠️ unknown object +- *8* ???*9*["pendingProps"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["children"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unknown mutation + ⚠️ This value might have side effects +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*["child"] + ⚠️ unknown object +- *14* arguments[1] + ⚠️ function calls are not analysed yet +- *15* ???*16*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* unknown mutation + ⚠️ This value might have side effects +- *17* c + ⚠️ circular variable reference + +0 -> 3887 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3887 -> 3890 conditional = ( + | (null !== ( + | ???*0* + | ???*1* + | 0["revealOrder"]["alternate"] + | ???*3* + | null["alternate"] + | null["sibling"]["alternate"] + | 0["revealOrder"]["sibling"] + | null["sibling"] + | null["sibling"]["sibling"] + )) + | (0 !== ???*6*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects + +3890 -> 3893 conditional = (13 === ( + | ???*0* + | 0["revealOrder"]["alternate"]["tag"] + | ???*2* + | null["alternate"]["tag"] + | null["sibling"]["alternate"]["tag"] + | 0["revealOrder"]["sibling"]["tag"] + | null["sibling"]["tag"] + | null["sibling"]["sibling"]["tag"] +)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +3893 -> 3895 call = (...) => undefined( + ( + | ???*0* + | ???*1* + | 0["revealOrder"]["alternate"] + | ???*3* + | null["alternate"] + | null["sibling"]["alternate"] + | 0["revealOrder"]["sibling"] + | null["sibling"] + | null["sibling"]["sibling"] + ), + (???*6* | ???*7* | 0["revealOrder"] | ???*9* | null | ???*11*), + ???*12* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["child"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unknown mutation + ⚠️ This value might have side effects +- *11* c + ⚠️ circular variable reference +- *12* arguments[1] + ⚠️ function calls are not analysed yet + +3893 -> 3897 conditional = (19 === ( + | ???*0* + | 0["revealOrder"]["alternate"]["tag"] + | ???*2* + | null["alternate"]["tag"] + | null["sibling"]["alternate"]["tag"] + | 0["revealOrder"]["sibling"]["tag"] + | null["sibling"]["tag"] + | null["sibling"]["sibling"]["tag"] +)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +3897 -> 3898 call = (...) => undefined( + ( + | ???*0* + | ???*1* + | 0["revealOrder"]["alternate"] + | ???*3* + | null["alternate"] + | null["sibling"]["alternate"] + | 0["revealOrder"]["sibling"] + | null["sibling"] + | null["sibling"]["sibling"] + ), + (???*6* | ???*7* | 0["revealOrder"] | ???*9* | null | ???*11*), + ???*12* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["child"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unknown mutation + ⚠️ This value might have side effects +- *11* c + ⚠️ circular variable reference +- *12* arguments[1] + ⚠️ function calls are not analysed yet + +3897 -> 3900 conditional = (null !== ( + | ???*0* + | 0["revealOrder"]["alternate"]["child"] + | ???*2* + | null["alternate"]["child"] + | null["sibling"]["alternate"]["child"] + | 0["revealOrder"]["sibling"]["child"] + | null["sibling"]["child"] + | null["sibling"]["sibling"]["child"] +)) +- *0* ???*1*["child"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +0 -> 3912 call = (...) => undefined({"current": 0}, (???*0* | 0 | ???*2* | ???*3* | ???*4*)) +- *0* ???*1*["pendingProps"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 3914 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3914 -> 3918 call = (...) => (b | null)( + ( + | ???*0* + | ???*1* + | 0["revealOrder"]["alternate"] + | ???*3* + | null["alternate"] + | null["sibling"]["alternate"] + | 0["revealOrder"]["sibling"] + | null["sibling"] + | null["sibling"]["sibling"] + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +3914 -> 3920 conditional = (null === (???*0* | ???*1* | 0["revealOrder"] | ???*3* | null | ???*5*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* c + ⚠️ circular variable reference + +3914 -> 3925 call = (...) => undefined( + ???*0*, + false, + (???*1* | 0["revealOrder"] | ???*4* | null | ???*6* | ???*7* | null["sibling"] | null["alternate"]), + (???*8* | ???*9* | 0["revealOrder"] | ???*11* | null | ???*13*), + (???*14* | 0["tail"] | ???*17*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["revealOrder"] + ⚠️ unknown object +- *2* ???*3*["pendingProps"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* e + ⚠️ circular variable reference +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* ???*10*["child"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unknown mutation + ⚠️ This value might have side effects +- *13* c + ⚠️ circular variable reference +- *14* ???*15*["tail"] + ⚠️ unknown object +- *15* ???*16*["pendingProps"] + ⚠️ unknown object +- *16* arguments[1] + ⚠️ function calls are not analysed yet +- *17* ???*18*["tail"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unknown mutation + ⚠️ This value might have side effects + +3914 -> 3929 call = (...) => (b | null)( + ( + | ???*0* + | ???*1* + | 0["revealOrder"]["alternate"] + | ???*3* + | null["alternate"] + | null["sibling"]["alternate"] + | 0["revealOrder"]["sibling"] + | null["sibling"] + | null["sibling"]["sibling"] + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +3914 -> 3930 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +3914 -> 3934 call = (...) => undefined( + ???*0*, + true, + (???*1* | ???*2* | 0["revealOrder"] | ???*4* | null | ???*6*), + null, + (???*7* | 0["tail"] | ???*10*) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["child"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* c + ⚠️ circular variable reference +- *7* ???*8*["tail"] + ⚠️ unknown object +- *8* ???*9*["pendingProps"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["tail"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unknown mutation + ⚠️ This value might have side effects + +3914 -> 3935 call = (...) => undefined(???*0*, false, null, null, ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 3948 conditional = ((null !== (???*0* | ???*1*)) | (???*3* !== ???*5*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["child"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["child"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +3948 -> 3949 free var = FreeVar(Error) + +3948 -> 3950 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(153) + +3948 -> 3951 call = ???*0*( + `Minified React error #${153}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${153}` + ⚠️ nested operation + +0 -> 3953 conditional = (null !== ???*0*) +- *0* ???*1*["child"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +3953 -> 3956 call = (...) => c((???*0* | ???*1*), ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["pendingProps"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +3953 -> 3963 call = (...) => c((???*0* | ???*1*), ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["pendingProps"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 3968 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3969 call = (...) => undefined() + +0 -> 3970 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3972 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3973 call = (...) => !(0)(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3976 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["containerInfo"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 3982 call = (...) => undefined({"current": null}, (???*0* | (0 !== ???*4*)["_currentValue"])) +- *0* ???*1*["_currentValue"] + ⚠️ unknown object +- *1* ???*2*["_context"] + ⚠️ unknown object +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* unsupported expression + ⚠️ This value might have side effects + +0 -> 3985 conditional = (null !== (???*0* | ???*3*)) +- *0* ???*1*["_context"] + ⚠️ unknown object +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (0 !== ???*4*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects + +3985 -> 3987 conditional = (null !== ???*0*) +- *0* ???*1*["dehydrated"] + ⚠️ unknown object +- *1* ???*2*["_context"] + ⚠️ unknown object +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +3987 -> 3989 call = (...) => undefined({"current": 0}, ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3985 -> 3993 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3993 -> 3994 call = (...) => (???*0* | (f ? ???*1* : rj(b, g)) | sj(a, b, g, d, h, e, c) | d)((???*2* | null | ???*3*), ???*5*, ???*6*) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["child"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* arguments[2] + ⚠️ function calls are not analysed yet + +3985 -> 3996 call = (...) => undefined({"current": 0}, ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +3985 -> 3997 call = (...) => (null | b["child"])((???*0* | null | ???*1*), ???*3*, ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +3985 -> 3998 conditional = (null !== (???*0* | null | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 4001 call = (...) => undefined({"current": 0}, ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 4004 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +4004 -> 4005 conditional = (???*0* | (0 !== ???*3*)) +- *0* ???*1*["_context"] + ⚠️ unknown object +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects + +4005 -> 4006 call = (...) => b["child"]((???*0* | null | ???*1*), ???*3*, ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 4013 call = (...) => undefined({"current": 0}, (0 | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +0 -> 4015 call = (...) => (???*0* | b["child"])((???*1* | null | ???*2*), ???*4*, ???*5*) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["child"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 4016 call = (...) => (null | b["child"])((???*0* | null | ???*1*), ???*3*, ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 4020 conditional = ((5 === ???*0*) | (6 === ???*3*)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["tag"] + ⚠️ unknown object +- *4* ???*5*["child"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet + +4020 -> 4023 member call = ???*0*["appendChild"](???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* ???*3*["child"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +4020 -> 4026 conditional = ((4 !== ???*0*) | (null !== ???*3*)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["child"] + ⚠️ unknown object +- *4* ???*5*["child"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 4039 conditional = ((???*0* | ???*2*) !== (???*8* | ???*9*)) +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*( + {}, + b, + { + "defaultChecked": ???*5*, + "defaultValue": ???*6*, + "value": ???*7*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[3] + ⚠️ function calls are not analysed yet +- *9* ???*10*( + {}, + b, + { + "defaultChecked": ???*12*, + "defaultValue": ???*13*, + "value": ???*14*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *10* ???*11*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4042 call = (...) => a(({} | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +4039 -> 4043 call = (...) => A( + {}, + b, + { + "defaultChecked": ???*0*, + "defaultValue": ???*1*, + "value": ???*2*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } +)((???*3* | ???*4*), (???*6* | ???*8*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["memoizedProps"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* ???*9*( + {}, + b, + { + "defaultChecked": ???*11*, + "defaultValue": ???*12*, + "value": ???*13*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *9* ???*10*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4044 call = (...) => A( + {}, + b, + { + "defaultChecked": ???*0*, + "defaultValue": ???*1*, + "value": ???*2*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } +)((???*3* | ???*4*), (???*6* | ???*7*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* arguments[3] + ⚠️ function calls are not analysed yet +- *7* ???*8*( + {}, + b, + { + "defaultChecked": ???*10*, + "defaultValue": ???*11*, + "value": ???*12*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *8* ???*9*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4045 call = ???*0*({}, (???*2* | ???*4*), {"value": ???*10*}) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["memoizedProps"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*( + {}, + b, + { + "defaultChecked": ???*7*, + "defaultValue": ???*8*, + "value": ???*9*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *5* ???*6*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4046 call = ???*0*({}, (???*2* | ???*3*), {"value": ???*9*}) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* ???*4*( + {}, + b, + { + "defaultChecked": ???*6*, + "defaultValue": ???*7*, + "value": ???*8*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *4* ???*5*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4047 call = (...) => A( + {}, + b, + { + "value": ???*0*, + "defaultValue": ???*1*, + "children": `${a["_wrapperState"]["initialValue"]}` + } +)((???*2* | ???*3*), (???*5* | ???*7*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["memoizedProps"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*( + {}, + b, + { + "defaultChecked": ???*10*, + "defaultValue": ???*11*, + "value": ???*12*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *8* ???*9*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4048 call = (...) => A( + {}, + b, + { + "value": ???*0*, + "defaultValue": ???*1*, + "children": `${a["_wrapperState"]["initialValue"]}` + } +)((???*2* | ???*3*), (???*5* | ???*6*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* ???*7*( + {}, + b, + { + "defaultChecked": ???*9*, + "defaultValue": ???*10*, + "value": ???*11*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *7* ???*8*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4052 call = (...) => undefined( + (???*0* | null | {} | ???*1* | ???*5* | (???*14* ? ???*15* : ???*17*)), + (???*18* | ???*19*) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*[(???*3* | null | [] | ???*4*)] + ⚠️ unknown object +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* l + ⚠️ pattern without value +- *4* f + ⚠️ circular variable reference +- *5* ???*6*[(???*12* | null | [] | ???*13*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*( + {}, + b, + { + "defaultChecked": ???*9*, + "defaultValue": ???*10*, + "value": ???*11*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *7* ???*8*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* l + ⚠️ pattern without value +- *13* f + ⚠️ circular variable reference +- *14* k + ⚠️ circular variable reference +- *15* ???*16*["__html"] + ⚠️ unknown object +- *16* k + ⚠️ circular variable reference +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* arguments[3] + ⚠️ function calls are not analysed yet +- *19* ???*20*( + {}, + b, + { + "defaultChecked": ???*22*, + "defaultValue": ???*23*, + "value": ???*24*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *20* ???*21*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4054 member call = (???*0* | ???*1*)["hasOwnProperty"]((???*7* | null | [] | ???*8*)) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*( + {}, + b, + { + "defaultChecked": ???*4*, + "defaultValue": ???*5*, + "value": ???*6*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* ???*3*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* l + ⚠️ pattern without value +- *8* f + ⚠️ circular variable reference + +4039 -> 4056 member call = (???*0* | ???*2*)["hasOwnProperty"]((???*8* | null | [] | ???*9*)) +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*( + {}, + b, + { + "defaultChecked": ???*5*, + "defaultValue": ???*6*, + "value": ???*7*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* l + ⚠️ pattern without value +- *9* f + ⚠️ circular variable reference + +4039 -> 4058 conditional = (!((???*0* | ???*4*)) | ???*13* | ???*18* | (null != (???*27* | ???*32*))) +- *0* ???*1*["hasOwnProperty"]((???*2* | null | [] | ???*3*)) + ⚠️ unknown callee object +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* l + ⚠️ pattern without value +- *3* f + ⚠️ circular variable reference +- *4* ???*5*["hasOwnProperty"]((???*11* | null | [] | ???*12*)) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* ???*6*( + {}, + b, + { + "defaultChecked": ???*8*, + "defaultValue": ???*9*, + "value": ???*10*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *6* ???*7*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* l + ⚠️ pattern without value +- *12* f + ⚠️ circular variable reference +- *13* ???*14*["hasOwnProperty"]((???*16* | null | [] | ???*17*)) + ⚠️ unknown callee object +- *14* ???*15*["memoizedProps"] + ⚠️ unknown object +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* l + ⚠️ pattern without value +- *17* f + ⚠️ circular variable reference +- *18* ???*19*["hasOwnProperty"]((???*25* | null | [] | ???*26*)) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *19* ???*20*( + {}, + b, + { + "defaultChecked": ???*22*, + "defaultValue": ???*23*, + "value": ???*24*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *20* ???*21*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* l + ⚠️ pattern without value +- *26* f + ⚠️ circular variable reference +- *27* ???*28*[(???*30* | null | [] | ???*31*)] + ⚠️ unknown object +- *28* ???*29*["memoizedProps"] + ⚠️ unknown object +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* l + ⚠️ pattern without value +- *31* f + ⚠️ circular variable reference +- *32* ???*33*[(???*39* | null | [] | ???*40*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* ???*34*( + {}, + b, + { + "defaultChecked": ???*36*, + "defaultValue": ???*37*, + "value": ???*38*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *34* ???*35*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *35* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *36* unsupported expression + ⚠️ This value might have side effects +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* l + ⚠️ pattern without value +- *40* f + ⚠️ circular variable reference + +4058 -> 4059 conditional = ("style" === (???*0* | null | [] | ???*1*)) +- *0* l + ⚠️ pattern without value +- *1* f + ⚠️ circular variable reference + +4059 -> 4062 member call = (???*0* | ???*5* | (???*14* ? (???*23* | ???*28*) : ???*37*) | (???*38* ? ???*39* : ???*41*))["hasOwnProperty"](???*42*) +- *0* ???*1*[(???*3* | null | [] | ???*4*)] + ⚠️ unknown object +- *1* ???*2*["memoizedProps"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* l + ⚠️ pattern without value +- *4* f + ⚠️ circular variable reference +- *5* ???*6*[(???*12* | null | [] | ???*13*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*( + {}, + b, + { + "defaultChecked": ???*9*, + "defaultValue": ???*10*, + "value": ???*11*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *7* ???*8*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* l + ⚠️ pattern without value +- *13* f + ⚠️ circular variable reference +- *14* (null != (???*15* | ???*17*)) + ⚠️ nested operation +- *15* ???*16*["memoizedProps"] + ⚠️ unknown object +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*( + {}, + b, + { + "defaultChecked": ???*20*, + "defaultValue": ???*21*, + "value": ???*22*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *18* ???*19*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*[(???*26* | null | [] | ???*27*)] + ⚠️ unknown object +- *24* ???*25*["memoizedProps"] + ⚠️ unknown object +- *25* arguments[0] + ⚠️ function calls are not analysed yet +- *26* l + ⚠️ pattern without value +- *27* f + ⚠️ circular variable reference +- *28* ???*29*[(???*35* | null | [] | ???*36*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* ???*30*( + {}, + b, + { + "defaultChecked": ???*32*, + "defaultValue": ???*33*, + "value": ???*34*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *30* ???*31*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *31* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* unsupported expression + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* l + ⚠️ pattern without value +- *36* f + ⚠️ circular variable reference +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* h + ⚠️ circular variable reference +- *39* ???*40*["__html"] + ⚠️ unknown object +- *40* h + ⚠️ circular variable reference +- *41* unsupported expression + ⚠️ This value might have side effects +- *42* g + ⚠️ pattern without value + +4059 -> 4065 member call = {}["hasOwnProperty"]((???*0* | null | [] | ???*1*)) +- *0* l + ⚠️ pattern without value +- *1* f + ⚠️ circular variable reference + +4059 -> 4066 conditional = ???*0* +- *0* (???*1* | ???*2*)((???*3* | null | [] | ???*4*)) + ⚠️ non-function callee +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* l + ⚠️ pattern without value +- *4* f + ⚠️ circular variable reference + +4066 -> 4068 member call = ???*0*["push"]((???*1* | null | [] | ???*2*), null) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* l + ⚠️ pattern without value +- *2* f + ⚠️ circular variable reference + +4039 -> 4070 conditional = (null != (???*0* | ???*2*)) +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*( + {}, + b, + { + "defaultChecked": ???*5*, + "defaultValue": ???*6*, + "value": ???*7*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4073 member call = (???*0* | ???*1*)["hasOwnProperty"]((???*7* | null | [] | ???*8*)) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*( + {}, + b, + { + "defaultChecked": ???*4*, + "defaultValue": ???*5*, + "value": ???*6*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* ???*3*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* l + ⚠️ pattern without value +- *8* f + ⚠️ circular variable reference + +4039 -> 4074 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4074 -> 4075 conditional = ("style" === (???*0* | null | [] | ???*1*)) +- *0* l + ⚠️ pattern without value +- *1* f + ⚠️ circular variable reference + +4075 -> 4076 conditional = (???*0* | ???*5* | (???*14* ? (???*23* | ???*28*) : ???*37*) | (???*38* ? ???*39* : ???*41*)) +- *0* ???*1*[(???*3* | null | [] | ???*4*)] + ⚠️ unknown object +- *1* ???*2*["memoizedProps"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* l + ⚠️ pattern without value +- *4* f + ⚠️ circular variable reference +- *5* ???*6*[(???*12* | null | [] | ???*13*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*( + {}, + b, + { + "defaultChecked": ???*9*, + "defaultValue": ???*10*, + "value": ???*11*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *7* ???*8*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* l + ⚠️ pattern without value +- *13* f + ⚠️ circular variable reference +- *14* (null != (???*15* | ???*17*)) + ⚠️ nested operation +- *15* ???*16*["memoizedProps"] + ⚠️ unknown object +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*( + {}, + b, + { + "defaultChecked": ???*20*, + "defaultValue": ???*21*, + "value": ???*22*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *18* ???*19*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*[(???*26* | null | [] | ???*27*)] + ⚠️ unknown object +- *24* ???*25*["memoizedProps"] + ⚠️ unknown object +- *25* arguments[0] + ⚠️ function calls are not analysed yet +- *26* l + ⚠️ pattern without value +- *27* f + ⚠️ circular variable reference +- *28* ???*29*[(???*35* | null | [] | ???*36*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* ???*30*( + {}, + b, + { + "defaultChecked": ???*32*, + "defaultValue": ???*33*, + "value": ???*34*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *30* ???*31*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *31* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* unsupported expression + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* l + ⚠️ pattern without value +- *36* f + ⚠️ circular variable reference +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* h + ⚠️ circular variable reference +- *39* ???*40*["__html"] + ⚠️ unknown object +- *40* h + ⚠️ circular variable reference +- *41* unsupported expression + ⚠️ This value might have side effects + +4076 -> 4078 member call = (???*0* | ???*5* | (???*14* ? (???*23* | ???*28*) : ???*37*) | (???*38* ? ???*39* : ???*41*))["hasOwnProperty"](???*42*) +- *0* ???*1*[(???*3* | null | [] | ???*4*)] + ⚠️ unknown object +- *1* ???*2*["memoizedProps"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* l + ⚠️ pattern without value +- *4* f + ⚠️ circular variable reference +- *5* ???*6*[(???*12* | null | [] | ???*13*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*( + {}, + b, + { + "defaultChecked": ???*9*, + "defaultValue": ???*10*, + "value": ???*11*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *7* ???*8*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* l + ⚠️ pattern without value +- *13* f + ⚠️ circular variable reference +- *14* (null != (???*15* | ???*17*)) + ⚠️ nested operation +- *15* ???*16*["memoizedProps"] + ⚠️ unknown object +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*( + {}, + b, + { + "defaultChecked": ???*20*, + "defaultValue": ???*21*, + "value": ???*22*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *18* ???*19*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*[(???*26* | null | [] | ???*27*)] + ⚠️ unknown object +- *24* ???*25*["memoizedProps"] + ⚠️ unknown object +- *25* arguments[0] + ⚠️ function calls are not analysed yet +- *26* l + ⚠️ pattern without value +- *27* f + ⚠️ circular variable reference +- *28* ???*29*[(???*35* | null | [] | ???*36*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* ???*30*( + {}, + b, + { + "defaultChecked": ???*32*, + "defaultValue": ???*33*, + "value": ???*34*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *30* ???*31*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *31* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* unsupported expression + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* l + ⚠️ pattern without value +- *36* f + ⚠️ circular variable reference +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* h + ⚠️ circular variable reference +- *39* ???*40*["__html"] + ⚠️ unknown object +- *40* h + ⚠️ circular variable reference +- *41* unsupported expression + ⚠️ This value might have side effects +- *42* g + ⚠️ pattern without value + +4076 -> 4080 member call = (???*0* | ???*4* | (???*13* ? ???*14* : ???*16*))["hasOwnProperty"](???*17*) +- *0* ???*1*[(???*2* | null | [] | ???*3*)] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* l + ⚠️ pattern without value +- *3* f + ⚠️ circular variable reference +- *4* ???*5*[(???*11* | null | [] | ???*12*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*( + {}, + b, + { + "defaultChecked": ???*8*, + "defaultValue": ???*9*, + "value": ???*10*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *6* ???*7*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* l + ⚠️ pattern without value +- *12* f + ⚠️ circular variable reference +- *13* k + ⚠️ circular variable reference +- *14* ???*15*["__html"] + ⚠️ unknown object +- *15* k + ⚠️ circular variable reference +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* g + ⚠️ pattern without value + +4076 -> 4083 member call = (???*0* | ???*4* | (???*13* ? ???*14* : ???*16*))["hasOwnProperty"](???*17*) +- *0* ???*1*[(???*2* | null | [] | ???*3*)] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* l + ⚠️ pattern without value +- *3* f + ⚠️ circular variable reference +- *4* ???*5*[(???*11* | null | [] | ???*12*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*( + {}, + b, + { + "defaultChecked": ???*8*, + "defaultValue": ???*9*, + "value": ???*10*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *6* ???*7*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* l + ⚠️ pattern without value +- *12* f + ⚠️ circular variable reference +- *13* k + ⚠️ circular variable reference +- *14* ???*15*["__html"] + ⚠️ unknown object +- *15* k + ⚠️ circular variable reference +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* g + ⚠️ pattern without value + +4076 -> 4089 member call = (null | [] | ???*0*)["push"]( + (???*1* | null | [] | ???*2*), + (???*3* | null | {} | ???*4* | ???*8* | (???*17* ? ???*18* : ???*20*)) +) +- *0* f + ⚠️ circular variable reference +- *1* l + ⚠️ pattern without value +- *2* f + ⚠️ circular variable reference +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* ???*5*[(???*6* | null | [] | ???*7*)] + ⚠️ unknown object +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* l + ⚠️ pattern without value +- *7* f + ⚠️ circular variable reference +- *8* ???*9*[(???*15* | null | [] | ???*16*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*( + {}, + b, + { + "defaultChecked": ???*12*, + "defaultValue": ???*13*, + "value": ???*14*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *10* ???*11*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* l + ⚠️ pattern without value +- *16* f + ⚠️ circular variable reference +- *17* k + ⚠️ circular variable reference +- *18* ???*19*["__html"] + ⚠️ unknown object +- *19* k + ⚠️ circular variable reference +- *20* unsupported expression + ⚠️ This value might have side effects + +4075 -> 4090 conditional = ("dangerouslySetInnerHTML" === (???*0* | null | [] | ???*1*)) +- *0* l + ⚠️ pattern without value +- *1* f + ⚠️ circular variable reference + +4090 -> 4091 conditional = (???*0* | ???*4* | (???*13* ? ???*14* : ???*16*)) +- *0* ???*1*[(???*2* | null | [] | ???*3*)] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* l + ⚠️ pattern without value +- *3* f + ⚠️ circular variable reference +- *4* ???*5*[(???*11* | null | [] | ???*12*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*( + {}, + b, + { + "defaultChecked": ???*8*, + "defaultValue": ???*9*, + "value": ???*10*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *6* ???*7*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* l + ⚠️ pattern without value +- *12* f + ⚠️ circular variable reference +- *13* k + ⚠️ circular variable reference +- *14* ???*15*["__html"] + ⚠️ unknown object +- *15* k + ⚠️ circular variable reference +- *16* unsupported expression + ⚠️ This value might have side effects + +4090 -> 4093 conditional = (???*0* | ???*5* | (???*14* ? (???*23* | ???*28*) : ???*37*) | (???*38* ? ???*39* : ???*41*)) +- *0* ???*1*[(???*3* | null | [] | ???*4*)] + ⚠️ unknown object +- *1* ???*2*["memoizedProps"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* l + ⚠️ pattern without value +- *4* f + ⚠️ circular variable reference +- *5* ???*6*[(???*12* | null | [] | ???*13*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*( + {}, + b, + { + "defaultChecked": ???*9*, + "defaultValue": ???*10*, + "value": ???*11*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *7* ???*8*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* l + ⚠️ pattern without value +- *13* f + ⚠️ circular variable reference +- *14* (null != (???*15* | ???*17*)) + ⚠️ nested operation +- *15* ???*16*["memoizedProps"] + ⚠️ unknown object +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*( + {}, + b, + { + "defaultChecked": ???*20*, + "defaultValue": ???*21*, + "value": ???*22*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *18* ???*19*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*[(???*26* | null | [] | ???*27*)] + ⚠️ unknown object +- *24* ???*25*["memoizedProps"] + ⚠️ unknown object +- *25* arguments[0] + ⚠️ function calls are not analysed yet +- *26* l + ⚠️ pattern without value +- *27* f + ⚠️ circular variable reference +- *28* ???*29*[(???*35* | null | [] | ???*36*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* ???*30*( + {}, + b, + { + "defaultChecked": ???*32*, + "defaultValue": ???*33*, + "value": ???*34*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *30* ???*31*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *31* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* unsupported expression + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* l + ⚠️ pattern without value +- *36* f + ⚠️ circular variable reference +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* h + ⚠️ circular variable reference +- *39* ???*40*["__html"] + ⚠️ unknown object +- *40* h + ⚠️ circular variable reference +- *41* unsupported expression + ⚠️ This value might have side effects + +4090 -> 4096 member call = ???*0*["push"]((???*1* | null | [] | ???*2*), (???*3* | ???*7* | (???*16* ? ???*17* : ???*19*))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* l + ⚠️ pattern without value +- *2* f + ⚠️ circular variable reference +- *3* ???*4*[(???*5* | null | [] | ???*6*)] + ⚠️ unknown object +- *4* arguments[3] + ⚠️ function calls are not analysed yet +- *5* l + ⚠️ pattern without value +- *6* f + ⚠️ circular variable reference +- *7* ???*8*[(???*14* | null | [] | ???*15*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???*9*( + {}, + b, + { + "defaultChecked": ???*11*, + "defaultValue": ???*12*, + "value": ???*13*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *9* ???*10*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* l + ⚠️ pattern without value +- *15* f + ⚠️ circular variable reference +- *16* k + ⚠️ circular variable reference +- *17* ???*18*["__html"] + ⚠️ unknown object +- *18* k + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects + +4090 -> 4097 conditional = ("children" === (???*0* | null | [] | ???*1*)) +- *0* l + ⚠️ pattern without value +- *1* f + ⚠️ circular variable reference + +4097 -> 4099 member call = ???*0*["push"]((???*1* | null | [] | ???*2*), (???*3* | ???*7* | (???*16* ? ???*17* : ???*19*))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* l + ⚠️ pattern without value +- *2* f + ⚠️ circular variable reference +- *3* ???*4*[(???*5* | null | [] | ???*6*)] + ⚠️ unknown object +- *4* arguments[3] + ⚠️ function calls are not analysed yet +- *5* l + ⚠️ pattern without value +- *6* f + ⚠️ circular variable reference +- *7* ???*8*[(???*14* | null | [] | ???*15*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???*9*( + {}, + b, + { + "defaultChecked": ???*11*, + "defaultValue": ???*12*, + "value": ???*13*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *9* ???*10*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* l + ⚠️ pattern without value +- *15* f + ⚠️ circular variable reference +- *16* k + ⚠️ circular variable reference +- *17* ???*18*["__html"] + ⚠️ unknown object +- *18* k + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects + +4097 -> 4101 member call = {}["hasOwnProperty"]((???*0* | null | [] | ???*1*)) +- *0* l + ⚠️ pattern without value +- *1* f + ⚠️ circular variable reference + +4097 -> 4102 conditional = ???*0* +- *0* (???*1* | ???*2*)((???*3* | null | [] | ???*4*)) + ⚠️ non-function callee +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* l + ⚠️ pattern without value +- *4* f + ⚠️ circular variable reference + +4102 -> 4103 call = (...) => undefined("scroll", (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +4102 -> 4105 member call = ???*0*["push"]((???*1* | null | [] | ???*2*), (???*3* | ???*7* | (???*16* ? ???*17* : ???*19*))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* l + ⚠️ pattern without value +- *2* f + ⚠️ circular variable reference +- *3* ???*4*[(???*5* | null | [] | ???*6*)] + ⚠️ unknown object +- *4* arguments[3] + ⚠️ function calls are not analysed yet +- *5* l + ⚠️ pattern without value +- *6* f + ⚠️ circular variable reference +- *7* ???*8*[(???*14* | null | [] | ???*15*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???*9*( + {}, + b, + { + "defaultChecked": ???*11*, + "defaultValue": ???*12*, + "value": ???*13*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *9* ???*10*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* l + ⚠️ pattern without value +- *15* f + ⚠️ circular variable reference +- *16* k + ⚠️ circular variable reference +- *17* ???*18*["__html"] + ⚠️ unknown object +- *18* k + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects + +4039 -> 4107 member call = ???*0*["push"]( + "style", + (???*1* | null | {} | ???*2* | ???*6* | (???*15* ? ???*16* : ???*18*)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*[(???*4* | null | [] | ???*5*)] + ⚠️ unknown object +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* l + ⚠️ pattern without value +- *5* f + ⚠️ circular variable reference +- *6* ???*7*[(???*13* | null | [] | ???*14*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*( + {}, + b, + { + "defaultChecked": ???*10*, + "defaultValue": ???*11*, + "value": ???*12*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *8* ???*9*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* l + ⚠️ pattern without value +- *14* f + ⚠️ circular variable reference +- *15* k + ⚠️ circular variable reference +- *16* ???*17*["__html"] + ⚠️ unknown object +- *17* k + ⚠️ circular variable reference +- *18* unsupported expression + ⚠️ This value might have side effects + +0 -> 4111 conditional = !((false | true)) + +4111 -> 4116 conditional = (null === (null | ???*0* | ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["tail"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +4111 -> 4122 conditional = (null === (null | ???*0* | ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["tail"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +4122 -> 4124 conditional = (???*0* | ???*1* | (null === ???*3*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["tail"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["tail"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4133 conditional = ((null !== ???*0*) | (???*2* === ???*5*)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["child"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["child"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4151 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4153 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4155 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4156 call = (...) => undefined() + +0 -> 4157 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4159 call = (...) => undefined() + +0 -> 4160 call = (...) => undefined({"current": false}) + +0 -> 4161 call = (...) => undefined({"current": {}}) + +0 -> 4162 call = (...) => undefined() + +0 -> 4168 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4168 -> 4169 call = (...) => (!(1) | ???*0* | !(0))(???*1*) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4168 -> 4170 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4170 -> 4176 call = (...) => undefined((null | [???*0*])) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4177 call = (???*0* | (...) => undefined)(???*1*, ???*2*) +- *0* Bj + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4178 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4179 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4181 call = (...) => a(({} | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +0 -> 4184 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4184 -> 4185 call = (???*0* | (...) => undefined)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* Cj + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +4184 -> 4190 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4190 -> 4192 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4192 -> 4193 free var = FreeVar(Error) + +4192 -> 4194 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(166) + +4192 -> 4195 call = ???*0*( + `Minified React error #${166}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${166}` + ⚠️ nested operation + +4190 -> 4196 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4184 -> 4198 call = (...) => a(({} | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +4184 -> 4199 call = (...) => (!(1) | ???*0* | !(0))(???*1*) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4184 -> 4200 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4207 call = (...) => undefined("cancel", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4208 call = (...) => undefined("close", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4209 call = (...) => undefined("load", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4212 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4213 call = (...) => undefined("error", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4214 call = (...) => undefined("error", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4215 call = (...) => undefined("load", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4216 call = (...) => undefined("toggle", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4217 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4218 call = (...) => undefined("invalid", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4221 call = (...) => undefined("invalid", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4222 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4223 call = (...) => undefined("invalid", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4224 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4226 member call = ???*0*["hasOwnProperty"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4227 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4227 -> 4229 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4229 -> 4230 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4230 -> 4234 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +4230 -> 4238 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +4229 -> 4240 member call = {}["hasOwnProperty"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4229 -> 4241 call = (...) => undefined("scroll", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4242 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4243 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*, true) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4244 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4245 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4251 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4253 call = (...) => ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" +)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4254 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4254 -> 4255 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4255 -> 4257 member call = ???*0*["createElement"]("div") +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4255 -> 4261 member call = ???*0*["removeChild"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4255 -> 4263 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4263 -> 4266 member call = ???*0*["createElement"](???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +4263 -> 4268 member call = ???*0*["createElement"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4263 -> 4270 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4254 -> 4276 member call = ???*0*["createElementNS"](???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4279 call = (???*0* | (...) => (undefined | FreeVar(undefined)))(???*1*, ???*2*, false, false) +- *0* Aj + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4281 call = (...) => (undefined | ("string" === typeof(b["is"])) | !(1) | !(0))(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4282 call = (...) => undefined("cancel", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4283 call = (...) => undefined("close", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4284 call = (...) => undefined("load", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4287 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4288 call = (...) => undefined("error", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4289 call = (...) => undefined("error", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4290 call = (...) => undefined("load", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4291 call = (...) => undefined("toggle", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4292 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4293 call = (...) => A( + {}, + b, + { + "defaultChecked": ???*0*, + "defaultValue": ???*1*, + "value": ???*2*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } +)(???*3*, ???*4*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4294 call = (...) => undefined("invalid", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4297 call = ???*0*({}, ???*2*, {"value": ???*3*}) +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +4200 -> 4298 call = (...) => undefined("invalid", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4299 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4300 call = (...) => A( + {}, + b, + { + "value": ???*0*, + "defaultValue": ???*1*, + "children": `${a["_wrapperState"]["initialValue"]}` + } +)(???*2*, ???*3*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4301 call = (...) => undefined("invalid", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4302 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4304 member call = ???*0*["hasOwnProperty"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4305 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4305 -> 4307 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4307 -> 4308 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4307 -> 4309 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4309 -> 4310 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4309 -> 4312 call = ???*0*(???*2*, ???*3*) +- *0* ???*1*(*anonymous function 13608*) + ⚠️ unknown callee +- *1* *anonymous function 13449* + ⚠️ no value of this variable analysed +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +4309 -> 4313 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4313 -> 4314 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4314 -> 4315 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4314 -> 4316 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4313 -> 4318 member call = {}["hasOwnProperty"](???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4313 -> 4319 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4319 -> 4320 call = (...) => undefined("scroll", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4319 -> 4321 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4322 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4323 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*, false) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4324 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4325 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4329 call = (...) => (undefined | a | "")(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4330 member call = ???*0*["setAttribute"]("value", ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4200 -> 4334 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4334 -> 4336 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*, ???*2*, false) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +4334 -> 4340 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*, ???*2*, true) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4348 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4350 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4350 -> 4352 call = (???*0* | (...) => undefined)(???*1*, ???*2*, ???*3*, ???*4*) +- *0* Dj + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +4350 -> 4354 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4354 -> 4355 free var = FreeVar(Error) + +4354 -> 4356 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(166) + +4354 -> 4357 call = ???*0*( + `Minified React error #${166}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${166}` + ⚠️ nested operation + +4350 -> 4359 call = (...) => a(({} | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +4350 -> 4361 call = (...) => a(({} | ???*0*)) +- *0* unknown mutation + ⚠️ This value might have side effects + +4350 -> 4362 call = (...) => (!(1) | ???*0* | !(0))(???*1*) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4350 -> 4363 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4363 -> 4371 call = (...) => undefined(???*0*, ???*1*, (0 !== ???*2*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +4363 -> 4376 call = (...) => undefined(???*0*, ???*1*, (0 !== ???*2*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +4363 -> 4380 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4363 -> 4382 member call = ???*0*["createTextNode"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4385 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4386 call = (...) => undefined({"current": 0}) + +0 -> 4391 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4391 -> 4394 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4394 -> 4395 call = (...) => undefined() + +4394 -> 4396 call = (...) => undefined() + +4394 -> 4398 call = (...) => (!(1) | ???*0* | !(0))(???*1*) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4394 -> 4400 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4400 -> 4401 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4401 -> 4402 free var = FreeVar(Error) + +4401 -> 4403 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(318) + +4401 -> 4404 call = ???*0*( + `Minified React error #${318}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${318}` + ⚠️ nested operation + +4400 -> 4406 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4400 -> 4408 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4408 -> 4409 free var = FreeVar(Error) + +4408 -> 4410 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(317) + +4408 -> 4411 call = ???*0*( + `Minified React error #${317}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${317}` + ⚠️ nested operation + +4400 -> 4413 call = (...) => undefined() + +4394 -> 4417 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4394 -> 4418 call = (...) => undefined((null | [???*0*])) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +4391 -> 4419 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4422 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 4429 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4429 -> 4430 call = (...) => undefined() + +0 -> 4433 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4434 call = (...) => undefined() + +0 -> 4435 call = (???*0* | (...) => undefined)(???*1*, ???*2*) +- *0* Bj + ⚠️ pattern without value +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4438 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4439 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4442 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4443 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4445 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4446 call = (...) => undefined() + +0 -> 4447 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4448 call = (...) => undefined({"current": 0}) + +0 -> 4450 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4450 -> 4451 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4454 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4454 -> 4455 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4455 -> 4456 call = (...) => undefined(???*0*, false) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4455 -> 4458 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4458 -> 4460 call = (...) => (b | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4458 -> 4461 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4461 -> 4463 call = (...) => undefined(???*0*, false) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4461 -> 4471 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4471 -> 4499 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4461 -> 4504 call = (...) => undefined({"current": 0}, ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +4455 -> 4508 call = module["unstable_now"]() + +4455 -> 4510 call = (...) => undefined(???*0*, false) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4454 -> 4512 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4512 -> 4513 call = (...) => (b | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4512 -> 4518 call = (...) => undefined(???*0*, true) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4512 -> 4522 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4512 -> 4523 call = module["unstable_now"]() + +4512 -> 4526 call = (...) => undefined(???*0*, false) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4454 -> 4529 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4529 -> 4534 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4539 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4539 -> 4545 call = module["unstable_now"]() + +4539 -> 4548 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4539 -> 4549 call = (...) => undefined({"current": 0}, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4550 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4551 call = (...) => undefined() + +0 -> 4556 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4556 -> 4557 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4556 -> 4560 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4561 free var = FreeVar(Error) + +0 -> 4563 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(156, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4564 call = ???*0*(???*1*) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4565 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 4568 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 4569 call = (...) => undefined() + +0 -> 4572 call = (...) => undefined() + +0 -> 4573 call = (...) => undefined({"current": false}) + +0 -> 4574 call = (...) => undefined({"current": {}}) + +0 -> 4575 call = (...) => undefined() + +0 -> 4577 conditional = ((0 !== ???*0*) | (0 === ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 4579 call = (...) => undefined(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 4580 call = (...) => undefined({"current": 0}) + +0 -> 4583 conditional = ((null !== (???*0* | ???*1*)) | (null !== ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["flags"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["dehydrated"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +4583 -> 4585 conditional = (null === ???*0*) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +4585 -> 4586 free var = FreeVar(Error) + +4585 -> 4587 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(340) + +4585 -> 4588 call = ???*0*( + `Minified React error #${340}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${340}` + ⚠️ nested operation + +4583 -> 4589 call = (...) => undefined() + +0 -> 4592 call = (...) => undefined({"current": 0}) + +0 -> 4593 call = (...) => undefined() + +0 -> 4596 call = (...) => undefined(???*0*) +- *0* ???*1*["_context"] + ⚠️ unknown object +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 4597 call = (...) => undefined() + +0 -> 4598 free var = FreeVar(WeakSet) + +0 -> 4599 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(WeakSet) + ⚠️ unknown global + ⚠️ This value might have side effects + +4599 -> 4600 free var = FreeVar(WeakSet) + +4599 -> 4601 free var = FreeVar(Set) + +0 -> 4603 conditional = (null !== ???*0*) +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4603 -> 4604 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +4604 -> 4605 call = ???*0*(null) +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4604 -> 4606 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* d + ⚠️ pattern without value + +0 -> 4608 call = ???*0*() +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 4609 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* d + ⚠️ pattern without value + +0 -> 4610 call = (...) => b() + +0 -> 4611 call = (...) => ( + && b + && ( + || ( + && ("input" === b) + && ( + || ("text" === a["type"]) + || ("search" === a["type"]) + || ("tel" === a["type"]) + || ("url" === a["type"]) + || ("password" === a["type"]) + ) + ) + || ("textarea" === b) + || ("true" === a["contentEditable"]) + ) +)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4612 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4612 -> 4617 free var = FreeVar(window) + +4612 -> 4620 member call = ???*0*["getSelection"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4612 -> 4622 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4622 -> 4637 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4643 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +4643 -> 4645 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4645 -> 4652 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4652 -> 4654 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4645 -> 4655 member call = ???*0*["getSnapshotBeforeUpdate"](???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +4643 -> 4660 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4660 -> 4666 member call = ???*0*["removeChild"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +4643 -> 4667 free var = FreeVar(Error) + +4643 -> 4668 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(163) + +4643 -> 4669 call = ???*0*( + `Minified React error #${163}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${163}` + ⚠️ nested operation + +0 -> 4671 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* F + ⚠️ pattern without value + +0 -> 4673 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4678 conditional = (null !== (???*0* | ???*2*)) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? ???*5* : null) + ⚠️ nested operation +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* d + ⚠️ circular variable reference +- *5* ???*6*["lastEffect"] + ⚠️ unknown object +- *6* d + ⚠️ circular variable reference + +0 -> 4680 conditional = (null !== (???*0* | ???*2*)) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? ???*5* : null) + ⚠️ nested operation +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* d + ⚠️ circular variable reference +- *5* ???*6*["lastEffect"] + ⚠️ unknown object +- *6* d + ⚠️ circular variable reference + +4680 -> 4683 conditional = (???*0* === ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4683 -> 4686 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*4*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["destroy"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["destroy"] + ⚠️ unknown object +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* e + ⚠️ circular variable reference + +0 -> 4689 conditional = (null !== (???*0* | ???*1* | ???*3*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* b + ⚠️ circular variable reference +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* b + ⚠️ circular variable reference +- *6* ???*7*["lastEffect"] + ⚠️ unknown object +- *7* b + ⚠️ circular variable reference + +0 -> 4691 conditional = (null !== (???*0* | ???*1* | ???*3*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* b + ⚠️ circular variable reference +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* b + ⚠️ circular variable reference +- *6* ???*7*["lastEffect"] + ⚠️ unknown object +- *7* b + ⚠️ circular variable reference + +4691 -> 4694 conditional = (???*0* === ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4694 -> 4697 call = (???*0* | ???*2*)() +- *0* ???*1*["create"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["create"] + ⚠️ unknown object +- *3* ???*4*["next"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4700 conditional = (null !== ???*0*) +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4700 -> 4703 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +4703 -> 4704 call = ???*0*((???*2* | ???*3*)) +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference + +0 -> 4708 call = (...) => undefined(???*0*) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4733 call = (...) => ((5 === a["tag"]) || (3 === a["tag"]) || (4 === a["tag"]))(???*0*) +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4745 conditional = ((null === ???*0*) | (4 === ???*2*)) +- *0* ???*1*["child"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4750 conditional = !(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 4753 conditional = ((5 === ???*0*) | (6 === ???*2*)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +4753 -> 4755 conditional = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["parentNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +4755 -> 4757 conditional = (8 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +4757 -> 4760 member call = ???*0*["insertBefore"]((???*2* | ???*3*), (???*5* | ???*6*)) +- *0* ???*1*["parentNode"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["parentNode"] + ⚠️ unknown object +- *7* arguments[2] + ⚠️ function calls are not analysed yet + +4757 -> 4762 member call = (???*0* | ???*1*)["insertBefore"]((???*3* | ???*4*), (???*6* | ???*7*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactRootContainer"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["parentNode"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet + +4755 -> 4764 conditional = (8 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +4764 -> 4767 member call = (???*0* | ???*1*)["insertBefore"]((???*3* | ???*4*), (???*6* | ???*7*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["parentNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["_reactRootContainer"] + ⚠️ unknown object +- *8* c + ⚠️ circular variable reference + +4764 -> 4769 member call = (???*0* | ???*1*)["appendChild"]((???*3* | ???*4*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["parentNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference + +4753 -> 4774 conditional = ((4 !== ???*0*) | ???*2*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (null !== a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +4774 -> 4775 call = (...) => undefined((???*0* | ???*1*), (???*3* | ???*4*), (???*6* | ???*7*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["parentNode"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["_reactRootContainer"] + ⚠️ unknown object +- *8* c + ⚠️ circular variable reference + +4774 -> 4777 call = (...) => undefined((???*0* | ???*1*), (???*3* | ???*4*), (???*6* | ???*7*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["parentNode"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["_reactRootContainer"] + ⚠️ unknown object +- *8* c + ⚠️ circular variable reference + +0 -> 4780 conditional = ((5 === ???*0*) | (6 === ???*2*)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +4780 -> 4782 conditional = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +4782 -> 4784 member call = ???*0*["insertBefore"]((???*1* | ???*2*), ???*4*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +4782 -> 4786 member call = ???*0*["appendChild"]((???*1* | ???*2*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +4780 -> 4788 conditional = ((4 !== ???*0*) | ???*2*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (null !== a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +4788 -> 4789 call = (...) => undefined((???*0* | ???*1*), ???*3*, ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +4788 -> 4791 call = (...) => undefined((???*0* | ???*1*), ???*3*, ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 4794 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["child"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4797 conditional = (null | ???*0* | ("function" === ???*1*)) +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* typeof((null["onCommitFiberUnmount"] | ???*2*)) + ⚠️ nested operation +- *2* ???*3*["onCommitFiberUnmount"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects + +4797 -> 4799 member call = (null | ???*0*)["onCommitFiberUnmount"]((null | ???*1*), (???*3* | ???*4*)) +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["inject"](vl) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* c + ⚠️ circular variable reference + +0 -> 4801 call = (...) => undefined((???*0* | ???*1*), ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 4802 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4803 conditional = (false | ???*0* | ???*1* | ???*2* | true) +- *0* Yj + ⚠️ circular variable reference +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["next"] + ⚠️ unknown object +- *3* e + ⚠️ circular variable reference + +4803 -> 4806 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4806 -> 4809 member call = ???*0*["removeChild"]((???*1* | ???*2*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference + +4806 -> 4811 member call = ???*0*["removeChild"]((???*1* | ???*2*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference + +4803 -> 4814 member call = ???*0*["removeChild"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 4815 conditional = (false | ???*0* | ???*1* | ???*2* | true) +- *0* Yj + ⚠️ circular variable reference +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["next"] + ⚠️ unknown object +- *3* e + ⚠️ circular variable reference + +4815 -> 4818 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4818 -> 4820 call = (...) => (undefined | FreeVar(undefined))(???*0*, (???*1* | ???*2*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference + +4818 -> 4822 call = (...) => (undefined | FreeVar(undefined))(???*0*, (???*1* | ???*2*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference + +4815 -> 4823 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4815 -> 4825 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 4828 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4831 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4831 -> 4835 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +4835 -> 4836 call = (...) => undefined( + (???*0* | ???*1*), + ???*3*, + (false["destroy"] | ???*4* | true["destroy"] | ???*6*) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["destroy"] + ⚠️ unknown object +- *5* e + ⚠️ circular variable reference +- *6* ???*7*["destroy"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects + +4835 -> 4837 call = (...) => undefined( + (???*0* | ???*1*), + ???*3*, + (false["destroy"] | ???*4* | true["destroy"] | ???*6*) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["destroy"] + ⚠️ unknown object +- *5* e + ⚠️ circular variable reference +- *6* ???*7*["destroy"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 4839 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4840 call = (...) => undefined((???*0* | ???*1*), ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 4843 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4843 -> 4849 member call = ???*0*["componentWillUnmount"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4843 -> 4850 call = (...) => undefined((???*0* | ???*1*), ???*3*, ???*4*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* h + ⚠️ pattern without value + +0 -> 4851 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4852 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4855 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4856 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4857 call = (...) => undefined(???*0*, ???*1*, (???*2* | ???*3*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +0 -> 4859 conditional = (null !== ???*0*) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4859 -> 4864 member call = ???*0*["forEach"]((...) => undefined) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4864 -> 4866 member call = (...) => undefined["bind"](null, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4864 -> 4868 member call = (???*0* | ???*2*)["has"](???*3*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +4864 -> 4870 member call = (???*0* | ???*2*)["add"](???*3*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +4864 -> 4872 member call = ???*0*["then"]((...) => undefined["bind"](null, ???*1*, ???*2*), (...) => undefined["bind"](null, ???*3*, ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4874 conditional = (null !== ???*0*) +- *0* ???*1*["deletions"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +4874 -> 4884 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4884 -> 4885 free var = FreeVar(Error) + +4884 -> 4886 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(160) + +4884 -> 4887 call = ???*0*( + `Minified React error #${160}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${160}` + ⚠️ nested operation + +4874 -> 4888 call = (...) => undefined(???*0*, (???*1* | ???*2*), ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["child"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference +- *4* ???*5*[d] + ⚠️ unknown object +- *5* ???*6*["deletions"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet + +4874 -> 4892 call = (...) => undefined(???*0*, (???*3* | ???*4*), ???*6*) +- *0* ???*1*[d] + ⚠️ unknown object +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["child"] + ⚠️ unknown object +- *5* b + ⚠️ circular variable reference +- *6* l + ⚠️ pattern without value + +0 -> 4895 call = (...) => undefined((???*0* | ???*1*), ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* b + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4900 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4901 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4903 call = (...) => undefined(3, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4904 call = (...) => undefined(3, ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4906 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* t + ⚠️ pattern without value + +0 -> 4908 call = (...) => undefined(5, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4910 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* t + ⚠️ pattern without value + +0 -> 4911 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4912 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4914 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4915 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4916 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4918 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 4921 call = (...) => (undefined | FreeVar(undefined))((???*0* | ???*2*), "") +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +0 -> 4923 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* t + ⚠️ pattern without value + +0 -> 4925 conditional = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null != e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +4925 -> 4927 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4925 -> 4932 conditional = (null !== (???*0* | ???*2*)) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["memoizedProps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +4932 -> 4935 call = (...) => undefined((???*0* | ???*2*), (???*4* | (null !== (???*6* | ???*9*)) | ???*12*)) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["memoizedProps"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* ???*8*["stateNode"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* ???*14*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects + +4932 -> 4936 call = (...) => (undefined | ("string" === typeof(b["is"])) | !(1) | !(0))((???*0* | ???*2*), ???*4*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +4932 -> 4937 call = (...) => (undefined | ("string" === typeof(b["is"])) | !(1) | !(0))((???*0* | ???*2*), (???*4* | (null !== (???*6* | ???*9*)) | ???*12*)) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["memoizedProps"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* ???*8*["stateNode"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* ???*14*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects + +4932 -> 4941 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4941 -> 4942 call = (...) => undefined((???*0* | ???*2*), (???*4* | ???*7* | ???*8*)) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*[(g + 1)] + ⚠️ unknown object +- *5* ???*6*["updateQueue"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[0] + ⚠️ function calls are not analysed yet + +4941 -> 4943 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4943 -> 4944 call = ???*0*((???*2* | ???*4*), (???*6* | ???*9* | ???*10*)) +- *0* ???*1*(*anonymous function 13608*) + ⚠️ unknown callee +- *1* *anonymous function 13449* + ⚠️ no value of this variable analysed +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*[(g + 1)] + ⚠️ unknown object +- *7* ???*8*["updateQueue"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet + +4943 -> 4945 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4945 -> 4946 call = (...) => (undefined | FreeVar(undefined))((???*0* | ???*2*), (???*4* | ???*7* | ???*8*)) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*[(g + 1)] + ⚠️ unknown object +- *5* ???*6*["updateQueue"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[0] + ⚠️ function calls are not analysed yet + +4945 -> 4947 call = (...) => undefined((???*0* | ???*2*), ???*4*, (???*5* | ???*8* | ???*9*), ???*10*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* ???*6*[(g + 1)] + ⚠️ unknown object +- *6* ???*7*["updateQueue"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* max number of linking steps reached + ⚠️ This value might have side effects + +4932 -> 4948 call = (...) => (undefined | FreeVar(undefined))((???*0* | ???*2*), (???*4* | (null !== (???*6* | ???*9*)) | ???*12*)) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["memoizedProps"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* ???*8*["stateNode"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* ???*14*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects + +4932 -> 4949 call = (...) => undefined((???*0* | ???*2*), (???*4* | (null !== (???*6* | ???*9*)) | ???*12*)) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["memoizedProps"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["memoizedState"] + ⚠️ unknown object +- *7* ???*8*["stateNode"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* ???*14*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects + +4932 -> 4956 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4956 -> 4958 call = (...) => (undefined | FreeVar(undefined))((???*0* | ???*2*), !(???*4*), ???*12*, false) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* !((???*5* | ???*8*)) + ⚠️ nested operation +- *5* ???*6*["multiple"] + ⚠️ unknown object +- *6* ???*7*["memoizedProps"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* ???*9*["multiple"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* max number of linking steps reached + ⚠️ This value might have side effects + +4956 -> 4961 conditional = (null != (???*0* | ???*3*)) +- *0* ???*1*["defaultValue"] + ⚠️ unknown object +- *1* ???*2*["memoizedProps"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["defaultValue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects + +4961 -> 4964 call = (...) => (undefined | FreeVar(undefined))( + (???*0* | ???*2*), + !(???*4*), + (???*12* | (null !== (???*15* | ???*18*))["defaultValue"] | ???*21*), + true +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* !((???*5* | ???*8*)) + ⚠️ nested operation +- *5* ???*6*["multiple"] + ⚠️ unknown object +- *6* ???*7*["memoizedProps"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* ???*9*["multiple"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["defaultValue"] + ⚠️ unknown object +- *13* ???*14*["memoizedProps"] + ⚠️ unknown object +- *14* arguments[0] + ⚠️ function calls are not analysed yet +- *15* ???*16*["memoizedState"] + ⚠️ unknown object +- *16* ???*17*["stateNode"] + ⚠️ unknown object +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* ???*20*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["defaultValue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* ???*23*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *23* ???*24*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects + +4961 -> 4967 conditional = (???*0* | (null !== (???*3* | ???*6*))["multiple"] | ???*9*) +- *0* ???*1*["multiple"] + ⚠️ unknown object +- *1* ???*2*["memoizedProps"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*["multiple"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* ???*12*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects + +4961 -> 4968 call = (...) => (undefined | FreeVar(undefined))((???*0* | ???*2*), !(???*4*), ((???*12* | ???*15*) ? [] : ""), false) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* !((???*5* | ???*8*)) + ⚠️ nested operation +- *5* ???*6*["multiple"] + ⚠️ unknown object +- *6* ???*7*["memoizedProps"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* ???*9*["multiple"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["multiple"] + ⚠️ unknown object +- *13* ???*14*["memoizedProps"] + ⚠️ unknown object +- *14* arguments[0] + ⚠️ function calls are not analysed yet +- *15* ???*16*["multiple"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* ???*17*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* ???*18*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects + +4932 -> 4971 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* t + ⚠️ pattern without value + +0 -> 4972 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4973 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4975 conditional = (null === ???*0*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +4975 -> 4976 free var = FreeVar(Error) + +4975 -> 4977 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(162) + +4975 -> 4978 call = ???*0*( + `Minified React error #${162}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${162}` + ⚠️ nested operation + +0 -> 4983 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* t + ⚠️ pattern without value + +0 -> 4984 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4985 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4988 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4988 -> 4990 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +4988 -> 4992 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* t + ⚠️ pattern without value + +0 -> 4993 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4994 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4995 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4996 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5005 call = module["unstable_now"]() + +0 -> 5006 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5009 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5010 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5011 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5016 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5016 -> 5021 call = (...) => undefined(4, ???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5016 -> 5023 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5016 -> 5026 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5026 -> 5033 member call = ???*0*["componentWillUnmount"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5026 -> 5034 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* t + ⚠️ pattern without value + +5016 -> 5036 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5016 -> 5038 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5038 -> 5039 call = (...) => undefined((???*0* | ???*3* | ???*4*)) +- *0* ???*1*[(g + 1)] + ⚠️ unknown object +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +5016 -> 5040 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5040 -> 5042 call = (...) => undefined((???*0* | ???*3* | ???*4*)) +- *0* ???*1*[(g + 1)] + ⚠️ unknown object +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5045 conditional = (5 === (???*0* | ???*4*)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* ???*2*[(g + 1)] + ⚠️ unknown object +- *2* ???*3*["updateQueue"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +5045 -> 5046 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5046 -> 5048 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5048 -> 5051 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | ???*4*)) + ⚠️ nested operation +- *1* ???*2*["setProperty"] + ⚠️ unknown object +- *2* ???*3*["memoizedProps"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["setProperty"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects + +5051 -> 5053 member call = (???*0* | (null !== (???*2* | ???*5*)) | ???*8*)["setProperty"]("display", "none", "important") +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["memoizedState"] + ⚠️ unknown object +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* ???*9*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects + +5048 -> 5059 member call = (???*0* | ???*2*)["hasOwnProperty"]("display") +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["memoizedProps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +5048 -> 5060 conditional = ((???*0* !== (???*1* | ???*3*)) | (null !== (???*6* | ???*8*)) | ???*11* | ???*14*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["memoizedProps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*["updateQueue"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* ???*9*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["memoizedProps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["hasOwnProperty"]("display") + ⚠️ unknown callee object +- *12* ???*13*["updateQueue"] + ⚠️ unknown object +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["hasOwnProperty"]("display") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *15* ???*16*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* ???*17*["memoizedProps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects + +5048 -> 5064 call = (...) => (((null == b) || ("boolean" === typeof(b)) || ("" === b)) ? "" : ((c || ("number" !== typeof(b)) || (0 === b) || (pb["hasOwnProperty"](a) && pb[a])) ? `${b}`["trim"]() : `${b}px`))("display", ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5046 -> 5066 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* t + ⚠️ pattern without value + +5045 -> 5068 conditional = (6 === (???*0* | ???*4*)) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* ???*2*[(g + 1)] + ⚠️ unknown object +- *2* ???*3*["updateQueue"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +5068 -> 5069 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5069 -> 5072 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5069 -> 5075 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* t + ⚠️ pattern without value + +5068 -> 5080 conditional = ( + | (22 !== (???*0* | ???*4*)) + | (23 !== (???*6* | ???*10*)) + | (null === (???*12* | ???*16*)) + | ((???*18* | ???*21* | ???*22*) === ???*23*) + | (null !== (???*24* | ???*28*)) +) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* ???*2*[(g + 1)] + ⚠️ unknown object +- *2* ???*3*["updateQueue"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*["tag"] + ⚠️ unknown object +- *7* ???*8*[(g + 1)] + ⚠️ unknown object +- *8* ???*9*["updateQueue"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* ???*13*["memoizedState"] + ⚠️ unknown object +- *13* ???*14*[(g + 1)] + ⚠️ unknown object +- *14* ???*15*["updateQueue"] + ⚠️ unknown object +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* ???*17*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* ???*19*[(g + 1)] + ⚠️ unknown object +- *19* ???*20*["updateQueue"] + ⚠️ unknown object +- *20* arguments[0] + ⚠️ function calls are not analysed yet +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* arguments[0] + ⚠️ function calls are not analysed yet +- *24* ???*25*["child"] + ⚠️ unknown object +- *25* ???*26*[(g + 1)] + ⚠️ unknown object +- *26* ???*27*["updateQueue"] + ⚠️ unknown object +- *27* arguments[0] + ⚠️ function calls are not analysed yet +- *28* ???*29*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* unsupported expression + ⚠️ This value might have side effects + +0 -> 5092 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5093 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5094 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5095 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5096 call = (...) => undefined(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5099 call = (...) => ((5 === a["tag"]) || (3 === a["tag"]) || (4 === a["tag"]))(???*0*) +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5101 free var = FreeVar(Error) + +0 -> 5102 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(160) + +0 -> 5103 call = ???*0*( + `Minified React error #${160}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${160}` + ⚠️ nested operation + +0 -> 5107 call = (...) => (undefined | FreeVar(undefined))(???*0*, "") +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5109 call = (...) => (undefined | null | a["stateNode"])(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5110 call = (...) => undefined(???*0*, (undefined | null | ???*1*), ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* ???*5*["return"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5113 call = (...) => (undefined | null | a["stateNode"])(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5114 call = (...) => undefined(???*0*, (undefined | null | ???*1*), ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["containerInfo"] + ⚠️ unknown object +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["return"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5115 free var = FreeVar(Error) + +0 -> 5116 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(161) + +0 -> 5117 call = ???*0*( + `Minified React error #${161}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${161}` + ⚠️ nested operation + +0 -> 5119 call = (...) => undefined(???*0*, ???*1*, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* k + ⚠️ pattern without value + +0 -> 5122 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 5126 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5126 -> 5128 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5128 -> 5131 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5131 -> 5135 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5135 -> 5136 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5135 -> 5137 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5137 -> 5139 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5128 -> 5140 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +5126 -> 5142 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +5126 -> 5144 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5144 -> 5146 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 5148 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5148 -> 5151 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5151 -> 5153 call = (...) => undefined(5, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5151 -> 5156 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5156 -> 5157 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5157 -> 5159 member call = ???*0*["componentDidMount"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5157 -> 5162 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5162 -> 5166 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5157 -> 5170 member call = ???*0*["componentDidUpdate"](???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +5151 -> 5172 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5151 -> 5174 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5174 -> 5176 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5174 -> 5183 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5151 -> 5186 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5186 -> 5191 member call = ???*0*["focus"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5151 -> 5196 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5196 -> 5198 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5198 -> 5200 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5200 -> 5202 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5151 -> 5203 free var = FreeVar(Error) + +5151 -> 5204 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(163) + +5151 -> 5205 call = ???*0*( + `Minified React error #${163}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${163}` + ⚠️ nested operation + +5148 -> 5207 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5148 -> 5209 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* r + ⚠️ pattern without value + +0 -> 5211 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5216 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5222 call = (...) => undefined(4, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5223 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* k + ⚠️ pattern without value + +0 -> 5226 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5226 -> 5229 member call = ???*0*["componentDidMount"]() +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5226 -> 5230 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* k + ⚠️ pattern without value + +0 -> 5232 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5233 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* k + ⚠️ pattern without value + +0 -> 5235 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5236 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* k + ⚠️ pattern without value + +0 -> 5238 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* k + ⚠️ pattern without value + +0 -> 5240 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5245 free var = FreeVar(Math) + +0 -> 5249 call = (...) => {"current": a}(0) + +0 -> 5250 free var = FreeVar(Infinity) + +0 -> 5251 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5251 -> 5252 call = module["unstable_now"]() + +5251 -> 5253 conditional = (???*0* !== (???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation + +5253 -> 5254 call = module["unstable_now"]() + +0 -> 5257 conditional = (null !== module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"]) + +5257 -> 5258 call = (...) => a() + +0 -> 5260 free var = FreeVar(window) + +0 -> 5261 conditional = (???*0* === (???*1* | 0 | 1 | ???*2* | 4 | ???*3* | ???*8*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* C + ⚠️ circular variable reference +- *3* ((???*4* | ???*6*) ? ???*7* : 4) + ⚠️ nested operation +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* C + ⚠️ circular variable reference +- *8* ???*9*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +5261 -> 5263 call = (...) => (undefined | 1 | 4 | 16 | 536870912)( + ( + | ???*0* + | 0["type"] + | 1["type"] + | 4["type"] + | ((???*2* | ???*4*) ? ???*5* : 4)["type"] + | (???*6* ? 16 : (???*7* | null | ???*14* | ???*15*))["type"] + | ???*17* + | (???*20* ? 16 : (undefined | 1 | 4 | 16 | 536870912))["type"] + ) +) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* C + ⚠️ circular variable reference +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* (???*8* ? ???*9* : 1) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 4) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? 16 : 536870912) + ⚠️ nested operation +- *12* (0 !== ???*13*) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* arguments[0] + ⚠️ function calls are not analysed yet +- *15* ???*16*["value"] + ⚠️ unknown object +- *16* arguments[1] + ⚠️ function calls are not analysed yet +- *17* ???*18*["type"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* ???*19*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *20* (???*21* === ???*22*) + ⚠️ nested operation +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* a + ⚠️ circular variable reference + +0 -> 5264 free var = FreeVar(Error) + +0 -> 5265 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(185) + +0 -> 5266 call = ???*0*( + `Minified React error #${185}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${185}` + ⚠️ nested operation + +0 -> 5267 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 5268 conditional = ((0 === ???*0*) | (???*1* !== (null | ???*2* | ???*3* | ???*6*))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* ???*5*["current"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* unknown new expression + ⚠️ This value might have side effects + +5268 -> 5269 call = (...) => undefined(???*0*, (0 | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +5268 -> 5270 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +5268 -> 5272 call = module["unstable_now"]() + +5268 -> 5273 call = (...) => null() + +0 -> 5275 call = (...) => undefined(???*0*, (???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 5276 conditional = (???*0* === (null | ???*1* | ???*2* | ???*5*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* ???*4*["current"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* unknown new expression + ⚠️ This value might have side effects + +0 -> 5277 call = (...) => (0 | b | d)(???*0*, (???*1* ? (0 | ???*8*) : 0)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (???*2* === (null | ???*3* | ???*4* | ???*7*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* ???*6*["current"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* unknown new expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects + +0 -> 5278 conditional = (0 === ( + | 0 + | ???*0* + | ???*9* + | ???*11* + | undefined + | 1 + | 2 + | 4 + | 8 + | 16 + | 32 + | ???*12* + | 134217728 + | 268435456 + | 536870912 + | 1073741824 +)) +- *0* (???*1* ? (0 | ???*8*) : 0) + ⚠️ nested operation +- *1* (???*2* === (null | ???*3* | ???*4* | ???*7*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* ???*6*["current"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* unknown new expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*["entangledLanes"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* unsupported assign operation + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects + +5278 -> 5279 call = module["unstable_cancelCallback"]( + ( + | ???*0* + | null + | module["unstable_ImmediatePriority"] + | module["unstable_UserBlockingPriority"] + | module["unstable_NormalPriority"] + | module["unstable_IdlePriority"] + | module["unstable_scheduleCallback"](???*2*, ???*3*) + ) +) +- *0* ???*1*["callbackNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ circular variable reference +- *3* (...) => (null | ???*4*)["bind"](null, ???*5*) + ⚠️ nested operation +- *4* ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) + ⚠️ nested operation +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +5278 -> 5283 call = module["unstable_cancelCallback"]( + ( + | ???*0* + | null + | module["unstable_ImmediatePriority"] + | module["unstable_UserBlockingPriority"] + | module["unstable_NormalPriority"] + | module["unstable_IdlePriority"] + | module["unstable_scheduleCallback"](???*2*, ???*3*) + ) +) +- *0* ???*1*["callbackNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ circular variable reference +- *3* (...) => (null | ???*4*)["bind"](null, ???*5*) + ⚠️ nested operation +- *4* ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) + ⚠️ nested operation +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +5278 -> 5284 conditional = (1 === (???*0* | ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +5284 -> 5286 conditional = (0 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +5286 -> 5288 member call = (...) => null["bind"](null, ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5286 -> 5289 call = (...) => undefined((...) => null["bind"](null, ???*0*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5286 -> 5291 member call = (...) => null["bind"](null, ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5286 -> 5292 call = (...) => undefined((...) => null["bind"](null, ???*0*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5284 -> 5293 call = (???*0* ? ???*3* : ???*4*)((...) => undefined) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(queueMicrotask) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(queueMicrotask) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* (???*5* ? (...) => ???*11* : ???*12*) + ⚠️ nested operation +- *5* ("undefined" !== ???*6*) + ⚠️ nested operation +- *6* typeof(???*7*) + ⚠️ nested operation +- *7* (???*8* ? ???*9* : ???*10*) + ⚠️ nested operation +- *8* ("function" === ???) + ⚠️ nested operation +- *9* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* Hf["resolve"](null)["then"](a)["catch"](If) + ⚠️ nested operation +- *12* (???*13* ? ???*16* : ???*17*) + ⚠️ nested operation +- *13* ("function" === ???*14*) + ⚠️ nested operation +- *14* typeof(???*15*) + ⚠️ nested operation +- *15* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects + +5293 -> 5294 call = (...) => null() + +5284 -> 5295 call = (...) => (???*0* ? (???*1* ? ((0 !== ???*2*) ? 16 : 536870912) : 4) : 1)( + ( + | 0 + | (???*3* ? (0 | ???*10*) : 0) + | ???*11* + | ???*13* + | undefined + | 1 + | 2 + | 4 + | 8 + | 16 + | 32 + | ???*14* + | 134217728 + | 268435456 + | 536870912 + | 1073741824 + ) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (???*4* === (null | ???*5* | ???*6* | ???*9*)) + ⚠️ nested operation +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* ???*8*["current"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* unknown new expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["entangledLanes"] + ⚠️ unknown object +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* unsupported assign operation + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects + +5284 -> 5297 member call = (...) => ( + | null + | ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) +)["bind"](null, ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5284 -> 5298 call = (...) => ac(a, b)( + ( + | ???*0* + | null + | module["unstable_ImmediatePriority"] + | module["unstable_UserBlockingPriority"] + | module["unstable_NormalPriority"] + | module["unstable_IdlePriority"] + | module["unstable_scheduleCallback"](???*2*, ???*3*) + ), + (...) => (null | ???*6*)["bind"](null, ???*7*) +) +- *0* ???*1*["callbackNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ circular variable reference +- *3* (...) => (null | ???*4*)["bind"](null, ???*5*) + ⚠️ nested operation +- *4* ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) + ⚠️ nested operation +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) + ⚠️ nested operation +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5301 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5301 -> 5302 free var = FreeVar(Error) + +5301 -> 5303 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(327) + +5301 -> 5304 call = ???*0*( + `Minified React error #${327}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${327}` + ⚠️ nested operation + +0 -> 5306 call = (...) => (d | !(1))() + +0 -> 5308 conditional = (???*0* === (null | ???*1* | ???*2* | ???*5*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* ???*4*["current"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* unknown new expression + ⚠️ This value might have side effects + +0 -> 5309 call = (...) => (0 | b | d)(???*0*, (???*1* ? (0 | ???*8*) : 0)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (???*2* === (null | ???*3* | ???*4* | ???*7*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* ???*6*["current"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* unknown new expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects + +0 -> 5311 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5311 -> 5312 call = (...) => T(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5311 -> 5313 call = (...) => ((null === a) ? ai : a)() + +5311 -> 5314 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5314 -> 5315 call = module["unstable_now"]() + +5314 -> 5316 call = (...) => a(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5311 -> 5317 call = (...) => undefined() + +5311 -> 5318 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* h + ⚠️ pattern without value + +5311 -> 5319 call = (...) => undefined() + +5311 -> 5321 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5322 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5322 -> 5323 call = (...) => ((0 !== a) ? a : (???*0* ? 1073741824 : 0))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +5322 -> 5324 call = (...) => a(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5322 -> 5325 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5325 -> 5326 call = (...) => a(???*0*, 0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5325 -> 5327 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5325 -> 5328 call = module["unstable_now"]() + +5325 -> 5329 call = (...) => undefined(???*0*, module["unstable_now"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5322 -> 5330 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5331 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5334 call = (...) => (!(1) | !(0))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5335 call = (...) => T(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5336 call = (...) => ((0 !== a) ? a : (???*0* ? 1073741824 : 0))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +5330 -> 5337 call = (...) => a( + ???*0*, + ( + | (???*1* ? { + "readContext": (...) => b, + "useCallback": (...) => undefined, + "useContext": (...) => undefined, + "useEffect": (...) => undefined, + "useImperativeHandle": (...) => undefined, + "useInsertionEffect": (...) => undefined, + "useLayoutEffect": (...) => undefined, + "useMemo": (...) => undefined, + "useReducer": (...) => undefined, + "useRef": (...) => undefined, + "useState": (...) => undefined, + "useDebugValue": (...) => undefined, + "useDeferredValue": (...) => undefined, + "useTransition": (...) => undefined, + "useMutableSource": (...) => undefined, + "useSyncExternalStore": (...) => undefined, + "useId": (...) => undefined, + "unstable_isNewReconciler": false + } : module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"]["current"]) + | (???*2* ? (???*5* | ???*6*) : ???*7*) + | ???*9* + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (null === module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"]["current"]) + ⚠️ nested operation +- *2* (0 !== (???*3* | ???*4*)) + ⚠️ nested operation +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* (???*8* ? 1073741824 : 0) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects + +5330 -> 5338 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5338 -> 5339 call = (...) => a(???*0*, 0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5338 -> 5340 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5338 -> 5341 call = module["unstable_now"]() + +5338 -> 5342 call = (...) => undefined(???*0*, module["unstable_now"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5330 -> 5345 free var = FreeVar(Error) + +5330 -> 5346 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(345) + +5330 -> 5347 call = ???*0*( + `Minified React error #${345}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${345}` + ⚠️ nested operation + +5330 -> 5348 call = (...) => null(???*0*, ???*1*, null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5349 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5350 call = module["unstable_now"]() + +5330 -> 5351 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5351 -> 5352 call = (...) => (0 | b | d)(???*0*, 0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5351 -> 5354 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5354 -> 5355 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +5351 -> 5360 member call = (...) => null["bind"](null, ???*0*, ???*1*, null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5351 -> 5361 call = (???*0* ? ???*3* : ???*4*)(???*5*, ???*6*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5362 call = (...) => null(???*0*, ???*1*, null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5363 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5365 call = (???*0* ? ???*2* : (...) => ???*4*)(???*6*) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5367 call = module["unstable_now"]() + +5330 -> 5368 call = ???*0*(???*2*) +- *0* ???*1*["ceil"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +5330 -> 5371 member call = (...) => null["bind"](null, ???*0*, ???*1*, null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5372 call = (???*0* ? ???*3* : ???*4*)(???*5*, ???*6*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5373 call = (...) => null(???*0*, ???*1*, null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5374 call = (...) => null(???*0*, ???*1*, null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5330 -> 5375 free var = FreeVar(Error) + +5330 -> 5376 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(329) + +5330 -> 5377 call = ???*0*( + `Minified React error #${329}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${329}` + ⚠️ nested operation + +0 -> 5378 call = module["unstable_now"]() + +0 -> 5379 call = (...) => undefined(???*0*, module["unstable_now"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5381 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5381 -> 5383 member call = (...) => ( + | null + | ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) +)["bind"](null, ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5388 call = (...) => a(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5389 call = (...) => T(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5390 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5391 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5391 -> 5394 member call = ???*0*["apply"](???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5398 conditional = ((null !== ???*0*) | ???*2*) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (null !== c) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +5398 -> 5403 call = ???*0*() +- *0* ???*1*["getSnapshot"] + ⚠️ unknown object +- *1* ???*2*[d] + ⚠️ unknown object +- *2* ???*3*["updateQueue"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +5398 -> 5404 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*(), ???*13*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*["getSnapshot"] + ⚠️ unknown object +- *10* ???*11*[d] + ⚠️ unknown object +- *11* ???*12*["updateQueue"] + ⚠️ unknown object +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* ???*14*[d] + ⚠️ unknown object +- *14* ???*15*["updateQueue"] + ⚠️ unknown object +- *15* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5407 conditional = (???*0* | (null !== ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5420 call = (???*0* ? ???*2* : (...) => ???*4*)((???*6* | ???*7*)) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 5422 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5422 -> 5423 free var = FreeVar(Error) + +5422 -> 5424 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(327) + +5422 -> 5425 call = ???*0*( + `Minified React error #${327}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${327}` + ⚠️ nested operation + +0 -> 5426 call = (...) => (d | !(1))() + +0 -> 5427 call = (...) => (0 | b | d)(???*0*, 0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5428 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5428 -> 5429 call = module["unstable_now"]() + +5428 -> 5430 call = (...) => undefined(???*0*, module["unstable_now"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5431 call = (...) => T( + ???*0*, + ( + | 0 + | ???*1* + | ???*3* + | undefined + | 1 + | 2 + | 4 + | 8 + | 16 + | 32 + | ???*4* + | 134217728 + | 268435456 + | 536870912 + | 1073741824 + | (???*5* ? (???*8* | ???*9*) : ???*10*) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["entangledLanes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* (0 !== (???*6* | ???*7*)) + ⚠️ nested operation +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 1073741824 : 0) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects + +0 -> 5433 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5433 -> 5434 call = (...) => ((0 !== a) ? a : (???*0* ? 1073741824 : 0))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +5433 -> 5435 call = (...) => a(???*0*, (???*1* ? (???*4* | ???*5*) : ???*6*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (0 !== (???*2* | ???*3*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? 1073741824 : 0) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects + +0 -> 5436 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5436 -> 5437 call = (...) => a(???*0*, 0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5436 -> 5438 call = (...) => undefined( + ???*0*, + ( + | 0 + | ???*1* + | ???*3* + | undefined + | 1 + | 2 + | 4 + | 8 + | 16 + | 32 + | ???*4* + | 134217728 + | 268435456 + | 536870912 + | 1073741824 + | (???*5* ? (???*8* | ???*9*) : ???*10*) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["entangledLanes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* (0 !== (???*6* | ???*7*)) + ⚠️ nested operation +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 1073741824 : 0) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects + +5436 -> 5439 call = module["unstable_now"]() + +5436 -> 5440 call = (...) => undefined(???*0*, module["unstable_now"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5441 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5441 -> 5442 free var = FreeVar(Error) + +5441 -> 5443 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(345) + +5441 -> 5444 call = ???*0*( + `Minified React error #${345}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${345}` + ⚠️ nested operation + +0 -> 5449 call = (...) => null(???*0*, ???*1*, null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5450 call = module["unstable_now"]() + +0 -> 5451 call = (...) => undefined(???*0*, module["unstable_now"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5452 call = ???*0*(???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 5453 call = module["unstable_now"]() + +0 -> 5454 call = (...) => null() + +0 -> 5456 call = (...) => (d | !(1))() + +0 -> 5459 call = ???*0*() +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5461 call = (...) => null() + +0 -> 5463 call = (...) => undefined({"current": 0}) + +0 -> 5468 call = (???*0* ? ???*3* : ???*4*)(???*5*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(clearTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(clearTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5469 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5469 -> 5471 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5469 -> 5475 call = (...) => undefined() + +5469 -> 5476 call = (...) => undefined() + +5469 -> 5477 call = (...) => undefined({"current": false}) + +5469 -> 5478 call = (...) => undefined({"current": {}}) + +5469 -> 5479 call = (...) => undefined() + +5469 -> 5480 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5469 -> 5481 call = (...) => undefined() + +5469 -> 5482 call = (...) => undefined({"current": 0}) + +5469 -> 5483 call = (...) => undefined({"current": 0}) + +5469 -> 5486 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5469 -> 5487 call = (...) => undefined() + +0 -> 5490 call = (...) => c((???*0* | ???*2*), null) +- *0* ???*1*["current"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unknown new expression + ⚠️ This value might have side effects + +0 -> 5491 conditional = (null !== (null | [???*0*])) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +5491 -> 5498 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5503 call = (...) => undefined() + +0 -> 5505 conditional = (false | true) + +0 -> 5515 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5515 -> 5518 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5518 -> 5520 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5515 -> 5529 call = (...) => (a | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5515 -> 5530 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5530 -> 5532 call = (...) => (???*0* | a)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +5530 -> 5534 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5530 -> 5536 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5536 -> 5537 free var = FreeVar(Set) + +5536 -> 5539 member call = ???*0*["add"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5536 -> 5542 member call = ???*0*["add"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5530 -> 5543 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5543 -> 5544 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5543 -> 5545 call = (...) => undefined() + +5530 -> 5546 free var = FreeVar(Error) + +5530 -> 5547 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(426) + +5530 -> 5548 call = ???*0*( + `Minified React error #${426}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${426}` + ⚠️ nested operation + +5515 -> 5550 conditional = (false | true | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5550 -> 5551 call = (...) => (a | null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5550 -> 5552 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5552 -> 5555 call = (...) => (???*0* | a)(???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +5552 -> 5556 call = (...) => {"value": a, "source": b, "stack": e, "digest": null}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5552 -> 5557 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5558 call = (...) => {"value": a, "source": b, "stack": e, "digest": null}(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5559 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5559 -> 5561 member call = ???*0*["push"](???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5565 call = (...) => c(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5566 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5573 member call = (???*0* | null)["has"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5574 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5574 -> 5577 call = (...) => c(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5574 -> 5578 call = (...) => (undefined | FreeVar(undefined))(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5580 call = (...) => (undefined | FreeVar(undefined))(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5584 conditional = (null === module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"]["current"]) + +0 -> 5585 call = (...) => undefined((null | ???*0* | ???*1* | ???*4*), (0 | ???*5*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +0 -> 5586 call = (...) => ((null === a) ? ai : a)() + +0 -> 5587 conditional = (((null | ???*0* | ???*1* | ???*4*) !== ???*5*) | ((0 | ???*6*) !== ???*7*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[1] + ⚠️ function calls are not analysed yet + +5587 -> 5588 call = (...) => a(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 5589 call = (...) => undefined() + +0 -> 5590 call = (...) => undefined(???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* e + ⚠️ pattern without value + +0 -> 5591 call = (...) => undefined() + +0 -> 5593 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5593 -> 5594 free var = FreeVar(Error) + +5593 -> 5595 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(261) + +5593 -> 5596 call = ???*0*( + `Minified React error #${261}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${261}` + ⚠️ nested operation + +0 -> 5597 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5598 call = module["unstable_shouldYield"]() + +0 -> 5599 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5601 call = ( + | ???*0* + | (...) => ( + | undefined + | ???*1* + | b + | null + | pj(a, b, c) + | b["child"] + | cj(a, b, b["type"], b["pendingProps"], c) + | yj(a, b, c) + | ej(a, b, c) + ) +)(???*2*, ???*4*, (???*5* | 0 | ???*6* | ???*7* | ???*8*)) +- *0* Wk + ⚠️ pattern without value +- *1* zj(a, b, c) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* unsupported assign operation + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* updated with update expression + ⚠️ This value might have side effects + +0 -> 5604 conditional = (null === ???*0*) +- *0* ( + | ???*1* + | (...) => ( + | undefined + | ???*2* + | b + | null + | pj(a, b, c) + | b["child"] + | cj(a, b, b["type"], b["pendingProps"], c) + | yj(a, b, c) + | ej(a, b, c) + ) + )(a["alternate"], a, gj) + ⚠️ non-function callee +- *1* Wk + ⚠️ pattern without value +- *2* zj(a, b, c) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +5604 -> 5605 call = (...) => (undefined | FreeVar(undefined))(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5610 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5610 -> 5611 call = (...) => (undefined | null | (???*0* ? b : null) | ???*1* | b["child"])(???*2*, (???*3* | ???*4*), (???*6* | 0 | ???*7* | ???*8* | ???*9*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["return"] + ⚠️ unknown object +- *5* b + ⚠️ circular variable reference +- *6* unsupported assign operation + ⚠️ This value might have side effects +- *7* unknown mutation + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* updated with update expression + ⚠️ This value might have side effects + +5610 -> 5612 call = (...) => (undefined | ???*0* | null | (???*3* ? ???*4* : null))(???*5*, (???*6* | ???*7*)) +- *0* (???*1* ? ???*2* : null) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*["return"] + ⚠️ unknown object +- *8* b + ⚠️ circular variable reference + +5610 -> 5613 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5610 -> 5615 conditional = (null !== (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +0 -> 5622 call = (...) => null( + ???*0*, + ???*1*, + ???*2*, + ( + | 0 + | 1 + | ???*3* + | 4 + | ((???*4* | ???*6*) ? ???*7* : 4) + | (???*8* ? 16 : (???*9* | null | ???*16* | ???*17*)) + | ???*19* + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* C + ⚠️ circular variable reference +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 1) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 4) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? 16 : 536870912) + ⚠️ nested operation +- *14* (0 !== ???*15*) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["value"] + ⚠️ unknown object +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5624 call = (...) => (d | !(1))() + +0 -> 5625 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5625 -> 5626 free var = FreeVar(Error) + +5625 -> 5627 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(327) + +5625 -> 5628 call = ???*0*( + `Minified React error #${327}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${327}` + ⚠️ nested operation + +0 -> 5634 conditional = ((???*0* | ???*1* | null["finishedWork"] | 0 | ???*3*) === (???*4* | null["current"])) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["finishedWork"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* ???*5*["current"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +5634 -> 5635 free var = FreeVar(Error) + +5634 -> 5636 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(177) + +5634 -> 5637 call = ???*0*( + `Minified React error #${177}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${177}` + ⚠️ nested operation + +0 -> 5642 call = (...) => undefined( + (???*0* | ???*1* | null), + ( + | ???*3* + | (0 !== ???*4*) + | module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + | ???*5* + | null["pendingLanes"] + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* ???*6*["pendingLanes"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5645 call = (...) => ac(a, b)(module["unstable_NormalPriority"], (...) => null) + +5645 -> 5646 call = (...) => (d | !(1))() + +0 -> 5649 conditional = ( + | (0 !== ???*0*) + | ???*1* + | module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + | ???*2* + | null["pendingLanes"] +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["pendingLanes"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +5649 -> 5653 call = (...) => n( + (???*0* | ???*1* | null), + (???*3* | ???*4* | null["finishedWork"] | 0 | ???*6*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* ???*5*["finishedWork"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects + +5649 -> 5654 call = (...) => undefined( + (???*0* | ???*1* | null["finishedWork"] | 0 | ???*3*), + (???*4* | ???*5* | null) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["finishedWork"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["value"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet + +5649 -> 5655 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5649 -> 5657 call = (...) => undefined( + (???*0* | ???*1* | null["finishedWork"] | 0 | ???*3*), + (???*4* | ???*5* | null), + (???*7* | null["finishedLanes"]) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["finishedWork"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["value"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["finishedLanes"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet + +5649 -> 5658 call = module["unstable_requestPaint"]() + +0 -> 5663 call = (...) => undefined( + (???*0* | null["finishedWork"]["stateNode"] | 0["stateNode"] | ???*2*), + (???*4* | ???*5* | null["onRecoverableError"]) +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* arguments[3] + ⚠️ function calls are not analysed yet +- *5* ???*6*["onRecoverableError"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5664 call = module["unstable_now"]() + +0 -> 5665 call = (...) => undefined((???*0* | ???*1* | null), module["unstable_now"]()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 5666 conditional = (null !== ???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +5666 -> 5673 call = (???*0* | ???*1* | null["onRecoverableError"])( + (???*3* | null["finishedLanes"]["value"]), + { + "componentStack": (???*6* | null["finishedLanes"]["stack"]), + "digest": (???*9* | null["finishedLanes"]["digest"]) + } +) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["onRecoverableError"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["value"] + ⚠️ unknown object +- *4* ???*5*["finishedLanes"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["stack"] + ⚠️ unknown object +- *7* ???*8*["finishedLanes"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["digest"] + ⚠️ unknown object +- *10* ???*11*["finishedLanes"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5675 call = (...) => (d | !(1))() + +0 -> 5677 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5677 -> 5678 conditional = ((???*0* | ???*1* | null) === (null | ???*3* | ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["value"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 5679 call = (...) => null() + +0 -> 5680 conditional = (null !== (null | ???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +5680 -> 5681 call = (...) => (???*0* ? (???*1* ? ((0 !== ???*2*) ? 16 : 536870912) : 4) : 1)((0 | ???*3* | null["finishedLanes"])) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["finishedLanes"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +5680 -> 5684 conditional = (null === (null | ???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +5684 -> 5685 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5685 -> 5686 free var = FreeVar(Error) + +5685 -> 5687 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(331) + +5685 -> 5688 call = ???*0*( + `Minified React error #${331}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${331}` + ⚠️ nested operation + +5684 -> 5692 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5692 -> 5694 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5694 -> 5698 call = (...) => undefined(8, ???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5694 -> 5700 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5700 -> 5704 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5700 -> 5705 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5694 -> 5708 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5708 -> 5710 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5684 -> 5715 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5715 -> 5718 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5718 -> 5721 call = (...) => undefined(9, ???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5715 -> 5723 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5684 -> 5730 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5730 -> 5733 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5733 -> 5735 call = (...) => undefined(9, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5733 -> 5737 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* na + ⚠️ pattern without value + +5730 -> 5739 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5684 -> 5743 call = (...) => null() + +5684 -> 5745 conditional = (null | ???*0* | ("function" === ???*1*)) +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* typeof((null["onPostCommitFiberRoot"] | ???*2*)) + ⚠️ nested operation +- *2* ???*3*["onPostCommitFiberRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects + +5745 -> 5747 member call = (null | ???*0*)["onPostCommitFiberRoot"]((null | ???*1*), ((???*3* ? ???*4* : 1) | null | ???*9* | ???*10*)) +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["inject"](vl) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* (???*5* ? ???*6* : 4) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? 16 : 536870912) + ⚠️ nested operation +- *7* (0 !== ???*8*) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*["value"] + ⚠️ unknown object +- *11* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 5749 call = (...) => {"value": a, "source": b, "stack": e, "digest": null}(???*0*, ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5750 call = (...) => c(???*0*, ???*1*, 1) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5751 call = (...) => (null | Zg(a, c))(???*0*, ???*1*, 1) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5752 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 5753 call = (...) => undefined(???*0*, 1, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5754 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5756 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5756 -> 5757 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +5756 -> 5759 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5759 -> 5760 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +5759 -> 5762 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5762 -> 5768 member call = (???*0* | null)["has"](???*1*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5762 -> 5769 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5769 -> 5770 call = (...) => {"value": a, "source": b, "stack": e, "digest": null}(???*0*, ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5769 -> 5771 call = (...) => c(???*0*, ???*1*, 1) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5769 -> 5772 call = (...) => (null | Zg(a, c))(???*0*, ???*1*, 1) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5769 -> 5773 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +5769 -> 5774 call = (...) => undefined(???*0*, 1, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5769 -> 5775 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5779 member call = ???*0*["delete"]((???*2* | (???*3* ? ???*5* : ???*6*))) +- *0* ???*1*["pingCache"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (0 !== ???*4*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* module["unstable_now"]() + ⚠️ nested operation +- *6* (???*7* ? (???*11* | ???*12*) : ???*13*) + ⚠️ nested operation +- *7* (???*8* !== (???*9* | ???*10*)) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* module["unstable_now"]() + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects + +0 -> 5780 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 5783 call = module["unstable_now"]() + +0 -> 5784 conditional = ( + | (4 === (3 | 0 | 1 | 2 | 4 | 6 | 5)) + | (3 === (3 | 0 | 1 | 2 | 4 | 6 | 5)) + | (???*0* === (0 | ???*1*)) + | ???*2* +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +5784 -> 5785 call = (...) => a(???*0*, 0) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5786 call = (...) => undefined(???*0*, (???*1* | (???*2* ? ???*4* : ???*5*))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* module["unstable_now"]() + ⚠️ nested operation +- *5* (???*6* ? (???*10* | ???*11*) : ???*12*) + ⚠️ nested operation +- *6* (???*7* !== (???*8* | ???*9*)) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* module["unstable_now"]() + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects + +0 -> 5788 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 5789 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 5790 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)((???*0* | (???*1* ? ???*5* : null)), (???*8* | 1 | 4194304 | ???*9*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 5791 call = (...) => undefined( + (???*0* | (???*1* ? ???*5* : null)), + (???*8* | 1 | 4194304 | ???*9*), + (???*10* ? ???*12* : ???*13*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported assign operation + ⚠️ This value might have side effects +- *10* (0 !== ???*11*) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* module["unstable_now"]() + ⚠️ nested operation +- *13* (???*14* ? (???*18* | ???*19*) : ???*20*) + ⚠️ nested operation +- *14* (???*15* !== (???*16* | ???*17*)) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* module["unstable_now"]() + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* module["unstable_now"]() + ⚠️ nested operation +- *20* unsupported expression + ⚠️ This value might have side effects + +0 -> 5792 call = (...) => undefined((???*0* | (???*1* ? ???*5* : null)), (???*8* ? ???*10* : ???*11*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* (0 !== ???*9*) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* (???*12* ? (???*16* | ???*17*) : ???*18*) + ⚠️ nested operation +- *12* (???*13* !== (???*14* | ???*15*)) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* module["unstable_now"]() + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* module["unstable_now"]() + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects + +0 -> 5795 call = (...) => undefined(???*0*, (0 | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["retryLane"] + ⚠️ unknown object +- *2* ???*3*["memoizedState"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5801 free var = FreeVar(Error) + +0 -> 5802 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(314) + +0 -> 5803 call = ???*0*( + `Minified React error #${314}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${314}` + ⚠️ nested operation + +0 -> 5805 member call = ???*0*["delete"](???*2*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 5806 call = (...) => undefined(???*0*, (0 | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["retryLane"] + ⚠️ unknown object +- *2* ???*3*["memoizedState"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 5807 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5807 -> 5811 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5811 -> 5814 conditional = (0 === ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5814 -> 5815 call = (...) => (???*0* | pj(a, b, c) | ((null !== a) ? a["sibling"] : null) | yj(a, b, c) | null | $i(a, b, c))(???*1*, ???*2*, ???*3*) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +5811 -> 5817 conditional = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +5807 -> 5820 call = (...) => undefined(???*0*, (0 | ???*1* | ???*2*), ???*4*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* [][???*3*] + ⚠️ unknown array prototype methods or values +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5824 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5827 call = (...) => (Vf | d["__reactInternalMemoizedMaskedChildContext"] | e)(???*0*, ({} | ???*1*)) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects + +0 -> 5828 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5829 call = (...) => a(null, ???*0*, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5830 call = (...) => a() + +0 -> 5834 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5834 -> 5838 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +5834 -> 5839 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5839 -> 5840 call = (...) => !(0)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5834 -> 5844 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5834 -> 5846 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5834 -> 5850 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +5834 -> 5851 call = (...) => ($i(a, b, f) | b["child"])(null, ???*0*, ???*1*, true, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +5834 -> 5853 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5834 -> 5854 call = (...) => undefined(null, ???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5857 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5861 call = ???*0*(???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5864 call = (...) => ((bj(a) ? 1 : 0) | 11 | 14 | 2)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5865 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5866 call = (...) => (???*0* | b["child"])(null, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5867 call = (...) => kj(a, b, c, d, f, e)(null, ???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5868 call = (...) => (???*0* | b["child"])(null, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5870 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5871 call = (...) => (???*0* | ???*1* | $i(a, b, e))(null, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* cj(a, b, f, d, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5872 free var = FreeVar(Error) + +0 -> 5873 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(306, ???*0*, "") +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5874 call = ???*0*(???*1*) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5878 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5878 -> 5879 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5880 call = (...) => (???*0* | b["child"])(???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5884 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5884 -> 5885 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5886 call = (...) => kj(a, b, c, d, f, e)(???*0*, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5887 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5888 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5888 -> 5889 free var = FreeVar(Error) + +5888 -> 5890 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(387) + +5888 -> 5891 call = ???*0*( + `Minified React error #${387}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${387}` + ⚠️ nested operation + +0 -> 5895 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5896 call = (...) => undefined(???*0*, ???*1*, null, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5900 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5900 -> 5908 free var = FreeVar(Error) + +5900 -> 5909 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(423) + +5900 -> 5910 call = ???*0*( + `Minified React error #${423}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${423}` + ⚠️ nested operation + +5900 -> 5911 call = (...) => {"value": a, "source": b, "stack": e, "digest": null}(???*0*, ???*2*) +- *0* ???*1*(p(423)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5900 -> 5912 call = (...) => b["child"](???*0*, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +5900 -> 5913 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5913 -> 5914 free var = FreeVar(Error) + +5913 -> 5915 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(424) + +5913 -> 5916 call = ???*0*( + `Minified React error #${424}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${424}` + ⚠️ nested operation + +5913 -> 5917 call = (...) => {"value": a, "source": b, "stack": e, "digest": null}(???*0*, ???*2*) +- *0* ???*1*(p(424)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5913 -> 5918 call = (...) => b["child"](???*0*, ???*1*, ???*2*, ???*3*, ???*4*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +5913 -> 5922 call = (...) => (null | a)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5913 -> 5923 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, null, ???*3*, ???*4*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +5900 -> 5928 call = (...) => undefined() + +5900 -> 5929 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5929 -> 5930 call = (...) => (null | b["child"])(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5900 -> 5931 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5933 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5934 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5937 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5940 call = (...) => ( + || ("textarea" === a) + || ("noscript" === a) + || ("string" === typeof(b["children"])) + || ("number" === typeof(b["children"])) + || ( + && ("object" === typeof(b["dangerouslySetInnerHTML"])) + && (null !== b["dangerouslySetInnerHTML"]) + && (null != b["dangerouslySetInnerHTML"]["__html"]) + ) +)(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5941 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5941 -> 5942 call = (...) => ( + || ("textarea" === a) + || ("noscript" === a) + || ("string" === typeof(b["children"])) + || ("number" === typeof(b["children"])) + || ( + && ("object" === typeof(b["dangerouslySetInnerHTML"])) + && (null !== b["dangerouslySetInnerHTML"]) + && (null != b["dangerouslySetInnerHTML"]["__html"]) + ) +)(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5944 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5945 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5947 call = (...) => undefined(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5948 call = (...) => (???*0* | (f ? ???*1* : rj(b, g)) | sj(a, b, g, d, h, e, c) | d)(???*2*, ???*3*, ???*4*) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5951 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5953 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5953 -> 5955 call = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +)(???*2*, null, ???*3*, ???*4*) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects + +5953 -> 5956 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5961 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5961 -> 5962 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5963 call = (...) => (???*0* | b["child"])(???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5965 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5969 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5973 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5981 call = (...) => undefined({"current": null}, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 5983 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5983 -> 5985 call = (???*0* ? ???*4* : (...) => ???*6*)(???*9*, ???*10*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* max number of linking steps reached + ⚠️ This value might have side effects +- *10* max number of linking steps reached + ⚠️ This value might have side effects + +5983 -> 5986 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5986 -> 5990 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5990 -> 5991 call = (...) => (null | b["child"])(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5986 -> 5995 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5995 -> 5999 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5999 -> 6001 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6001 -> 6002 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}(???*0*, ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +6001 -> 6005 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6005 -> 6008 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +5999 -> 6018 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5995 -> 6022 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6022 -> 6025 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6022 -> 6028 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6028 -> 6030 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6030 -> 6031 free var = FreeVar(Error) + +6030 -> 6032 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(341) + +6030 -> 6033 call = ???*0*( + `Minified React error #${341}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${341}` + ⚠️ nested operation + +6028 -> 6037 call = (...) => undefined(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +5986 -> 6040 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6040 -> 6043 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6048 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6053 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6054 call = (...) => b(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6055 call = ???*0*(???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6057 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6061 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6063 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6064 call = (...) => (???*0* | ???*1* | $i(a, b, e))(???*2*, ???*3*, ???*4*, ???*5*, ???*6*) +- *0* cj(a, b, f, d, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects +- *6* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6067 call = (...) => (???*0* | dj(a, b, c, d, e))(???*1*, ???*2*, ???*3*, ???*4*, ???*5*) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects +- *4* max number of linking steps reached + ⚠️ This value might have side effects +- *5* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6071 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6071 -> 6072 call = (...) => b(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6073 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6075 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6076 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6076 -> 6077 call = (...) => !(0)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6078 call = (...) => undefined(???*0*, ???*1*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6079 call = (...) => b(???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6080 call = (...) => undefined(???*0*, ???*1*, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6081 call = (...) => ($i(a, b, f) | b["child"])(null, ???*0*, ???*1*, true, ???*2*, ???*3*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6082 call = (...) => b["child"](???*0*, ???*1*, ???*2*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6083 call = (...) => (???*0* | b["child"])(???*1*, ???*2*, ???*3*) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* max number of linking steps reached + ⚠️ This value might have side effects +- *3* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6084 free var = FreeVar(Error) + +0 -> 6086 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(156, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6087 call = ???*0*(???*1*) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6088 call = module["unstable_scheduleCallback"](???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6113 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["$$typeof"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +6113 -> 6114 call = (...) => !((!(a) || !(a["isReactComponent"])))((???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["$$typeof"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +6113 -> 6115 conditional = !(???*0*) +- *0* !((???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["$$typeof"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference + +0 -> 6116 conditional = ((???*0* !== (???*1* | ???*2*)) | (null !== (???*4* | ???*5*))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["$$typeof"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["$$typeof"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference + +0 -> 6119 conditional = (null === (???*0* | ???*2*)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects + +6119 -> 6123 call = (...) => ???*0*(???*1*, (???*3* | ???*4*), ???*6*, ???*8*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["dependencies"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["key"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* ???*9*["mode"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6154 conditional = (null === (???*0* | ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["dependencies"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6163 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects + +6163 -> 6164 call = (...) => !((!(a) || !(a["isReactComponent"])))((???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +6163 -> 6165 conditional = ("string" === ???*0*) +- *0* typeof((???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects + +6165 -> 6167 call = (...) => a(???*0*, (???*2* | ???*3*), ???*4*, (???*5* | ???*6*)) +- *0* ???*1*["children"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[4] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects +- *4* arguments[5] + ⚠️ function calls are not analysed yet +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* unknown new expression + ⚠️ This value might have side effects + +6165 -> 6168 call = (...) => ???*0*(12, ???*1*, (???*2* | ???*3*), ???*4*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +6165 -> 6171 call = (...) => ???*0*(13, ???*1*, (???*2* | ???*3*), (???*4* | ???*5*)) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* arguments[4] + ⚠️ function calls are not analysed yet +- *5* unsupported assign operation + ⚠️ This value might have side effects + +6165 -> 6174 call = (...) => ???*0*(19, ???*1*, (???*2* | ???*3*), (???*4* | ???*5*)) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* arguments[4] + ⚠️ function calls are not analysed yet +- *5* unsupported assign operation + ⚠️ This value might have side effects + +6165 -> 6177 call = (...) => a(???*0*, (???*1* | ???*2*), ???*3*, (???*4* | ???*5*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[4] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects +- *3* arguments[5] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* unknown new expression + ⚠️ This value might have side effects + +6165 -> 6178 conditional = (("object" === ???*0*) | (null !== (???*3* | ???*4*))) +- *0* typeof((???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* unknown new expression + ⚠️ This value might have side effects + +6165 -> 6180 free var = FreeVar(Error) + +6165 -> 6181 conditional = (null == (???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +6165 -> 6182 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(130, (???*0* ? (???*3* | ???*4*) : ???*5*), "") +- *0* (null == (???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* typeof((???*6* | ???*7*)) + ⚠️ nested operation +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unknown new expression + ⚠️ This value might have side effects + +6165 -> 6183 call = ???*0*( + `Minified React error #${130}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${130}` + ⚠️ nested operation + +0 -> 6184 call = (...) => ???*0*((2 | 1 | 5 | 8 | 10 | 9 | 11 | 14 | 16), ???*1*, (???*2* | ???*3*), (???*4* | ???*5*)) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* arguments[4] + ⚠️ function calls are not analysed yet +- *5* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 6188 call = (...) => ???*0*(7, (???*1* | ???*2*), ???*3*, ???*4*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6190 call = (...) => ???*0*(22, (???*1* | ???*2*), ???*3*, ???*4*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6194 call = (...) => ???*0*(6, (???*1* | ???*2*), null, ???*3*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6197 conditional = (null !== ???*0*) +- *0* ???*1*["children"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6200 call = (...) => ???*0*(4, (???*1* ? ???*4* : []), ???*6*, (???*8* | ???*9*)) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* (null !== ???*2*) + ⚠️ nested operation +- *2* ???*3*["children"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["children"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["key"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unknown new expression + ⚠️ This value might have side effects + +0 -> 6217 call = (...) => b(0) + +0 -> 6219 call = (...) => b(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 6228 call = (...) => b(0) + +0 -> 6232 conditional = (1 === (???*0* | 1 | ???*1* | 0)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 6233 call = (...) => ???*0*(3, null, null, (???*1* | 1 | ???*2* | 0)) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects + +0 -> 6237 call = (...) => undefined((???*0* | ???*1*)) +- *0* arguments[5] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +0 -> 6239 free var = FreeVar(arguments) + +0 -> 6241 free var = FreeVar(arguments) + +0 -> 6242 conditional = (???*0* | (???*1* !== ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*[3] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +6242 -> 6244 free var = FreeVar(arguments) + +0 -> 6245 conditional = (null == ???*0*) +- *0* ((???*1* | ???*2*) ? ???*6* : null) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* (???*3* !== ???*4*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*[3] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* ???*7*[3] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 6247 call = (...) => ((3 === b["tag"]) ? c : null)((???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +0 -> 6249 conditional = ((???*0* !== (???*8* | ???*9*)) | (1 !== ???*11*)) +- *0* (???*1* ? (???*4* | ???*5* | ???*7*) : null) + ⚠️ nested operation +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["_reactInternals"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* a + ⚠️ circular variable reference +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["_reactInternals"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["tag"] + ⚠️ unknown object +- *12* arguments[0] + ⚠️ function calls are not analysed yet + +6249 -> 6250 free var = FreeVar(Error) + +6249 -> 6251 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(170) + +6249 -> 6252 call = ???*0*( + `Minified React error #${170}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${170}` + ⚠️ nested operation + +0 -> 6257 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6258 conditional = ((null !== ???*0*) | (???*2* !== ???*3*)) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["type"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6262 free var = FreeVar(Error) + +0 -> 6263 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(171) + +0 -> 6264 call = ???*0*( + `Minified React error #${171}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${171}` + ⚠️ nested operation + +0 -> 6266 conditional = (1 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +6266 -> 6268 call = (...) => ((null !== a) && (???*0* !== a))(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +6266 -> 6269 conditional = ((null !== ???*0*) | (???*2* !== ???*3*)) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["type"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +6269 -> 6270 call = (...) => (c | A({}, c, d))((???*0* | ???*1*), ???*3*, (???*5* | ???*6*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["type"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* ???*7*["_reactInternals"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference + +0 -> 6271 call = (...) => a( + (???*0* | ???*1* | ???*3*), + (???*5* | (???*6* ? ???*8* : ???*9*)), + true, + (???*17* | ???*18* | ???*20*), + ( + | ???*21* + | 1 + | ???*22* + | ???*23* + | ???*24* + | ???*26* + | 0 + | ???*28* + | 4 + | ((???*29* | ???*31*) ? ???*32* : 4) + | (???*33* ? 16 : (???*34* | null | ???*41* | ???*42*)) + | (???*44* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + ( + | ???*47* + | { + "eventTime": (???*48* | (???*49* ? ???*51* : ???*52*)), + "lane": ( + | ???*60* + | 1 + | ???*61* + | ???*62* + | ???*63* + | ???*65* + | 0 + | ???*67* + | 4 + | ((???*68* | ???*70*) ? ???*71* : 4) + | (???*72* ? 16 : (???*73* | null | ???*80* | ???*81*)) + | (???*83* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + } + ), + ???*86*, + ???*87*, + ???*88* +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* arguments[3] + ⚠️ function calls are not analysed yet +- *6* (0 !== ???*7*) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* module["unstable_now"]() + ⚠️ nested operation +- *9* (???*10* ? (???*14* | ???*15*) : ???*16*) + ⚠️ nested operation +- *10* (???*11* !== (???*12* | ???*13*)) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* module["unstable_now"]() + ⚠️ nested operation +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* module["unstable_now"]() + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["current"] + ⚠️ unknown object +- *19* a + ⚠️ circular variable reference +- *20* unknown new expression + ⚠️ This value might have side effects +- *21* arguments[4] + ⚠️ function calls are not analysed yet +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *24* ???*25*["current"] + ⚠️ unknown object +- *25* arguments[0] + ⚠️ function calls are not analysed yet +- *26* ???*27*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *27* unknown new expression + ⚠️ This value might have side effects +- *28* C + ⚠️ circular variable reference +- *29* (0 !== ???*30*) + ⚠️ nested operation +- *30* C + ⚠️ circular variable reference +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* C + ⚠️ circular variable reference +- *33* unsupported expression + ⚠️ This value might have side effects +- *34* (???*35* ? ???*36* : 1) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* (???*37* ? ???*38* : 4) + ⚠️ nested operation +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* (???*39* ? 16 : 536870912) + ⚠️ nested operation +- *39* (0 !== ???*40*) + ⚠️ nested operation +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* arguments[0] + ⚠️ function calls are not analysed yet +- *42* ???*43*["value"] + ⚠️ unknown object +- *43* arguments[1] + ⚠️ function calls are not analysed yet +- *44* (???*45* === ???*46*) + ⚠️ nested operation +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* a + ⚠️ circular variable reference +- *47* arguments[5] + ⚠️ function calls are not analysed yet +- *48* arguments[3] + ⚠️ function calls are not analysed yet +- *49* (0 !== ???*50*) + ⚠️ nested operation +- *50* unsupported expression + ⚠️ This value might have side effects +- *51* module["unstable_now"]() + ⚠️ nested operation +- *52* (???*53* ? (???*57* | ???*58*) : ???*59*) + ⚠️ nested operation +- *53* (???*54* !== (???*55* | ???*56*)) + ⚠️ nested operation +- *54* unsupported expression + ⚠️ This value might have side effects +- *55* unsupported expression + ⚠️ This value might have side effects +- *56* module["unstable_now"]() + ⚠️ nested operation +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* module["unstable_now"]() + ⚠️ nested operation +- *59* unsupported expression + ⚠️ This value might have side effects +- *60* arguments[4] + ⚠️ function calls are not analysed yet +- *61* unsupported expression + ⚠️ This value might have side effects +- *62* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *63* ???*64*["current"] + ⚠️ unknown object +- *64* arguments[0] + ⚠️ function calls are not analysed yet +- *65* ???*66*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *66* unknown new expression + ⚠️ This value might have side effects +- *67* C + ⚠️ circular variable reference +- *68* (0 !== ???*69*) + ⚠️ nested operation +- *69* C + ⚠️ circular variable reference +- *70* unsupported expression + ⚠️ This value might have side effects +- *71* C + ⚠️ circular variable reference +- *72* unsupported expression + ⚠️ This value might have side effects +- *73* (???*74* ? ???*75* : 1) + ⚠️ nested operation +- *74* unsupported expression + ⚠️ This value might have side effects +- *75* (???*76* ? ???*77* : 4) + ⚠️ nested operation +- *76* unsupported expression + ⚠️ This value might have side effects +- *77* (???*78* ? 16 : 536870912) + ⚠️ nested operation +- *78* (0 !== ???*79*) + ⚠️ nested operation +- *79* unsupported expression + ⚠️ This value might have side effects +- *80* arguments[0] + ⚠️ function calls are not analysed yet +- *81* ???*82*["value"] + ⚠️ unknown object +- *82* arguments[1] + ⚠️ function calls are not analysed yet +- *83* (???*84* === ???*85*) + ⚠️ nested operation +- *84* unsupported expression + ⚠️ This value might have side effects +- *85* a + ⚠️ circular variable reference +- *86* arguments[6] + ⚠️ function calls are not analysed yet +- *87* arguments[7] + ⚠️ function calls are not analysed yet +- *88* arguments[8] + ⚠️ function calls are not analysed yet + +0 -> 6273 call = (...) => (Vf | bg(a, c, b) | b)(null) + +0 -> 6275 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 6276 call = (...) => (1 | ???*0* | ???*1* | a)((???*2* | ???*3* | ???*5*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["current"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* unknown new expression + ⚠️ This value might have side effects + +0 -> 6277 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}( + (???*0* | (???*1* ? ???*3* : ???*4*)), + ( + | ???*12* + | 1 + | ???*13* + | ???*14* + | ???*15* + | ???*17* + | 0 + | ???*19* + | 4 + | ((???*20* | ???*22*) ? ???*23* : 4) + | (???*24* ? 16 : (???*25* | null | ???*32* | ???*33*)) + | (???*35* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* module["unstable_now"]() + ⚠️ nested operation +- *4* (???*5* ? (???*9* | ???*10*) : ???*11*) + ⚠️ nested operation +- *5* (???*6* !== (???*7* | ???*8*)) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* module["unstable_now"]() + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* arguments[4] + ⚠️ function calls are not analysed yet +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *15* ???*16*["current"] + ⚠️ unknown object +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unknown new expression + ⚠️ This value might have side effects +- *19* C + ⚠️ circular variable reference +- *20* (0 !== ???*21*) + ⚠️ nested operation +- *21* C + ⚠️ circular variable reference +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* C + ⚠️ circular variable reference +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* (???*26* ? ???*27* : 1) + ⚠️ nested operation +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* (???*28* ? ???*29* : 4) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* (???*30* ? 16 : 536870912) + ⚠️ nested operation +- *30* (0 !== ???*31*) + ⚠️ nested operation +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* arguments[0] + ⚠️ function calls are not analysed yet +- *33* ???*34*["value"] + ⚠️ unknown object +- *34* arguments[1] + ⚠️ function calls are not analysed yet +- *35* (???*36* === ???*37*) + ⚠️ nested operation +- *36* unsupported expression + ⚠️ This value might have side effects +- *37* a + ⚠️ circular variable reference + +0 -> 6279 conditional = ((???*0* !== ???*1*) | (null !== ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6280 call = (...) => (null | Zg(a, c))( + (???*0* | ???*1* | ???*3*), + ( + | ???*5* + | { + "eventTime": (???*6* | (???*7* ? ???*9* : ???*10*)), + "lane": ( + | ???*18* + | 1 + | ???*19* + | ???*20* + | ???*21* + | ???*23* + | 0 + | ???*25* + | 4 + | ((???*26* | ???*28*) ? ???*29* : 4) + | (???*30* ? 16 : (???*31* | null | ???*38* | ???*39*)) + | (???*41* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + } + ), + ( + | ???*44* + | 1 + | ???*45* + | ???*46* + | ???*47* + | ???*49* + | 0 + | ???*51* + | 4 + | ((???*52* | ???*54*) ? ???*55* : 4) + | (???*56* ? 16 : (???*57* | null | ???*64* | ???*65*)) + | (???*67* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* arguments[5] + ⚠️ function calls are not analysed yet +- *6* arguments[3] + ⚠️ function calls are not analysed yet +- *7* (0 !== ???*8*) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* (???*11* ? (???*15* | ???*16*) : ???*17*) + ⚠️ nested operation +- *11* (???*12* !== (???*13* | ???*14*)) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* module["unstable_now"]() + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* module["unstable_now"]() + ⚠️ nested operation +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* arguments[4] + ⚠️ function calls are not analysed yet +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *21* ???*22*["current"] + ⚠️ unknown object +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* ???*24*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* unknown new expression + ⚠️ This value might have side effects +- *25* C + ⚠️ circular variable reference +- *26* (0 !== ???*27*) + ⚠️ nested operation +- *27* C + ⚠️ circular variable reference +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* C + ⚠️ circular variable reference +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* (???*32* ? ???*33* : 1) + ⚠️ nested operation +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* (???*34* ? ???*35* : 4) + ⚠️ nested operation +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* (???*36* ? 16 : 536870912) + ⚠️ nested operation +- *36* (0 !== ???*37*) + ⚠️ nested operation +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* arguments[0] + ⚠️ function calls are not analysed yet +- *39* ???*40*["value"] + ⚠️ unknown object +- *40* arguments[1] + ⚠️ function calls are not analysed yet +- *41* (???*42* === ???*43*) + ⚠️ nested operation +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* a + ⚠️ circular variable reference +- *44* arguments[4] + ⚠️ function calls are not analysed yet +- *45* unsupported expression + ⚠️ This value might have side effects +- *46* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *47* ???*48*["current"] + ⚠️ unknown object +- *48* arguments[0] + ⚠️ function calls are not analysed yet +- *49* ???*50*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *50* unknown new expression + ⚠️ This value might have side effects +- *51* C + ⚠️ circular variable reference +- *52* (0 !== ???*53*) + ⚠️ nested operation +- *53* C + ⚠️ circular variable reference +- *54* unsupported expression + ⚠️ This value might have side effects +- *55* C + ⚠️ circular variable reference +- *56* unsupported expression + ⚠️ This value might have side effects +- *57* (???*58* ? ???*59* : 1) + ⚠️ nested operation +- *58* unsupported expression + ⚠️ This value might have side effects +- *59* (???*60* ? ???*61* : 4) + ⚠️ nested operation +- *60* unsupported expression + ⚠️ This value might have side effects +- *61* (???*62* ? 16 : 536870912) + ⚠️ nested operation +- *62* (0 !== ???*63*) + ⚠️ nested operation +- *63* unsupported expression + ⚠️ This value might have side effects +- *64* arguments[0] + ⚠️ function calls are not analysed yet +- *65* ???*66*["value"] + ⚠️ unknown object +- *66* arguments[1] + ⚠️ function calls are not analysed yet +- *67* (???*68* === ???*69*) + ⚠️ nested operation +- *68* unsupported expression + ⚠️ This value might have side effects +- *69* a + ⚠️ circular variable reference + +0 -> 6283 call = (...) => undefined( + (???*0* | ???*1* | ???*3*), + ( + | ???*4* + | 1 + | ???*5* + | ???*6* + | ???*7* + | ???*9* + | 0 + | ???*11* + | 4 + | ((???*12* | ???*14*) ? ???*15* : 4) + | (???*16* ? 16 : (???*17* | null | ???*24* | ???*25*)) + | (???*27* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + (???*30* | (???*31* ? ???*33* : ???*34*)) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* arguments[4] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *7* ???*8*["current"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unknown new expression + ⚠️ This value might have side effects +- *11* C + ⚠️ circular variable reference +- *12* (0 !== ???*13*) + ⚠️ nested operation +- *13* C + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* C + ⚠️ circular variable reference +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* (???*18* ? ???*19* : 1) + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* (???*20* ? ???*21* : 4) + ⚠️ nested operation +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* (???*22* ? 16 : 536870912) + ⚠️ nested operation +- *22* (0 !== ???*23*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* arguments[0] + ⚠️ function calls are not analysed yet +- *25* ???*26*["value"] + ⚠️ unknown object +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* (???*28* === ???*29*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* a + ⚠️ circular variable reference +- *30* arguments[3] + ⚠️ function calls are not analysed yet +- *31* (0 !== ???*32*) + ⚠️ nested operation +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* module["unstable_now"]() + ⚠️ nested operation +- *34* (???*35* ? (???*39* | ???*40*) : ???*41*) + ⚠️ nested operation +- *35* (???*36* !== (???*37* | ???*38*)) + ⚠️ nested operation +- *36* unsupported expression + ⚠️ This value might have side effects +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* module["unstable_now"]() + ⚠️ nested operation +- *39* unsupported expression + ⚠️ This value might have side effects +- *40* module["unstable_now"]() + ⚠️ nested operation +- *41* unsupported expression + ⚠️ This value might have side effects + +0 -> 6284 call = (...) => undefined((???*0* | ???*1* | ???*3*), (???*4* | (???*5* ? ???*7* : ???*8*))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* arguments[3] + ⚠️ function calls are not analysed yet +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* (???*9* ? (???*13* | ???*14*) : ???*15*) + ⚠️ nested operation +- *9* (???*10* !== (???*11* | ???*12*)) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* module["unstable_now"]() + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* module["unstable_now"]() + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects + +0 -> 6286 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 6287 call = (...) => (1 | ???*0* | ???*1* | a)((???*2* | ???*4* | ???*5*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +0 -> 6288 call = (...) => (Vf | bg(a, c, b) | b)((???*0* | {} | ???*1* | ???*2* | ???*4*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* c + ⚠️ circular variable reference +- *2* ???*3*["_reactInternals"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* ???*5*({}, c, d) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *5* ???*6*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 6290 conditional = (null === (???*0* | ???*2* | ???*3*)) +- *0* ???*1*["context"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects + +0 -> 6293 call = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null}( + (???*0* ? ???*2* : ???*3*), + ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*15* + | ???*16* + | 0 + | ???*17* + | 4 + | ((???*18* | ???*20*) ? ???*21* : 4) + | (???*22* ? 16 : (???*23* | null | ???*30* | ???*31*)) + | ???*33* + | ???*34* + | (???*36* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* ???*14*["current"] + ⚠️ unknown object +- *14* arguments[1] + ⚠️ function calls are not analysed yet +- *15* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* unknown mutation + ⚠️ This value might have side effects +- *17* C + ⚠️ circular variable reference +- *18* (0 !== ???*19*) + ⚠️ nested operation +- *19* C + ⚠️ circular variable reference +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* C + ⚠️ circular variable reference +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* (???*24* ? ???*25* : 1) + ⚠️ nested operation +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* (???*26* ? ???*27* : 4) + ⚠️ nested operation +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* (???*28* ? 16 : 536870912) + ⚠️ nested operation +- *28* (0 !== ???*29*) + ⚠️ nested operation +- *29* unsupported expression + ⚠️ This value might have side effects +- *30* arguments[0] + ⚠️ function calls are not analysed yet +- *31* ???*32*["value"] + ⚠️ unknown object +- *32* arguments[1] + ⚠️ function calls are not analysed yet +- *33* arguments[0] + ⚠️ function calls are not analysed yet +- *34* ???*35*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *35* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *36* (???*37* === ???*38*) + ⚠️ nested operation +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* a + ⚠️ circular variable reference + +0 -> 6295 conditional = (???*0* === (???*1* | ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? null : ???*6*) + ⚠️ nested operation +- *3* (???*4* === ???*5*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* d + ⚠️ circular variable reference +- *6* d + ⚠️ circular variable reference + +0 -> 6297 call = (...) => (null | Zg(a, c))( + (???*0* | ???*2* | ???*3*), + ( + | ???*4* + | { + "eventTime": (???*5* ? ???*7* : ???*8*), + "lane": ( + | 1 + | ???*16* + | ???*17* + | ???*18* + | 0 + | ???*20* + | 4 + | ((???*21* | ???*23*) ? ???*24* : 4) + | (???*25* ? 16 : (???*26* | null | ???*33* | ???*34*)) + | ???*36* + | ???*37* + | (???*39* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + } + ), + ( + | 1 + | ???*42* + | ???*43* + | ???*44* + | ???*46* + | ???*47* + | 0 + | ???*48* + | 4 + | ((???*49* | ???*51*) ? ???*52* : 4) + | (???*53* ? 16 : (???*54* | null | ???*61* | ???*62*)) + | ???*64* + | ???*65* + | (???*67* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* ???*1*["current"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* (???*9* ? (???*13* | ???*14*) : ???*15*) + ⚠️ nested operation +- *9* (???*10* !== (???*11* | ???*12*)) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* module["unstable_now"]() + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* module["unstable_now"]() + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *18* ???*19*["current"] + ⚠️ unknown object +- *19* b + ⚠️ circular variable reference +- *20* C + ⚠️ circular variable reference +- *21* (0 !== ???*22*) + ⚠️ nested operation +- *22* C + ⚠️ circular variable reference +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* C + ⚠️ circular variable reference +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? ???*28* : 1) + ⚠️ nested operation +- *27* unsupported expression + ⚠️ This value might have side effects +- *28* (???*29* ? ???*30* : 4) + ⚠️ nested operation +- *29* unsupported expression + ⚠️ This value might have side effects +- *30* (???*31* ? 16 : 536870912) + ⚠️ nested operation +- *31* (0 !== ???*32*) + ⚠️ nested operation +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* arguments[0] + ⚠️ function calls are not analysed yet +- *34* ???*35*["value"] + ⚠️ unknown object +- *35* arguments[1] + ⚠️ function calls are not analysed yet +- *36* arguments[0] + ⚠️ function calls are not analysed yet +- *37* ???*38*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *38* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *39* (???*40* === ???*41*) + ⚠️ nested operation +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* a + ⚠️ circular variable reference +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *44* ???*45*["current"] + ⚠️ unknown object +- *45* arguments[1] + ⚠️ function calls are not analysed yet +- *46* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *47* unknown mutation + ⚠️ This value might have side effects +- *48* C + ⚠️ circular variable reference +- *49* (0 !== ???*50*) + ⚠️ nested operation +- *50* C + ⚠️ circular variable reference +- *51* unsupported expression + ⚠️ This value might have side effects +- *52* C + ⚠️ circular variable reference +- *53* unsupported expression + ⚠️ This value might have side effects +- *54* (???*55* ? ???*56* : 1) + ⚠️ nested operation +- *55* unsupported expression + ⚠️ This value might have side effects +- *56* (???*57* ? ???*58* : 4) + ⚠️ nested operation +- *57* unsupported expression + ⚠️ This value might have side effects +- *58* (???*59* ? 16 : 536870912) + ⚠️ nested operation +- *59* (0 !== ???*60*) + ⚠️ nested operation +- *60* unsupported expression + ⚠️ This value might have side effects +- *61* arguments[0] + ⚠️ function calls are not analysed yet +- *62* ???*63*["value"] + ⚠️ unknown object +- *63* arguments[1] + ⚠️ function calls are not analysed yet +- *64* arguments[0] + ⚠️ function calls are not analysed yet +- *65* ???*66*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *66* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *67* (???*68* === ???*69*) + ⚠️ nested operation +- *68* unsupported expression + ⚠️ This value might have side effects +- *69* a + ⚠️ circular variable reference + +0 -> 6298 call = (...) => undefined( + ???*0*, + (???*1* | ???*3* | ???*4*), + ( + | 1 + | ???*5* + | ???*6* + | ???*7* + | ???*9* + | ???*10* + | 0 + | ???*11* + | 4 + | ((???*12* | ???*14*) ? ???*15* : 4) + | (???*16* ? 16 : (???*17* | null | ???*24* | ???*25*)) + | ???*27* + | ???*28* + | (???*30* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + (???*33* ? ???*35* : ???*36*) +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *7* ???*8*["current"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unknown mutation + ⚠️ This value might have side effects +- *11* C + ⚠️ circular variable reference +- *12* (0 !== ???*13*) + ⚠️ nested operation +- *13* C + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* C + ⚠️ circular variable reference +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* (???*18* ? ???*19* : 1) + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* (???*20* ? ???*21* : 4) + ⚠️ nested operation +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* (???*22* ? 16 : 536870912) + ⚠️ nested operation +- *22* (0 !== ???*23*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* arguments[0] + ⚠️ function calls are not analysed yet +- *25* ???*26*["value"] + ⚠️ unknown object +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* arguments[0] + ⚠️ function calls are not analysed yet +- *28* ???*29*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *30* (???*31* === ???*32*) + ⚠️ nested operation +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* a + ⚠️ circular variable reference +- *33* (0 !== ???*34*) + ⚠️ nested operation +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* module["unstable_now"]() + ⚠️ nested operation +- *36* (???*37* ? (???*41* | ???*42*) : ???*43*) + ⚠️ nested operation +- *37* (???*38* !== (???*39* | ???*40*)) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* unsupported expression + ⚠️ This value might have side effects +- *40* module["unstable_now"]() + ⚠️ nested operation +- *41* unsupported expression + ⚠️ This value might have side effects +- *42* module["unstable_now"]() + ⚠️ nested operation +- *43* unsupported expression + ⚠️ This value might have side effects + +0 -> 6299 call = (...) => undefined( + ???*0*, + (???*1* | ???*3* | ???*4*), + ( + | 1 + | ???*5* + | ???*6* + | ???*7* + | ???*9* + | ???*10* + | 0 + | ???*11* + | 4 + | ((???*12* | ???*14*) ? ???*15* : 4) + | (???*16* ? 16 : (???*17* | null | ???*24* | ???*25*)) + | ???*27* + | ???*28* + | (???*30* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *7* ???*8*["current"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unknown mutation + ⚠️ This value might have side effects +- *11* C + ⚠️ circular variable reference +- *12* (0 !== ???*13*) + ⚠️ nested operation +- *13* C + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* C + ⚠️ circular variable reference +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* (???*18* ? ???*19* : 1) + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* (???*20* ? ???*21* : 4) + ⚠️ nested operation +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* (???*22* ? 16 : 536870912) + ⚠️ nested operation +- *22* (0 !== ???*23*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* arguments[0] + ⚠️ function calls are not analysed yet +- *25* ???*26*["value"] + ⚠️ unknown object +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* arguments[0] + ⚠️ function calls are not analysed yet +- *28* ???*29*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *30* (???*31* === ???*32*) + ⚠️ nested operation +- *31* unsupported expression + ⚠️ This value might have side effects +- *32* a + ⚠️ circular variable reference + +0 -> 6310 conditional = ((null !== (???*0* | ???*1*)) | (null !== ???*3*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["dehydrated"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +6310 -> 6313 conditional = ((0 !== ???*0*) | ???*2*) +- *0* ???*1*["retryLane"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 6314 call = (...) => undefined((???*0* | ???*1*), ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6316 call = (...) => undefined((???*0* | ???*1*), ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6317 free var = FreeVar(reportError) + +0 -> 6318 conditional = ("function" === ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects + +6318 -> 6319 free var = FreeVar(reportError) + +6318 -> 6321 free var = FreeVar(console) + +6318 -> 6322 member call = ???*0*["error"](???*1*) +- *0* FreeVar(console) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6329 conditional = (null === ???*0*) +- *0* ???*1*["_internalRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +6329 -> 6330 free var = FreeVar(Error) + +6329 -> 6331 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(409) + +6329 -> 6332 call = ???*0*( + `Minified React error #${409}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${409}` + ⚠️ nested operation + +0 -> 6333 call = (...) => g(???*0*, ???*1*, null, null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_internalRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +0 -> 6339 conditional = (null !== ???*0*) +- *0* ???*1*["_internalRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +6339 -> 6342 call = (...) => (undefined | a())((...) => undefined) + +6342 -> 6343 call = (...) => g(null, ???*0*, null, null) +- *0* ???*1*["_internalRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +0 -> 6348 conditional = ( + | ???*0* + | { + "blockedOn": null, + "target": ???*1*, + "priority": ( + | ???*2*() + | 0 + | 1 + | ???*3* + | 4 + | ((???*4* | ???*6*) ? ???*7* : 4) + | (???*8* ? 16 : (???*9* | null | ???*16* | ???*17*)) + | ???*19* + ) + } +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* Hc + ⚠️ pattern without value +- *3* C + ⚠️ circular variable reference +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 1) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 4) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? 16 : 536870912) + ⚠️ nested operation +- *14* (0 !== ???*15*) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["value"] + ⚠️ unknown object +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* arguments[0] + ⚠️ function calls are not analysed yet + +6348 -> 6349 call = (???*0* | (...) => C)() +- *0* Hc + ⚠️ pattern without value + +6348 -> 6354 member call = []["splice"]( + (0 | ???*0*), + 0, + ( + | ???*1* + | { + "blockedOn": null, + "target": ???*2*, + "priority": ( + | ???*3*() + | 0 + | 1 + | ???*4* + | 4 + | ((???*5* | ???*7*) ? ???*8* : 4) + | (???*9* ? 16 : (???*10* | null | ???*17* | ???*18*)) + | ???*20* + ) + } + ) +) +- *0* updated with update expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* Hc + ⚠️ pattern without value +- *4* C + ⚠️ circular variable reference +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* C + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? ???*12* : 1) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 4) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? 16 : 536870912) + ⚠️ nested operation +- *15* (0 !== ???*16*) + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["value"] + ⚠️ unknown object +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* arguments[0] + ⚠️ function calls are not analysed yet + +6348 -> 6355 call = (...) => (undefined | FreeVar(undefined))( + ( + | ???*0* + | { + "blockedOn": null, + "target": ???*1*, + "priority": ( + | ???*2*() + | 0 + | 1 + | ???*3* + | 4 + | ((???*4* | ???*6*) ? ???*7* : 4) + | (???*8* ? 16 : (???*9* | null | ???*16* | ???*17*)) + | ???*19* + ) + } + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* Hc + ⚠️ pattern without value +- *3* C + ⚠️ circular variable reference +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 1) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 4) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? 16 : 536870912) + ⚠️ nested operation +- *14* (0 !== ???*15*) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["value"] + ⚠️ unknown object +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6364 conditional = (???*0* | ???*1*) +- *0* arguments[4] + ⚠️ function calls are not analysed yet +- *1* ???*2*["lastChild"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +6364 -> 6365 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | (...) => undefined)) + ⚠️ nested operation +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +6365 -> 6366 call = (...) => (undefined | null | a["child"]["stateNode"])((???*0* | ???*1* | ???*3*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects + +6365 -> 6368 member call = (???*0* | (...) => undefined)["call"](???*1*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +6364 -> 6369 call = (...) => a(???*0*, (???*1* | (...) => undefined), ???*2*, 0, null, false, false, "", (...) => undefined) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +6364 -> 6374 conditional = (8 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +6364 -> 6376 call = (...) => undefined((???*0* ? ???*3* : ???*5*)) +- *0* (8 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["parentNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +6364 -> 6377 call = (...) => (undefined | a())() + +0 -> 6380 member call = ???*0*["removeChild"]((???*1* | ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[4] + ⚠️ function calls are not analysed yet +- *2* ???*3*["lastChild"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6381 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | (...) => undefined)) + ⚠️ nested operation +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +6381 -> 6382 call = (...) => (undefined | null | a["child"]["stateNode"])((???*0* | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +6381 -> 6384 member call = (???*0* | (...) => undefined)["call"]((undefined | null | ???*1* | ???*4*)) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* ???*3*["child"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* unknown new expression + ⚠️ This value might have side effects + +0 -> 6385 call = (...) => a(???*0*, 0, false, null, null, false, false, "", (...) => undefined) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6390 conditional = (8 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6392 call = (...) => undefined((???*0* ? ???*3* : ???*5*)) +- *0* (8 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["parentNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6393 call = (...) => (undefined | a())((...) => undefined) + +6393 -> 6394 call = (...) => g(???*0*, (???*1* | ???*2*), ???*3*, (???*4* | (...) => undefined)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 6396 conditional = ???*0* +- *0* ???*1*["_reactRootContainer"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +6396 -> 6397 conditional = ("function" === ???*0*) +- *0* typeof((???*1* | (...) => undefined)) + ⚠️ nested operation +- *1* arguments[4] + ⚠️ function calls are not analysed yet + +6397 -> 6398 call = (...) => (undefined | null | a["child"]["stateNode"])(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6397 -> 6400 member call = (???*0* | (...) => undefined)["call"](???*1*) +- *0* arguments[4] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +6396 -> 6401 call = (...) => g(???*0*, ???*1*, ???*2*, (???*3* | (...) => undefined)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* max number of linking steps reached + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[4] + ⚠️ function calls are not analysed yet + +6396 -> 6402 call = (...) => (g | k)(???*0*, ???*1*, ???*2*, (???*3* | (...) => undefined), ???*4*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[4] + ⚠️ function calls are not analysed yet +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 6403 call = (...) => (undefined | null | a["child"]["stateNode"])(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6409 conditional = ???*0* +- *0* ???*1*["isDehydrated"] + ⚠️ unknown object +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +6409 -> 6411 call = (...) => (undefined | 1 | 2 | 4 | 8 | 16 | 32 | ???*0* | 134217728 | 268435456 | 536870912 | 1073741824 | a)(???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["pendingLanes"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +6409 -> 6412 call = (...) => undefined(???*0*, ???*2*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +6409 -> 6413 call = module["unstable_now"]() + +6409 -> 6414 call = (...) => undefined(???*0*, module["unstable_now"]()) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +6409 -> 6415 call = module["unstable_now"]() + +6409 -> 6416 call = (...) => null() + +0 -> 6417 call = (...) => (undefined | a())((...) => undefined) + +6417 -> 6418 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)(???*0*, 1) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +6417 -> 6419 conditional = (null !== ???*0*) +- *0* (???*1* ? ???*5* : null) + ⚠️ nested operation +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +6419 -> 6420 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +6419 -> 6421 call = (...) => undefined((???*0* ? ???*4* : null), ???*7*, 1, (???*8* ? ???*10* : ???*11*)) +- *0* (3 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["alternate"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* (0 !== ???*9*) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* (???*12* ? (???*16* | ???*17*) : ???*18*) + ⚠️ nested operation +- *12* (???*13* !== (???*14* | ???*15*)) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* module["unstable_now"]() + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* module["unstable_now"]() + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects + +0 -> 6422 call = (...) => undefined(???*0*, 1) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6424 conditional = (13 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +6424 -> 6425 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)(???*0*, 134217728) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +6424 -> 6426 conditional = (null !== ???*0*) +- *0* (???*1* ? ???*5* : null) + ⚠️ nested operation +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +6426 -> 6427 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +6426 -> 6428 call = (...) => undefined((???*0* ? ???*4* : null), ???*7*, 134217728, (???*8* ? ???*10* : ???*11*)) +- *0* (3 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["alternate"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* (0 !== ???*9*) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* (???*12* ? (???*16* | ???*17*) : ???*18*) + ⚠️ nested operation +- *12* (???*13* !== (???*14* | ???*15*)) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* module["unstable_now"]() + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* module["unstable_now"]() + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects + +6424 -> 6429 call = (...) => undefined(???*0*, 134217728) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6431 conditional = (13 === ???*0*) +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +6431 -> 6432 call = (...) => (1 | ???*0* | ???*1* | a)(???*2*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +6431 -> 6433 call = (...) => ((3 === c["tag"]) ? c["stateNode"] : null)( + ???*0*, + ( + | 1 + | ???*1* + | ???*2* + | ???*3* + | 0 + | ???*4* + | 4 + | ((???*5* | ???*7*) ? ???*8* : 4) + | (???*9* ? 16 : (???*10* | null | ???*17* | ???*18*)) + | ???*20* + | (???*22* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* C + ⚠️ circular variable reference +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* C + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? ???*12* : 1) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 4) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? 16 : 536870912) + ⚠️ nested operation +- *15* (0 !== ???*16*) + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["value"] + ⚠️ unknown object +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *22* (???*23* === ???*24*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* a + ⚠️ circular variable reference + +6431 -> 6434 conditional = (null !== ???*0*) +- *0* (???*1* ? ???*5* : null) + ⚠️ nested operation +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +6434 -> 6435 call = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*))() +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +6434 -> 6436 call = (...) => undefined( + (???*0* ? ???*4* : null), + ???*7*, + ( + | 1 + | ???*8* + | ???*9* + | ???*10* + | 0 + | ???*11* + | 4 + | ((???*12* | ???*14*) ? ???*15* : 4) + | (???*16* ? 16 : (???*17* | null | ???*24* | ???*25*)) + | ???*27* + | (???*29* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + (???*32* ? ???*34* : ???*35*) +) +- *0* (3 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["alternate"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* C + ⚠️ circular variable reference +- *12* (0 !== ???*13*) + ⚠️ nested operation +- *13* C + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* C + ⚠️ circular variable reference +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* (???*18* ? ???*19* : 1) + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* (???*20* ? ???*21* : 4) + ⚠️ nested operation +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* (???*22* ? 16 : 536870912) + ⚠️ nested operation +- *22* (0 !== ???*23*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* arguments[0] + ⚠️ function calls are not analysed yet +- *25* ???*26*["value"] + ⚠️ unknown object +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* ???*28*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *28* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *29* (???*30* === ???*31*) + ⚠️ nested operation +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* a + ⚠️ circular variable reference +- *32* (0 !== ???*33*) + ⚠️ nested operation +- *33* unsupported expression + ⚠️ This value might have side effects +- *34* module["unstable_now"]() + ⚠️ nested operation +- *35* (???*36* ? (???*40* | ???*41*) : ???*42*) + ⚠️ nested operation +- *36* (???*37* !== (???*38* | ???*39*)) + ⚠️ nested operation +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* module["unstable_now"]() + ⚠️ nested operation +- *40* unsupported expression + ⚠️ This value might have side effects +- *41* module["unstable_now"]() + ⚠️ nested operation +- *42* unsupported expression + ⚠️ This value might have side effects + +6431 -> 6437 call = (...) => undefined( + ???*0*, + ( + | 1 + | ???*1* + | ???*2* + | ???*3* + | 0 + | ???*4* + | 4 + | ((???*5* | ???*7*) ? ???*8* : 4) + | (???*9* ? 16 : (???*10* | null | ???*17* | ???*18*)) + | ???*20* + | (???*22* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* C + ⚠️ circular variable reference +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* C + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? ???*12* : 1) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 4) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? 16 : 536870912) + ⚠️ nested operation +- *15* (0 !== ???*16*) + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["value"] + ⚠️ unknown object +- *19* arguments[1] + ⚠️ function calls are not analysed yet +- *20* ???*21*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *22* (???*23* === ???*24*) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* a + ⚠️ circular variable reference + +0 -> 6438 call = ???*0*() +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6439 call = (...) => (undefined | FreeVar(undefined))(???*0*, (???*1* | ???*2* | ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["parentNode"] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference +- *4* ???*5*["querySelectorAll"]( + `input[name=${FreeVar(JSON)["stringify"](`${b}`)}][type="radio"]` + ) + ⚠️ unknown callee object +- *5* c + ⚠️ circular variable reference + +0 -> 6442 conditional = (("radio" === ???*0*) | (null != (???*2* | ???*3* | 0 | ???*5*))) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["name"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects + +6442 -> 6447 free var = FreeVar(JSON) + +6442 -> 6448 member call = ???*0*["stringify"]((???*1* | ???*2* | 0 | ???*4*)) +- *0* FreeVar(JSON) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["name"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects + +6442 -> 6449 member call = (???*0* | ???*1* | ???*3*)["querySelectorAll"](`input[name=${???*5*}][type="radio"]`) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["parentNode"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference +- *3* ???*4*["querySelectorAll"]( + `input[name=${FreeVar(JSON)["stringify"](`${b}`)}][type="radio"]` + ) + ⚠️ unknown callee object +- *4* c + ⚠️ circular variable reference +- *5* ???*6*["stringify"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *6* FreeVar(JSON) + ⚠️ unknown global + ⚠️ This value might have side effects + +6442 -> 6454 conditional = ((???*0* !== ???*6*) | (???*7* === ???*14*)) +- *0* ???*1*[(???*2* | ???*3* | 0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["name"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*["form"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???*9*[(???*10* | ???*11* | 0 | ???*13*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["name"] + ⚠️ unknown object +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* updated with update expression + ⚠️ This value might have side effects +- *14* ???*15*["form"] + ⚠️ unknown object +- *15* arguments[0] + ⚠️ function calls are not analysed yet + +6454 -> 6455 call = (...) => (a[Pf] || null)(???*0*) +- *0* ???*1*[(???*2* | ???*3* | 0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["name"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects + +6454 -> 6456 conditional = !((???*0* | null)) +- *0* ???*1*[Pf] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(???*3* | ???*4* | 0 | ???*6*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["name"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects + +6456 -> 6457 free var = FreeVar(Error) + +6456 -> 6458 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(90) + +6456 -> 6459 call = ???*0*( + `Minified React error #${90}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${90}` + ⚠️ nested operation + +6454 -> 6460 call = (...) => (!(1) | !(0) | ((a !== c) ? !(0) : !(1)))(???*0*) +- *0* ???*1*[(???*2* | ???*3* | 0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["name"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects + +6454 -> 6461 call = (...) => (undefined | FreeVar(undefined))(???*0*, (???*6* | null)) +- *0* ???*1*[(???*2* | ???*3* | 0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["name"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* ???*7*[Pf] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*[(???*9* | ???*10* | 0 | ???*12*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* ???*11*["name"] + ⚠️ unknown object +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* updated with update expression + ⚠️ This value might have side effects + +0 -> 6462 call = (...) => undefined(???*0*, (???*1* | ???*2* | ???*4*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*["parentNode"] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference +- *4* ???*5*["querySelectorAll"]( + `input[name=${FreeVar(JSON)["stringify"](`${b}`)}][type="radio"]` + ) + ⚠️ unknown callee object +- *5* c + ⚠️ circular variable reference + +0 -> 6465 call = (...) => (undefined | FreeVar(undefined))(???*0*, !(???*1*), (???*4* | ???*5* | 0 | ???*7*), false) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* !(???*2*) + ⚠️ nested operation +- *2* ???*3*["multiple"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["name"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* updated with update expression + ⚠️ This value might have side effects + +0 -> 6471 call = (...) => ((null !== a) ? $b(a) : null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6472 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6475 free var = FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + +0 -> 6476 conditional = ("undefined" !== ???*0*) +- *0* typeof(???*1*) + ⚠️ nested operation +- *1* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects + +6476 -> 6477 free var = FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + +6476 -> 6480 conditional = (!(???*0*) | ???*2*) +- *0* ???*1*["isDisabled"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["supportsFiber"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects + +6480 -> 6482 member call = ???*0*["inject"]( + { + "bundleType": (0 | ???*1*), + "version": ("18.2.0" | ???*2*), + "rendererPackageName": ("react-dom" | ???*3*), + "rendererConfig": (???*4* | ???*5*), + "overrideHookState": null, + "overrideHookStateDeletePath": null, + "overrideHookStateRenamePath": null, + "overrideProps": null, + "overridePropsDeletePath": null, + "overridePropsRenamePath": null, + "setErrorHandler": null, + "setSuspenseHandler": null, + "scheduleUpdate": null, + "currentDispatcherRef": module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"], + "findHostInstanceByFiber": (...) => ((null === a) ? null : a["stateNode"]), + "findFiberByHostInstance": ((...) => (b | c | null) | ???*6* | (...) => null), + "findHostInstancesForRefresh": null, + "scheduleRefresh": null, + "scheduleRoot": null, + "setRefreshHandler": null, + "getCurrentFiber": null, + "reconcilerVersion": "18.2.0-next-9e3b772b8-20220608" + } +) +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects + +0 -> 6484 free var = FreeVar(exports) + +0 -> 6486 free var = FreeVar(exports) + +0 -> 6488 free var = FreeVar(arguments) + +0 -> 6490 free var = FreeVar(arguments) + +0 -> 6491 conditional = (???*0* | (???*1* !== ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*[2] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +6491 -> 6493 free var = FreeVar(arguments) + +0 -> 6494 call = (...) => !(( + || !(a) + || ((1 !== a["nodeType"]) && (9 !== a["nodeType"]) && (11 !== a["nodeType"])) +))(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6495 conditional = !(???*0*) +- *0* !(???*1*) + ⚠️ nested operation +- *1* !(???*2*) + ⚠️ nested operation +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +6495 -> 6496 free var = FreeVar(Error) + +6495 -> 6497 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(200) + +6495 -> 6498 call = ???*0*( + `Minified React error #${200}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${200}` + ⚠️ nested operation + +0 -> 6499 call = (...) => { + "$$typeof": wa, + "key": ((null == d) ? null : `${d}`), + "children": a, + "containerInfo": b, + "implementation": c +}(???*0*, ???*1*, null, ((???*2* | ???*3*) ? ???*7* : null)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (???*4* !== ???*5*) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* ???*6*[2] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* ???*8*[2] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +0 -> 6501 free var = FreeVar(exports) + +0 -> 6502 call = (...) => !(( + || !(a) + || ((1 !== a["nodeType"]) && (9 !== a["nodeType"]) && (11 !== a["nodeType"])) +))(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6503 conditional = !(???*0*) +- *0* !(???*1*) + ⚠️ nested operation +- *1* !(???*2*) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +6503 -> 6504 free var = FreeVar(Error) + +6503 -> 6505 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(299) + +6503 -> 6506 call = ???*0*( + `Minified React error #${299}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${299}` + ⚠️ nested operation + +0 -> 6512 call = (...) => a( + ???*0*, + 1, + false, + null, + null, + (false | true), + false, + ("" | ???*1* | ???*3*), + ((???*5* ? ???*8* : (...) => undefined) | ???*9* | ???*11*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["identifierPrefix"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["identifierPrefix"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* ("function" === ???*6*) + ⚠️ nested operation +- *6* typeof(???*7*) + ⚠️ nested operation +- *7* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* ???*10*["onRecoverableError"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["onRecoverableError"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unknown new expression + ⚠️ This value might have side effects + +0 -> 6516 conditional = (8 === ???*0*) +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6518 call = (...) => undefined((???*0* ? ???*3* : ???*5*)) +- *0* (8 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["parentNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6520 free var = FreeVar(exports) + +0 -> 6523 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6523 -> 6525 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6525 -> 6526 free var = FreeVar(Error) + +6525 -> 6527 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(188) + +6525 -> 6528 call = ???*0*( + `Minified React error #${188}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${188}` + ⚠️ nested operation + +6523 -> 6531 free var = FreeVar(Object) + +6523 -> 6532 member call = ???*0*["keys"](???*1*) +- *0* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +6523 -> 6533 member call = ???*0*["join"](",") +- *0* ???*1*["keys"](a) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +6523 -> 6534 free var = FreeVar(Error) + +6523 -> 6535 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(268, ???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6523 -> 6536 call = ???*0*(???*1*) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6537 call = (...) => ((null !== a) ? $b(a) : null)(???*0*) +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6538 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +0 -> 6541 free var = FreeVar(exports) + +0 -> 6542 call = (...) => (undefined | a())(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6544 free var = FreeVar(exports) + +0 -> 6545 call = (...) => !(( + || !(a) + || ( + && (1 !== a["nodeType"]) + && (9 !== a["nodeType"]) + && (11 !== a["nodeType"]) + && ( + || (8 !== a["nodeType"]) + || (" react-mount-point-unstable " !== a["nodeValue"]) + ) + ) +))(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6546 conditional = !(???*0*) +- *0* !(???*1*) + ⚠️ nested operation +- *1* !(???*2*) + ⚠️ nested operation +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +6546 -> 6547 free var = FreeVar(Error) + +6546 -> 6548 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(200) + +6546 -> 6549 call = ???*0*( + `Minified React error #${200}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${200}` + ⚠️ nested operation + +0 -> 6550 call = (...) => hl(g)(null, ???*0*, ???*1*, true, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 6552 free var = FreeVar(exports) + +0 -> 6553 call = (...) => !(( + || !(a) + || ((1 !== a["nodeType"]) && (9 !== a["nodeType"]) && (11 !== a["nodeType"])) +))((???*0* | 0 | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +0 -> 6554 conditional = !(???*0*) +- *0* !(???*1*) + ⚠️ nested operation +- *1* !((???*2* | 0 | ???*3*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects + +6554 -> 6555 free var = FreeVar(Error) + +6554 -> 6556 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(405) + +6554 -> 6557 call = ???*0*( + `Minified React error #${405}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${405}` + ⚠️ nested operation + +0 -> 6564 conditional = (null != (???*0* | ???*1* | null[(???*6* | 0 | ???*7*)])) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*[(???*4* | 0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* (null != ???*3*) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* updated with update expression + ⚠️ This value might have side effects + +0 -> 6565 call = (...) => a( + ???*0*, + null, + (???*1* | 0 | ???*2*), + 1, + (???*3* ? (???*12* | ???*13* | null[(???*18* | 0 | ???*19*)]) : null), + ( + | false + | true + | ???*20* + | (null != ???*22*)[(???*23* | 0 | ???*24*)]["_getVersion"] + | ???*25* + | null[(???*31* | 0 | ???*32*)]["_getVersion"] + | ???*33* + ), + false, + ( + | "" + | ???*35* + | (null != ???*37*)[(???*38* | 0 | ???*39*)]["identifierPrefix"] + | ???*40* + | null[(???*46* | 0 | ???*47*)]["identifierPrefix"] + ), + ( + | (???*48* ? ???*51* : (...) => undefined) + | ???*52* + | (null != ???*54*)[(???*55* | 0 | ???*56*)]["onRecoverableError"] + | ???*57* + | null[(???*63* | 0 | ???*64*)]["onRecoverableError"] + ) +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* updated with update expression + ⚠️ This value might have side effects +- *3* (null != (???*4* | ???*5* | null[(???*10* | 0 | ???*11*)])) + ⚠️ nested operation +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*[(???*8* | 0 | ???*9*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* (null != ???*7*) + ⚠️ nested operation +- *7* c + ⚠️ circular variable reference +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* updated with update expression + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*[(???*16* | 0 | ???*17*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* (null != ???*15*) + ⚠️ nested operation +- *15* c + ⚠️ circular variable reference +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* updated with update expression + ⚠️ This value might have side effects +- *18* arguments[0] + ⚠️ function calls are not analysed yet +- *19* updated with update expression + ⚠️ This value might have side effects +- *20* ???*21*["_getVersion"] + ⚠️ unknown object +- *21* arguments[2] + ⚠️ function calls are not analysed yet +- *22* c + ⚠️ circular variable reference +- *23* arguments[0] + ⚠️ function calls are not analysed yet +- *24* updated with update expression + ⚠️ This value might have side effects +- *25* ???*26*["_getVersion"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* ???*27*[(???*29* | 0 | ???*30*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *27* ???*28*["hydratedSources"] + ⚠️ unknown object +- *28* c + ⚠️ circular variable reference +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* updated with update expression + ⚠️ This value might have side effects +- *31* arguments[0] + ⚠️ function calls are not analysed yet +- *32* updated with update expression + ⚠️ This value might have side effects +- *33* ???*34*(c["_source"]) + ⚠️ unknown callee +- *34* e + ⚠️ circular variable reference +- *35* ???*36*["identifierPrefix"] + ⚠️ unknown object +- *36* arguments[2] + ⚠️ function calls are not analysed yet +- *37* c + ⚠️ circular variable reference +- *38* arguments[0] + ⚠️ function calls are not analysed yet +- *39* updated with update expression + ⚠️ This value might have side effects +- *40* ???*41*["identifierPrefix"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *41* ???*42*[(???*44* | 0 | ???*45*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *42* ???*43*["hydratedSources"] + ⚠️ unknown object +- *43* c + ⚠️ circular variable reference +- *44* arguments[0] + ⚠️ function calls are not analysed yet +- *45* updated with update expression + ⚠️ This value might have side effects +- *46* arguments[0] + ⚠️ function calls are not analysed yet +- *47* updated with update expression + ⚠️ This value might have side effects +- *48* ("function" === ???*49*) + ⚠️ nested operation +- *49* typeof(???*50*) + ⚠️ nested operation +- *50* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *51* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *52* ???*53*["onRecoverableError"] + ⚠️ unknown object +- *53* arguments[2] + ⚠️ function calls are not analysed yet +- *54* c + ⚠️ circular variable reference +- *55* arguments[0] + ⚠️ function calls are not analysed yet +- *56* updated with update expression + ⚠️ This value might have side effects +- *57* ???*58*["onRecoverableError"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *58* ???*59*[(???*61* | 0 | ???*62*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *59* ???*60*["hydratedSources"] + ⚠️ unknown object +- *60* c + ⚠️ circular variable reference +- *61* arguments[0] + ⚠️ function calls are not analysed yet +- *62* updated with update expression + ⚠️ This value might have side effects +- *63* arguments[0] + ⚠️ function calls are not analysed yet +- *64* updated with update expression + ⚠️ This value might have side effects + +0 -> 6568 call = (...) => undefined((???*0* | 0 | ???*1*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +0 -> 6569 conditional = ((null != (???*0* | ???*1*)) | ???*3* | null) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*[a] + ⚠️ unknown object +- *2* d + ⚠️ circular variable reference +- *3* ???*4*["hydratedSources"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +6569 -> 6574 call = ( + | false + | true + | ???*0* + | (null != ???*2*)[(???*3* | 0 | ???*4*)]["_getVersion"] + | ???*5* + | null[(???*11* | 0 | ???*12*)]["_getVersion"] + | ???*13* +)( + ( + | ???*15* + | (null != ???*17*)[(???*18* | 0 | ???*19*)]["_source"] + | ???*20* + | null[(???*26* | 0 | ???*27*)]["_source"] + ) +) +- *0* ???*1*["_getVersion"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["_getVersion"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*[(???*9* | 0 | ???*10*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["hydratedSources"] + ⚠️ unknown object +- *8* c + ⚠️ circular variable reference +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* updated with update expression + ⚠️ This value might have side effects +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* updated with update expression + ⚠️ This value might have side effects +- *13* ???*14*(c["_source"]) + ⚠️ unknown callee +- *14* e + ⚠️ circular variable reference +- *15* ???*16*["_source"] + ⚠️ unknown object +- *16* arguments[2] + ⚠️ function calls are not analysed yet +- *17* c + ⚠️ circular variable reference +- *18* arguments[0] + ⚠️ function calls are not analysed yet +- *19* updated with update expression + ⚠️ This value might have side effects +- *20* ???*21*["_source"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* ???*22*[(???*24* | 0 | ???*25*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* ???*23*["hydratedSources"] + ⚠️ unknown object +- *23* c + ⚠️ circular variable reference +- *24* arguments[0] + ⚠️ function calls are not analysed yet +- *25* updated with update expression + ⚠️ This value might have side effects +- *26* arguments[0] + ⚠️ function calls are not analysed yet +- *27* updated with update expression + ⚠️ This value might have side effects + +6569 -> 6576 conditional = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +6576 -> 6580 member call = ???*0*["push"]( + (???*1* | (null != ???*2*)[(???*3* | 0 | ???*4*)] | ???*5* | null[(???*10* | 0 | ???*11*)]), + ( + | false + | true + | ???*12* + | (null != ???*14*)[(???*15* | 0 | ???*16*)]["_getVersion"] + | ???*17* + | null[(???*23* | 0 | ???*24*)]["_getVersion"] + | ???*25* + ) +) +- *0* max number of linking steps reached + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*[(???*8* | 0 | ???*9*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["hydratedSources"] + ⚠️ unknown object +- *7* c + ⚠️ circular variable reference +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* updated with update expression + ⚠️ This value might have side effects +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* ???*13*["_getVersion"] + ⚠️ unknown object +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* c + ⚠️ circular variable reference +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* updated with update expression + ⚠️ This value might have side effects +- *17* ???*18*["_getVersion"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* ???*19*[(???*21* | 0 | ???*22*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* ???*20*["hydratedSources"] + ⚠️ unknown object +- *20* c + ⚠️ circular variable reference +- *21* arguments[0] + ⚠️ function calls are not analysed yet +- *22* updated with update expression + ⚠️ This value might have side effects +- *23* arguments[0] + ⚠️ function calls are not analysed yet +- *24* updated with update expression + ⚠️ This value might have side effects +- *25* ???*26*(c["_source"]) + ⚠️ unknown callee +- *26* e + ⚠️ circular variable reference + +0 -> 6582 free var = FreeVar(exports) + +0 -> 6583 call = (...) => !(( + || !(a) + || ( + && (1 !== a["nodeType"]) + && (9 !== a["nodeType"]) + && (11 !== a["nodeType"]) + && ( + || (8 !== a["nodeType"]) + || (" react-mount-point-unstable " !== a["nodeValue"]) + ) + ) +))(???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 6584 conditional = !(???*0*) +- *0* !(???*1*) + ⚠️ nested operation +- *1* !(???*2*) + ⚠️ nested operation +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +6584 -> 6585 free var = FreeVar(Error) + +6584 -> 6586 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(200) + +6584 -> 6587 call = ???*0*( + `Minified React error #${200}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${200}` + ⚠️ nested operation + +0 -> 6588 call = (...) => hl(g)(null, ???*0*, ???*1*, false, ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 6590 free var = FreeVar(exports) + +0 -> 6591 call = (...) => !(( + || !(a) + || ( + && (1 !== a["nodeType"]) + && (9 !== a["nodeType"]) + && (11 !== a["nodeType"]) + && ( + || (8 !== a["nodeType"]) + || (" react-mount-point-unstable " !== a["nodeValue"]) + ) + ) +))(???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6592 conditional = !(???*0*) +- *0* !(???*1*) + ⚠️ nested operation +- *1* !(???*2*) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +6592 -> 6593 free var = FreeVar(Error) + +6592 -> 6594 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(40) + +6592 -> 6595 call = ???*0*( + `Minified React error #${40}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${40}` + ⚠️ nested operation + +0 -> 6597 conditional = ???*0* +- *0* ???*1*["_reactRootContainer"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +6597 -> 6598 call = (...) => (undefined | a())((...) => undefined) + +6598 -> 6599 call = (...) => hl(g)(null, null, ???*0*, false, (...) => undefined) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6603 free var = FreeVar(exports) + +0 -> 6605 free var = FreeVar(exports) + +0 -> 6606 call = (...) => !(( + || !(a) + || ( + && (1 !== a["nodeType"]) + && (9 !== a["nodeType"]) + && (11 !== a["nodeType"]) + && ( + || (8 !== a["nodeType"]) + || (" react-mount-point-unstable " !== a["nodeValue"]) + ) + ) +))(???*0*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +0 -> 6607 conditional = !(???*0*) +- *0* !(???*1*) + ⚠️ nested operation +- *1* !(???*2*) + ⚠️ nested operation +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +6607 -> 6608 free var = FreeVar(Error) + +6607 -> 6609 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(200) + +6607 -> 6610 call = ???*0*( + `Minified React error #${200}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${200}` + ⚠️ nested operation + +0 -> 6612 conditional = ((null == ???*0*) | (???*1* === ???*2*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["_reactInternals"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +6612 -> 6613 free var = FreeVar(Error) + +6612 -> 6614 call = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`(38) + +6612 -> 6615 call = ???*0*( + `Minified React error #${38}; visit ${???*1*} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` +) +- *0* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${38}` + ⚠️ nested operation + +0 -> 6616 call = (...) => hl(g)(???*0*, ???*1*, ???*2*, false, ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[3] + ⚠️ function calls are not analysed yet + +0 -> 6618 free var = FreeVar(exports) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/resolved-explained.snapshot new file mode 100644 index 0000000000000..3f3f15aaba265 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/react-dom-production/resolved-explained.snapshot @@ -0,0 +1,20238 @@ +$a = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +$b = (...) => (a | b | null) + +$c = (...) => undefined + +$d = [9, 13, 27, 32] + +$e = (???*0* | ???*1* | "animationend" | ???*2*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +$f = (...) => undefined + +$g = (false | true) + +$h = { + "readContext": (...) => b, + "useCallback": (...) => (d[0] | a), + "useContext": (...) => b, + "useEffect": (...) => ui(2048, 8, a, b), + "useImperativeHandle": (...) => ui(4, 4, yi["bind"](null, b, a), c), + "useInsertionEffect": (...) => ui(4, 2, a, b), + "useLayoutEffect": (...) => ui(4, 4, a, b), + "useMemo": (...) => (d[0] | a), + "useReducer": (...) => [f, d], + "useRef": (...) => di()["memoizedState"], + "useState": (...) => gi(ei), + "useDebugValue": (...) => undefined, + "useDeferredValue": (...) => ((null === O) ? ???*0* : Di(b, O["memoizedState"], a)), + "useTransition": (...) => [a, b], + "useMutableSource": (...) => undefined, + "useSyncExternalStore": (...) => e, + "useId": (...) => di()["memoizedState"], + "unstable_isNewReconciler": false +} +- *0* unsupported expression + ⚠️ This value might have side effects + +$i = (...) => (null | b["child"]) + +$k = (...) => ((bj(a) ? 1 : 0) | 11 | 14 | 2) + +*anonymous function 10089* = (...) => d + +*anonymous function 100988* = (...) => undefined + +*anonymous function 10119* = (...) => undefined + +*anonymous function 10152* = (...) => undefined + +*anonymous function 108286* = (...) => undefined + +*anonymous function 114743* = (...) => null + +*anonymous function 117815* = (...) => ( + | undefined + | ???*0* + | b + | null + | pj(a, b, c) + | b["child"] + | cj(a, b, b["type"], b["pendingProps"], c) + | yj(a, b, c) + | ej(a, b, c) +) +- *0* zj(a, b, c) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +*anonymous function 126145* = (...) => undefined + +*anonymous function 126252* = (...) => undefined + +*anonymous function 126382* = (...) => undefined + +*anonymous function 126480* = (...) => undefined + +*anonymous function 126604* = (...) => undefined + +*anonymous function 127055* = (...) => undefined + +*anonymous function 127285* = (...) => undefined + +*anonymous function 127435* = (...) => undefined + +*anonymous function 127571* = (...) => undefined + +*anonymous function 127654* = (...) => undefined + +*anonymous function 127846* = (...) => undefined + +*anonymous function 127923* = (...) => undefined + +*anonymous function 128036* = (...) => undefined + +*anonymous function 128133* = (...) => C + +*anonymous function 128157* = (...) => (undefined | ???*0*) +- *0* b() + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +*anonymous function 128216* = (...) => undefined + +*anonymous function 129223* = (...) => ((null === a) ? null : a["stateNode"]) + +*anonymous function 129753* = (...) => dl(a, b, null, c) + +*anonymous function 129905* = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +*anonymous function 130256* = (...) => (null | a) + +*anonymous function 130523* = (...) => Sk(a) + +*anonymous function 130565* = (...) => sl(null, a, b, !(0), c) + +*anonymous function 130658* = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +*anonymous function 131212* = (...) => sl(null, a, b, !(1), c) + +*anonymous function 131315* = (...) => (a["_reactRootContainer"] ? !(0) : !(1)) + +*anonymous function 131389* = (...) => undefined + +*anonymous function 131418* = (...) => undefined + +*anonymous function 131559* = (...) => sl(a, b, c, !(1), d) + +*anonymous function 13525* = (...) => undefined + +*anonymous function 13573* = (...) => a(b, c, d, e) + +*anonymous function 13608* = (...) => undefined + +*anonymous function 14731* = (...) => undefined + +*anonymous function 14754* = (...) => undefined + +*anonymous function 17157* = (...) => undefined + +*anonymous function 17435* = (...) => undefined + +*anonymous function 2285* = (...) => undefined + +*anonymous function 23424* = (...) => undefined + +*anonymous function 2443* = (...) => undefined + +*anonymous function 2564* = (...) => undefined + +*anonymous function 2705* = (...) => undefined + +*anonymous function 27645* = (...) => undefined + +*anonymous function 27843* = (...) => undefined + +*anonymous function 28013* = (...) => undefined + +*anonymous function 28108* = (...) => (a["timeStamp"] || FreeVar(Date)["now"]()) + +*anonymous function 28404* = (...) => ((???*0* === a["relatedTarget"]) ? ((a["fromElement"] === a["srcElement"]) ? a["toElement"] : a["fromElement"]) : a["relatedTarget"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 28530* = (...) => (a["movementX"] | wd) + +*anonymous function 28699* = (...) => (???*0* ? a["movementY"] : xd) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 28936* = (...) => (???*0* ? a["clipboardData"] : FreeVar(window)["clipboardData"]) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 29891* = (...) => ( + | b + | (("keypress" === a["type"]) ? ???*0* : ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? (Nd[a["keyCode"]] || "Unidentified") : "")) +) +- *0* ((13 === a) ? "Enter" : FreeVar(String)["fromCharCode"](a)) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +*anonymous function 3008* = (...) => undefined + +*anonymous function 30217* = (...) => (("keypress" === a["type"]) ? od(a) : 0) + +*anonymous function 30272* = (...) => ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? a["keyCode"] : 0) + +*anonymous function 30346* = (...) => (("keypress" === a["type"]) ? od(a) : ((("keydown" === a["type"]) || ("keyup" === a["type"])) ? a["keyCode"] : 0)) + +*anonymous function 30803* = (...) => (???*0* ? a["deltaX"] : (???*1* ? ???*2* : 0)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 30887* = (...) => (???*0* ? a["deltaY"] : (???*1* ? ???*2* : (???*3* ? ???*4* : 0))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 3119* = (...) => undefined + +*anonymous function 3196* = (...) => undefined + +*anonymous function 3280* = (...) => undefined + +*anonymous function 3354* = (...) => undefined + +*anonymous function 39904* = (...) => undefined + +*anonymous function 40883* = (...) => undefined + +*anonymous function 4580* = (...) => undefined + +*anonymous function 45964* = (...) => Hf["resolve"](null)["then"](a)["catch"](If) + +*anonymous function 46048* = (...) => undefined + +*anonymous function 4744* = (...) => undefined + +*anonymous function 4883* = (...) => undefined + +*anonymous function 5021* = (...) => undefined + +*anonymous function 5213* = (...) => undefined + +*anonymous function 55504* = (...) => (???*0* ? (Vb(a) === a) : !(1)) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 55574* = (...) => undefined + +*anonymous function 55754* = (...) => undefined + +*anonymous function 55941* = (...) => undefined + +*anonymous function 58064* = (...) => undefined + +*anonymous function 61566* = (...) => b(e, a) + +*anonymous function 62327* = (...) => b(e, a) + +*anonymous function 67764* = (...) => undefined + +*anonymous function 6811* = (...) => undefined + +*anonymous function 6885* = (...) => undefined + +*anonymous function 69020* = (...) => undefined + +*anonymous function 69089* = (...) => undefined + +*anonymous function 71076* = (...) => a + +*anonymous function 71188* = (...) => ti(4194308, 4, yi["bind"](null, b, a), c) + +*anonymous function 71305* = (...) => ti(4194308, 4, a, b) + +*anonymous function 71364* = (...) => ti(4, 2, a, b) + +*anonymous function 71406* = (...) => a + +*anonymous function 71500* = (...) => [d["memoizedState"], a] + +*anonymous function 71750* = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 71860* = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 71915* = (...) => [b, a] + +*anonymous function 72018* = (...) => undefined + +*anonymous function 72052* = (...) => c + +*anonymous function 72352* = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 72781* = (...) => fi(ei) + +*anonymous function 72842* = (...) => Di(b, O["memoizedState"], a) + +*anonymous function 72911* = (...) => [a, b] + +*anonymous function 73223* = (...) => gi(ei) + +*anonymous function 73283* = (...) => ((null === O) ? ???*0* : Di(b, O["memoizedState"], a)) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 73380* = (...) => [a, b] + +*anonymous function 73860* = (...) => undefined + +*anonymous function 74018* = (...) => undefined + +*anonymous function 74191* = (...) => d(e) + +*anonymous function 74226* = (...) => undefined + +*anonymous function 74327* = (...) => undefined + +*anonymous function 86042* = (...) => (undefined | FreeVar(undefined)) + +*anonymous function 86340* = (...) => undefined + +*anonymous function 86357* = (...) => undefined + +*anonymous function 87803* = (...) => undefined + +*anonymous function 9947* = (...) => e["call"](???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +*anonymous function 9983* = (...) => undefined + +A = ???*0* +- *0* ???*1*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Aa = ???*0* +- *0* ???*1*["for"]("react.profiler") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ab = (null | [???*0*] | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +Ac = (...) => undefined + +Ad = ???*0* +- *0* ???*1*( + {}, + ud, + { + "screenX": 0, + "screenY": 0, + "clientX": 0, + "clientY": 0, + "pageX": 0, + "pageY": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "getModifierState": zd, + "button": 0, + "buttons": 0, + "relatedTarget": *anonymous function 28404*, + "movementX": *anonymous function 28530*, + "movementY": *anonymous function 28699* + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ae = (...) => undefined + +Af = (...) => undefined + +Ag = (...) => undefined + +Ah = (...) => a + +Ai = (...) => undefined + +Aj = (???*0* | (...) => (undefined | FreeVar(undefined))) +- *0* Aj + ⚠️ pattern without value + +Ak = (null | ???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +B = module["unstable_now"] + +Ba = ???*0* +- *0* ???*1*["for"]("react.provider") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Bb = (...) => undefined + +Bc = (...) => undefined + +Bd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Be = (...) => undefined + +Bf = (...) => undefined + +Bg = (...) => ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +Bh = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Bi = (...) => (d[0] | a) + +Bj = (???*0* | (...) => undefined) +- *0* Bj + ⚠️ pattern without value + +Bk = (???*0* | module["unstable_now"]()) +- *0* unsupported expression + ⚠️ This value might have side effects + +C = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Ca = ???*0* +- *0* ???*1*["for"]("react.context") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Cb = (...) => (( + || !(a) + || ((5 !== a["tag"]) && (6 !== a["tag"]) && (13 !== a["tag"]) && (3 !== a["tag"])) +) ? null : a) + +Cc = (...) => undefined + +Cd = ???*0* +- *0* ???*1*({}, Ad, {"dataTransfer": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ce = (...) => undefined + +Cf = (null | true | false | !(???*0*)) +- *0* !((null | ???*1*)) + ⚠️ nested operation +- *1* dd + ⚠️ circular variable reference + +Cg = (...) => (undefined | ((null !== b) ? ???*0* : !(1)) | ???*1* | !(1)) +- *0* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* ((null !== b) ? ???*2* : !(1)) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Ch = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Ci = (...) => (d[0] | a) + +Cj = (???*0* | (...) => undefined) +- *0* Cj + ⚠️ pattern without value + +Ck = (0 | 64 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +D = (...) => undefined + +Da = ???*0* +- *0* ???*1*["for"]("react.forward_ref") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Db = (...) => (a[Pf] || null) + +Dc = (...) => (???*0* ? (???*1* ? ((0 !== ???*2*) ? 16 : 536870912) : 4) : 1) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +Dd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +De = (...) => (undefined | te(qe)) + +Df = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Dg = (...) => ((0 !== ???*0*) && (0 === ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Dh = {} + +Di = (...) => (???*0* | b) +- *0* ???*1* + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Dj = (???*0* | (...) => undefined) +- *0* Dj + ⚠️ pattern without value + +Dk = (...) => undefined + +E = (...) => undefined + +Ea = ???*0* +- *0* ???*1*["for"]("react.suspense") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Eb = (...) => undefined + +Ec = (???*0* | (...) => undefined) +- *0* Ec + ⚠️ pattern without value + +Ed = ???*0* +- *0* ???*1*({}, ud, {"relatedTarget": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ee = (...) => (undefined | te(b)) + +Ef = (...) => ( + || ("textarea" === a) + || ("noscript" === a) + || ("string" === typeof(b["children"])) + || ("number" === typeof(b["children"])) + || ( + && ("object" === typeof(b["dangerouslySetInnerHTML"])) + && (null !== b["dangerouslySetInnerHTML"]) + && (null != b["dangerouslySetInnerHTML"]["__html"]) + ) +) + +Eg = (...) => undefined + +Eh = {"current": {}} + +Ei = (...) => undefined + +Ej = (...) => undefined + +Ek = (...) => undefined + +F#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +F#678 = ???*0* +- *0* F + ⚠️ pattern without value + +F#685 = ???*0* +- *0* F + ⚠️ pattern without value + +F#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +F#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Fa = ???*0* +- *0* ???*1*["for"]("react.suspense_list") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Fb = (...) => undefined + +Fc = (???*0* | (...) => undefined) +- *0* Fc + ⚠️ pattern without value + +Fd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Fe = (...) => (undefined | te(b)) + +Ff = (???*0* ? ???*3* : ???*4*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +Fg = (...) => undefined + +Fh = {"current": {}} + +Fi = (...) => di()["memoizedState"] + +Fj = (...) => (undefined | null | (???*0* ? b : null) | ???*1* | b["child"]) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Fk = (...) => null + +G = (...) => undefined + +Ga = ???*0* +- *0* ???*1*["for"]("react.memo") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Gb = ((...) => a(b) | (...) => (undefined | a(b))) + +Gc = (???*0* | (...) => undefined) +- *0* Gc + ⚠️ pattern without value + +Gd = ???*0* +- *0* ???*1*( + {}, + sd, + {"animationName": 0, "elapsedTime": 0, "pseudoElement": 0} + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ge = (...) => (((a === b) && ((0 !== a) || (???*0* === ???*1*))) || ((a !== a) && (b !== b))) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Gf = (???*0* ? ???*3* : ???*4*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(clearTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(clearTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +Gg = (...) => (!(1) | ???*0* | !(0)) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Gh = {"current": {}} + +Gi = (...) => undefined + +Gj = (...) => undefined + +Gk = (...) => ac(a, b) + +H = {"current": {}} + +Ha = ???*0* +- *0* ???*1*["for"]("react.lazy") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Hb = ((...) => undefined | (...) => (undefined | a())) + +Hc = (???*0* | (...) => C) +- *0* Hc + ⚠️ pattern without value + +Hd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +He = (???*0* ? ???*4* : (...) => ???*6*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["is"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* (((a === b) && ((0 !== a) || (???*7* === ???*8*))) || ((a !== a) && (b !== b))) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects + +Hf = (???*0* ? ???*3* : ???*4*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +Hg = (...) => undefined + +Hh = (...) => a + +Hi = (...) => ((a === N) || ((null !== b) && (b === N))) + +Hj = (???*0* | (???*1* + 500)) +- *0* FreeVar(Infinity) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* module["unstable_now"]() + ⚠️ nested operation + +Hk = (...) => ( + | null + | ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) +) + +I = (false | true) + +Ia = ???*0* +- *0* ???*1*["for"]("react.offscreen") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ib = (false | true) + +Ic = (???*0* | (...) => (undefined | ???*1*)) +- *0* Ic + ⚠️ pattern without value +- *1* b() + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Id = ???*0* +- *0* ???*1*({}, sd, {"clipboardData": *anonymous function 28936*}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ie = (...) => (!(0) | !(1)) + +If = (...) => undefined + +Ig = (...) => undefined + +Ih = (...) => undefined + +Ii = (...) => undefined + +Ij = (...) => undefined + +Ik = (...) => (d | !(1)) + +J#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +J#431 = (...) => ( + | g(a) + | ???*0* + | n(a, d, f, h) + | t(a, d, f, h) + | (((("string" === typeof(f)) && ("" !== f)) || ("number" === typeof(f))) ? ???*1* : c(a, d)) +) +- *0* J(a, d, l(f["_payload"]), h) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* g(a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +J#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +J#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +J#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Ja = ???*0* +- *0* ???*1*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +Jb = (...) => (undefined | a(b, c) | Gb(a, b, c)) + +Jc = (false | true) + +Jd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Je = (...) => a + +Jf = (???*0* ? ???*3* : ???*4*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(queueMicrotask) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(queueMicrotask) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* (???*5* ? (...) => ???*11* : ???*12*) + ⚠️ nested operation +- *5* ("undefined" !== ???*6*) + ⚠️ nested operation +- *6* typeof(???*7*) + ⚠️ nested operation +- *7* (???*8* ? ???*9* : ???*10*) + ⚠️ nested operation +- *8* ("function" === ???) + ⚠️ nested operation +- *9* FreeVar(Promise) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* Hf["resolve"](null)["then"](a)["catch"](If) + ⚠️ nested operation +- *12* (???*13* ? ???*16* : ???*17*) + ⚠️ nested operation +- *13* ("function" === ???*14*) + ⚠️ nested operation +- *14* typeof(???*15*) + ⚠️ nested operation +- *15* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* FreeVar(setTimeout) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects + +Jg = (...) => undefined + +Jh = (...) => undefined + +Ji = (...) => undefined + +Jj = (...) => (undefined | ???*0* | null | (???*3* ? ???*4* : null)) +- *0* (???*1* ? ???*2* : null) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Jk = (...) => T + +K = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Ka = (...) => (null | (("function" === typeof(a)) ? a : null)) + +Kb = (...) => (null | c) + +Kc = [] + +Kd = ???*0* +- *0* ???*1*({}, sd, {"data": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ke = (...) => (undefined | {"node": c, "offset": ???*0*}) +- *0* unsupported expression + ⚠️ This value might have side effects + +Kf = (...) => (undefined | FreeVar(undefined)) + +Kg = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"] + +Kh = (...) => undefined + +Ki = (...) => {"value": a, "source": b, "stack": e, "digest": null} + +Kj = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Kk = (...) => ((null === a) ? ai : a) + +L = (...) => ((0 !== ???*0*) ? B() : ((???*1* !== Bk) ? Bk : ???*2*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +La = (???*0* | ???*1* | ???*6* | "") +- *0* La + ⚠️ pattern without value +- *1* ???*2*(/\n( *(at )?)/) + ⚠️ unknown callee +- *2* ???*3*["match"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???*5*["trim"] + ⚠️ unknown object +- *5* ???["stack"] + ⚠️ unknown object +- *6* ???*7*[1] + ⚠️ unknown object +- *7* ???*8*(/\n( *(at )?)/) + ⚠️ unknown callee +- *8* ???*9*["match"] + ⚠️ unknown object +- *9* ???*10*() + ⚠️ nested operation +- *10* ???["trim"] + ⚠️ unknown object + +Lb = (false | true) + +Lc = ( + | null + | ???*0* + | ???*1* + | { + "blockedOn": (???*2* | (???*3* ? null : (???*7* | ???*8*)) | ???*10*), + "domEventName": ???*12*, + "eventSystemFlags": ???*13*, + "nativeEvent": ???*14*, + "targetContainers": [???*15*] + } + | { + "blockedOn": (???*16* | (???*17* ? null : (???*21* | ???*22*)) | ???*24*), + "domEventName": ???*26*, + "eventSystemFlags": ???*27*, + "nativeEvent": ???*28*, + "targetContainers": [???*29*] + } +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* Lc + ⚠️ circular variable reference +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* !((???*4* | ???*5*)) + ⚠️ nested operation +- *4* b + ⚠️ circular variable reference +- *5* ???*6*[Of] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* b + ⚠️ circular variable reference +- *8* ???*9*[Of] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["targetContainers"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* arguments[4] + ⚠️ function calls are not analysed yet +- *15* arguments[3] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* !((???*18* | ???*19*)) + ⚠️ nested operation +- *18* b + ⚠️ circular variable reference +- *19* ???*20*[Of] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* b + ⚠️ circular variable reference +- *22* ???*23*[Of] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference +- *24* ???*25*["targetContainers"] + ⚠️ unknown object +- *25* a + ⚠️ circular variable reference +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* arguments[2] + ⚠️ function calls are not analysed yet +- *28* arguments[4] + ⚠️ function calls are not analysed yet +- *29* arguments[3] + ⚠️ function calls are not analysed yet + +Ld = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Le = (...) => ((a && b) ? ((a === b) ? !(0) : ((a && (3 === a["nodeType"])) ? !(1) : ((b && (3 === b["nodeType"])) ? Le(a, b["parentNode"]) : (???*0* ? a["contains"](b) : (a["compareDocumentPosition"] ? !(!(???*1*)) : !(1)))))) : !(1)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +Lf = (...) => (null | a) + +Lg = (...) => b + +Lh = (...) => undefined + +Li = (...) => {"value": a, "source": null, "stack": ((null != c) ? c : null), "digest": ((null != b) ? b : null)} + +Lj = (???*0* ? ???*3* : ???*4*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(WeakSet) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(WeakSet) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* FreeVar(Set) + ⚠️ unknown global + ⚠️ This value might have side effects + +Lk = (...) => a + +M = {"current": 0} + +Ma = (...) => ` +${La}${a}` + +Mb = {} + +Mc = ( + | null + | ???*0* + | ???*1* + | { + "blockedOn": (???*2* | (???*3* ? null : (???*7* | ???*8*)) | ???*10*), + "domEventName": ???*12*, + "eventSystemFlags": ???*13*, + "nativeEvent": ???*14*, + "targetContainers": [???*15*] + } + | { + "blockedOn": (???*16* | (???*17* ? null : (???*21* | ???*22*)) | ???*24*), + "domEventName": ???*26*, + "eventSystemFlags": ???*27*, + "nativeEvent": ???*28*, + "targetContainers": [???*29*] + } +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* Mc + ⚠️ circular variable reference +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* !((???*4* | ???*5*)) + ⚠️ nested operation +- *4* b + ⚠️ circular variable reference +- *5* ???*6*[Of] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* b + ⚠️ circular variable reference +- *8* ???*9*[Of] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["targetContainers"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* arguments[4] + ⚠️ function calls are not analysed yet +- *15* arguments[3] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* !((???*18* | ???*19*)) + ⚠️ nested operation +- *18* b + ⚠️ circular variable reference +- *19* ???*20*[Of] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* b + ⚠️ circular variable reference +- *22* ???*23*[Of] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference +- *24* ???*25*["targetContainers"] + ⚠️ unknown object +- *25* a + ⚠️ circular variable reference +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* arguments[2] + ⚠️ function calls are not analysed yet +- *28* arguments[4] + ⚠️ function calls are not analysed yet +- *29* arguments[3] + ⚠️ function calls are not analysed yet + +Md = { + "Esc": "Escape", + "Spacebar": " ", + "Left": "ArrowLeft", + "Up": "ArrowUp", + "Right": "ArrowRight", + "Down": "ArrowDown", + "Del": "Delete", + "Win": "OS", + "Menu": "ContextMenu", + "Apps": "ContextMenu", + "Scroll": "ScrollLock", + "MozPrintableKey": "Unidentified" +} + +Me = (...) => b + +Mf = (...) => (a | null) + +Mg = {"current": null} + +Mh = (...) => (b | null) + +Mi = (...) => undefined + +Mj = (...) => undefined + +Mk = (...) => undefined + +N = ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | null["alternate"] + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | null["alternate"]["next"] | ???*19* | null | ???*22*)) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* b + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects + +Na = (false | true) + +Nb = (...) => undefined + +Nc = ( + | null + | ???*0* + | ???*1* + | { + "blockedOn": (???*2* | (???*3* ? null : (???*7* | ???*8*)) | ???*10*), + "domEventName": ???*12*, + "eventSystemFlags": ???*13*, + "nativeEvent": ???*14*, + "targetContainers": [???*15*] + } + | { + "blockedOn": (???*16* | (???*17* ? null : (???*21* | ???*22*)) | ???*24*), + "domEventName": ???*26*, + "eventSystemFlags": ???*27*, + "nativeEvent": ???*28*, + "targetContainers": [???*29*] + } +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* Nc + ⚠️ circular variable reference +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* !((???*4* | ???*5*)) + ⚠️ nested operation +- *4* b + ⚠️ circular variable reference +- *5* ???*6*[Of] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* b + ⚠️ circular variable reference +- *8* ???*9*[Of] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["targetContainers"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* arguments[4] + ⚠️ function calls are not analysed yet +- *15* arguments[3] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* !((???*18* | ???*19*)) + ⚠️ nested operation +- *18* b + ⚠️ circular variable reference +- *19* ???*20*[Of] + ⚠️ unknown object +- *20* a + ⚠️ circular variable reference +- *21* b + ⚠️ circular variable reference +- *22* ???*23*[Of] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference +- *24* ???*25*["targetContainers"] + ⚠️ unknown object +- *25* a + ⚠️ circular variable reference +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* arguments[2] + ⚠️ function calls are not analysed yet +- *28* arguments[4] + ⚠️ function calls are not analysed yet +- *29* arguments[3] + ⚠️ function calls are not analysed yet + +Nd = { + 8: "Backspace", + 9: "Tab", + 12: "Clear", + 13: "Enter", + 16: "Shift", + 17: "Control", + 18: "Alt", + 19: "Pause", + 20: "CapsLock", + 27: "Escape", + 32: " ", + 33: "PageUp", + 34: "PageDown", + 35: "End", + 36: "Home", + 37: "ArrowLeft", + 38: "ArrowUp", + 39: "ArrowRight", + 40: "ArrowDown", + 45: "Insert", + 46: "Delete", + 112: "F1", + 113: "F2", + 114: "F3", + 115: "F4", + 116: "F5", + 117: "F6", + 118: "F7", + 119: "F8", + 120: "F9", + 121: "F10", + 122: "F11", + 123: "F12", + 144: "NumLock", + 145: "ScrollLock", + 224: "Meta" +} + +Ne = (...) => ( + && b + && ( + || ( + && ("input" === b) + && ( + || ("text" === a["type"]) + || ("search" === a["type"]) + || ("tel" === a["type"]) + || ("url" === a["type"]) + || ("password" === a["type"]) + ) + ) + || ("textarea" === b) + || ("true" === a["contentEditable"]) + ) +) + +Nf = ???*0* +- *0* ???*1*["slice"](2) + ⚠️ unknown callee object +- *1* ???*2*(36) + ⚠️ unknown callee +- *2* ???*3*["toString"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +Ng = (null | ???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["dependencies"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +Nh = [] + +Ni = (???*0* ? ???*3* : ???*4*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(WeakMap) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(WeakMap) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* FreeVar(Map) + ⚠️ unknown global + ⚠️ This value might have side effects + +Nj = (...) => undefined + +Nk = (...) => undefined + +O = ( + | null + | ???*0* + | null["alternate"] + | ???*1* + | (null !== (null | ???*3* | ???*4*))["alternate"] + | (null !== (null["next"] | ???*5* | ???*7*))["alternate"] + | (???*9* ? ???*11* : null) + | null["next"] + | ???*13* + | { + "memoizedState": (null["memoizedState"] | ???*15* | ???*17*), + "baseState": (null["baseState"] | ???*19* | ???*21*), + "baseQueue": (null["baseQueue"] | ???*23* | ???*25*), + "queue": (null["queue"] | ???*27* | ???*29*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* ???*8*["next"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* (null !== ???*10*) + ⚠️ nested operation +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* ???*14*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* ???*16*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["baseState"] + ⚠️ unknown object +- *22* a + ⚠️ circular variable reference +- *23* ???*24*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* ???*26*["baseQueue"] + ⚠️ unknown object +- *26* a + ⚠️ circular variable reference +- *27* ???*28*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* ???*30*["queue"] + ⚠️ unknown object +- *30* a + ⚠️ circular variable reference + +Oa = (...) => ("" | k | (???*0* ? Ma(a) : "")) +- *0* unsupported expression + ⚠️ This value might have side effects + +Ob = (false | true) + +Oc = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +Od = {"Alt": "altKey", "Control": "ctrlKey", "Meta": "metaKey", "Shift": "shiftKey"} + +Oe = (...) => undefined + +Of = `__reactFiber$${???*0*}` +- *0* ???*1*["slice"](2) + ⚠️ unknown callee object +- *1* ???*2*(36) + ⚠️ unknown callee +- *2* ???*3*["toString"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +Og = ( + | null + | ???*0* + | ???*1* + | {"context": ???*2*, "memoizedValue": ???*3*, "next": null} +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["_currentValue"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference + +Oh = (...) => undefined + +Oi = (...) => c + +Oj = false + +Ok = (...) => a + +P = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Pa = (...) => (undefined | Ma(a["type"]) | Ma("Lazy") | Ma("Suspense") | Ma("SuspenseList") | ???*0* | "") +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Pb = (null | ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +Pc = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +Pd = (...) => (b["getModifierState"] ? b["getModifierState"](a) : (???*0* ? !(!(b[a])) : !(1))) +- *0* unsupported expression + ⚠️ This value might have side effects + +Pe = (!(???*0*) | ???*3*) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +Pf = `__reactProps$${???*0*}` +- *0* ???*1*["slice"](2) + ⚠️ unknown callee object +- *1* ???*2*(36) + ⚠️ unknown callee +- *2* ???*3*["toString"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +Pg = (null | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Ph = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"] + +Pi = (true | false) + +Pj = (...) => n + +Pk = (...) => (!(1) | !(0)) + +Q = (...) => undefined + +Qa = (...) => ( + | null + | (a["displayName"] || a["name"] || null) + | a + | "Fragment" + | "Portal" + | "Profiler" + | "StrictMode" + | "Suspense" + | "SuspenseList" + | `${(a["displayName"] || "Context")}.Consumer` + | `${(a["_context"]["displayName"] || "Context")}.Provider` + | ???*0* + | Qa(a(b)) +) +- *0* ((null !== b) ? b : (Qa(a["type"]) || "Memo")) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Qb = (false | true) + +Qc = [] + +Qd = ???*0* +- *0* ???*1*( + {}, + ud, + { + "key": *anonymous function 29891*, + "code": 0, + "location": 0, + "ctrlKey": 0, + "shiftKey": 0, + "altKey": 0, + "metaKey": 0, + "repeat": 0, + "locale": 0, + "getModifierState": zd, + "charCode": *anonymous function 30217*, + "keyCode": *anonymous function 30272*, + "which": *anonymous function 30346* + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Qe = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Qf = `__reactListeners$${???*0*}` +- *0* ???*1*["slice"](2) + ⚠️ unknown callee object +- *1* ???*2*(36) + ⚠️ unknown callee +- *2* ???*3*["toString"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +Qg = (...) => undefined + +Qh = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"] + +Qi = (???*0* | null) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +Qj = (...) => undefined + +Qk = (...) => null + +R = (null | ???*0* | ???*1* | ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* unknown new expression + ⚠️ This value might have side effects + +Ra = (...) => ( + | "Cache" + | `${(b["displayName"] || "Context")}.Consumer` + | `${(b["_context"]["displayName"] || "Context")}.Provider` + | "DehydratedFragment" + | ???*0* + | "Fragment" + | b + | "Portal" + | "Root" + | "Text" + | Qa(b) + | ((b === za) ? "StrictMode" : "Mode") + | "Offscreen" + | "Profiler" + | "Scope" + | "Suspense" + | "SuspenseList" + | "TracingMarker" + | (b["displayName"] || b["name"] || null) + | null +) +- *0* ( + || b["displayName"] + || (("" !== a) ? ("ForwardRef(" + a + ")") : "ForwardRef") + ) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Rb = (null | ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +Rc = "mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit"["split"](" ") + +Rd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Re = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Rf = `__reactHandles$${???*0*}` +- *0* ???*1*["slice"](2) + ⚠️ unknown callee object +- *1* ???*2*(36) + ⚠️ unknown callee +- *2* ???*3*["toString"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +Rg = (...) => undefined + +Rh = (0 | ???*0* | (???*1* + 1)) +- *0* arguments[5] + ⚠️ function calls are not analysed yet +- *1* f + ⚠️ circular variable reference + +Ri = (...) => c + +Rj = (...) => undefined + +Rk = (...) => (undefined | a(b)) + +S = (...) => b + +Sa = (...) => (undefined | a | "") + +Sb = {"onError": (...) => undefined} + +Sc = (...) => undefined + +Sd = ???*0* +- *0* ???*1*( + {}, + Ad, + { + "pointerId": 0, + "width": 0, + "height": 0, + "pressure": 0, + "tangentialPressure": 0, + "tiltX": 0, + "tiltY": 0, + "twist": 0, + "pointerType": 0, + "isPrimary": 0 + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Se = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Sf = [] + +Sg = (...) => undefined + +Sh = (false | true) + +Si = (???*0* | null) +- *0* unknown new expression + ⚠️ This value might have side effects + +Sj = (...) => undefined + +Sk = (...) => (undefined | a()) + +T = (3 | 0 | 1 | 2 | 4 | 6 | 5) + +Ta = (...) => (???*0* && ("input" === a["toLowerCase"]()) && (("checkbox" === b) || ("radio" === b))) +- *0* unsupported expression + ⚠️ This value might have side effects + +Tb = (...) => undefined + +Tc = (...) => (???*0* | a) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Td = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Te = (false | true) + +Tf = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +Tg = (...) => undefined + +Th = (false | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Ti = (...) => undefined + +Tj = (...) => undefined + +Tk = (...) => (undefined | FreeVar(undefined)) + +U = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Ua = (...) => ( + | undefined + | { + "getValue": *anonymous function 10089*, + "setValue": *anonymous function 10119*, + "stopTracking": *anonymous function 10152* + } +) + +Ub = (...) => undefined + +Uc = (...) => (???*0* | !(0) | !(1)) +- *0* !(0) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Ud = ???*0* +- *0* ???*1*( + {}, + ud, + { + "touches": 0, + "targetTouches": 0, + "changedTouches": 0, + "altKey": 0, + "metaKey": 0, + "ctrlKey": 0, + "shiftKey": 0, + "getModifierState": zd + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ue = (...) => undefined + +Uf = (...) => {"current": a} + +Ug = (true | false | (???*0* ? true : false)) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects + +Uh = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +Ui = (...) => undefined + +Uj = (...) => ((5 === a["tag"]) || (3 === a["tag"]) || (4 === a["tag"])) + +Uk = (...) => undefined + +V = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Va = (...) => undefined + +Vb = (...) => ((3 === b["tag"]) ? c : null) + +Vc = (...) => (undefined | FreeVar(undefined)) + +Vd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Ve = (...) => c + +Vf = {} + +Vg = (...) => b + +Vh = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +Vi = (...) => (a | null) + +Vj = (...) => (undefined | null | a["stateNode"]) + +Vk = (...) => undefined + +W = (...) => undefined + +Wa = (...) => (!(1) | !(0) | ((a !== c) ? !(0) : !(1))) + +Wb = (...) => (b["dehydrated"] | null) + +Wc = (...) => (b | c | null) + +Wd = ???*0* +- *0* ???*1*( + {}, + sd, + {"propertyName": 0, "elapsedTime": 0, "pseudoElement": 0} + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +We = {"animationend": {}, "animationiteration": {}, "animationstart": {}, "transitionend": {}} + +Wf = {"current": false} + +Wg = (null | [???*0*]) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +Wh = (...) => (!(1) | !(0)) + +Wi = (...) => (???*0* | a) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Wj = (...) => undefined + +Wk = ( + | ???*0* + | (...) => ( + | undefined + | ???*1* + | b + | null + | pj(a, b, c) + | b["child"] + | cj(a, b, b["type"], b["pendingProps"], c) + | yj(a, b, c) + | ej(a, b, c) + ) +) +- *0* Wk + ⚠️ pattern without value +- *1* zj(a, b, c) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +X = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Xa = (...) => (undefined | null | (a["activeElement"] || a["body"]) | a["body"]) + +Xb = (...) => undefined + +Xc = (...) => (!(1) | ???*0* | !(0)) +- *0* !(1) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Xd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Xe = {} + +Xf = ({} | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +Xg = (...) => undefined + +Xh = (...) => a + +Xi = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentOwner"] + +Xj = (...) => undefined + +Xk = (...) => null + +Y = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +Ya = (...) => A( + {}, + b, + { + "defaultChecked": ???*0*, + "defaultValue": ???*1*, + "value": ???*2*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +Yb = (...) => (((b !== a) ? null : a) | a | b | ((c["stateNode"]["current"] === c) ? a : b)) + +Yc = (...) => ( + | a + | ((3 === b["tag"]) ? b["stateNode"]["containerInfo"] : null) + | null +) + +Yd = ???*0* +- *0* ???*1*( + {}, + Ad, + { + "deltaX": *anonymous function 30803*, + "deltaY": *anonymous function 30887*, + "deltaZ": 0, + "deltaMode": 0 + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +Ye = ({} | ???*0*) +- *0* ???*1*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +Yf = (...) => (Vf | d["__reactInternalMemoizedMaskedChildContext"] | e) + +Yg = (...) => Zg(a, d) + +Yh = { + "readContext": (...) => b, + "useCallback": (...) => a, + "useContext": (...) => b, + "useEffect": (...) => ti(8390656, 8, a, b), + "useImperativeHandle": (...) => ti(4194308, 4, yi["bind"](null, b, a), c), + "useLayoutEffect": (...) => ti(4194308, 4, a, b), + "useInsertionEffect": (...) => ti(4, 2, a, b), + "useMemo": (...) => a, + "useReducer": (...) => [d["memoizedState"], a], + "useRef": (...) => ???*0*, + "useState": (...) => [b["memoizedState"], a], + "useDebugValue": (...) => undefined, + "useDeferredValue": (...) => ???*1*, + "useTransition": (...) => [b, a], + "useMutableSource": (...) => undefined, + "useSyncExternalStore": (...) => c, + "useId": (...) => ???*2*, + "unstable_isNewReconciler": false +} +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +Yi = (...) => undefined + +Yj = (false | ???*0* | true | ???*1* | ???*2*) +- *0* e + ⚠️ circular variable reference +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["next"] + ⚠️ unknown object +- *3* e + ⚠️ circular variable reference + +Yk = (...) => undefined + +Z = (0 | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Za = (...) => undefined + +Zb = (...) => ((null !== a) ? $b(a) : null) + +Zc = (...) => undefined + +Zd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +Ze = (...) => (Xe[a] | a | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +Zf = (...) => ((null !== a) && (???*0* !== a)) +- *0* unsupported expression + ⚠️ This value might have side effects + +Zg = (...) => ((3 === c["tag"]) ? c["stateNode"] : null) + +Zh = { + "readContext": (...) => b, + "useCallback": (...) => (d[0] | a), + "useContext": (...) => b, + "useEffect": (...) => ui(2048, 8, a, b), + "useImperativeHandle": (...) => ui(4, 4, yi["bind"](null, b, a), c), + "useInsertionEffect": (...) => ui(4, 2, a, b), + "useLayoutEffect": (...) => ui(4, 4, a, b), + "useMemo": (...) => (d[0] | a), + "useReducer": (...) => [b["memoizedState"], c["dispatch"]], + "useRef": (...) => di()["memoizedState"], + "useState": (...) => fi(ei), + "useDebugValue": (...) => undefined, + "useDeferredValue": (...) => Di(b, O["memoizedState"], a), + "useTransition": (...) => [a, b], + "useMutableSource": (...) => undefined, + "useSyncExternalStore": (...) => e, + "useId": (...) => di()["memoizedState"], + "unstable_isNewReconciler": false +} + +Zi = (...) => (???*0* | b["child"]) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +Zj = (...) => undefined + +Zk = (...) => undefined + +a#10 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1001 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1004 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1008 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#101 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1011 = ???*0* +- *0* a + ⚠️ pattern without value + +a#1012 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1013 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1014 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#1016 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1017 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1018 = (???*0* | 0 | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +a#1019 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#102 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["style"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#1020 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#1023 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#104 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#107 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#108 = (???*0* | ???*1* | ???*3* | ???*5*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["target"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["target"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +a#109 = (???*0* | (???*1* ? null : (???*13* | ???*14* | ???*22*))) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* !((???*2* | ???*3* | ???*11*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? null : (???*8* | ???*9*)) + ⚠️ nested operation +- *4* !((???*5* | ???*6*)) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ???*7*[Of] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* a + ⚠️ circular variable reference +- *9* ???*10*[Of] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*[Of] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* (???*15* ? null : (???*19* | ???*20*)) + ⚠️ nested operation +- *15* !((???*16* | ???*17*)) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*[Of] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* a + ⚠️ circular variable reference +- *20* ???*21*[Of] + ⚠️ unknown object +- *21* a + ⚠️ circular variable reference +- *22* ???*23*[Of] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference + +a#11 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#111 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#112 = (null | ???*0* | 0 | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +a#114 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#116 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#119 = ( + | ???*0* + | ???*1* + | !((???*3* | null | ???*6*))["type"] + | false["type"] + | !((???*9* | false["stateNode"][???*16*] | null | ???*21*)) + | false +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*[Pf] + ⚠️ unknown object +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* !(???*7*) + ⚠️ nested operation +- *7* ???*8*["disabled"] + ⚠️ unknown object +- *8* d + ⚠️ circular variable reference +- *9* ???*10*[`__reactProps$${???*12*}`] + ⚠️ unknown object +- *10* ???*11*["stateNode"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* ???*13*["slice"](2) + ⚠️ unknown callee object +- *13* ???*14*(36) + ⚠️ unknown callee +- *14* ???*15*["toString"] + ⚠️ unknown object +- *15* ???() + ⚠️ nested operation +- *16* `__reactProps$${???*17*}` + ⚠️ nested operation +- *17* ???*18*["slice"](2) + ⚠️ unknown callee object +- *18* ???*19*(36) + ⚠️ unknown callee +- *19* ???*20*["toString"] + ⚠️ unknown object +- *20* ???() + ⚠️ nested operation +- *21* !(???*22*) + ⚠️ nested operation +- *22* ???*23*["disabled"] + ⚠️ unknown object +- *23* d + ⚠️ circular variable reference + +a#12 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#122 = ???*0* +- *0* a + ⚠️ pattern without value + +a#123 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#126 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#127 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#128 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#13 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#131 = (???*0* | ???*1* | ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* b + ⚠️ circular variable reference +- *2* ???*3*["return"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference + +a#133 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#135 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#136 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#14 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#15 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#151 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#152 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#154 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#157 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +a#158 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#159 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["entanglements"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#16 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#161 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#162 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#165 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +a#166 = (64 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +a#167 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#168 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["eventTimes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#169 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["expirationTimes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#17 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#171 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["entanglements"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#173 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +a#174 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#175 = ( + | ???*0* + | { + "blockedOn": (???*1* | (???*2* ? null : (???*6* | ???*7*)) | ???*9* | [???*11*] | ???*12*), + "domEventName": ???*13*, + "eventSystemFlags": ???*14*, + "nativeEvent": ???*15*, + "targetContainers": [???*16*] + } +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* !((???*3* | ???*4*)) + ⚠️ nested operation +- *3* b + ⚠️ circular variable reference +- *4* ???*5*[Of] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* b + ⚠️ circular variable reference +- *7* ???*8*[Of] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["targetContainers"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* arguments[4] + ⚠️ function calls are not analysed yet +- *12* unknown mutation + ⚠️ This value might have side effects +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* arguments[3] + ⚠️ function calls are not analysed yet +- *15* arguments[5] + ⚠️ function calls are not analysed yet +- *16* arguments[4] + ⚠️ function calls are not analysed yet + +a#176 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#177 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#18 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#183 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#186 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#188 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#189 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#19 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#193 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#196 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#199 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#20 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#203 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#206 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#207 = (???*0* | 0 | ???*1*) +- *0* a + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +a#208 = (???*0* | ???*1* | 13["charCode"] | 13 | 13["keyCode"]) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["charCode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#21 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#211 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#213 = ???*0* +- *0* ???*1*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +a#214 = ???*0* +- *0* ???*1*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +a#216 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#217 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#218 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#219 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#22 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#220 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#221 = (???*0* | "altKey" | "ctrlKey" | "metaKey" | "shiftKey" | ???*1* | ???*3* | ???*4*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* {}[???*2*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects + +a#223 = ( + | ???*0* + | ((???*1* | ???*2*) ? (???*15* | ???*16* | ???*25* | 13) : 0) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* (13 === (???*3* | ???*4* | ???*13* | 13)) + ⚠️ nested operation +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ((???*5* | ???*6*) ? (???*10* | ???*11* | 13) : 0) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (13 === (???*7* | ???*8* | 13)) + ⚠️ nested operation +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["charCode"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["charCode"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* ???*14*["charCode"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* ((???*17* | ???*18*) ? (???*22* | ???*23* | 13) : 0) + ⚠️ nested operation +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* (13 === (???*19* | ???*20* | 13)) + ⚠️ nested operation +- *19* a + ⚠️ circular variable reference +- *20* ???*21*["charCode"] + ⚠️ unknown object +- *21* a + ⚠️ circular variable reference +- *22* a + ⚠️ circular variable reference +- *23* ???*24*["charCode"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["charCode"] + ⚠️ unknown object +- *26* a + ⚠️ circular variable reference + +a#225 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#226 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#227 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#228 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#229 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#23 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#230 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#231 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["detail"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#232 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["data"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +a#233 = (???*0* | null | ???*1* | ???*19*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*((???*13* | 0 | ???*14*), ???*15*) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* ???*3*["slice"] + ⚠️ unknown object +- *3* (???*4* ? (null["value"] | ???*5* | ???*7*) : (null["textContent"] | ???*9* | ???*11*)) + ⚠️ nested operation +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* ???*6*["value"] + ⚠️ unknown object +- *6* (??? ? (??? | ???) : (??? | ??? | ???)) + ⚠️ nested operation +- *7* ???*8*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects +- *9* ???*10*["textContent"] + ⚠️ unknown object +- *10* (??? ? (??? | ???) : (??? | ??? | ???)) + ⚠️ nested operation +- *11* ???*12*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unknown new expression + ⚠️ This value might have side effects +- *13* a + ⚠️ pattern without value +- *14* updated with update expression + ⚠️ This value might have side effects +- *15* (???*16* ? ???*17* : ???*18*) + ⚠️ nested operation +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* unsupported expression + ⚠️ This value might have side effects + +a#235 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#236 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#237 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#238 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#239 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#24 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#244 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#246 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#247 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#248 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#249 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#25 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#250 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#251 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#253 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["firstChild"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#254 = ( + | ???*0* + | 0 + | ???*1* + | ((???*2* | 0 | ???*3*) + (???*4* | 0["textContent"]["length"] | ???*7*)) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* d + ⚠️ pattern without value +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* d + ⚠️ circular variable reference +- *4* ???*5*["length"] + ⚠️ unknown object +- *5* ???*6*["textContent"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*["length"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???*9*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects + +a#26 = (???*0* | ???*1* | ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["iterator"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* ???*4*["@@iterator"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +a#260 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#261 = ( + | ???*0* + | undefined["contentWindow"] + | null["contentWindow"] + | ???*1* + | (???*4* ? ???*7* : ???*8*)["activeElement"]["contentWindow"] + | (???*9* ? ???*12* : ???*13*)["body"]["contentWindow"] + | (???*14* ? ???*17* : ???*18*)["body"]["contentWindow"] + | ???*19* + | (???*23* ? ???*26* : ???*27*)["activeElement"]["contentWindow"] + | (???*28* ? ???*31* : ???*32*)["body"]["contentWindow"] + | (???*33* ? ???*36* : ???*37*)["body"]["contentWindow"] +) +- *0* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* ???*2*["contentWindow"] + ⚠️ unknown object +- *2* ???*3*["activeElement"] + ⚠️ unknown object +- *3* unknown function argument (out of bounds) +- *4* ("undefined" !== ???*5*) + ⚠️ nested operation +- *5* typeof(???*6*) + ⚠️ nested operation +- *6* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ("undefined" !== ???*10*) + ⚠️ nested operation +- *10* typeof(???*11*) + ⚠️ nested operation +- *11* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* ("undefined" !== ???*15*) + ⚠️ nested operation +- *15* typeof(???*16*) + ⚠️ nested operation +- *16* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["contentWindow"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* ???*21*["activeElement"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* ???*22*["document"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *23* ("undefined" !== ???*24*) + ⚠️ nested operation +- *24* typeof(???*25*) + ⚠️ nested operation +- *25* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *26* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *27* unsupported expression + ⚠️ This value might have side effects +- *28* ("undefined" !== ???*29*) + ⚠️ nested operation +- *29* typeof(???*30*) + ⚠️ nested operation +- *30* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *31* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* ("undefined" !== ???*34*) + ⚠️ nested operation +- *34* typeof(???*35*) + ⚠️ nested operation +- *35* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *36* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *37* unsupported expression + ⚠️ This value might have side effects + +a#265 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#266 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#269 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#27 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#270 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#271 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#272 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#274 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#275 = (???*0* | null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#280 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#281 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#282 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#285 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#286 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#3 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#30 = (???*0* | ((???*1* | ???*2*) ? ???*6* : "")) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? ???*4* : "") + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* ???*5*["displayName"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["displayName"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +a#307 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#308 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#310 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#311 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#313 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#314 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#316 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#317 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#318 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#320 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#324 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nextSibling"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#327 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["previousSibling"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#331 = ( + | ???*0* + | ???*1* + | ???*2* + | null + | null["parentNode"] + | null[`__reactFiber$${???*4*}`]["alternate"] + | null[`__reactFiber$${???*9*}`] +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["previousSibling"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* ???*5*["slice"](2) + ⚠️ unknown callee object +- *5* ???*6*(36) + ⚠️ unknown callee +- *6* ???*7*["toString"] + ⚠️ unknown object +- *7* ???*8*() + ⚠️ nested operation +- *8* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["slice"](2) + ⚠️ unknown callee object +- *10* ???*11*(36) + ⚠️ unknown callee +- *11* ???*12*["toString"] + ⚠️ unknown object +- *12* ???*13*() + ⚠️ nested operation +- *13* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +a#335 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*[`__reactFiber$${???*3*}`] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["slice"](2) + ⚠️ unknown callee object +- *4* ???*5*(36) + ⚠️ unknown callee +- *5* ???*6*["toString"] + ⚠️ unknown object +- *6* ???() + ⚠️ nested operation + +a#336 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#337 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#338 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#339 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#340 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#341 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#342 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["childContextTypes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#344 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#345 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#346 = (???*0* | ???*1* | ???*2* | ???*4* | ???*6* | ???*7* | {}) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["__reactInternalMemoizedMergedChildContext"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["__reactInternalMemoizedMergedChildContext"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* unknown mutation + ⚠️ This value might have side effects + +a#347 = (???*0* | {} | ???*1* | ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* ???*3*({}, c, d) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +a#348 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#349 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#350 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +a#356 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#357 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#359 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#360 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#361 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#362 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#363 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#364 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#369 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#370 = ( + | ???*0* + | ???*1* + | (???*3* ? ???*5* : null)["memoizedState"] + | (???*7* ? ???*16* : null) + | (???*18* ? ???*20* : null)["nextSibling"] +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["dehydrated"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* (null !== (???*8* | ???*9* | ???*11*)) + ⚠️ nested operation +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* (???*12* ? ???*14* : null) + ⚠️ nested operation +- *12* (null !== ???*13*) + ⚠️ nested operation +- *13* a + ⚠️ circular variable reference +- *14* ???*15*["dehydrated"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* ???*17*["dehydrated"] + ⚠️ unknown object +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* (null !== ???*19*) + ⚠️ nested operation +- *19* a + ⚠️ circular variable reference +- *20* ???*21*["dehydrated"] + ⚠️ unknown object +- *21* a + ⚠️ circular variable reference + +a#378 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#380 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#381 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["defaultProps"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#384 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#385 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#387 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["dependencies"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#388 = ( + | ???*0* + | { + "context": ( + | ???*1* + | {"context": ???*2*, "memoizedValue": ???*3*, "next": null} + ), + "memoizedValue": (???*5* | ???*7* | ???*8*), + "next": null + } +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["_currentValue"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["_currentValue"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* unknown mutation + ⚠️ This value might have side effects + +a#390 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#391 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#392 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#393 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#394 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#395 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#396 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#398 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#4 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#400 = ( + | ???*0* + | ???*1* + | null + | { + "eventTime": ???*4*, + "lane": ???*6*, + "tag": ???*8*, + "payload": ???*10*, + "callback": ???*12*, + "next": null + } + | ???*14* + | ???*15* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["lastBaseUpdate"] + ⚠️ unknown object +- *2* ???*3*["updateQueue"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["eventTime"] + ⚠️ unknown object +- *5* c + ⚠️ circular variable reference +- *6* ???*7*["lane"] + ⚠️ unknown object +- *7* c + ⚠️ circular variable reference +- *8* ???*9*["tag"] + ⚠️ unknown object +- *9* c + ⚠️ circular variable reference +- *10* ???*11*["payload"] + ⚠️ unknown object +- *11* c + ⚠️ circular variable reference +- *12* ???*13*["callback"] + ⚠️ unknown object +- *13* c + ⚠️ circular variable reference +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* unknown mutation + ⚠️ This value might have side effects + +a#404 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#412 = (???*0* | ???*1* | 0["effects"] | ???*3*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["effects"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["effects"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +a#415 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#416 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#417 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#418 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#419 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#420 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#421 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#422 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["state"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +a#423 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#424 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +a#428 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#429 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["call"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* ???*3*["toString"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +a#430 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#431 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#435 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +a#436 = (???*0* | ???*1* | ???*3* | ???*5*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects +- *5* unknown new expression + ⚠️ This value might have side effects + +a#439 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#440 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#441 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#442 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#443 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#445 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#447 = (???*0* | ???*1* | null["get"](???*4*) | null | null["get"](???*5*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["get"](???*3*) + ⚠️ unknown callee object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* (???*6* ? ???*9* : ???*10*) + ⚠️ nested operation +- *6* (null === ???*7*) + ⚠️ nested operation +- *7* ???*8*["key"] + ⚠️ unknown object +- *8* arguments[3] + ⚠️ function calls are not analysed yet +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["key"] + ⚠️ unknown object +- *11* arguments[3] + ⚠️ function calls are not analysed yet + +a#453 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#458 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#459 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#471 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#472 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#474 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#475 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#476 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#482 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +a#484 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#485 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*(d, e) + ⚠️ unknown callee +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +a#488 = (0 !== (0 | ???*0*)) +- *0* updated with update expression + ⚠️ This value might have side effects + +a#489 = {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + +a#49 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#490 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#493 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#5 = (???*0* | 0 | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +a#50 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#501 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#504 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#506 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#507 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#508 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#510 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#513 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#514 = ( + | ???*0* + | ???*1*() + | ???*2*() + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": (...) => ???*4*, + "lastRenderedState": ???*5* + }() + | ???*6*() + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": (...) => (("function" === typeof(b)) ? b(a) : b), + "lastRenderedState": ( + | ???*7* + | ???*8*() + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": (...) => (("function" === typeof(b)) ? b(a) : b), + "lastRenderedState": ???*9* + } + | ???*10* + ) + } + | ???*11* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*() + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* (("function" === typeof(b)) ? b(a) : b) + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* a + ⚠️ circular variable reference +- *9* a + ⚠️ circular variable reference +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects + +a#515 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#517 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#518 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#521 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#522 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#523 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#524 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#525 = (???*0* | ???*1*() | ???*2*()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*() + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference + +a#528 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#53 = (???*0* | ???*1* | ""["type"]["render"] | ""["displayName"] | ""["name"] | "") +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["render"] + ⚠️ unknown object +- *2* ???*3*["type"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +a#530 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#531 = (???*0* | ???*1*() | ???*2*()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*() + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference + +a#532 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#533 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#537 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#539 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#54 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#545 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#546 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#547 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#549 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#55 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeName"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#550 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#551 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#552 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#553 = (???*0* | ???*1*() | ???*2*()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*() + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference + +a#554 = ( + | ???*0* + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": ( + | ???*1* + | { + "pending": null, + "interleaved": null, + "lanes": 0, + "dispatch": null, + "lastRenderedReducer": ???*2*, + "lastRenderedState": (???*3* | (???*4* ? ???*7* : ???*9*)) + } + | ???*10* + ), + "lastRenderedState": (???*11* | (???*12* ? ???*15* : ???*17*)) + } + | ???*18* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* (???*5* !== ???*6*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*(b) + ⚠️ unknown callee +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* b + ⚠️ circular variable reference +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* (???*13* !== ???*14*) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* ???*16*(b) + ⚠️ unknown callee +- *16* arguments[2] + ⚠️ function calls are not analysed yet +- *17* b + ⚠️ circular variable reference +- *18* unsupported expression + ⚠️ This value might have side effects + +a#555 = (???*0* | {"current": (???*1* | {"current": ???*2*})}) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference + +a#556 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#557 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#559 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#56 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#562 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +a#565 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#566 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#568 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#569 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#570 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#573 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#574 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#578 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#580 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#585 = ( + | ???*0* + | (...) => undefined["bind"](null, (???*1* | ???*2*), ???*6*, ???*7*) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (...) => undefined["bind"](null, ???*3*, ???*4*, ???*5*) + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* arguments[2] + ⚠️ function calls are not analysed yet + +a#587 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#589 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#59 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#590 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#591 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#592 = ( + | ???*0* + | ???*1* + | ???*3* + | ???*4* + | null + | (???*5* ? ???*7* : (...) => (???*8* | ???*9*))["type"]["alternate"] + | ???*10* + | null["child"]["alternate"] +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* c + ⚠️ circular variable reference +- *7* c + ⚠️ circular variable reference +- *8* !(0) + ⚠️ nested operation +- *9* !(1) + ⚠️ nested operation +- *10* ???*11*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* ???*12*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unknown new expression + ⚠️ This value might have side effects + +a#595 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#597 = (???*0* | (???*1* ? ???*11* : ???*12*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (null !== ???*2*) + ⚠️ nested operation +- *2* (???*3* ? ???*9* : null) + ⚠️ nested operation +- *3* (null !== (???*4* | ???*5*)) + ⚠️ nested operation +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* (???*6* ? ???*7* : ???*8*) + ⚠️ nested operation +- *6* (null !== ???) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* arguments[2] + ⚠️ function calls are not analysed yet + +a#599 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#6 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#600 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#601 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#605 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#606 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#607 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#608 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#609 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#61 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#612 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#613 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +a#614 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#619 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#620 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#621 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#628 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#629 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +a#63 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#631 = (???*0* | null | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +a#634 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#639 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +a#64 = (???*0* | "" | ((???*1* | ???*2*) ? ???*6* : ???*9*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ("input" === ???*3*) + ⚠️ nested operation +- *3* ???*4*() + ⚠️ nested operation +- *4* ???*5*["toLowerCase"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* (???*7* ? "true" : "false") + ⚠️ nested operation +- *7* ???*8*["checked"] + ⚠️ unknown object +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* ???*10*["value"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet + +a#644 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#645 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#646 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#65 = (???*0* | ???*1* | (???*2* ? ???*5* : ???*6*) | (???*7* ? ???*10* : ???*11*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ("undefined" !== ???*3*) + ⚠️ nested operation +- *3* typeof(???*4*) + ⚠️ nested operation +- *4* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* ("undefined" !== ???*8*) + ⚠️ nested operation +- *8* typeof(???*9*) + ⚠️ nested operation +- *9* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects + +a#665 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["flags"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +a#667 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#670 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#68 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#687 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#69 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#691 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#695 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#697 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#698 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#699 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#7 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*(0, 5) + ⚠️ unknown callee +- *2* ???*3*["slice"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???*5*["toLowerCase"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +a#70 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#703 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#704 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#705 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#706 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#71 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#713 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#716 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#721 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#74 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#756 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#76 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#763 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#764 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#768 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#77 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["options"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#781 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#785 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#8 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#801 = ( + | ???*0* + | 0 + | 1 + | ???*1* + | 4 + | ((???*2* | ???*4*) ? ???*5* : 4) + | (???*6* ? 16 : (???*7* | null | ???*14* | ???*15*)) + | ???*17* + | (???*19* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* C + ⚠️ circular variable reference +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* C + ⚠️ circular variable reference +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* (???*8* ? ???*9* : 1) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 4) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? 16 : 536870912) + ⚠️ nested operation +- *12* (0 !== ???*13*) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* arguments[0] + ⚠️ function calls are not analysed yet +- *15* ???*16*["value"] + ⚠️ unknown object +- *16* arguments[1] + ⚠️ function calls are not analysed yet +- *17* ???*18*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *19* (???*20* === (???*21* | 0 | 1 | ???*22* | 4 | ???*23* | ???*28*)) + ⚠️ nested operation +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* arguments[0] + ⚠️ function calls are not analysed yet +- *22* C + ⚠️ circular variable reference +- *23* ((???*24* | ???*26*) ? ???*27* : 4) + ⚠️ nested operation +- *24* (0 !== ???*25*) + ⚠️ nested operation +- *25* C + ⚠️ circular variable reference +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* C + ⚠️ circular variable reference +- *28* ???*29*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +a#802 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#803 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#807 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#817 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#818 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#819 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#82 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#827 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["expirationTimes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#829 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#83 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#831 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#834 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#838 = (???*0* | ???*1* | ???*4* | ???*7*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* unknown new expression + ⚠️ This value might have side effects +- *7* unknown new expression + ⚠️ This value might have side effects + +a#843 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#861 = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"]["current"] + +a#863 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#868 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#869 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#87 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#877 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#88 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#880 = (???*0* | ???*1* | null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +a#883 = ((???*0* ? ???*1* : 1) | null | ???*6* | ???*7*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (???*2* ? ???*3* : 4) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (???*4* ? 16 : 536870912) + ⚠️ nested operation +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*["value"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet + +a#89 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#9 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#90 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#909 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#91 = (...) => undefined + +a#910 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#915 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#916 = (???*0* | (???*1* ? ???*5* : null)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +a#917 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#918 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#94 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#940 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#941 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#942 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#943 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["prototype"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#944 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["$$typeof"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#946 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#947 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +a#948 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +a#949 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +a#950 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +a#951 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#952 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#953 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +a#954 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#955 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#96 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#960 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#961 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#962 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#963 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#965 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +a#967 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#968 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#969 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#970 = ???*0* +- *0* ???*1*["_internalRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +a#973 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#974 = ( + | ???*0* + | { + "blockedOn": null, + "target": ( + | ???*1* + | { + "blockedOn": null, + "target": ???*2*, + "priority": ( + | ???*3*() + | 0 + | 1 + | ???*4* + | 4 + | ((???*5* | ???*7*) ? ???*8* : 4) + | (???*9* ? 16 : (???*10* | null | ???*16* | ???*17*)) + | ???*19* + ) + } + ), + "priority": ( + | ???*20*() + | 0 + | 1 + | ???*21* + | 4 + | ((???*22* | ???*24*) ? ???*25* : 4) + | (???*26* ? 16 : (???*27* | null | ???*34* | ???*35*)) + | ???*37* + ) + } +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* Hc + ⚠️ pattern without value +- *4* C + ⚠️ circular variable reference +- *5* (0 !== ???*6*) + ⚠️ nested operation +- *6* C + ⚠️ circular variable reference +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? ???*12* : 1) + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 4) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? 16 : 536870912) + ⚠️ nested operation +- *15* (... !== ...) + ⚠️ nested operation +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["value"] + ⚠️ unknown object +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* arguments[0] + ⚠️ function calls are not analysed yet +- *20* Hc + ⚠️ pattern without value +- *21* C + ⚠️ circular variable reference +- *22* (0 !== ???*23*) + ⚠️ nested operation +- *23* C + ⚠️ circular variable reference +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* C + ⚠️ circular variable reference +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* (???*28* ? ???*29* : 1) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* (???*30* ? ???*31* : 4) + ⚠️ nested operation +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* (???*32* ? 16 : 536870912) + ⚠️ nested operation +- *32* (0 !== ???*33*) + ⚠️ nested operation +- *33* unsupported expression + ⚠️ This value might have side effects +- *34* arguments[0] + ⚠️ function calls are not analysed yet +- *35* ???*36*["value"] + ⚠️ unknown object +- *36* arguments[1] + ⚠️ function calls are not analysed yet +- *37* arguments[0] + ⚠️ function calls are not analysed yet + +a#976 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#977 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#979 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#982 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#984 = (undefined | null | ???*0* | ???*3*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown new expression + ⚠️ This value might have side effects + +a#986 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#989 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +a#99 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#990 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#994 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +a#997 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +aa = module + +ab = (...) => undefined + +ac = module["unstable_scheduleCallback"] + +ad = (...) => undefined + +ae = (!(???*0*) | ???*3*) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +af = (???*0* | ???*1* | "animationiteration" | ???*2*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +ag = (...) => undefined + +ah = (...) => undefined + +ai = { + "readContext": (...) => b, + "useCallback": (...) => undefined, + "useContext": (...) => undefined, + "useEffect": (...) => undefined, + "useImperativeHandle": (...) => undefined, + "useInsertionEffect": (...) => undefined, + "useLayoutEffect": (...) => undefined, + "useMemo": (...) => undefined, + "useReducer": (...) => undefined, + "useRef": (...) => undefined, + "useState": (...) => undefined, + "useDebugValue": (...) => undefined, + "useDeferredValue": (...) => undefined, + "useTransition": (...) => undefined, + "useMutableSource": (...) => undefined, + "useSyncExternalStore": (...) => undefined, + "useId": (...) => undefined, + "unstable_isNewReconciler": false +} + +aj = (...) => (???*0* | ???*1* | $i(a, b, e)) +- *0* cj(a, b, f, d, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +ak = (...) => undefined + +al = (...) => undefined + +b#100 = (???*0* | ((???*1* | ???*2*) + ???*10* + ???*14*)) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (???*3* + ???*4* + ???*8*) + ⚠️ nested operation +- *3* b + ⚠️ circular variable reference +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toUpperCase"] + ⚠️ unknown object +- *6* ???*7*["charAt"](0) + ⚠️ unknown callee object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* ???*9*["substring"](1) + ⚠️ unknown callee object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*() + ⚠️ nested operation +- *11* ???*12*["toUpperCase"] + ⚠️ unknown object +- *12* ???*13*["charAt"](0) + ⚠️ unknown callee object +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["substring"](1) + ⚠️ unknown callee object +- *15* arguments[0] + ⚠️ function calls are not analysed yet + +b#1001 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#1004 = (???*0* | ???*1* | 0 | ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["name"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects + +b#101 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#1012 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#1013 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +b#1014 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#1017 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#1018 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#1019 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#102 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#1023 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#104 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#107 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#109 = ( + | ???*0* + | (???*2* ? null : (???*6* | ???*7*))["stateNode"] + | (???*9* ? null : (???*13* | ???*14*))["stateNode"][`__reactProps$${???*16*}`] + | null[`__reactProps$${???*21*}`] + | null +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* !((???*3* | ???*4*)) + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* ???*5*[Of] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* a + ⚠️ circular variable reference +- *7* ???*8*[Of] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* !((???*10* | ???*11*)) + ⚠️ nested operation +- *10* a + ⚠️ circular variable reference +- *11* ???*12*[Of] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference +- *13* a + ⚠️ circular variable reference +- *14* ???*15*[Of] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* ???*17*["slice"](2) + ⚠️ unknown callee object +- *17* ???*18*(36) + ⚠️ unknown callee +- *18* ???*19*["toString"] + ⚠️ unknown object +- *19* ???*20*() + ⚠️ nested operation +- *20* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* ???*22*["slice"](2) + ⚠️ unknown callee object +- *22* ???*23*(36) + ⚠️ unknown callee +- *23* ???*24*["toString"] + ⚠️ unknown object +- *24* ???*25*() + ⚠️ nested operation +- *25* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +b#11 = ???*0* +- *0* ???*1*[0] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#112 = (null | [???*0*] | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +b#114 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#116 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#119 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#123 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#127 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#128 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#131 = (???*0* | ???*1* | ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["return"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference + +b#133 = ???*0* +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#136 = (???*0* | (???*2* ? (???*5* | ???*6* | ???*7*) : null)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (3 === ???*3*) + ⚠️ nested operation +- *3* ???*4*["tag"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["return"] + ⚠️ unknown object +- *8* b + ⚠️ circular variable reference + +b#152 = (???*0* | ???*1* | ???*3* | null) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* (...) => (a | b | null)((???*4* | ???*5*)) + ⚠️ recursive function call + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["child"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference + +b#156 = ???*0* +- *0* b + ⚠️ pattern without value + +b#159 = (???*0* | ???*1* | ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["entangledLanes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects + +b#161 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#162 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#167 = [] + +b#168 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +b#169 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["entanglements"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +b#171 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#174 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#175 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#176 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#177 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#183 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#186 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#188 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#189 = (...) => ad(b, a) + +b#190 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#193 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#196 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#199 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#20 = ???*0* +- *0* ???*1*["replace"](ra, sa) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#203 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#207 = ( + | null + | ???*0* + | (???*1* ? (null["value"] | ???*2* | ???*17*) : (null["textContent"] | ???*19* | ???*34*)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["value"] + ⚠️ unknown object +- *3* (???*4* ? (???*9* | ???*11*) : (???*13* | ???*14* | ???*16*)) + ⚠️ nested operation +- *4* (3 === (???*5* | ???*7*)) + ⚠️ nested operation +- *5* ???*6*["nodeType"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* ???*10*["parentNode"] + ⚠️ unknown object +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* ???*12*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* ???*15*["target"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* ???*18*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unknown new expression + ⚠️ This value might have side effects +- *19* ???*20*["textContent"] + ⚠️ unknown object +- *20* (???*21* ? (???*26* | ???*28*) : (???*30* | ???*31* | ???*33*)) + ⚠️ nested operation +- *21* (3 === (???*22* | ???*24*)) + ⚠️ nested operation +- *22* ???*23*["nodeType"] + ⚠️ unknown object +- *23* arguments[2] + ⚠️ function calls are not analysed yet +- *24* ???*25*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *25* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *26* ???*27*["parentNode"] + ⚠️ unknown object +- *27* arguments[2] + ⚠️ function calls are not analysed yet +- *28* ???*29*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *30* arguments[2] + ⚠️ function calls are not analysed yet +- *31* ???*32*["target"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* ???*35*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *35* unknown new expression + ⚠️ This value might have side effects + +b#208 = (???*0* | 13["keyCode"]) +- *0* ???*1*["keyCode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#21 = ???*0* +- *0* ???*1*["replace"](ra, sa) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#211 = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +b#212 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*[c] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +b#22 = ???*0* +- *0* ???*1*["replace"](ra, sa) + ⚠️ unknown callee object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#221 = ???*0* +- *0* ???*1*["nativeEvent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +b#223 = ( + | "Escape" + | " " + | "ArrowLeft" + | "ArrowUp" + | "ArrowRight" + | "ArrowDown" + | "Delete" + | "OS" + | "ContextMenu" + | "ScrollLock" + | "Unidentified" + | ???*0* + | ???*3* + | ((???*5* | ???*6*) ? (???*10* | ???*11* | 13) : 0)["key"] +) +- *0* {}[???*1*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *1* ???*2*["key"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["key"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (13 === (???*7* | ???*8* | 13)) + ⚠️ nested operation +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["charCode"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["charCode"] + ⚠️ unknown object +- *12* a + ⚠️ circular variable reference + +b#230 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#232 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#233 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#235 = (???*0* | ???*1* | ???*3*()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeName"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["toLowerCase"] + ⚠️ unknown object +- *4* ???*5*["nodeName"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +b#236 = (???*0* | []) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#238 = (undefined | ???*0*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#239 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#244 = [] + +b#246 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#248 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#249 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#25 = (???*0* | (???*1* ? ???*7* : null)["attributeName"] | ???*9*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* | ???*3*)((???*4* | ???*5*)) + ⚠️ non-function callee +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["attributeName"] + ⚠️ unknown object +- *6* e + ⚠️ circular variable reference +- *7* {}[???*8*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["attributeName"] + ⚠️ unknown object +- *10* ???*11*["type"] + ⚠️ unknown object +- *11* e + ⚠️ circular variable reference + +b#250 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#251 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#254 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#260 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#261 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#265 = (???*0* | ???*1* | ???*3*()) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["nodeName"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["toLowerCase"] + ⚠️ unknown object +- *4* ???*5*["nodeName"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +b#266 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#269 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +b#27 = ???*0* +- *0* ???*1*(/\n( *(at )?)/) + ⚠️ unknown callee +- *1* ???*2*["match"] + ⚠️ unknown object +- *2* ???*3*() + ⚠️ nested operation +- *3* ???*4*["trim"] + ⚠️ unknown object +- *4* ???["stack"] + ⚠️ unknown object + +b#270 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#271 = ({} | ???*0*) +- *0* {}[???*1*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#272 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#274 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#275 = (???*0* | (0 !== ???*1*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +b#280 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#281 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#282 = (???*0* ? ???*3* : ???*4*) +- *0* (9 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["ownerDocument"] + ⚠️ unknown object +- *5* arguments[0] + ⚠️ function calls are not analysed yet + +b#284 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#285 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#286 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#3 = ( + | `https://reactjs.org/docs/error-decoder.html?invariant=${???*0*}` + | `${???*1*}&args[]=${???*3*}` +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* `https://reactjs.org/docs/error-decoder.html?invariant=${???*2*}` + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*(FreeVar(arguments)[c]) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *4* FreeVar(encodeURIComponent) + ⚠️ unknown global + ⚠️ This value might have side effects + +b#30 = (???*0* | (...) => undefined) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#307 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#308 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#311 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#314 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["replace"](yf, "") + ⚠️ unknown callee object +- *2* ???*3*(/\r\n?/g, "\n") + ⚠️ unknown callee +- *3* ???*4*["replace"] + ⚠️ unknown object +- *4* (???*5* ? (???*6* | ???*7*) : (???*8* | ???*9*)) + ⚠️ nested operation +- *5* ("string" === ???) + ⚠️ nested operation +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???["replace"](yf, "") + ⚠️ unknown callee object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???["replace"](yf, "") + ⚠️ unknown callee object + +b#316 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#320 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#324 = ???*0* +- *0* ???*1*["nodeType"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#327 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +b#331 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#340 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#341 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#344 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#345 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["childContextTypes"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +b#347 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#350 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +b#356 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#357 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#361 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +b#362 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#364 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#370 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#381 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*({}, b) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* ???*3*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +b#384 = (null | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b#385 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#387 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#388 = (???*0* | ???*2* | ???*3*) +- *0* ???*1*["_currentValue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects + +b#391 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#392 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#394 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#395 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#396 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#398 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +b#4 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#400 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#404 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["interleaved"] + ⚠️ unknown object +- *2* ???*3*["shared"] + ⚠️ unknown object +- *3* ???*4*["updateQueue"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +b#412 = (???*0* | 0 | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +b#415 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +b#417 = (???*0* | null | (???*1* ? ???*5* : null)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +b#418 = (???*0* | null | (???*1* ? ???*5* : null)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +b#419 = (???*0* | null | (???*1* ? ???*5* : null)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (3 === ???*2*) + ⚠️ nested operation +- *2* ???*3*["tag"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +b#420 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#421 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +b#422 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#423 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["state"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +b#424 = (???*0* | (...) => undefined) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#428 = (???*0* | ???*3*) +- *0* ???*1*["refs"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects + +b#429 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#430 = ???*0* +- *0* ???*1*["_init"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#431 = (...) => undefined + +b#432 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#435 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["sibling"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +b#436 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#437 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#438 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#439 = (???*0* | ???*1* | ???*2* | ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* b + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference + +b#440 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#441 = (???*0* | ???*1* | ???*3* | ???*4*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["mode"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* b + ⚠️ circular variable reference + +b#442 = (???*0* | ???*1* | ???*2* | ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects +- *2* b + ⚠️ circular variable reference +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference + +b#443 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#445 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#447 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#472 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#474 = ({} | ???*0*) +- *0* unknown mutation + ⚠️ This value might have side effects + +b#476 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +b#484 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#485 = ( + | ???*0* + | (null !== ( + | null + | ???*1* + | null["alternate"] + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | null["alternate"]["next"] | ???*19* | null | ???*22*)) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* unknown mutation + ⚠️ This value might have side effects + +b#490 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#493 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#494 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +b#5 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#50 = ( + | ???*0* + | null["displayName"]["render"] + | null["name"]["render"] + | ""["render"] + | (???*2* ? ???*4* : "ForwardRef")["render"] + | null["displayName"]["displayName"] + | null["name"]["displayName"] + | ""["displayName"] + | (???*6* ? ???*8* : "ForwardRef")["displayName"] + | null + | null["displayName"]["_payload"] + | null["name"]["_payload"] + | ""["_payload"] + | (???*10* ? ???*12* : "ForwardRef")["_payload"] +) +- *0* ???*1*["render"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ("" !== ???*3*) + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* `ForwardRef(${???*5*})` + ⚠️ nested operation +- *5* a + ⚠️ circular variable reference +- *6* ("" !== ???*7*) + ⚠️ nested operation +- *7* a + ⚠️ circular variable reference +- *8* `ForwardRef(${???*9*})` + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* ("" !== ???*11*) + ⚠️ nested operation +- *11* a + ⚠️ circular variable reference +- *12* `ForwardRef(${???*13*})` + ⚠️ nested operation +- *13* a + ⚠️ circular variable reference + +b#501 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +b#504 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#506 = ( + | ???*0* + | null["updateQueue"] + | ???*1* + | (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + ))["updateQueue"] + | (null !== (null["next"] | ???*19* | ???*21* | null | ???*24*))["updateQueue"] + | {"lastEffect": null, "stores": null} +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["next"] + ⚠️ unknown object +- *22* ???*23*["alternate"] + ⚠️ unknown object +- *23* N + ⚠️ circular variable reference +- *24* unknown mutation + ⚠️ This value might have side effects + +b#507 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#508 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#510 = ???*0* +- *0* ???*1*["getSnapshot"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#513 = (???*0* ? ???*4* : null) +- *0* (3 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["alternate"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +b#514 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +b#515 = ( + | ???*0* + | null["updateQueue"] + | ???*1* + | (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + ))["updateQueue"] + | (null !== (null["next"] | ???*19* | ???*21* | null | ???*24*))["updateQueue"] + | {"lastEffect": null, "stores": null} +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["next"] + ⚠️ unknown object +- *22* ???*23*["alternate"] + ⚠️ unknown object +- *23* N + ⚠️ circular variable reference +- *24* unknown mutation + ⚠️ This value might have side effects + +b#517 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#518 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#521 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#522 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#523 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#524 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#525 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#528 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#53 = (???*0* | ""["type"]) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#530 = (???*0* | (???*1* ? null : (???*9* | ???*10*))) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* === (???*3* | ???*4*)) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* (???*5* ? null : ???*8*) + ⚠️ nested operation +- *5* (???*6* === ???*7*) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* (???*11* ? null : ???*14*) + ⚠️ nested operation +- *11* (???*12* === ???*13*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* b + ⚠️ circular variable reference +- *14* b + ⚠️ circular variable reference + +b#531 = (???*0* | (???*1* ? null : (???*9* | ???*10*))) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* === (???*3* | ???*4*)) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* (???*5* ? null : ???*8*) + ⚠️ nested operation +- *5* (???*6* === ???*7*) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* (???*11* ? null : ???*14*) + ⚠️ nested operation +- *11* (???*12* === ???*13*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* b + ⚠️ circular variable reference +- *14* b + ⚠️ circular variable reference + +b#532 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#533 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#537 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#539 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#545 = ???*0* +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#546 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#547 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#549 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#55 = ???*0* +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#550 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#551 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#552 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#553 = (???*0* | (???*1* ? null : (???*9* | ???*10*))) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* === (???*3* | ???*4*)) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* (???*5* ? null : ???*8*) + ⚠️ nested operation +- *5* (???*6* === ???*7*) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* b + ⚠️ circular variable reference +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* (???*11* ? null : ???*14*) + ⚠️ nested operation +- *11* (???*12* === ???*13*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* b + ⚠️ circular variable reference +- *14* b + ⚠️ circular variable reference + +b#554 = (???*0* | (???*1* ? ???*4* : (???*6* | ???*7*))) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (???*2* !== ???*3*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* ???*5*(b) + ⚠️ unknown callee +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* (???*8* ? ???*11* : ???*13*) + ⚠️ nested operation +- *8* (???*9* !== ???*10*) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* ???*12*(b) + ⚠️ unknown callee +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* b + ⚠️ circular variable reference + +b#555 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +b#557 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#559 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#56 = ((???*0* | ???*1*) ? "checked" : "value") +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ("input" === ???*2*) + ⚠️ nested operation +- *2* ???*3*() + ⚠️ nested operation +- *3* ???*4*["toLowerCase"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +b#562 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#565 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +b#566 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#568 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +b#569 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#570 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#573 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#574 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#578 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#580 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#585 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#587 = (???*0* | (13 === ???*1*) | ???*3* | (???*5* ? ???*12* : true)) +- *0* b + ⚠️ pattern without value +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* (null !== (???*6* | ???*7* | ???*10*)) + ⚠️ nested operation +- *6* b + ⚠️ pattern without value +- *7* (13 === ???*8*) + ⚠️ nested operation +- *8* ???*9*["tag"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*["memoizedState"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* (???*13* ? true : false) + ⚠️ nested operation +- *13* (null !== ???*14*) + ⚠️ nested operation +- *14* ???*15*["dehydrated"] + ⚠️ unknown object +- *15* b + ⚠️ pattern without value + +b#589 = ( + | ???*0* + | {"eventTime": ???*1*, "lane": 1, "tag": 0, "payload": null, "callback": null, "next": null} +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +b#590 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#591 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#592 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#595 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#597 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#599 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#600 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#601 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#605 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#606 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#607 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#609 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#612 = ( + | ???*0* + | { + "mode": "visible", + "children": (???*1* | {"mode": "visible", "children": ???*2*} | ???*3*) + } + | ???*4* +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* b + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects + +b#613 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#614 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#619 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#620 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#621 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#628 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#629 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#631 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#634 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#639 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#64 = ( + | ???*0* + | ""["_valueTracker"] + | ((???*2* | ???*3*) ? ???*7* : ???*10*)["_valueTracker"] +) +- *0* ???*1*["_valueTracker"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ("input" === ???*4*) + ⚠️ nested operation +- *4* ???*5*() + ⚠️ nested operation +- *5* ???*6*["toLowerCase"] + ⚠️ unknown object +- *6* a + ⚠️ circular variable reference +- *7* (???*8* ? "true" : "false") + ⚠️ nested operation +- *8* ???*9*["checked"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["value"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference + +b#644 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#645 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["tail"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +b#646 = ((null !== ???*0*) | (???*2* === ???*5*)) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["child"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["child"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +b#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#665 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#667 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#67 = ???*0* +- *0* b + ⚠️ pattern without value + +b#670 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#68 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#687 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#69 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#691 = ( + | ???*0* + | ???*1* + | (???*3* ? ???*5* : null)["updateQueue"] + | (???*7* ? ???*16* : null) + | (???*18* ? ???*20* : null)["next"] +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* b + ⚠️ circular variable reference +- *5* ???*6*["lastEffect"] + ⚠️ unknown object +- *6* b + ⚠️ circular variable reference +- *7* (null !== (???*8* | ???*9* | ???*11*)) + ⚠️ nested operation +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["updateQueue"] + ⚠️ unknown object +- *10* b + ⚠️ circular variable reference +- *11* (???*12* ? ???*14* : null) + ⚠️ nested operation +- *12* (null !== ???*13*) + ⚠️ nested operation +- *13* b + ⚠️ circular variable reference +- *14* ???*15*["lastEffect"] + ⚠️ unknown object +- *15* b + ⚠️ circular variable reference +- *16* ???*17*["lastEffect"] + ⚠️ unknown object +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* (null !== ???*19*) + ⚠️ nested operation +- *19* b + ⚠️ circular variable reference +- *20* ???*21*["lastEffect"] + ⚠️ unknown object +- *21* b + ⚠️ circular variable reference + +b#695 = ???*0* +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#697 = ???*0* +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#7 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#70 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["checked"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +b#703 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["parentNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +b#704 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#705 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#706 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#71 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#713 = ???*0* +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#715 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#716 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +b#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#74 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["initialValue"] + ⚠️ unknown object +- *2* ???*3*["_wrapperState"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +b#756 = ???*0* +- *0* ???*1*["flags"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#76 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#763 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#764 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#77 = (???*0* | {} | null | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*[(0 | ???*3* | ???*4* | ???*12* | null["hasOwnProperty"](???*21*))] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* ???*5*["hasOwnProperty"](`$${???*6*}`) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*[(???*9* | 0 | ???*10* | undefined | ???*11* | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* updated with update expression + ⚠️ This value might have side effects +- *11* c + ⚠️ circular variable reference +- *12* (???*13* | ???*14*)(`$${???*15*}`) + ⚠️ non-function callee + ⚠️ This value might have side effects +- *13* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *14* unknown mutation + ⚠️ This value might have side effects +- *15* ???*16*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* ???*17*[(???*18* | 0 | ???*19* | undefined | ???*20* | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* arguments[2] + ⚠️ function calls are not analysed yet +- *19* updated with update expression + ⚠️ This value might have side effects +- *20* c + ⚠️ circular variable reference +- *21* `$${???*22*}` + ⚠️ nested operation +- *22* ???*23*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *23* ???*24*[(???*25* | 0 | ???*26* | undefined | ???*27* | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* arguments[0] + ⚠️ function calls are not analysed yet +- *25* arguments[2] + ⚠️ function calls are not analysed yet +- *26* updated with update expression + ⚠️ This value might have side effects +- *27* c + ⚠️ circular variable reference + +b#781 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#785 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#8 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#802 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#803 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects + +b#807 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#817 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#819 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +b#82 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#827 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +b#829 = ( + | 0 + | ???*0* + | ???*2* + | undefined + | 1 + | 2 + | 4 + | 8 + | 16 + | 32 + | ???*3* + | 134217728 + | 268435456 + | 536870912 + | 1073741824 + | (???*4* ? (???*7* | ???*8*) : ???*9*) +) +- *0* ???*1*["entangledLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* (0 !== (???*5* | ???*6*)) + ⚠️ nested operation +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? 1073741824 : 0) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +b#83 = (???*0* | ???*1* | ""["defaultValue"] | ""["value"] | ""["children"] | ???*3* | "") +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["defaultValue"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* c + ⚠️ circular variable reference + +b#831 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#834 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#838 = (???*0* | 0 | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +b#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#863 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#868 = ???*0* +- *0* ( + | ???*1* + | (...) => ( + | undefined + | ???*2* + | b + | null + | pj(a, b, c) + | b["child"] + | cj(a, b, b["type"], b["pendingProps"], c) + | yj(a, b, c) + | ej(a, b, c) + ) + )(a["alternate"], a, gj) + ⚠️ non-function callee +- *1* Wk + ⚠️ pattern without value +- *2* zj(a, b, c) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +b#869 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +b#87 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#877 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#88 = ???*0* +- *0* ???*1*["textContent"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#880 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#883 = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + +b#9 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#90 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#909 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#910 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#915 = (???*0* | (???*1* ? ???*3* : ???*4*)) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* module["unstable_now"]() + ⚠️ nested operation +- *4* (???*5* ? (???*9* | ???*10*) : ???*11*) + ⚠️ nested operation +- *5* (???*6* !== (???*7* | ???*8*)) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* module["unstable_now"]() + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects + +b#916 = (???*0* | 1 | 4194304 | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +b#917 = ???*0* +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#918 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +b#92 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +b#94 = (???*0* | ???*1* | ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["firstChild"] + ⚠️ unknown object +- *2* mb + ⚠️ pattern without value +- *3* ???*4*["firstChild"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +b#940 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#941 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#942 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#946 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["dependencies"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +b#947 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +b#948 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#949 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#950 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#951 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +b#952 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#953 = (???*0* | 1 | ???*1* | 0) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +b#954 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#955 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactInternals"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference + +b#96 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#960 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#961 = ( + | ???*0* + | { + "eventTime": (???*1* ? ???*3* : ???*4*), + "lane": ( + | 1 + | ???*12* + | ???*13* + | ???*14* + | ???*16* + | ???*17* + | 0 + | ???*18* + | 4 + | ((???*19* | ???*21*) ? ???*22* : 4) + | (???*23* ? 16 : (???*24* | null | ???*31* | ???*32*)) + | ???*34* + | ???*35* + | (???*37* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + } +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* module["unstable_now"]() + ⚠️ nested operation +- *4* (???*5* ? (???*9* | ???*10*) : ???*11*) + ⚠️ nested operation +- *5* (???*6* !== (???*7* | ???*8*)) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* module["unstable_now"]() + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *14* ???*15*["current"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* unknown mutation + ⚠️ This value might have side effects +- *18* C + ⚠️ circular variable reference +- *19* (0 !== ???*20*) + ⚠️ nested operation +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* C + ⚠️ circular variable reference +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 1) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? ???*28* : 4) + ⚠️ nested operation +- *27* unsupported expression + ⚠️ This value might have side effects +- *28* (???*29* ? 16 : 536870912) + ⚠️ nested operation +- *29* (0 !== ???*30*) + ⚠️ nested operation +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* arguments[0] + ⚠️ function calls are not analysed yet +- *32* ???*33*["value"] + ⚠️ unknown object +- *33* arguments[1] + ⚠️ function calls are not analysed yet +- *34* arguments[0] + ⚠️ function calls are not analysed yet +- *35* ???*36*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *36* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *37* (???*38* === ???*39*) + ⚠️ nested operation +- *38* unsupported expression + ⚠️ This value might have side effects +- *39* a + ⚠️ circular variable reference + +b#963 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#965 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#969 = ???*0* +- *0* ???*1*["_internalRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +b#970 = ???*0* +- *0* ???*1*["containerInfo"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["_internalRoot"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +b#974 = ( + | ???*0*() + | 0 + | 1 + | ???*1* + | 4 + | ((???*2* | ???*4*) ? ???*5* : 4) + | (???*6* ? 16 : (???*7* | null | ???*14* | ???*15*)) + | ???*17* +) +- *0* Hc + ⚠️ pattern without value +- *1* C + ⚠️ circular variable reference +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* C + ⚠️ circular variable reference +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* (???*8* ? ???*9* : 1) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 4) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? 16 : 536870912) + ⚠️ nested operation +- *12* (0 !== ???*13*) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* arguments[0] + ⚠️ function calls are not analysed yet +- *15* ???*16*["value"] + ⚠️ unknown object +- *16* arguments[1] + ⚠️ function calls are not analysed yet +- *17* arguments[0] + ⚠️ function calls are not analysed yet + +b#979 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#986 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +b#990 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +b#992 = (???*0* ? ???*4* : null) +- *0* (3 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["alternate"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +b#994 = (???*0* ? ???*4* : null) +- *0* (3 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["alternate"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +b#997 = ( + | 1 + | ???*0* + | ???*1* + | ???*2* + | 0 + | ???*3* + | 4 + | ((???*4* | ???*6*) ? ???*7* : 4) + | (???*8* ? 16 : (???*9* | null | ???*16* | ???*17*)) + | ???*19* + | (???*21* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* C + ⚠️ circular variable reference +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 1) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 4) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? 16 : 536870912) + ⚠️ nested operation +- *14* (0 !== ???*15*) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["value"] + ⚠️ unknown object +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* ???*20*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *21* (???*22* === ???*23*) + ⚠️ nested operation +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* a + ⚠️ circular variable reference + +ba = ("onCompositionStart" | "onCompositionEnd" | "onCompositionUpdate" | ???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unknown new expression + ⚠️ This value might have side effects + +bb = (...) => (undefined | FreeVar(undefined)) + +bc = module["unstable_cancelCallback"] + +bd = (...) => undefined + +be = (null | ???*0*) +- *0* ???*1*["documentMode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +bf = (???*0* | ???*1* | "animationstart" | ???*2*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +bg = (...) => (c | A({}, c, d)) + +bh = (...) => undefined + +bi = (...) => a + +bj = (...) => !((!(a) || !(a["isReactComponent"]))) + +bk = (...) => undefined + +bl = (...) => undefined + +c#1001 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +c#1004 = (???*0* | ???*1* | ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["parentNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["querySelectorAll"](`input[name=${???*5*}][type="radio"]`) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* ???*6*["stringify"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *6* FreeVar(JSON) + ⚠️ unknown global + ⚠️ This value might have side effects + +c#101 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#1012 = ((???*0* | ???*1*) ? ???*5* : null) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (???*2* !== ???*3*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*[2] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* ???*6*[2] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +c#1013 = (false | true) + +c#1017 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#1018 = ( + | ???*0* + | (null != (???*1* | ???*2*))[(???*4* | 0 | ???*5*)] + | ???*6* + | null[(???*11* | 0 | ???*12*)] +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*[a] + ⚠️ unknown object +- *3* d + ⚠️ circular variable reference +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* ???*7*[(???*9* | 0 | ???*10*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["hydratedSources"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* updated with update expression + ⚠️ This value might have side effects +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* updated with update expression + ⚠️ This value might have side effects + +c#1019 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#102 = (???*0* | "cssFloat") +- *0* c + ⚠️ pattern without value + +c#1023 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#116 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#119 = ( + | ???*0* + | !((???*2* | null | ???*5*))["stateNode"] + | false["stateNode"] + | !(???*8*)["stateNode"][`__reactProps$${???*9*}`][???*14*] + | false["stateNode"][`__reactProps$${???*15*}`][???*20*] + | null[???*21*] + | !(???*22*)[???*24*] + | !(???*25*)[???*31*] +) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*[Pf] + ⚠️ unknown object +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* !(???*6*) + ⚠️ nested operation +- *6* ???*7*["disabled"] + ⚠️ unknown object +- *7* d + ⚠️ circular variable reference +- *8* d + ⚠️ circular variable reference +- *9* ???*10*["slice"](2) + ⚠️ unknown callee object +- *10* ???*11*(36) + ⚠️ unknown callee +- *11* ???*12*["toString"] + ⚠️ unknown object +- *12* ???*13*() + ⚠️ nested operation +- *13* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* arguments[1] + ⚠️ function calls are not analysed yet +- *15* ???*16*["slice"](2) + ⚠️ unknown callee object +- *16* ???*17*(36) + ⚠️ unknown callee +- *17* ???*18*["toString"] + ⚠️ unknown object +- *18* ???*19*() + ⚠️ nested operation +- *19* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* ???*23*["disabled"] + ⚠️ unknown object +- *23* d + ⚠️ circular variable reference +- *24* arguments[1] + ⚠️ function calls are not analysed yet +- *25* ("button" === (???*26* | ???*27* | ???*29* | false)) + ⚠️ nested operation +- *26* arguments[0] + ⚠️ function calls are not analysed yet +- *27* ???*28*["type"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* !(???*30*) + ⚠️ nested operation +- *30* d + ⚠️ circular variable reference +- *31* arguments[1] + ⚠️ function calls are not analysed yet + +c#123 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#127 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#128 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#131 = (???*0* | ???*1* | ???*2*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* a + ⚠️ circular variable reference +- *2* ???*3*["return"] + ⚠️ unknown object +- *3* b + ⚠️ circular variable reference + +c#136 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#159 = (???*0* | ???*2*) +- *0* ???*1*["pendingLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +c#162 = ???*0* +- *0* ???*1*["suspendedLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#167 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#168 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#169 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +c#171 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +c#175 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#176 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#177 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#183 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#186 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#189 = (1 | ???*0* | 0 | ???*1*) +- *0* updated with update expression + ⚠️ This value might have side effects +- *1* [][0] + ⚠️ invalid index + +c#193 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#196 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#199 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#203 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#207 = ( + | null["length"] + | ???*0* + | (???*2* ? (null["value"] | ???*3* | ???*18*) : (null["textContent"] | ???*20* | ???*35*))["length"] +) +- *0* ???*1*["length"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["value"] + ⚠️ unknown object +- *4* (???*5* ? (???*10* | ???*12*) : (???*14* | ???*15* | ???*17*)) + ⚠️ nested operation +- *5* (3 === (???*6* | ???*8*)) + ⚠️ nested operation +- *6* ???*7*["nodeType"] + ⚠️ unknown object +- *7* arguments[2] + ⚠️ function calls are not analysed yet +- *8* ???*9*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* ???*11*["parentNode"] + ⚠️ unknown object +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* ???*13*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* ???*16*["target"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *18* ???*19*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* unknown new expression + ⚠️ This value might have side effects +- *20* ???*21*["textContent"] + ⚠️ unknown object +- *21* (???*22* ? (???*27* | ???*29*) : (???*31* | ???*32* | ???*34*)) + ⚠️ nested operation +- *22* (3 === (???*23* | ???*25*)) + ⚠️ nested operation +- *23* ???*24*["nodeType"] + ⚠️ unknown object +- *24* arguments[2] + ⚠️ function calls are not analysed yet +- *25* ???*26*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *27* ???*28*["parentNode"] + ⚠️ unknown object +- *28* arguments[2] + ⚠️ function calls are not analysed yet +- *29* ???*30*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *31* arguments[2] + ⚠️ function calls are not analysed yet +- *32* ???*33*["target"] + ⚠️ unknown object +- *33* a + ⚠️ circular variable reference +- *34* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *35* ???*36*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *36* unknown new expression + ⚠️ This value might have side effects + +c#212 = ???*0* +- *0* c + ⚠️ pattern without value + +c#236 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +c#246 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#25 = (???*0* | null | (???*1* ? "" : (???*13* | null | ???*14*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (3 === (???*2* | ???*11*)) + ⚠️ nested operation +- *2* (???*3* ? ???*9* : null) + ⚠️ nested operation +- *3* (???*4* | ???*5*)((???*6* | ???*7*)) + ⚠️ non-function callee +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* arguments[1] + ⚠️ function calls are not analysed yet +- *7* ???*8*["attributeName"] + ⚠️ unknown object +- *8* e + ⚠️ circular variable reference +- *9* {}[???*10*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* ???*12*["type"] + ⚠️ unknown object +- *12* e + ⚠️ circular variable reference +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* (???*15* ? "" : ???*26*) + ⚠️ nested operation +- *15* (3 === (???*16* | ???*24*)) + ⚠️ nested operation +- *16* (???*17* ? ???*22* : null) + ⚠️ nested operation +- *17* (???*18* | ???*19*)((???*20* | ???*21*)) + ⚠️ non-function callee +- *18* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *19* unknown mutation + ⚠️ This value might have side effects +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???["attributeName"] + ⚠️ unknown object +- *22* {}[???*23*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *23* arguments[1] + ⚠️ function calls are not analysed yet +- *24* ???*25*["type"] + ⚠️ unknown object +- *25* e + ⚠️ circular variable reference +- *26* c + ⚠️ circular variable reference + +c#251 = ???*0* +- *0* ???*1*["keys"](a) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +c#254 = ( + | ???*0* + | 0 + | ???*1* + | (???*2* + (???*3* | ???*6*)) + | ???*9* + | 0["nextSibling"] + | (???*11* + ???*12*)["nextSibling"] + | ???*15* + | 0["parentNode"] + | (???*17* + ???*18*)["parentNode"] + | ???*21* + | (???*22* + ???*23*) + | ???*26* +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* d + ⚠️ pattern without value +- *2* a + ⚠️ circular variable reference +- *3* ???*4*["length"] + ⚠️ unknown object +- *4* ???*5*["textContent"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* ???*7*["length"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* ???*10*["firstChild"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* a + ⚠️ circular variable reference +- *12* ???*13*["length"] + ⚠️ unknown object +- *13* ???*14*["textContent"] + ⚠️ unknown object +- *14* c + ⚠️ circular variable reference +- *15* ???*16*["nextSibling"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* a + ⚠️ circular variable reference +- *18* ???*19*["length"] + ⚠️ unknown object +- *19* ???*20*["textContent"] + ⚠️ unknown object +- *20* c + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* a + ⚠️ circular variable reference +- *23* ???*24*["length"] + ⚠️ unknown object +- *24* ???*25*["textContent"] + ⚠️ unknown object +- *25* c + ⚠️ circular variable reference +- *26* c + ⚠️ circular variable reference + +c#261 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#266 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#269 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#270 = {} + +c#271 = ???*0* +- *0* c + ⚠️ pattern without value + +c#274 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#275 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#280 = (???*0* | ???*2*) +- *0* ???*1*[of] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +c#281 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#285 = ( + | ???*0* + | (...) => undefined["bind"](null, ???*1*, (???*2* | ???*3* | ???*7*), ???*12*) + | ???*13* + | true["bind"](null, ???*29*, (???*30* | ???*31* | ???*35*), ???*40*) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* (...) => undefined["bind"](null, ???*4*, ???*5*, ???*6*) + ⚠️ nested operation +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* c + ⚠️ circular variable reference +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* ???*8*["bind"](null, ???*9*, ???*10*, ???*11*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* c + ⚠️ circular variable reference +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* ???*14*["bind"]( + null, + ???*15*, + ( + | ???*16* + | (...) => undefined["bind"](null, ???*17*, ???*18*, ???*19*) + | ???*20* + | true["bind"](null, ???*25*, ???*26*, ???*27*) + ), + ???*28* + ) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[2] + ⚠️ function calls are not analysed yet +- *17* arguments[1] + ⚠️ function calls are not analysed yet +- *18* c + ⚠️ circular variable reference +- *19* arguments[0] + ⚠️ function calls are not analysed yet +- *20* ???*21*["bind"](null, ???*22*, ???*23*, ???*24*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* arguments[1] + ⚠️ function calls are not analysed yet +- *23* c + ⚠️ circular variable reference +- *24* arguments[0] + ⚠️ function calls are not analysed yet +- *25* arguments[1] + ⚠️ function calls are not analysed yet +- *26* c + ⚠️ circular variable reference +- *27* arguments[0] + ⚠️ function calls are not analysed yet +- *28* arguments[0] + ⚠️ function calls are not analysed yet +- *29* arguments[1] + ⚠️ function calls are not analysed yet +- *30* arguments[2] + ⚠️ function calls are not analysed yet +- *31* (...) => undefined["bind"](null, ???*32*, ???*33*, ???*34*) + ⚠️ nested operation +- *32* arguments[1] + ⚠️ function calls are not analysed yet +- *33* c + ⚠️ circular variable reference +- *34* arguments[0] + ⚠️ function calls are not analysed yet +- *35* ???*36*["bind"](null, ???*37*, ???*38*, ???*39*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *36* unsupported expression + ⚠️ This value might have side effects +- *37* arguments[1] + ⚠️ function calls are not analysed yet +- *38* c + ⚠️ circular variable reference +- *39* arguments[0] + ⚠️ function calls are not analysed yet +- *40* arguments[0] + ⚠️ function calls are not analysed yet + +c#286 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#29 = ???*0* +- *0* c + ⚠️ pattern without value + +c#3 = (1 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#30 = ???*0* +- *0* ???*1*["prepareStackTrace"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Error) + ⚠️ unknown global + ⚠️ This value might have side effects + +c#307 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#308 = `${???*0*}Capture` +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +c#311 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +c#314 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#320 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["data"] + ⚠️ unknown object +- *2* ???*3*["nextSibling"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +c#327 = ???*0* +- *0* ???*1*["data"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#331 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#341 = ???*0* +- *0* ???*1*["contextTypes"] + ⚠️ unknown object +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +c#344 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#345 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#347 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#350 = (null | [???*0*] | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["slice"]((a + 1)) + ⚠️ unknown callee object +- *2* eg + ⚠️ circular variable reference + +c#357 = (???*0* | ((???*1* | ???*2*) + 1)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* (???*3* + 1) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference + +c#361 = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +c#362 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#364 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#370 = (???*0* | (???*2* ? ???*4* : null)["data"]) +- *0* ???*1*["data"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* a + ⚠️ circular variable reference +- *4* ???*5*["dehydrated"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference + +c#381 = ???*0* +- *0* c + ⚠️ pattern without value + +c#385 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#391 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#392 = (???*0* | ???*2*) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +c#396 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#398 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +c#400 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#404 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#412 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#415 = (???*0* | ???*1* | (???*13* ? (???*26* | ???*27*) : ???*29*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (???*2* | ???*3* | (???*5* ? (???*7* | ???*8*) : ???*10*))(d, b) + ⚠️ non-function callee +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*(d, b) + ⚠️ unknown callee +- *4* c + ⚠️ circular variable reference +- *5* (null === ???*6*) + ⚠️ nested operation +- *6* c + ⚠️ circular variable reference +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* ???*11*({}, b, c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *11* ???*12*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* (null === (???*14* | ???*15* | ???*17*)) + ⚠️ nested operation +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* ???*16*(d, b) + ⚠️ unknown callee +- *16* c + ⚠️ circular variable reference +- *17* (???*18* ? (???*20* | ???*21*) : ???*23*) + ⚠️ nested operation +- *18* (null === ???*19*) + ⚠️ nested operation +- *19* c + ⚠️ circular variable reference +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*["memoizedState"] + ⚠️ unknown object +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* ???*24*({}, b, c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *24* ???*25*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *25* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *26* arguments[1] + ⚠️ function calls are not analysed yet +- *27* ???*28*["memoizedState"] + ⚠️ unknown object +- *28* arguments[0] + ⚠️ function calls are not analysed yet +- *29* ???*30*({}, b, c) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *30* ???*31*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *31* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +c#417 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#418 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#419 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +c#420 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#421 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#422 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#423 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#424 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_owner"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +c#431 = (...) => null + +c#432 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +c#434 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +c#437 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +c#439 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#440 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#441 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#442 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#443 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#445 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#447 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#474 = (???*0* ? ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" +) : ???*2*) +- *0* (null == ({} | ???*1*)) + ⚠️ nested operation +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* (???*3* ? "http://www.w3.org/1999/xhtml" : ({} | ???*5*)) + ⚠️ nested operation +- *3* ("http://www.w3.org/2000/svg" === ({} | ???*4*)) + ⚠️ nested operation +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +c#476 = ???*0* +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#484 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#485 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#501 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#504 = ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects + +c#506 = ( + | ???*0* + | ???*1* + | null["updateQueue"]["stores"] + | (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + ))["updateQueue"]["stores"] + | (null !== (null["next"] | ???*19* | ???*21* | null | ???*24*))["updateQueue"]["stores"] + | null + | ???*25* +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stores"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["next"] + ⚠️ unknown object +- *22* ???*23*["alternate"] + ⚠️ unknown object +- *23* N + ⚠️ circular variable reference +- *24* unknown mutation + ⚠️ This value might have side effects +- *25* unknown mutation + ⚠️ This value might have side effects + +c#507 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#508 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#510 = ???*0*() +- *0* ???*1*["getSnapshot"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#515 = ( + | ???*0* + | ???*1* + | null["updateQueue"]["lastEffect"] + | (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + ))["updateQueue"]["lastEffect"] + | (null !== (null["next"] | ???*19* | ???*21* | null | ???*24*))["updateQueue"]["lastEffect"] + | null + | ???*25* +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["lastEffect"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["next"] + ⚠️ unknown object +- *22* ???*23*["alternate"] + ⚠️ unknown object +- *23* N + ⚠️ circular variable reference +- *24* unknown mutation + ⚠️ This value might have side effects +- *25* unknown mutation + ⚠️ This value might have side effects + +c#517 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#518 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#52 = ???*0* +- *0* c + ⚠️ pattern without value + +c#528 = (???*0* | (???*1* ? (???*8* | ???*11*) : null)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (null !== (???*2* | ???*3*)) + ⚠️ nested operation +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* c + ⚠️ circular variable reference +- *6* ???*7*["concat"]([a]) + ⚠️ unknown callee object +- *7* c + ⚠️ circular variable reference +- *8* ???*9*["concat"]([???*10*]) + ⚠️ unknown callee object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* ???*12*([???*18*]) + ⚠️ unknown callee +- *12* ???*13*["concat"] + ⚠️ unknown object +- *13* (???*14* ? ???*16* : null) + ⚠️ nested operation +- *14* (null !== ???*15*) + ⚠️ nested operation +- *15* c + ⚠️ circular variable reference +- *16* ???*17*["concat"]([a]) + ⚠️ unknown callee object +- *17* c + ⚠️ circular variable reference +- *18* arguments[0] + ⚠️ function calls are not analysed yet + +c#530 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +c#531 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +c#532 = (???*0* | 64 | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +c#533 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +c#537 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#539 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#546 = ???*0* +- *0* ???*1*["pending"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#547 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +c#550 = (???*0* | (???*1* ? (???*8* | ???*11*) : null)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (null !== (???*2* | ???*3*)) + ⚠️ nested operation +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* (???*4* ? ???*6* : null) + ⚠️ nested operation +- *4* (null !== ???*5*) + ⚠️ nested operation +- *5* c + ⚠️ circular variable reference +- *6* ???*7*["concat"]([a]) + ⚠️ unknown callee object +- *7* c + ⚠️ circular variable reference +- *8* ???*9*["concat"]([???*10*]) + ⚠️ unknown callee object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* arguments[0] + ⚠️ function calls are not analysed yet +- *11* ???*12*([???*18*]) + ⚠️ unknown callee +- *12* ???*13*["concat"] + ⚠️ unknown object +- *13* (???*14* ? ???*16* : null) + ⚠️ nested operation +- *14* (null !== ???*15*) + ⚠️ nested operation +- *15* c + ⚠️ circular variable reference +- *16* ???*17*["concat"]([a]) + ⚠️ unknown callee object +- *17* c + ⚠️ circular variable reference +- *18* arguments[0] + ⚠️ function calls are not analysed yet + +c#553 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +c#554 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#559 = (???*0* | ???*1*() | ???*2*()) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*() + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference + +c#56 = ???*0* +- *0* ???*1*["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +c#562 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#570 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#573 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#576 = ???*0* +- *0* c + ⚠️ pattern without value + +c#578 = ( + | ???*0* + | { + "eventTime": ???*1*, + "lane": ( + | ???*2* + | {"eventTime": ???*3*, "lane": ???*4*, "tag": 0, "payload": null, "callback": null, "next": null} + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + } +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* c + ⚠️ circular variable reference + +c#580 = ( + | ???*0* + | { + "eventTime": ???*1*, + "lane": ( + | ???*2* + | {"eventTime": ???*3*, "lane": ???*4*, "tag": 0, "payload": null, "callback": null, "next": null} + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + } +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* c + ⚠️ circular variable reference + +c#584 = ???*0* +- *0* ???*1*["stack"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +c#585 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#589 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#590 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#591 = (???*0* | ???*1* | (0 !== (0 | ???*3*))["render"] | (0 !== (0 | ???*4*))) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["render"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects + +c#592 = ( + | ???*0* + | ???*1* + | (???*3* ? ???*5* : (...) => (???*6* | ???*7*))["compare"] + | (???*8* ? (???*18* | ???*19* | ???*21*) : (...) => (???*27* | ???*28*)) +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["compare"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* c + ⚠️ circular variable reference +- *5* c + ⚠️ circular variable reference +- *6* !(0) + ⚠️ nested operation +- *7* !(1) + ⚠️ nested operation +- *8* (null !== (???*9* | ???*10* | ???*12*)) + ⚠️ nested operation +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["compare"] + ⚠️ unknown object +- *11* c + ⚠️ circular variable reference +- *12* (???*13* ? ???*15* : (...) => (???*16* | ???*17*)) + ⚠️ nested operation +- *13* (null !== ???*14*) + ⚠️ nested operation +- *14* c + ⚠️ circular variable reference +- *15* c + ⚠️ circular variable reference +- *16* !(0) + ⚠️ nested operation +- *17* !(1) + ⚠️ nested operation +- *18* arguments[2] + ⚠️ function calls are not analysed yet +- *19* ???*20*["compare"] + ⚠️ unknown object +- *20* c + ⚠️ circular variable reference +- *21* (???*22* ? ???*24* : (...) => (???*25* | ???*26*)) + ⚠️ nested operation +- *22* (null !== ???*23*) + ⚠️ nested operation +- *23* c + ⚠️ circular variable reference +- *24* c + ⚠️ circular variable reference +- *25* !(0) + ⚠️ nested operation +- *26* !(1) + ⚠️ nested operation +- *27* !(0) + ⚠️ nested operation +- *28* !(1) + ⚠️ nested operation + +c#595 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#597 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#599 = ???*0* +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +c#600 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* (???*2* | ???*3*)(d, e) + ⚠️ non-function callee +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*(d, e) + ⚠️ unknown callee +- *4* c + ⚠️ circular variable reference + +c#601 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#605 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#607 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#609 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +c#613 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#614 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#619 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#620 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#621 = ( + | ???*0* + | ???*1* + | 0["revealOrder"]["sibling"] + | ???*3* + | null["sibling"] + | 0["revealOrder"] + | null + | ???*6* + | null["alternate"] +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["sibling"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* e + ⚠️ circular variable reference + +c#629 = (???*0* | ???*1* | ???*3* | ???*4*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +c#631 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#634 = ???*0* +- *0* ???*1*["child"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +c#639 = (???*0* | null | {} | ???*1* | ???*5* | (???*14* ? ???*15* : ???*17*)) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*[(???*3* | null | [] | ???*4*)] + ⚠️ unknown object +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* l + ⚠️ pattern without value +- *4* f + ⚠️ circular variable reference +- *5* ???*6*[(???*12* | null | [] | ???*13*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*( + {}, + b, + { + "defaultChecked": ???*9*, + "defaultValue": ???*10*, + "value": ???*11*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *7* ???*8*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* l + ⚠️ pattern without value +- *13* f + ⚠️ circular variable reference +- *14* k + ⚠️ circular variable reference +- *15* ???*16*["__html"] + ⚠️ unknown object +- *16* k + ⚠️ circular variable reference +- *17* unsupported expression + ⚠️ This value might have side effects + +c#64 = (???*0*() | ""["_valueTracker"]["getValue"]()) +- *0* ???*1*["getValue"] + ⚠️ unknown object +- *1* ???*2*["_valueTracker"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +c#644 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#645 = (null | ???*0* | ???*1* | null["sibling"]) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["tail"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +c#646 = (0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +c#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#667 = ???*0* +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#670 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#68 = ???*0* +- *0* ???*1*["checked"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +c#687 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#69 = ((???*0* ? "" : ???*3*) | undefined | (???*5* ? ???*8* : (???*10* | undefined | "")) | "") +- *0* (null == ???*1*) + ⚠️ nested operation +- *1* ???*2*["defaultValue"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["defaultValue"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* (null != ???*6*) + ⚠️ nested operation +- *6* ???*7*["value"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* ???*9*["value"] + ⚠️ unknown object +- *9* arguments[1] + ⚠️ function calls are not analysed yet +- *10* (???*11* ? "" : ???*14*) + ⚠️ nested operation +- *11* (null == ???*12*) + ⚠️ nested operation +- *12* ???*13*["defaultValue"] + ⚠️ unknown object +- *13* arguments[1] + ⚠️ function calls are not analysed yet +- *14* ???*15*["defaultValue"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet + +c#691 = (???*0* | ???*1* | ???*3*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["next"] + ⚠️ unknown object +- *4* ???*5*["next"] + ⚠️ unknown object +- *5* c + ⚠️ circular variable reference + +c#695 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#7 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#703 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["_reactRootContainer"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +c#704 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#705 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +c#706 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +c#71 = (undefined | ???*0* | "") +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +c#713 = (???*0* | ???*2*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +c#716 = ???*0* +- *0* ???*1*["deletions"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +c#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#74 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["name"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +c#756 = ???*0* +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#76 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#763 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#764 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#77 = (???*0* | 0 | ???*1* | undefined | ???*2* | "") +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects +- *2* c + ⚠️ circular variable reference + +c#781 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#785 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#8 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#802 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#803 = ( + | ???*0* + | null + | module["unstable_ImmediatePriority"] + | module["unstable_UserBlockingPriority"] + | module["unstable_NormalPriority"] + | module["unstable_IdlePriority"] + | module["unstable_scheduleCallback"]( + ( + | ???*2* + | null + | module["unstable_ImmediatePriority"] + | module["unstable_UserBlockingPriority"] + | module["unstable_NormalPriority"] + | module["unstable_IdlePriority"] + | ???*4* + ), + ???*9* + ) +) +- *0* ???*1*["callbackNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["callbackNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* module["unstable_scheduleCallback"](???*5*, ???*6*) + ⚠️ nested operation +- *5* c + ⚠️ circular variable reference +- *6* (...) => (null | ???*7*)["bind"](null, ???*8*) + ⚠️ nested operation +- *7* ((...[...] === c) ? Hk["bind"](null, a) : null) + ⚠️ nested operation +- *8* arguments[0] + ⚠️ function calls are not analysed yet +- *9* (...) => (null | ???*10*)["bind"](null, ???*11*) + ⚠️ nested operation +- *10* ((a["callbackNode"] === c) ? Hk["bind"](null, a) : null) + ⚠️ nested operation +- *11* arguments[0] + ⚠️ function calls are not analysed yet + +c#807 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#817 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#819 = ???*0* +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#827 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +c#829 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#83 = ( + | ???*0* + | ""["value"] + | ""["children"] + | ""["value"][0] + | ""["children"][0] + | ""[0] + | ???*2* + | ???*3* + | "" +) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* b + ⚠️ circular variable reference + +c#831 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#834 = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + +c#838 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#863 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#869 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#87 = (undefined | ???*0* | "" | ???*2*) +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ circular variable reference + +c#877 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#880 = (???*0* | ???*1* | null["finishedWork"] | 0 | ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["finishedWork"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects + +c#883 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +c#9 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#909 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#910 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#915 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#916 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +c#917 = (0 | ???*0*) +- *0* ???*1*["retryLane"] + ⚠️ unknown object +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +c#918 = (0 | ???*0*) +- *0* ???*1*["retryLane"] + ⚠️ unknown object +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +c#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +c#92 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +c#941 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#942 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#946 = (???*0* | ???*2*) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects + +c#947 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#948 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#949 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#950 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#951 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#952 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#953 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#954 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#955 = ???*0* +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#96 = ???*0* +- *0* ???*1*["firstChild"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#960 = (???*0* | ???*1* | ???*3*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown new expression + ⚠️ This value might have side effects + +c#961 = (???*0* | {} | ???*1* | ???*2* | ???*4*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* c + ⚠️ circular variable reference +- *2* ???*3*["_reactInternals"] + ⚠️ unknown object +- *3* a + ⚠️ circular variable reference +- *4* ???*5*({}, c, d) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *5* ???*6*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +c#963 = ???*0* +- *0* ???*1*["retryLane"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +c#974 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +c#979 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#986 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +c#990 = ( + | undefined + | 1 + | 2 + | 4 + | 8 + | 16 + | 32 + | ???*0* + | 134217728 + | 268435456 + | 536870912 + | 1073741824 + | ???*1* +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["pendingLanes"] + ⚠️ unknown object +- *2* ???*3*["stateNode"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +c#992 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +c#994 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +c#997 = (???*0* ? ???*4* : null) +- *0* (3 === ???*1*) + ⚠️ nested operation +- *1* ???*2*["tag"] + ⚠️ unknown object +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* ???*5*["stateNode"] + ⚠️ unknown object +- *5* ???*6*["alternate"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet + +ca = module + +cb = (...) => undefined + +cc = module["unstable_shouldYield"] + +cd = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"] + +ce = (!(???*0*) | ???*3* | !((null | ???*4*))) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["documentMode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +cf = (???*0* | ???*1* | "transitionend" | ???*2*) +- *0* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects + +cg = (...) => !(0) + +ch = (...) => {"eventTime": a, "lane": b, "tag": 0, "payload": null, "callback": null, "next": null} + +ci = (...) => P + +cj = (...) => (???*0* | dj(a, b, c, d, e)) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +ck = (...) => undefined + +cl = (...) => a + +d#1004 = ???*0* +- *0* ???*1*[(???*2* | ???*3* | 0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["name"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects + +d#1013 = ("" | ???*0* | ???*2*) +- *0* ???*1*["identifierPrefix"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["identifierPrefix"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unknown new expression + ⚠️ This value might have side effects + +d#1018 = ( + | (null != (???*0* | ???*1* | null[(???*6* | 0 | ???*7*)])) + | ???*8* + | (null != ???*10*)[(???*11* | 0 | ???*12*)]["hydratedSources"] + | ???*13* + | null[(???*19* | 0 | ???*20*)]["hydratedSources"] + | null +) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*[(???*4* | 0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* (null != ???*3*) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* updated with update expression + ⚠️ This value might have side effects +- *8* ???*9*["hydratedSources"] + ⚠️ unknown object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* c + ⚠️ circular variable reference +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* updated with update expression + ⚠️ This value might have side effects +- *13* ???*14*["hydratedSources"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* ???*15*[(???*17* | 0 | ???*18*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *15* ???*16*["hydratedSources"] + ⚠️ unknown object +- *16* c + ⚠️ circular variable reference +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* updated with update expression + ⚠️ This value might have side effects +- *19* arguments[0] + ⚠️ function calls are not analysed yet +- *20* updated with update expression + ⚠️ This value might have side effects + +d#102 = (0 === (???*0* | ???*2*)) +- *0* ???*1*["indexOf"]("--") + ⚠️ unknown callee object +- *1* c + ⚠️ pattern without value +- *2* "cssFloat"["indexOf"]("--") + ⚠️ nested operation + +d#1023 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#119 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#123 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#127 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#128 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#136 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#159 = ( + | 0 + | undefined + | 1 + | 2 + | 4 + | 8 + | 16 + | 32 + | ???*0* + | 134217728 + | 268435456 + | 536870912 + | 1073741824 + | ???*1* + | ???*3* +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["pingedLanes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported assign operation + ⚠️ This value might have side effects + +d#162 = ???*0* +- *0* ???*1*["pingedLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#169 = ???*0* +- *0* ???*1*["eventTimes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#171 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +d#175 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#176 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#183 = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +d#189 = (???*0* | ???*1*) +- *0* [][1] + ⚠️ invalid index +- *1* [][???*2*] + ⚠️ unknown array prototype methods or values +- *2* updated with update expression + ⚠️ This value might have side effects + +d#193 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#196 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#199 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#203 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#207 = (???*0* | 1 | ???*1*) +- *0* d + ⚠️ pattern without value +- *1* updated with update expression + ⚠️ This value might have side effects + +d#212 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +d#236 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#25 = (???*0* | (???*1* ? ???*7* : null)["attributeNamespace"] | ???*9*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (???*2* | ???*3*)((???*4* | ???*5*)) + ⚠️ non-function callee +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["attributeName"] + ⚠️ unknown object +- *6* e + ⚠️ circular variable reference +- *7* {}[???*8*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["attributeNamespace"] + ⚠️ unknown object +- *10* ???*11*["type"] + ⚠️ unknown object +- *11* e + ⚠️ circular variable reference + +d#251 = (???*0* | 0 | ???*2*) +- *0* ???*1*["keys"](b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* updated with update expression + ⚠️ This value might have side effects + +d#254 = ( + | ???*0* + | ((???*1* | 0 | ???*2* | ???*3*) + (???*11* | 0["textContent"]["length"] | ???*14*)) +) +- *0* d + ⚠️ pattern without value +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* d + ⚠️ pattern without value +- *3* (???*4* + (???*5* | ???*8*)) + ⚠️ nested operation +- *4* a + ⚠️ circular variable reference +- *5* ???*6*["length"] + ⚠️ unknown object +- *6* ???*7*["textContent"] + ⚠️ unknown object +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["length"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["length"] + ⚠️ unknown object +- *12* ???*13*["textContent"] + ⚠️ unknown object +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["length"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *15* ???*16*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* unsupported expression + ⚠️ This value might have side effects + +d#264 = ???*0* +- *0* d + ⚠️ pattern without value + +d#266 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#269 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#274 = (???*0* | "unknown-event") +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#275 = (???*0* | null[(0 | ???*3*)] | null[(0 | ???*4*)]["listeners"] | ???*5*) +- *0* ???*1*[(0 | ???*2*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* updated with update expression + ⚠️ This value might have side effects +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["listeners"] + ⚠️ unknown object +- *6* ???*7*["listeners"] + ⚠️ unknown object +- *7* d + ⚠️ circular variable reference + +d#280 = `${???*0*}__bubble` +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +d#281 = (0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +d#285 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#286 = (???*0* | ???*1* | ???*2* | ???*4*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["return"] + ⚠️ unknown object +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* ???*5*["return"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +d#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#30 = ???*0* +- *0* l + ⚠️ pattern without value + +d#308 = [] + +d#311 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#320 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d#341 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#345 = (???*0* | ???*2*()) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["getChildContext"] + ⚠️ unknown object +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet + +d#347 = (???*0* | ???*2* | ???*3* | ???*4*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* ???*5*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +d#350 = (null[(0 | ???*0*)] | ???*1* | ???*2* | ???*3* | ???*5* | ???*9*) +- *0* updated with update expression + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* [][???*4*] + ⚠️ unknown array prototype methods or values +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*[(0 | ???*8*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["slice"]((a + 1)) + ⚠️ unknown callee object +- *7* eg + ⚠️ circular variable reference +- *8* updated with update expression + ⚠️ This value might have side effects +- *9* (null[(0 | ???*10*)] | ???*11* | ???*12* | ???*13* | ???*15* | ???*19*)(!(0)) + ⚠️ non-function callee +- *10* updated with update expression + ⚠️ This value might have side effects +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* unknown mutation + ⚠️ This value might have side effects +- *13* [][???*14*] + ⚠️ unknown array prototype methods or values +- *14* updated with update expression + ⚠️ This value might have side effects +- *15* ???*16*[(0 | ???*18*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *16* ???*17*["slice"]((a + 1)) + ⚠️ unknown callee object +- *17* eg + ⚠️ circular variable reference +- *18* updated with update expression + ⚠️ This value might have side effects +- *19* ???*20*(!(0)) + ⚠️ unknown callee +- *20* d + ⚠️ circular variable reference + +d#357 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#364 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#385 = ???*0* +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#391 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#396 = ???*0* +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#398 = (???*0* | ???*2*) +- *0* ???*1*["lanes"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects + +d#400 = (???*0* | null["alternate"] | ???*2* | ???*3* | ???*4* | null["alternate"]["updateQueue"]) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +d#404 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#412 = (???*0* | 0["effects"][(???*4* | 0 | ???*5*)] | ???*6*) +- *0* ???*1*[(???*2* | 0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* arguments[2] + ⚠️ function calls are not analysed yet + +d#415 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#417 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +d#418 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +d#419 = ( + | 1 + | ???*0* + | ???*1* + | ???*2* + | ???*3* + | 0 + | ???*5* + | 4 + | ((???*6* | ???*8*) ? ???*9* : 4) + | (???*10* ? 16 : (???*11* | null | ???*18* | ???*19*)) + | ???*21* + | (???*23* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["_reactInternals"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* C + ⚠️ circular variable reference +- *6* (0 !== ???*7*) + ⚠️ nested operation +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* C + ⚠️ circular variable reference +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 1) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? ???*15* : 4) + ⚠️ nested operation +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* (???*16* ? 16 : 536870912) + ⚠️ nested operation +- *16* (0 !== ???*17*) + ⚠️ nested operation +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* arguments[0] + ⚠️ function calls are not analysed yet +- *19* ???*20*["value"] + ⚠️ unknown object +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *23* (???*24* === ???*25*) + ⚠️ nested operation +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* a + ⚠️ circular variable reference + +d#420 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#421 = ( + | false + | ???*0* + | ???*2* + | (null !== (false | ???*4* | ???*6* | ???*8*)) + | (???*10* !== (false | ???*11* | ???*13* | ???*15*)) +) +- *0* ???*1*["contextTypes"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["contextTypes"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* ???*5*["contextTypes"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["contextTypes"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unknown new expression + ⚠️ This value might have side effects +- *8* (null !== ???*9*) + ⚠️ nested operation +- *9* d + ⚠️ circular variable reference +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["contextTypes"] + ⚠️ unknown object +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* ???*14*["contextTypes"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* unknown new expression + ⚠️ This value might have side effects +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* d + ⚠️ circular variable reference + +d#422 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#423 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#424 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +d#431 = (...) => a + +d#432 = ???*0* +- *0* ???*1*["deletions"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#434 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["sibling"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +d#437 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +d#439 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#440 = (???*0* | ???*1* | ???*3* | ???*4*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +d#441 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#442 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#443 = (???*0* | ???*2*) +- *0* ???*1*["_init"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["_init"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unknown new expression + ⚠️ This value might have side effects + +d#445 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#447 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#459 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#485 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#501 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#504 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#507 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#512 = ???*0* +- *0* d + ⚠️ pattern without value + +d#515 = ( + | ???*0* + | ???*1* + | null["updateQueue"]["lastEffect"]["next"] + | (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + ))["updateQueue"]["lastEffect"]["next"] + | (null !== (null["next"] | ???*19* | ???*21* | null | ???*24*))["updateQueue"]["lastEffect"]["next"] + | null["next"] + | ???*25* +) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["next"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["next"] + ⚠️ unknown object +- *22* ???*23*["alternate"] + ⚠️ unknown object +- *23* N + ⚠️ circular variable reference +- *24* unknown mutation + ⚠️ This value might have side effects +- *25* ???*26*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unknown mutation + ⚠️ This value might have side effects + +d#517 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#518 = (???*0* | (???*1* ? null : (???*9* | ???*10*))) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (???*2* === (???*3* | ???*4*)) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* (???*5* ? null : ???*8*) + ⚠️ nested operation +- *5* (???*6* === ???*7*) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* d + ⚠️ circular variable reference +- *8* d + ⚠️ circular variable reference +- *9* arguments[3] + ⚠️ function calls are not analysed yet +- *10* (???*11* ? null : ???*14*) + ⚠️ nested operation +- *11* (???*12* === ???*13*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* d + ⚠️ circular variable reference +- *14* d + ⚠️ circular variable reference + +d#530 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#531 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#533 = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + +d#537 = ( + | 1 + | ???*0* + | ???*1* + | ???*2* + | 0 + | ???*3* + | 4 + | ((???*4* | ???*6*) ? ???*7* : 4) + | (???*8* ? 16 : (???*9* | null | ???*16* | ???*17*)) + | ???*19* + | (???*21* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* C + ⚠️ circular variable reference +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 1) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 4) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? 16 : 536870912) + ⚠️ nested operation +- *14* (0 !== ???*15*) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["value"] + ⚠️ unknown object +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* ???*20*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *21* (???*22* === ???*23*) + ⚠️ nested operation +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* a + ⚠️ circular variable reference + +d#539 = ( + | 1 + | ???*0* + | ???*1* + | ???*2* + | 0 + | ???*3* + | 4 + | ((???*4* | ???*6*) ? ???*7* : 4) + | (???*8* ? 16 : (???*9* | null | ???*16* | ???*17*)) + | ???*19* + | (???*21* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* C + ⚠️ circular variable reference +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* C + ⚠️ circular variable reference +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* (???*10* ? ???*11* : 1) + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 4) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? 16 : 536870912) + ⚠️ nested operation +- *14* (0 !== ???*15*) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* ???*18*["value"] + ⚠️ unknown object +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* ???*20*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *21* (???*22* === ???*23*) + ⚠️ nested operation +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* a + ⚠️ circular variable reference + +d#547 = (???*0* | ???*2*) +- *0* ???*1*["lanes"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects + +d#554 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +d#559 = ( + | null + | ???*0* + | (null !== ( + | null + | ???*1* + | ???*2* + | ???*4* + | { + "memoizedState": ???*9*, + "baseState": ???*11*, + "baseQueue": ???*13*, + "queue": ???*15*, + "next": null + } + )) + | (null !== (null["next"] | ???*17* | ???*19* | null | ???*22*)) +) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["alternate"] + ⚠️ unknown object +- *3* N + ⚠️ circular variable reference +- *4* (???*5* ? ???*7* : null) + ⚠️ nested operation +- *5* (null !== ???*6*) + ⚠️ nested operation +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["memoizedState"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* ???*12*["baseState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseQueue"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["queue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* ???*20*["next"] + ⚠️ unknown object +- *20* ???*21*["alternate"] + ⚠️ unknown object +- *21* N + ⚠️ circular variable reference +- *22* unknown mutation + ⚠️ This value might have side effects + +d#56 = (???*0* | ???*2*) +- *0* ???*1*[b] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +d#562 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#570 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +d#578 = ???*0* +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +d#580 = ???*0* +- *0* ???*1*["getDerivedStateFromError"] + ⚠️ unknown object +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +d#585 = ( + | ???*0* + | (...) => undefined["bind"](null, ???*2*, ???*3*, ???*4*)["pingCache"] + | ???*5* +) +- *0* ???*1*["pingCache"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* a + ⚠️ circular variable reference +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* arguments[2] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects + +d#589 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#590 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#591 = (???*0* | ???*1*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (???*2* | ???*3* | (0 !== (0 | ???*5*)))(d, e) + ⚠️ non-function callee +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["render"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference +- *5* updated with update expression + ⚠️ This value might have side effects + +d#592 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#595 = (???*0* | ???*1*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["memoizedProps"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +d#597 = (???*0* | (???*2* ? ???*12* : ???*22*) | ???*23* | ???*24*) +- *0* ???*1*["pendingProps"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* (???*4* ? ???*10* : null) + ⚠️ nested operation +- *4* (null !== (???*5* | ???*6*)) + ⚠️ nested operation +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* (???*7* ? ???*8* : ???*9*) + ⚠️ nested operation +- *7* (null !== ???) + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["memoizedState"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* ???*13*["baseLanes"] + ⚠️ unknown object +- *13* (???*14* ? ???*20* : null) + ⚠️ nested operation +- *14* (null !== (???*15* | ???*16*)) + ⚠️ nested operation +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* (???*17* ? ???*18* : ???*19*) + ⚠️ nested operation +- *17* (null !== ???) + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* arguments[2] + ⚠️ function calls are not analysed yet +- *20* ???*21*["memoizedState"] + ⚠️ unknown object +- *21* arguments[0] + ⚠️ function calls are not analysed yet +- *22* arguments[2] + ⚠️ function calls are not analysed yet +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* arguments[2] + ⚠️ function calls are not analysed yet + +d#600 = (???*0* | (0 !== (0 | ???*1*))) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* updated with update expression + ⚠️ This value might have side effects + +d#601 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#605 = (???*0* | ???*1*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +d#607 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#609 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#613 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#614 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#619 = ???*0* +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#620 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#621 = (???*0* | 0 | ???*2* | ???*3* | ???*4*) +- *0* ???*1*["pendingProps"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* unsupported assign operation + ⚠️ This value might have side effects + +d#631 = (???*0* | (0 !== ???*3*)) +- *0* ???*1*["_context"] + ⚠️ unknown object +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects + +d#639 = (???*0* | ???*1*) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*( + {}, + b, + { + "defaultChecked": ???*4*, + "defaultValue": ???*5*, + "value": ???*6*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *2* ???*3*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects + +d#64 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#644 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#645 = (null | ???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["tail"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +d#646 = (0 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +d#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#669 = ???*0* +- *0* d + ⚠️ pattern without value + +d#672 = ???*0* +- *0* d + ⚠️ pattern without value + +d#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#687 = (???*0* | (???*2* ? ???*10* : null) | (???*13* ? ???*15* : null)["next"]) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (null !== (???*3* | ???*5*)) + ⚠️ nested operation +- *3* ???*4*["updateQueue"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* (???*6* ? ???*8* : null) + ⚠️ nested operation +- *6* (null !== ???*7*) + ⚠️ nested operation +- *7* d + ⚠️ circular variable reference +- *8* ???*9*["lastEffect"] + ⚠️ unknown object +- *9* d + ⚠️ circular variable reference +- *10* ???*11*["lastEffect"] + ⚠️ unknown object +- *11* ???*12*["updateQueue"] + ⚠️ unknown object +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* (null !== ???*14*) + ⚠️ nested operation +- *14* d + ⚠️ circular variable reference +- *15* ???*16*["lastEffect"] + ⚠️ unknown object +- *16* d + ⚠️ circular variable reference + +d#69 = (???*0* ? ???*3* : ???*5*) +- *0* (null != ???*1*) + ⚠️ nested operation +- *1* ???*2*["checked"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["checked"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["defaultChecked"] + ⚠️ unknown object +- *6* arguments[1] + ⚠️ function calls are not analysed yet + +d#691 = (???*0* | ???*2*) +- *0* ???*1*["create"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["create"] + ⚠️ unknown object +- *3* ???*4*["next"] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference + +d#7 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#703 = ???*0* +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#704 = ???*0* +- *0* ???*1*["tag"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#706 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#71 = ???*0* +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +d#715 = (...) => undefined["bind"](null, ???*0*, ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#716 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#74 = ???*0* +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +d#756 = ???*0* +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#764 = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +d#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#77 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#785 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#8 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#802 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#803 = ( + | 0 + | (???*0* ? (0 | ???*7*) : 0) + | ???*8* + | ???*10* + | undefined + | 1 + | 2 + | 4 + | 8 + | 16 + | 32 + | ???*11* + | 134217728 + | 268435456 + | 536870912 + | 1073741824 +) +- *0* (???*1* === (null | ???*2* | ???*3* | ???*6*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* ???*5*["current"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* unknown new expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* ???*9*["entangledLanes"] + ⚠️ unknown object +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* unsupported assign operation + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects + +d#807 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#819 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +d#827 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +d#829 = (???*0* ? (???*3* | ???*4*) : ???*5*) +- *0* (0 !== (???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* (???*6* ? 1073741824 : 0) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects + +d#834 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +d#838 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#843 = ( + | null["memoizedState"] + | ???*0* + | (null !== ( + | null + | ???*2* + | ???*3* + | ???*5* + | { + "memoizedState": ???*10*, + "baseState": ???*12*, + "baseQueue": ???*14*, + "queue": ???*16*, + "next": null + } + ))["memoizedState"] + | (null !== (null["next"] | ???*18* | ???*20* | null | ???*23*))["memoizedState"] + | null["memoizedState"]["next"] + | (null !== ( + | null + | ???*24* + | ???*25* + | ???*27* + | { + "memoizedState": ???*32*, + "baseState": ???*34*, + "baseQueue": ???*36*, + "queue": ???*38*, + "next": null + } + ))["memoizedState"]["next"] + | (null !== (null["next"] | ???*40* | ???*42* | null | ???*45*))["memoizedState"]["next"] +) +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* N + ⚠️ circular variable reference +- *5* (???*6* ? ???*8* : null) + ⚠️ nested operation +- *6* (null !== ???*7*) + ⚠️ nested operation +- *7* a + ⚠️ circular variable reference +- *8* ???*9*["memoizedState"] + ⚠️ unknown object +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["memoizedState"] + ⚠️ unknown object +- *11* O + ⚠️ circular variable reference +- *12* ???*13*["baseState"] + ⚠️ unknown object +- *13* O + ⚠️ circular variable reference +- *14* ???*15*["baseQueue"] + ⚠️ unknown object +- *15* O + ⚠️ circular variable reference +- *16* ???*17*["queue"] + ⚠️ unknown object +- *17* O + ⚠️ circular variable reference +- *18* ???*19*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* ???*21*["next"] + ⚠️ unknown object +- *21* ???*22*["alternate"] + ⚠️ unknown object +- *22* N + ⚠️ circular variable reference +- *23* unknown mutation + ⚠️ This value might have side effects +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* ???*26*["alternate"] + ⚠️ unknown object +- *26* N + ⚠️ circular variable reference +- *27* (???*28* ? ???*30* : null) + ⚠️ nested operation +- *28* (null !== ???*29*) + ⚠️ nested operation +- *29* a + ⚠️ circular variable reference +- *30* ???*31*["memoizedState"] + ⚠️ unknown object +- *31* a + ⚠️ circular variable reference +- *32* ???*33*["memoizedState"] + ⚠️ unknown object +- *33* O + ⚠️ circular variable reference +- *34* ???*35*["baseState"] + ⚠️ unknown object +- *35* O + ⚠️ circular variable reference +- *36* ???*37*["baseQueue"] + ⚠️ unknown object +- *37* O + ⚠️ circular variable reference +- *38* ???*39*["queue"] + ⚠️ unknown object +- *39* O + ⚠️ circular variable reference +- *40* ???*41*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *41* unsupported expression + ⚠️ This value might have side effects +- *42* ???*43*["next"] + ⚠️ unknown object +- *43* ???*44*["alternate"] + ⚠️ unknown object +- *44* N + ⚠️ circular variable reference +- *45* unknown mutation + ⚠️ This value might have side effects + +d#863 = (???*0* ? { + "readContext": (...) => b, + "useCallback": (...) => undefined, + "useContext": (...) => undefined, + "useEffect": (...) => undefined, + "useImperativeHandle": (...) => undefined, + "useInsertionEffect": (...) => undefined, + "useLayoutEffect": (...) => undefined, + "useMemo": (...) => undefined, + "useReducer": (...) => undefined, + "useRef": (...) => undefined, + "useState": (...) => undefined, + "useDebugValue": (...) => undefined, + "useDeferredValue": (...) => undefined, + "useTransition": (...) => undefined, + "useMutableSource": (...) => undefined, + "useSyncExternalStore": (...) => undefined, + "useId": (...) => undefined, + "unstable_isNewReconciler": false +} : module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"]["current"]) +- *0* (null === module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"]["current"]) + ⚠️ nested operation + +d#87 = (undefined | ???*0* | "") +- *0* ???*1*["defaultValue"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +d#877 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +d#880 = (???*0* | ???*1* | null["onRecoverableError"]) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* ???*2*["onRecoverableError"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +d#883 = (false | true) + +d#9 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#910 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#915 = ???*0* +- *0* ???*1*["pingCache"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#918 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +d#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +d#92 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +d#941 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#942 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#947 = (???*0* | ???*1* | null) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +d#948 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#949 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#952 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#953 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#954 = ((???*0* | ???*1*) ? ???*5* : null) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (???*2* !== ???*3*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*[3] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* ???*6*[3] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* FreeVar(arguments) + ⚠️ unknown global + ⚠️ This value might have side effects + +d#960 = (???*0* | (???*1* ? ???*3* : ???*4*)) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* module["unstable_now"]() + ⚠️ nested operation +- *4* (???*5* ? (???*9* | ???*10*) : ???*11*) + ⚠️ nested operation +- *5* (???*6* !== (???*7* | ???*8*)) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* module["unstable_now"]() + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* module["unstable_now"]() + ⚠️ nested operation +- *11* unsupported expression + ⚠️ This value might have side effects + +d#961 = (???*0* | (???*1* ? null : (???*9* | ???*10*))) +- *0* arguments[3] + ⚠️ function calls are not analysed yet +- *1* (???*2* === (???*3* | ???*4*)) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* arguments[3] + ⚠️ function calls are not analysed yet +- *4* (???*5* ? null : ???*8*) + ⚠️ nested operation +- *5* (???*6* === ???*7*) + ⚠️ nested operation +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* d + ⚠️ circular variable reference +- *8* d + ⚠️ circular variable reference +- *9* arguments[3] + ⚠️ function calls are not analysed yet +- *10* (???*11* ? null : ???*14*) + ⚠️ nested operation +- *11* (???*12* === ???*13*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* d + ⚠️ circular variable reference +- *14* d + ⚠️ circular variable reference + +d#979 = (???*0* | (...) => undefined) +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#986 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +d#997 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +da = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +db = (...) => (undefined | FreeVar(undefined)) + +dc = module["unstable_requestPaint"] + +dd = (true | false | !(???*0*)) +- *0* !((null | true | false | ???*1*)) + ⚠️ nested operation +- *1* !(???*2*) + ⚠️ nested operation +- *2* !(???*3*) + ⚠️ nested operation +- *3* Cf + ⚠️ circular variable reference + +de = (!(???*0*) | !((???*3* | ???*7*)) | null | ???*8* | ???*10*) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* !(???*4*) + ⚠️ nested operation +- *4* ("undefined" === ???*5*) + ⚠️ nested operation +- *5* typeof(???*6*) + ⚠️ nested operation +- *6* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* ???*9*["documentMode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects + +df = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +dg = (...) => undefined + +dh = (...) => (null | Zg(a, c)) + +di = (...) => P + +dj = (...) => (???*0* | b["child"]) +- *0* $i(a, b, e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +dk = (...) => undefined + +dl = (...) => { + "$$typeof": wa, + "key": ((null == d) ? null : d), + "children": a, + "containerInfo": b, + "implementation": c +} + +e#1004 = (???*0* | null) +- *0* ???*1*[Pf] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(???*3* | ???*4* | 0 | ???*6*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["name"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects + +e#1013 = ((???*0* ? ???*3* : (...) => undefined) | ???*4* | ???*6*) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["onRecoverableError"] + ⚠️ unknown object +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* ???*7*["onRecoverableError"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unknown new expression + ⚠️ This value might have side effects + +e#1018 = ( + | false + | true + | ???*0* + | (null != ???*2*)[(???*3* | 0 | ???*4*)]["_getVersion"] + | ???*5* + | null[(???*11* | 0 | ???*12*)]["_getVersion"] + | ???*13* +) +- *0* ???*1*["_getVersion"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["_getVersion"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*[(???*9* | 0 | ???*10*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["hydratedSources"] + ⚠️ unknown object +- *8* c + ⚠️ circular variable reference +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* updated with update expression + ⚠️ This value might have side effects +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* updated with update expression + ⚠️ This value might have side effects +- *13* ( + | false + | true + | ???*14* + | (null != ???*16*)[(???*17* | 0 | ???*18*)]["_getVersion"] + | ???*19* + | null[(???*25* | 0 | ???*26*)]["_getVersion"] + | ???*27* + )(c["_source"]) + ⚠️ non-function callee +- *14* ???*15*["_getVersion"] + ⚠️ unknown object +- *15* arguments[2] + ⚠️ function calls are not analysed yet +- *16* c + ⚠️ circular variable reference +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* updated with update expression + ⚠️ This value might have side effects +- *19* ???*20*["_getVersion"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* ???*21*[(???*23* | 0 | ???*24*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* ???*22*["hydratedSources"] + ⚠️ unknown object +- *22* c + ⚠️ circular variable reference +- *23* arguments[0] + ⚠️ function calls are not analysed yet +- *24* updated with update expression + ⚠️ This value might have side effects +- *25* arguments[0] + ⚠️ function calls are not analysed yet +- *26* updated with update expression + ⚠️ This value might have side effects +- *27* ???*28*(c["_source"]) + ⚠️ unknown callee +- *28* e + ⚠️ circular variable reference + +e#102 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#123 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#127 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#128 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#136 = ( + | ???*0* + | (???*2* ? (???*5* | ???*6* | ???*7*) : null)["return"] +) +- *0* ???*1*["return"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (3 === ???*3*) + ⚠️ nested operation +- *3* ???*4*["tag"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* a + ⚠️ circular variable reference +- *7* ???*8*["return"] + ⚠️ unknown object +- *8* b + ⚠️ circular variable reference + +e#159 = (???*0* | ???*2*) +- *0* ???*1*["suspendedLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported expression + ⚠️ This value might have side effects + +e#162 = ???*0* +- *0* ???*1*["expirationTimes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +e#169 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +e#171 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +e#175 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#176 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#193 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +e#196 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +e#199 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#207 = (???*0* ? (null["value"] | ???*1* | ???*16*) : (null["textContent"] | ???*18* | ???*33*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* (???*3* ? (???*8* | ???*10*) : (???*12* | ???*13* | ???*15*)) + ⚠️ nested operation +- *3* (3 === (???*4* | ???*6*)) + ⚠️ nested operation +- *4* ???*5*["nodeType"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* ???*7*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* ???*9*["parentNode"] + ⚠️ unknown object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*["target"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* ???*17*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* unknown new expression + ⚠️ This value might have side effects +- *18* ???*19*["textContent"] + ⚠️ unknown object +- *19* (???*20* ? (???*25* | ???*27*) : (???*29* | ???*30* | ???*32*)) + ⚠️ nested operation +- *20* (3 === (???*21* | ???*23*)) + ⚠️ nested operation +- *21* ???*22*["nodeType"] + ⚠️ unknown object +- *22* arguments[2] + ⚠️ function calls are not analysed yet +- *23* ???*24*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *25* ???*26*["parentNode"] + ⚠️ unknown object +- *26* arguments[2] + ⚠️ function calls are not analysed yet +- *27* ???*28*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *28* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *29* arguments[2] + ⚠️ function calls are not analysed yet +- *30* ???*31*["target"] + ⚠️ unknown object +- *31* a + ⚠️ circular variable reference +- *32* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *33* ???*34*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unknown new expression + ⚠️ This value might have side effects + +e#212 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +e#25 = ((???*0* ? ???*13* : null) | (???*15* ? ???*21* : null)["type"] | ???*23*) +- *0* (???*1* | ???*2*)( + (???*3* | (???*4* ? ???*8* : null)["attributeName"] | ???*10*) + ) + ⚠️ non-function callee + ⚠️ This value might have side effects +- *1* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* (???*5* | ???*6*)(???*7*) + ⚠️ non-function callee +- *5* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* b + ⚠️ circular variable reference +- *8* {}[???*9*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *9* b + ⚠️ circular variable reference +- *10* ???*11*["attributeName"] + ⚠️ unknown object +- *11* ???*12*["type"] + ⚠️ unknown object +- *12* e + ⚠️ circular variable reference +- *13* {}[???*14*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *14* arguments[1] + ⚠️ function calls are not analysed yet +- *15* (???*16* | ???*17*)((???*18* | ???*19*)) + ⚠️ non-function callee +- *16* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* unknown mutation + ⚠️ This value might have side effects +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* ???*20*["attributeName"] + ⚠️ unknown object +- *20* e + ⚠️ circular variable reference +- *21* {}[???*22*] + ⚠️ unknown object prototype methods or values + ⚠️ This value might have side effects +- *22* arguments[1] + ⚠️ function calls are not analysed yet +- *23* ???*24*["type"] + ⚠️ unknown object +- *24* ???*25*["type"] + ⚠️ unknown object +- *25* e + ⚠️ circular variable reference + +e#251 = ???*0* +- *0* ???*1*[d] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["keys"](a) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +e#266 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#275 = (???*0* | null[(0 | ???*4*)]["event"] | ???*5*) +- *0* ???*1*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["event"] + ⚠️ unknown object +- *6* ???*7*["listeners"] + ⚠️ unknown object +- *7* d + ⚠️ circular variable reference + +e#285 = ((...) => undefined | ???*0* | true) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#286 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#292 = ( + | (???*0* ? (???*5* | ???*7*) : (???*9* | ???*10* | ???*12*)) + | ???*13* +) +- *0* (3 === (???*1* | ???*3*)) + ⚠️ nested operation +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* ???*6*["parentNode"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["target"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* unknown new expression + ⚠️ This value might have side effects + +e#30 = ???*0* +- *0* ???*1*["split"]("\n") + ⚠️ unknown callee object +- *1* ???*2*["stack"] + ⚠️ unknown object +- *2* l + ⚠️ pattern without value + +e#308 = ( + | ???*0* + | ???*1* + | null + | !((???*3* | null | ???*5*))["stateNode"] + | false["stateNode"] + | null[`${???*8*}Capture`] + | !(???*9*)[`${???*11*}Capture`] + | !(???*12*)[`${???*18*}Capture`] + | !((???*19* | null | ???*21*))["stateNode"] + | null[???*24*] + | !(???*25*)[???*27*] + | !(???*28*)[???*34*] +) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* ???*4*[Pf] + ⚠️ unknown object +- *4* c + ⚠️ circular variable reference +- *5* !(???*6*) + ⚠️ nested operation +- *6* ???*7*["disabled"] + ⚠️ unknown object +- *7* d + ⚠️ circular variable reference +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["disabled"] + ⚠️ unknown object +- *10* d + ⚠️ circular variable reference +- *11* arguments[1] + ⚠️ function calls are not analysed yet +- *12* ("button" === (???*13* | ???*14* | ???*16* | false)) + ⚠️ nested operation +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["return"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* !(???*17*) + ⚠️ nested operation +- *17* d + ⚠️ circular variable reference +- *18* arguments[1] + ⚠️ function calls are not analysed yet +- *19* ???*20*[Pf] + ⚠️ unknown object +- *20* c + ⚠️ circular variable reference +- *21* !(???*22*) + ⚠️ nested operation +- *22* ???*23*["disabled"] + ⚠️ unknown object +- *23* d + ⚠️ circular variable reference +- *24* arguments[1] + ⚠️ function calls are not analysed yet +- *25* ???*26*["disabled"] + ⚠️ unknown object +- *26* d + ⚠️ circular variable reference +- *27* arguments[1] + ⚠️ function calls are not analysed yet +- *28* ("button" === (???*29* | ???*30* | ???*32* | false)) + ⚠️ nested operation +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["return"] + ⚠️ unknown object +- *31* a + ⚠️ circular variable reference +- *32* !(???*33*) + ⚠️ nested operation +- *33* d + ⚠️ circular variable reference +- *34* arguments[1] + ⚠️ function calls are not analysed yet + +e#311 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#320 = ???*0* +- *0* ???*1*["nextSibling"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +e#341 = {} + +e#345 = ???*0* +- *0* e + ⚠️ pattern without value + +e#354 = ???*0* +- *0* e + ⚠️ pattern without value + +e#357 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +e#391 = ???*0* +- *0* ???*1*["interleaved"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +e#396 = ???*0* +- *0* ???*1*["pending"] + ⚠️ unknown object +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +e#400 = (null | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +e#404 = (???*0* | ???*2*) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +e#412 = (???*0* | 0["effects"][(???*5* | 0 | ???*6*)]["callback"] | ???*7*) +- *0* ???*1*["callback"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(???*3* | 0 | ???*4*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* arguments[1] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* ???*8*["callback"] + ⚠️ unknown object +- *8* arguments[2] + ⚠️ function calls are not analysed yet + +e#417 = ( + | 1 + | ???*0* + | ???*1* + | ???*2* + | ???*3* + | 0 + | ???*5* + | 4 + | ((???*6* | ???*8*) ? ???*9* : 4) + | (???*10* ? 16 : (???*11* | null | ???*18* | ???*19*)) + | ???*21* + | (???*23* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["_reactInternals"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* C + ⚠️ circular variable reference +- *6* (0 !== ???*7*) + ⚠️ nested operation +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* C + ⚠️ circular variable reference +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 1) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? ???*15* : 4) + ⚠️ nested operation +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* (???*16* ? 16 : 536870912) + ⚠️ nested operation +- *16* (0 !== ???*17*) + ⚠️ nested operation +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* arguments[0] + ⚠️ function calls are not analysed yet +- *19* ???*20*["value"] + ⚠️ unknown object +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *23* (???*24* === ???*25*) + ⚠️ nested operation +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* a + ⚠️ circular variable reference + +e#418 = ( + | 1 + | ???*0* + | ???*1* + | ???*2* + | ???*3* + | 0 + | ???*5* + | 4 + | ((???*6* | ???*8*) ? ???*9* : 4) + | (???*10* ? 16 : (???*11* | null | ???*18* | ???*19*)) + | ???*21* + | (???*23* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* ???*4*["_reactInternals"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* C + ⚠️ circular variable reference +- *6* (0 !== ???*7*) + ⚠️ nested operation +- *7* C + ⚠️ circular variable reference +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* C + ⚠️ circular variable reference +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* (???*12* ? ???*13* : 1) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* (???*14* ? ???*15* : 4) + ⚠️ nested operation +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* (???*16* ? 16 : 536870912) + ⚠️ nested operation +- *16* (0 !== ???*17*) + ⚠️ nested operation +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* arguments[0] + ⚠️ function calls are not analysed yet +- *19* ???*20*["value"] + ⚠️ unknown object +- *20* arguments[1] + ⚠️ function calls are not analysed yet +- *21* ???*22*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *23* (???*24* === ???*25*) + ⚠️ nested operation +- *24* unsupported expression + ⚠️ This value might have side effects +- *25* a + ⚠️ circular variable reference + +e#419 = { + "eventTime": (???*0* ? ???*2* : ???*3*), + "lane": ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null +} +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +e#420 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#421 = ({} | (???*0* ? ({} | ???*5*) : ({} | ???*6*))) +- *0* (null !== (???*1* | ???*2* | ???*3*)) + ⚠️ nested operation +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* unknown new expression + ⚠️ This value might have side effects +- *3* ???*4*["childContextTypes"] + ⚠️ unknown object +- *4* a + ⚠️ circular variable reference +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* unknown mutation + ⚠️ This value might have side effects + +e#423 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +e#424 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +e#431 = (...) => a + +e#445 = ((???*0* ? ???*2* : null) | ???*4*) +- *0* (null !== ???*1*) + ⚠️ nested operation +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["key"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["_init"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet + +e#447 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#449 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +e#454 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +e#485 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#501 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#504 = ???*0*() +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +e#517 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +e#518 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +e#537 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +e#539 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#559 = ( + | null + | ???*0* + | {"memoizedState": null, "baseState": null, "baseQueue": null, "queue": null, "next": null} + | (???*1* ? (null["memoizedState"] | ???*3*) : ???*5*) + | null["alternate"] + | ???*7* + | (null !== (null | ???*9* | ???*10*))["alternate"] + | (null !== (null["next"] | ???*11* | ???*13*))["alternate"] + | (???*15* ? ???*17* : null) + | null["next"] + | ???*19* + | { + "memoizedState": (null["memoizedState"] | ???*21* | ???*23*), + "baseState": (null["baseState"] | ???*25* | ???*27*), + "baseQueue": (null["baseQueue"] | ???*29* | ???*31*), + "queue": (null["queue"] | ???*33* | ???*35*), + "next": null + } +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (null === ???*2*) + ⚠️ nested operation +- *2* P + ⚠️ circular variable reference +- *3* ???*4*["memoizedState"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*["next"] + ⚠️ unknown object +- *6* P + ⚠️ circular variable reference +- *7* ???*8*["alternate"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* ???*14*["next"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* (null !== ???*16*) + ⚠️ nested operation +- *16* a + ⚠️ circular variable reference +- *17* ???*18*["memoizedState"] + ⚠️ unknown object +- *18* a + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* ???*24*["memoizedState"] + ⚠️ unknown object +- *24* a + ⚠️ circular variable reference +- *25* ???*26*["baseState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* ???*28*["baseState"] + ⚠️ unknown object +- *28* a + ⚠️ circular variable reference +- *29* ???*30*["baseQueue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["baseQueue"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* ???*34*["queue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unsupported expression + ⚠️ This value might have side effects +- *35* ???*36*["queue"] + ⚠️ unknown object +- *36* a + ⚠️ circular variable reference + +e#56 = ???*0* +- *0* ???*1*["get"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +e#570 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#580 = ???*0* +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +e#585 = (???*0* | ???*1* | ???*5* | ???*13*) +- *0* unknown new expression + ⚠️ This value might have side effects +- *1* ???*2*["get"](???*4*) + ⚠️ unknown callee object +- *2* ???*3*["pingCache"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* ???*6*(???*12*) + ⚠️ unknown callee +- *6* ???*7*["get"] + ⚠️ unknown object +- *7* ???*8*["pingCache"] + ⚠️ unknown object +- *8* (...) => undefined["bind"](null, ???*9*, ???*10*, ???*11*) + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* arguments[1] + ⚠️ function calls are not analysed yet +- *11* arguments[2] + ⚠️ function calls are not analysed yet +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* ???*14*["get"](???*15*) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* arguments[1] + ⚠️ function calls are not analysed yet + +e#589 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#591 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#592 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#595 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#597 = (???*0* | (???*3* ? ???*13* : ???*23*)["children"] | ???*24*) +- *0* ???*1*["children"] + ⚠️ unknown object +- *1* ???*2*["pendingProps"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* (???*5* ? ???*11* : null) + ⚠️ nested operation +- *5* (null !== (???*6* | ???*7*)) + ⚠️ nested operation +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* (???*8* ? ???*9* : ???*10*) + ⚠️ nested operation +- *8* (null !== ???) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* arguments[0] + ⚠️ function calls are not analysed yet +- *13* ???*14*["baseLanes"] + ⚠️ unknown object +- *14* (???*15* ? ???*21* : null) + ⚠️ nested operation +- *15* (null !== (???*16* | ???*17*)) + ⚠️ nested operation +- *16* arguments[0] + ⚠️ function calls are not analysed yet +- *17* (???*18* ? ???*19* : ???*20*) + ⚠️ nested operation +- *18* (null !== ???) + ⚠️ nested operation +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* arguments[2] + ⚠️ function calls are not analysed yet +- *21* ???*22*["memoizedState"] + ⚠️ unknown object +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* arguments[2] + ⚠️ function calls are not analysed yet +- *24* ???*25*["children"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *25* unsupported expression + ⚠️ This value might have side effects + +e#600 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#601 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#605 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#607 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#609 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#614 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#620 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#621 = ( + | ???*0* + | 0["revealOrder"] + | ???*3* + | null + | ???*5* + | ???*6* + | 0["revealOrder"]["sibling"] + | null["sibling"] + | 0["revealOrder"]["alternate"] + | null["alternate"] + | null["sibling"]["alternate"] + | null["sibling"]["sibling"] +) +- *0* ???*1*["revealOrder"] + ⚠️ unknown object +- *1* ???*2*["pendingProps"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["revealOrder"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* c + ⚠️ circular variable reference + +e#631 = ???*0* +- *0* ???*1*["value"] + ⚠️ unknown object +- *1* ???*2*["memoizedProps"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +e#639 = (???*0* | ???*2*) +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*( + {}, + b, + { + "defaultChecked": ???*5*, + "defaultValue": ???*6*, + "value": ???*7*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *3* ???*4*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects + +e#646 = ???*0* +- *0* ???*1*["child"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +e#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#687 = (???*0* | ???*1* | ???*3*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["next"] + ⚠️ unknown object +- *4* ???*5*["next"] + ⚠️ unknown object +- *5* e + ⚠️ circular variable reference + +e#706 = (false | ???*0* | ???*1* | ???*2* | true | false["next"] | true["next"] | ???*4*) +- *0* Yj + ⚠️ circular variable reference +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["next"] + ⚠️ unknown object +- *3* e + ⚠️ circular variable reference +- *4* ???*5*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +e#716 = ???*0* +- *0* ???*1*[d] + ⚠️ unknown object +- *1* ???*2*["deletions"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +e#721 = (???*0* | ???*2*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +e#756 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +e#764 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#77 = (0 | ???*0* | ???*1* | ???*9* | null["hasOwnProperty"](???*18*)) +- *0* updated with update expression + ⚠️ This value might have side effects +- *1* ???*2*["hasOwnProperty"](`$${???*3*}`) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*[(???*6* | 0 | ???*7* | undefined | ???*8* | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* updated with update expression + ⚠️ This value might have side effects +- *8* c + ⚠️ circular variable reference +- *9* (???*10* | ???*11*)(`$${???*12*}`) + ⚠️ non-function callee + ⚠️ This value might have side effects +- *10* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *11* unknown mutation + ⚠️ This value might have side effects +- *12* ???*13*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *13* ???*14*[(???*15* | 0 | ???*16* | undefined | ???*17* | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *14* arguments[0] + ⚠️ function calls are not analysed yet +- *15* arguments[2] + ⚠️ function calls are not analysed yet +- *16* updated with update expression + ⚠️ This value might have side effects +- *17* c + ⚠️ circular variable reference +- *18* `$${???*19*}` + ⚠️ nested operation +- *19* ???*20*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* ???*21*[(???*22* | 0 | ???*23* | undefined | ???*24* | "")] + ⚠️ unknown object + ⚠️ This value might have side effects +- *21* arguments[0] + ⚠️ function calls are not analysed yet +- *22* arguments[2] + ⚠️ function calls are not analysed yet +- *23* updated with update expression + ⚠️ This value might have side effects +- *24* c + ⚠️ circular variable reference + +e#785 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#807 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#819 = ???*0* +- *0* ???*1*[d] + ⚠️ unknown object +- *1* ???*2*["updateQueue"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +e#838 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#843 = ( + | null["memoizedState"]["queue"] + | ???*0* + | (null !== ( + | null + | ???*3* + | ???*4* + | ???*6* + | { + "memoizedState": ???*11*, + "baseState": ???*13*, + "baseQueue": ???*15*, + "queue": ???*17*, + "next": null + } + ))["memoizedState"]["queue"] + | (null !== (null["next"] | ???*19* | ???*21* | null | ???*24*))["memoizedState"]["queue"] +) +- *0* ???*1*["queue"] + ⚠️ unknown object +- *1* ???*2*["memoizedState"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["alternate"] + ⚠️ unknown object +- *5* N + ⚠️ circular variable reference +- *6* (???*7* ? ???*9* : null) + ⚠️ nested operation +- *7* (null !== ???*8*) + ⚠️ nested operation +- *8* a + ⚠️ circular variable reference +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* a + ⚠️ circular variable reference +- *11* ???*12*["memoizedState"] + ⚠️ unknown object +- *12* O + ⚠️ circular variable reference +- *13* ???*14*["baseState"] + ⚠️ unknown object +- *14* O + ⚠️ circular variable reference +- *15* ???*16*["baseQueue"] + ⚠️ unknown object +- *16* O + ⚠️ circular variable reference +- *17* ???*18*["queue"] + ⚠️ unknown object +- *18* O + ⚠️ circular variable reference +- *19* ???*20*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* unsupported expression + ⚠️ This value might have side effects +- *21* ???*22*["next"] + ⚠️ unknown object +- *22* ???*23*["alternate"] + ⚠️ unknown object +- *23* N + ⚠️ circular variable reference +- *24* unknown mutation + ⚠️ This value might have side effects + +e#865 = ???*0* +- *0* e + ⚠️ pattern without value + +e#877 = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + +e#880 = (???*0* | null["finishedLanes"]) +- *0* ???*1*["finishedLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +e#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#9 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#918 = ???*0* +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +e#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#92 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +e#947 = (???*0* | ???*1*) +- *0* arguments[4] + ⚠️ function calls are not analysed yet +- *1* unsupported assign operation + ⚠️ This value might have side effects + +e#952 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#953 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +e#960 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +e#961 = (???*0* | ???*2* | ???*3*) +- *0* ???*1*["current"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* unknown mutation + ⚠️ This value might have side effects + +e#979 = (???*0* | ???*1*) +- *0* arguments[4] + ⚠️ function calls are not analysed yet +- *1* ???*2*["lastChild"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +e#986 = (???*0* | (...) => undefined) +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +ea = {} + +eb = ???*0* +- *0* ???*1*["isArray"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +ec = module["unstable_getCurrentPriorityLevel"] + +ed = (...) => undefined + +ee = ???*0* +- *0* ???*1*["fromCharCode"](32) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(String) + ⚠️ unknown global + ⚠️ This value might have side effects + +ef = "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ") + +eg = (null | [???*0*] | null["slice"](???*1*) | ???*3* | ???*7*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ((0 | ???*2*) + 1) + ⚠️ nested operation +- *2* updated with update expression + ⚠️ This value might have side effects +- *3* ???*4*(((0 | ???*6*) + 1)) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *4* [???*5*]["slice"] + ⚠️ non-num constant property on array +- *5* arguments[0] + ⚠️ function calls are not analysed yet +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* ???*8*["slice"](((0 | ???*10*) + 1)) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *8* ???*9*["slice"]((a + 1)) + ⚠️ unknown callee object +- *9* eg + ⚠️ circular variable reference +- *10* updated with update expression + ⚠️ This value might have side effects + +eh = (...) => undefined + +ei = (...) => (("function" === typeof(b)) ? b(a) : b) + +ej = (...) => (???*0* | b["child"]) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +ek = (...) => undefined + +el = (...) => (Vf | bg(a, c, b) | b) + +f#1018 = ( + | "" + | ???*0* + | (null != ???*2*)[(???*3* | 0 | ???*4*)]["identifierPrefix"] + | ???*5* + | null[(???*11* | 0 | ???*12*)]["identifierPrefix"] +) +- *0* ???*1*["identifierPrefix"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* c + ⚠️ circular variable reference +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* ???*6*["identifierPrefix"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*[(???*9* | 0 | ???*10*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* ???*8*["hydratedSources"] + ⚠️ unknown object +- *8* c + ⚠️ circular variable reference +- *9* arguments[0] + ⚠️ function calls are not analysed yet +- *10* updated with update expression + ⚠️ This value might have side effects +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* updated with update expression + ⚠️ This value might have side effects + +f#123 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +f#127 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +f#128 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +f#136 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#159 = (???*0* | ???*2* | ???*3*) +- *0* ???*1*["pingedLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +f#162 = (???*0* | ???*2*) +- *0* ???*1*["pendingLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* unsupported assign operation + ⚠️ This value might have side effects + +f#169 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +f#175 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +f#176 = ???*0* +- *0* ???*1*["pointerId"] + ⚠️ unknown object +- *1* arguments[4] + ⚠️ function calls are not analysed yet + +f#193 = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + +f#196 = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + +f#199 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#207 = (???*0* ? (null["value"] | ???*1* | ???*16*) : (null["textContent"] | ???*18* | ???*33*))["length"] +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* (???*3* ? (???*8* | ???*10*) : (???*12* | ???*13* | ???*15*)) + ⚠️ nested operation +- *3* (3 === (???*4* | ???*6*)) + ⚠️ nested operation +- *4* ???*5*["nodeType"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* ???*7*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* ???*9*["parentNode"] + ⚠️ unknown object +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* arguments[2] + ⚠️ function calls are not analysed yet +- *13* ???*14*["target"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference +- *15* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *16* ???*17*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *17* unknown new expression + ⚠️ This value might have side effects +- *18* ???*19*["textContent"] + ⚠️ unknown object +- *19* (???*20* ? (???*25* | ???*27*) : (???*29* | ???*30* | ???*32*)) + ⚠️ nested operation +- *20* (3 === (???*21* | ???*23*)) + ⚠️ nested operation +- *21* ???*22*["nodeType"] + ⚠️ unknown object +- *22* arguments[2] + ⚠️ function calls are not analysed yet +- *23* ???*24*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *25* ???*26*["parentNode"] + ⚠️ unknown object +- *26* arguments[2] + ⚠️ function calls are not analysed yet +- *27* ???*28*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *28* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *29* arguments[2] + ⚠️ function calls are not analysed yet +- *30* ???*31*["target"] + ⚠️ unknown object +- *31* a + ⚠️ circular variable reference +- *32* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *33* ???*34*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *34* unknown new expression + ⚠️ This value might have side effects + +f#212 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +f#266 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#275 = ( + | ???*0* + | ???*1* + | null[(0 | ???*8*)][(???*9* | ???*10* | 0)]["instance"] + | ???*11* +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["instance"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* ???*3*[(???*6* | ???*7* | 0)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*[(0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* updated with update expression + ⚠️ This value might have side effects +- *8* updated with update expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* updated with update expression + ⚠️ This value might have side effects +- *11* ???*12*["instance"] + ⚠️ unknown object +- *12* ???*13*["listener"] + ⚠️ unknown object +- *13* h + ⚠️ circular variable reference + +f#286 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#30 = ???*0* +- *0* ???*1*["split"]("\n") + ⚠️ unknown callee object +- *1* ???*2*["stack"] + ⚠️ unknown object +- *2* l + ⚠️ pattern without value + +f#308 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#311 = ???*0* +- *0* ???*1*["_reactName"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +f#341 = ???*0* +- *0* f + ⚠️ pattern without value + +f#357 = ((???*0* + (???*1* | ???*2*)) | ???*3*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* unsupported assign operation + ⚠️ This value might have side effects +- *3* ???*4*["toString"](32) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +f#400 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#417 = { + "eventTime": (???*0* ? ???*2* : ???*3*), + "lane": ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null +} +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +f#418 = { + "eventTime": (???*0* ? ???*2* : ???*3*), + "lane": ( + | 1 + | ???*11* + | ???*12* + | ???*13* + | ???*14* + | 0 + | ???*16* + | 4 + | ((???*17* | ???*19*) ? ???*20* : 4) + | (???*21* ? 16 : (???*22* | null | ???*29* | ???*30*)) + | ???*32* + | (???*34* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null +} +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["_reactInternals"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* C + ⚠️ circular variable reference +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* C + ⚠️ circular variable reference +- *19* unsupported expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* (???*23* ? ???*24* : 1) + ⚠️ nested operation +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* (???*25* ? ???*26* : 4) + ⚠️ nested operation +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? 16 : 536870912) + ⚠️ nested operation +- *27* (0 !== ???*28*) + ⚠️ nested operation +- *28* unsupported expression + ⚠️ This value might have side effects +- *29* arguments[0] + ⚠️ function calls are not analysed yet +- *30* ???*31*["value"] + ⚠️ unknown object +- *31* arguments[1] + ⚠️ function calls are not analysed yet +- *32* ???*33*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* (???*35* === ???*36*) + ⚠️ nested operation +- *35* unsupported expression + ⚠️ This value might have side effects +- *36* a + ⚠️ circular variable reference + +f#420 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +f#421 = ( + | ???*0* + | ???*2* + | (???*4* ? ({} | ???*5*) : {})["_currentValue"] + | ???*8* + | ???*9* + | (???*10* ? ({} | ???*11*) : {}) +) +- *0* ???*1*["contextType"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* ???*3*["contextType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unknown new expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* ???*6*["__reactInternalMemoizedMaskedChildContext"] + ⚠️ unknown object +- *6* ???*7*["stateNode"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* unknown mutation + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* ???*12*["__reactInternalMemoizedMaskedChildContext"] + ⚠️ unknown object +- *12* ???*13*["stateNode"] + ⚠️ unknown object +- *13* arguments[0] + ⚠️ function calls are not analysed yet + +f#423 = (???*0* | (???*2* ? ({} | ???*7*) : ({} | ???*8*))) +- *0* ???*1*["contextType"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet +- *2* (null !== (???*3* | ???*4*)) + ⚠️ nested operation +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* ???*5*["state"] + ⚠️ unknown object +- *5* ???*6*["stateNode"] + ⚠️ unknown object +- *6* arguments[0] + ⚠️ function calls are not analysed yet +- *7* unknown mutation + ⚠️ This value might have side effects +- *8* unknown mutation + ⚠️ This value might have side effects + +f#424 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["ref"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet + +f#431 = (...) => (???*0* | c) +- *0* c + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +f#440 = ???*0* +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +f#442 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +f#447 = ???*0* +- *0* ???*1*["_init"] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet + +f#459 = (???*0* | ???*1* | ???*4*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["children"] + ⚠️ unknown object +- *2* ???*3*["props"] + ⚠️ unknown object +- *3* arguments[2] + ⚠️ function calls are not analysed yet +- *4* f + ⚠️ circular variable reference + +f#485 = (???*0* | 0 | ((???*1* | 0 | ???*2*) + 1)) +- *0* arguments[5] + ⚠️ function calls are not analysed yet +- *1* arguments[5] + ⚠️ function calls are not analysed yet +- *2* (???*3* + 1) + ⚠️ nested operation +- *3* f + ⚠️ circular variable reference + +f#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#501 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#504 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#518 = ( + | ???*0* + | null["memoizedState"]["destroy"] + | ???*1* + | null["alternate"]["memoizedState"]["destroy"] + | ???*4* + | (null !== ???*8*)["alternate"]["memoizedState"]["destroy"] + | (null !== ???*9*)["alternate"]["memoizedState"]["destroy"] + | (???*11* ? ???*13* : null)["memoizedState"]["destroy"] +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["destroy"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* ???*3*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["destroy"] + ⚠️ unknown object +- *5* ???*6*["memoizedState"] + ⚠️ unknown object +- *6* ???*7*["alternate"] + ⚠️ unknown object +- *7* arguments[1] + ⚠️ function calls are not analysed yet +- *8* O + ⚠️ circular variable reference +- *9* ???*10*["next"] + ⚠️ unknown object +- *10* O + ⚠️ circular variable reference +- *11* (null !== ???*12*) + ⚠️ nested operation +- *12* a + ⚠️ circular variable reference +- *13* ???*14*["memoizedState"] + ⚠️ unknown object +- *14* a + ⚠️ circular variable reference + +f#539 = ???*0* +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +f#559 = {"value": (???*0* | ???*1*() | ???*2*()), "getSnapshot": ???*3*} +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* c + ⚠️ circular variable reference +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +f#56 = ???*0* +- *0* ???*1*["set"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["getOwnPropertyDescriptor"](a["constructor"]["prototype"], b) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +f#572 = ???*0* +- *0* f + ⚠️ pattern without value + +f#580 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +f#591 = ???*0* +- *0* ???*1*["ref"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +f#592 = ( + | ???*0* + | (???*2* ? ???*4* : (...) => (???*5* | ???*6*))["type"] + | ???*7* + | null["child"] + | (???*9* ? ???*11* : (...) => (???*12* | ???*13*))["type"]["alternate"]["child"] +) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* (null !== ???*3*) + ⚠️ nested operation +- *3* c + ⚠️ circular variable reference +- *4* c + ⚠️ circular variable reference +- *5* !(0) + ⚠️ nested operation +- *6* !(1) + ⚠️ nested operation +- *7* ???*8*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* unknown new expression + ⚠️ This value might have side effects +- *9* (null !== ???*10*) + ⚠️ nested operation +- *10* c + ⚠️ circular variable reference +- *11* c + ⚠️ circular variable reference +- *12* !(0) + ⚠️ nested operation +- *13* !(1) + ⚠️ nested operation + +f#595 = ???*0* +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +f#597 = (???*0* ? ???*9* : null) +- *0* (null !== (???*1* | ???*2*)) + ⚠️ nested operation +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* (???*3* ? ???*7* : ???*8*) + ⚠️ nested operation +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* (???*5* ? ???*6* : null) + ⚠️ nested operation +- *5* (null !== ???) + ⚠️ nested operation +- *6* ???["memoizedState"] + ⚠️ unknown object +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* arguments[2] + ⚠️ function calls are not analysed yet +- *9* ???*10*["memoizedState"] + ⚠️ unknown object +- *10* arguments[0] + ⚠️ function calls are not analysed yet + +f#600 = ((???*0* ? ({} | ???*6*) : ({} | ???*7*)) | {} | ???*8*) +- *0* (null !== (???*1* | ???*2* | ???*4*)) + ⚠️ nested operation +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*(d, e) + ⚠️ unknown callee +- *3* c + ⚠️ circular variable reference +- *4* ???*5*["childContextTypes"] + ⚠️ unknown object +- *5* a + ⚠️ circular variable reference +- *6* unknown mutation + ⚠️ This value might have side effects +- *7* unknown mutation + ⚠️ This value might have side effects +- *8* ???*9*["__reactInternalMemoizedMaskedChildContext"] + ⚠️ unknown object +- *9* ???*10*["stateNode"] + ⚠️ unknown object +- *10* arguments[1] + ⚠️ function calls are not analysed yet + +f#601 = (true | false) + +f#605 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +f#609 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#614 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#620 = ???*0* +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +f#621 = (???*0* | 0["tail"] | ???*3*) +- *0* ???*1*["tail"] + ⚠️ unknown object +- *1* ???*2*["pendingProps"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["tail"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects + +f#639 = (null | [] | ???*0*) +- *0* f + ⚠️ circular variable reference + +f#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#687 = (???*0* | ???*2*) +- *0* ???*1*["destroy"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["destroy"] + ⚠️ unknown object +- *3* ???*4*["next"] + ⚠️ unknown object +- *4* e + ⚠️ circular variable reference + +f#706 = (false | ???*0* | true | ???*1* | ???*2* | false["tag"] | true["tag"] | ???*4*) +- *0* e + ⚠️ circular variable reference +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["next"] + ⚠️ unknown object +- *3* e + ⚠️ circular variable reference +- *4* ???*5*["tag"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +f#716 = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +f#721 = (???*0* | (null !== (???*2* | ???*5*)) | ???*8*) +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["memoizedState"] + ⚠️ unknown object +- *3* ???*4*["stateNode"] + ⚠️ unknown object +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* ???*6*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *6* ???*7*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* ???*9*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects + +f#756 = (undefined | null | ???*0*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +f#764 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#785 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#807 = ( + | (???*0* ? { + "readContext": (...) => b, + "useCallback": (...) => undefined, + "useContext": (...) => undefined, + "useEffect": (...) => undefined, + "useImperativeHandle": (...) => undefined, + "useInsertionEffect": (...) => undefined, + "useLayoutEffect": (...) => undefined, + "useMemo": (...) => undefined, + "useReducer": (...) => undefined, + "useRef": (...) => undefined, + "useState": (...) => undefined, + "useDebugValue": (...) => undefined, + "useDeferredValue": (...) => undefined, + "useTransition": (...) => undefined, + "useMutableSource": (...) => undefined, + "useSyncExternalStore": (...) => undefined, + "useId": (...) => undefined, + "unstable_isNewReconciler": false + } : module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"]["current"]) + | (???*1* ? (???*4* | ???*5*) : ???*6*) + | ???*8* +) +- *0* (null === module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"]["current"]) + ⚠️ nested operation +- *1* (0 !== (???*2* | ???*3*)) + ⚠️ nested operation +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* arguments[0] + ⚠️ function calls are not analysed yet +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? 1073741824 : 0) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects + +f#819 = ???*0* +- *0* ???*1*["getSnapshot"] + ⚠️ unknown object +- *1* ???*2*[d] + ⚠️ unknown object +- *2* ???*3*["updateQueue"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +f#838 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#880 = ( + | ???*0* + | (0 !== ???*1*) + | module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"]["transition"] + | ???*2* + | null["pendingLanes"] +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["pendingLanes"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +f#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#9 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +f#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +f#947 = ???*0* +- *0* arguments[5] + ⚠️ function calls are not analysed yet + +f#953 = (???*0* | ???*1*) +- *0* arguments[5] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +f#960 = ( + | ???*0* + | { + "eventTime": (???*1* | (???*2* ? ???*4* : ???*5*)), + "lane": ( + | ???*13* + | 1 + | ???*14* + | ???*15* + | ???*16* + | ???*18* + | 0 + | ???*20* + | 4 + | ((???*21* | ???*23*) ? ???*24* : 4) + | (???*25* ? 16 : (???*26* | null | ???*33* | ???*34*)) + | (???*36* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) + ), + "tag": 0, + "payload": null, + "callback": null, + "next": null + } +) +- *0* arguments[5] + ⚠️ function calls are not analysed yet +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* (0 !== ???*3*) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* module["unstable_now"]() + ⚠️ nested operation +- *5* (???*6* ? (???*10* | ???*11*) : ???*12*) + ⚠️ nested operation +- *6* (???*7* !== (???*8* | ???*9*)) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* module["unstable_now"]() + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[4] + ⚠️ function calls are not analysed yet +- *14* unsupported expression + ⚠️ This value might have side effects +- *15* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *16* ???*17*["current"] + ⚠️ unknown object +- *17* arguments[0] + ⚠️ function calls are not analysed yet +- *18* ???*19*["current"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *19* unknown new expression + ⚠️ This value might have side effects +- *20* C + ⚠️ circular variable reference +- *21* (0 !== ???*22*) + ⚠️ nested operation +- *22* C + ⚠️ circular variable reference +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* C + ⚠️ circular variable reference +- *25* unsupported expression + ⚠️ This value might have side effects +- *26* (???*27* ? ???*28* : 1) + ⚠️ nested operation +- *27* unsupported expression + ⚠️ This value might have side effects +- *28* (???*29* ? ???*30* : 4) + ⚠️ nested operation +- *29* unsupported expression + ⚠️ This value might have side effects +- *30* (???*31* ? 16 : 536870912) + ⚠️ nested operation +- *31* (0 !== ???*32*) + ⚠️ nested operation +- *32* unsupported expression + ⚠️ This value might have side effects +- *33* arguments[0] + ⚠️ function calls are not analysed yet +- *34* ???*35*["value"] + ⚠️ unknown object +- *35* arguments[1] + ⚠️ function calls are not analysed yet +- *36* (???*37* === ???*38*) + ⚠️ nested operation +- *37* unsupported expression + ⚠️ This value might have side effects +- *38* a + ⚠️ circular variable reference + +f#961 = (???*0* ? ???*2* : ???*3*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* module["unstable_now"]() + ⚠️ nested operation +- *3* (???*4* ? (???*8* | ???*9*) : ???*10*) + ⚠️ nested operation +- *4* (???*5* !== (???*6* | ???*7*)) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* unsupported expression + ⚠️ This value might have side effects +- *7* module["unstable_now"]() + ⚠️ nested operation +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* module["unstable_now"]() + ⚠️ nested operation +- *10* unsupported expression + ⚠️ This value might have side effects + +f#979 = (???*0* | (...) => undefined) +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +f#986 = ???*0* +- *0* ???*1*["_reactRootContainer"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +fa = (...) => undefined + +fb = (...) => (undefined | FreeVar(undefined)) + +fc = module["unstable_ImmediatePriority"] + +fd = (...) => undefined + +fe = (false | true) + +ff = (...) => undefined + +fg = (false | true) + +fh = (...) => (undefined | FreeVar(undefined)) + +fi = (...) => [b["memoizedState"], c["dispatch"]] + +fj = {"current": 0} + +fk = (...) => undefined + +fl = (...) => a + +g#1018 = ( + | (???*0* ? ???*3* : (...) => undefined) + | ???*4* + | (null != ???*6*)[(???*7* | 0 | ???*8*)]["onRecoverableError"] + | ???*9* + | null[(???*15* | 0 | ???*16*)]["onRecoverableError"] +) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ???*5*["onRecoverableError"] + ⚠️ unknown object +- *5* arguments[2] + ⚠️ function calls are not analysed yet +- *6* c + ⚠️ circular variable reference +- *7* arguments[0] + ⚠️ function calls are not analysed yet +- *8* updated with update expression + ⚠️ This value might have side effects +- *9* ???*10*["onRecoverableError"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* ???*11*[(???*13* | 0 | ???*14*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* ???*12*["hydratedSources"] + ⚠️ unknown object +- *12* c + ⚠️ circular variable reference +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* updated with update expression + ⚠️ This value might have side effects +- *15* arguments[0] + ⚠️ function calls are not analysed yet +- *16* updated with update expression + ⚠️ This value might have side effects + +g#123 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +g#127 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +g#128 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +g#136 = (false | true) + +g#159 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +g#162 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +g#207 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +g#212 = ???*0* +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +g#266 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#275 = (???*0* | ???*1* | 0) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +g#286 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#292 = [] + +g#30 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +g#311 = [] + +g#357 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +g#400 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#420 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +g#431 = (...) => b + +g#449 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#501 = (???*0* | ???*1* | ???*3*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* ???*2*["next"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* ???*4*["next"] + ⚠️ unknown object +- *4* ???*5*["next"] + ⚠️ unknown object +- *5* g + ⚠️ circular variable reference + +g#518 = ( + | null["memoizedState"] + | ???*0* + | null["alternate"]["memoizedState"] + | ???*2* + | (null !== ???*5*)["alternate"]["memoizedState"] + | (null !== ???*6*)["alternate"]["memoizedState"] + | (???*8* ? ???*10* : null)["memoizedState"] + | ???*12* +) +- *0* ???*1*["memoizedState"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["memoizedState"] + ⚠️ unknown object +- *3* ???*4*["alternate"] + ⚠️ unknown object +- *4* arguments[1] + ⚠️ function calls are not analysed yet +- *5* O + ⚠️ circular variable reference +- *6* ???*7*["next"] + ⚠️ unknown object +- *7* O + ⚠️ circular variable reference +- *8* (null !== ???*9*) + ⚠️ nested operation +- *9* a + ⚠️ circular variable reference +- *10* ???*11*["memoizedState"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* unknown mutation + ⚠️ This value might have side effects + +g#539 = ???*0* +- *0* ???*1*["lastRenderedState"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +g#592 = ( + | ???*0* + | (???*3* ? ???*5* : (...) => (???*6* | ???*7*))["type"]["memoizedProps"] + | ???*8* + | null["child"]["memoizedProps"] +) +- *0* ???*1*["memoizedProps"] + ⚠️ unknown object +- *1* ???*2*["type"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* (null !== ???*4*) + ⚠️ nested operation +- *4* c + ⚠️ circular variable reference +- *5* c + ⚠️ circular variable reference +- *6* !(0) + ⚠️ nested operation +- *7* !(1) + ⚠️ nested operation +- *8* ???*9*["memoizedProps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* ???*10*["child"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *10* unknown new expression + ⚠️ This value might have side effects + +g#601 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +g#605 = (0 !== ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +g#609 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#614 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +g#639 = ???*0* +- *0* g + ⚠️ pattern without value + +g#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#706 = (false["destroy"] | ???*0* | true["destroy"] | ???*2*) +- *0* ???*1*["destroy"] + ⚠️ unknown object +- *1* e + ⚠️ circular variable reference +- *2* ???*3*["destroy"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +g#716 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* b + ⚠️ circular variable reference + +g#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#756 = ???*0* +- *0* ???*1*["containerInfo"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* ???*3*["return"] + ⚠️ unknown object +- *3* arguments[0] + ⚠️ function calls are not analysed yet + +g#764 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#785 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#807 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#824 = ???*0* +- *0* g + ⚠️ pattern without value + +g#838 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#880 = ( + | 0 + | 1 + | ???*0* + | 4 + | ((???*1* | ???*3*) ? ???*4* : 4) + | (???*5* ? 16 : (???*6* | null | ???*13* | ???*14*)) + | ???*16* +) +- *0* C + ⚠️ circular variable reference +- *1* (0 !== ???*2*) + ⚠️ nested operation +- *2* C + ⚠️ circular variable reference +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* C + ⚠️ circular variable reference +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* (???*7* ? ???*8* : 1) + ⚠️ nested operation +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* (???*9* ? ???*10* : 4) + ⚠️ nested operation +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* (???*11* ? 16 : 536870912) + ⚠️ nested operation +- *11* (0 !== ???*12*) + ⚠️ nested operation +- *12* unsupported expression + ⚠️ This value might have side effects +- *13* arguments[0] + ⚠️ function calls are not analysed yet +- *14* ???*15*["value"] + ⚠️ unknown object +- *15* arguments[1] + ⚠️ function calls are not analysed yet +- *16* arguments[0] + ⚠️ function calls are not analysed yet + +g#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#9 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +g#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +g#947 = (2 | 1 | 5 | 8 | 10 | 9 | 11 | 14 | 16) + +g#953 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +g#960 = ???*0* +- *0* arguments[6] + ⚠️ function calls are not analysed yet + +g#961 = ( + | 1 + | ???*0* + | ???*1* + | ???*2* + | ???*4* + | ???*5* + | 0 + | ???*6* + | 4 + | ((???*7* | ???*9*) ? ???*10* : 4) + | (???*11* ? 16 : (???*12* | null | ???*19* | ???*20*)) + | ???*22* + | ???*23* + | (???*25* ? 16 : (undefined | 1 | 4 | 16 | 536870912)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *2* ???*3*["current"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects +- *6* C + ⚠️ circular variable reference +- *7* (0 !== ???*8*) + ⚠️ nested operation +- *8* C + ⚠️ circular variable reference +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* C + ⚠️ circular variable reference +- *11* unsupported expression + ⚠️ This value might have side effects +- *12* (???*13* ? ???*14* : 1) + ⚠️ nested operation +- *13* unsupported expression + ⚠️ This value might have side effects +- *14* (???*15* ? ???*16* : 4) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* (???*17* ? 16 : 536870912) + ⚠️ nested operation +- *17* (0 !== ???*18*) + ⚠️ nested operation +- *18* unsupported expression + ⚠️ This value might have side effects +- *19* arguments[0] + ⚠️ function calls are not analysed yet +- *20* ???*21*["value"] + ⚠️ unknown object +- *21* arguments[1] + ⚠️ function calls are not analysed yet +- *22* arguments[0] + ⚠️ function calls are not analysed yet +- *23* ???*24*["event"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *24* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *25* (???*26* === ???*27*) + ⚠️ nested operation +- *26* unsupported expression + ⚠️ This value might have side effects +- *27* a + ⚠️ circular variable reference + +g#979 = (???*0* | ???*1* | ???*3*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["current"] + ⚠️ unknown object +- *2* a + ⚠️ circular variable reference +- *3* unknown new expression + ⚠️ This value might have side effects + +g#986 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +gb = (...) => A( + {}, + b, + {"value": ???*0*, "defaultValue": ???*1*, "children": a["_wrapperState"]["initialValue"]} +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +gc = module["unstable_UserBlockingPriority"] + +gd = (...) => undefined + +ge = (...) => (undefined | (???*0* !== $d["indexOf"](b["keyCode"])) | (229 !== b["keyCode"]) | !(0) | !(1)) +- *0* unsupported expression + ⚠️ This value might have side effects + +gf = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +gg = (false | true) + +gh = (...) => undefined + +gi = (...) => [f, d] + +gj = (???*0* | 0 | ???*1* | ???*2* | ???*3*) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects + +gk = (module["unstable_now"]() | 0) + +gl = (...) => g + +h#123 = ???*0* +- *0* arguments[7] + ⚠️ function calls are not analysed yet + +h#127 = ???*0* +- *0* arguments[7] + ⚠️ function calls are not analysed yet + +h#128 = ???*0* +- *0* arguments[7] + ⚠️ function calls are not analysed yet + +h#136 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#159 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +h#162 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +h#275 = ( + | ???*0* + | null[(0 | ???*6*)][(???*7* | ???*8* | 0)] + | null[(0 | ???*9*)][(???*10* | ???*11* | 0)]["listener"] + | ???*12* +) +- *0* ???*1*[(???*4* | ???*5* | 0)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* arguments[0] + ⚠️ function calls are not analysed yet +- *3* updated with update expression + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* unsupported expression + ⚠️ This value might have side effects +- *8* updated with update expression + ⚠️ This value might have side effects +- *9* updated with update expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* updated with update expression + ⚠️ This value might have side effects +- *12* ???*13*["listener"] + ⚠️ unknown object +- *13* ???*14*["listener"] + ⚠️ unknown object +- *14* h + ⚠️ circular variable reference + +h#286 = (???*0* | ???*3*) +- *0* ???*1*["containerInfo"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[3] + ⚠️ function calls are not analysed yet +- *3* ???*4*["containerInfo"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects + +h#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#30 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +h#311 = (???*0* | ???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* ???*2*["return"] + ⚠️ unknown object +- *2* c + ⚠️ circular variable reference + +h#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#431 = (...) => (???*0* | b) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +h#449 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +h#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#459 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#494 = ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +h#539 = ???*0* +- *0* ???*1*(g, c) + ⚠️ unknown callee +- *1* ???*2*["alternate"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +h#601 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#605 = (???*0* ? null : ???*2*) +- *0* (0 !== ???*1*) + ⚠️ nested operation +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*() + ⚠️ nested operation +- *3* ???*4*["render"] + ⚠️ unknown object +- *4* arguments[3] + ⚠️ function calls are not analysed yet + +h#609 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#614 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#639 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#708 = ???*0* +- *0* h + ⚠️ pattern without value + +h#712 = ???*0* +- *0* h + ⚠️ pattern without value + +h#716 = (???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* ???*2*["child"] + ⚠️ unknown object +- *2* b + ⚠️ circular variable reference + +h#721 = (???*0* | ???*2*) +- *0* ???*1*["type"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["stateNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* unsupported expression + ⚠️ This value might have side effects + +h#756 = (undefined | null | ???*0*) +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +h#764 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#785 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#810 = ???*0* +- *0* h + ⚠️ pattern without value + +h#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#880 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +h#953 = ???*0* +- *0* arguments[7] + ⚠️ function calls are not analysed yet + +h#960 = ???*0* +- *0* arguments[7] + ⚠️ function calls are not analysed yet + +h#979 = (???*0* | (...) => undefined) +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +h#986 = (???*0* | (...) => undefined) +- *0* arguments[4] + ⚠️ function calls are not analysed yet + +ha = (...) => undefined + +hb = (...) => undefined + +hc = module["unstable_NormalPriority"] + +hd = (...) => (undefined | FreeVar(undefined)) + +he = (...) => ((("object" === typeof(a)) && ???*0*) ? a["data"] : null) +- *0* unsupported expression + ⚠️ This value might have side effects + +hf = "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ")[(0 | ???*0*)] +- *0* updated with update expression + ⚠️ This value might have side effects + +hg = (...) => undefined + +hh = (???*0* | 0) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +hi = (...) => undefined + +hj = (...) => undefined + +hk = (...) => undefined + +hl = (...) => (undefined | null | a["child"]["stateNode"]) + +ia = !(???*0*) +- *0* ("undefined" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects + +ib = (...) => undefined + +ic = module["unstable_LowPriority"] + +id = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ie = (false | true) + +ig = (...) => undefined + +ih = (...) => undefined + +ii = (...) => e + +ij = (...) => kj(a, b, c, d, f, e) + +ik = (...) => undefined + +il = (...) => undefined + +ja = ???*0* +- *0* ???*1*["hasOwnProperty"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +jb = (...) => undefined + +jc = module["unstable_IdlePriority"] + +jd = (...) => (undefined | 1 | 4 | 16 | 536870912) + +je = (...) => (undefined | he(b) | null | ee | ???*0*) +- *0* (((a === ee) && fe) ? null : a) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +jf = ???*0*() +- *0* ???*1*["toLowerCase"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(0 | ???*3*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ") + ⚠️ nested operation +- *3* updated with update expression + ⚠️ This value might have side effects + +jg = (...) => null + +jh = ???*0* +- *0* ???*1*["refs"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* unknown new expression + ⚠️ This value might have side effects + +ji = (...) => ui(2048, 8, a, b) + +jj = (...) => undefined + +jk = (...) => undefined + +jl = (...) => undefined + +k#123 = ???*0* +- *0* arguments[8] + ⚠️ function calls are not analysed yet + +k#127 = ???*0* +- *0* arguments[8] + ⚠️ function calls are not analysed yet + +k#128 = ???*0* +- *0* arguments[8] + ⚠️ function calls are not analysed yet + +k#162 = ???*0* +- *0* ???*1*[g] + ⚠️ unknown object +- *1* ???*2*["expirationTimes"] + ⚠️ unknown object +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +k#275 = ( + | ???*0* + | null[(0 | ???*7*)][(???*8* | ???*9* | 0)]["instance"] + | ???*10* +) +- *0* ???*1*["instance"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(???*5* | ???*6* | 0)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* ???*3*[(0 | ???*4*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* updated with update expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* updated with update expression + ⚠️ This value might have side effects +- *10* ???*11*["instance"] + ⚠️ unknown object +- *11* ???*12*["listener"] + ⚠️ unknown object +- *12* h + ⚠️ circular variable reference + +k#286 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#30 = ( + | ` +${???*0*}` + | ???*5* + | ???*16* +) +- *0* ???*1*["replace"](" at new ", " at ") + ⚠️ unknown callee object +- *1* ???*2*[g] + ⚠️ unknown object +- *2* ???*3*["split"]("\n") + ⚠️ unknown callee object +- *3* ???*4*["stack"] + ⚠️ unknown object +- *4* l + ⚠️ pattern without value +- *5* ???*6*("", (???*10* | ???*12*["displayName"])) + ⚠️ unknown callee +- *6* ???*7*["replace"] + ⚠️ unknown object +- *7* ` +${???*8*}` + ⚠️ nested operation +- *8* ???*9*["replace"](" at new ", " at ") + ⚠️ unknown callee object +- *9* ???[g] + ⚠️ unknown object +- *10* ???*11*["displayName"] + ⚠️ unknown object +- *11* arguments[0] + ⚠️ function calls are not analysed yet +- *12* (???*13* ? ???*14* : "") + ⚠️ nested operation +- *13* a + ⚠️ circular variable reference +- *14* ???*15*["displayName"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* ???*17*["replace"]( + "", + (???*19* | (???*21* ? ???*22* : "")["displayName"]) + ) + ⚠️ unknown callee object +- *17* ???*18*["replace"]("", a["displayName"]) + ⚠️ unknown callee object +- *18* k + ⚠️ circular variable reference +- *19* ???*20*["displayName"] + ⚠️ unknown object +- *20* arguments[0] + ⚠️ function calls are not analysed yet +- *21* a + ⚠️ circular variable reference +- *22* ???*23*["displayName"] + ⚠️ unknown object +- *23* a + ⚠️ circular variable reference + +k#311 = ( + | ???*0* + | null + | !((???*2* | null | ???*4*))["stateNode"] + | false["stateNode"] + | null[???*7*] + | !(???*9*)[???*11*] + | !(???*13*)[???*19*] +) +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* ???*3*[Pf] + ⚠️ unknown object +- *3* c + ⚠️ circular variable reference +- *4* !(???*5*) + ⚠️ nested operation +- *5* ???*6*["disabled"] + ⚠️ unknown object +- *6* d + ⚠️ circular variable reference +- *7* ???*8*["_reactName"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet +- *9* ???*10*["disabled"] + ⚠️ unknown object +- *10* d + ⚠️ circular variable reference +- *11* ???*12*["_reactName"] + ⚠️ unknown object +- *12* arguments[1] + ⚠️ function calls are not analysed yet +- *13* ("button" === (???*14* | ???*15* | ???*17* | false)) + ⚠️ nested operation +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* ???*16*["return"] + ⚠️ unknown object +- *16* c + ⚠️ circular variable reference +- *17* !(???*18*) + ⚠️ nested operation +- *18* d + ⚠️ circular variable reference +- *19* ???*20*["_reactName"] + ⚠️ unknown object +- *20* arguments[1] + ⚠️ function calls are not analysed yet + +k#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#431 = (...) => (m(a, b, c["props"]["children"], d, c["key"]) | ???*0* | d) +- *0* d + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +k#449 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +k#454 = ???*0* +- *0* arguments[3] + ⚠️ function calls are not analysed yet + +k#459 = ???*0* +- *0* ???*1*["key"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +k#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#539 = ???*0* +- *0* ???*1*["interleaved"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +k#601 = ( + | ???*0* + | ???*3* + | (???*5* ? ({} | ???*9*) : ({} | ???*10*))["_currentValue"] + | ???*11* + | ???*12* + | (???*13* ? ({} | ???*17*) : ({} | ???*18*)) + | {} +) +- *0* ???*1*["context"] + ⚠️ unknown object +- *1* ???*2*["stateNode"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet +- *3* ???*4*["_currentValue"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* (null !== (???*6* | ???*7*)) + ⚠️ nested operation +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["childContextTypes"] + ⚠️ unknown object +- *8* a + ⚠️ circular variable reference +- *9* unknown mutation + ⚠️ This value might have side effects +- *10* unknown mutation + ⚠️ This value might have side effects +- *11* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *12* unknown mutation + ⚠️ This value might have side effects +- *13* (null !== (???*14* | ???*15*)) + ⚠️ nested operation +- *14* arguments[2] + ⚠️ function calls are not analysed yet +- *15* ???*16*["childContextTypes"] + ⚠️ unknown object +- *16* a + ⚠️ circular variable reference +- *17* unknown mutation + ⚠️ This value might have side effects +- *18* unknown mutation + ⚠️ This value might have side effects + +k#609 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#639 = ( + | ???*0* + | ???*4* + | ((???*13* | ???*17* | ???*26*) ? (???*31* | ???*36*) : ???*46*) +) +- *0* ???*1*[(???*2* | null | [] | ???*3*)] + ⚠️ unknown object +- *1* arguments[3] + ⚠️ function calls are not analysed yet +- *2* l + ⚠️ pattern without value +- *3* f + ⚠️ circular variable reference +- *4* ???*5*[(???*11* | null | [] | ???*12*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *5* ???*6*( + {}, + b, + { + "defaultChecked": ???*8*, + "defaultValue": ???*9*, + "value": ???*10*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *6* ???*7*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* unsupported expression + ⚠️ This value might have side effects +- *10* unsupported expression + ⚠️ This value might have side effects +- *11* l + ⚠️ pattern without value +- *12* f + ⚠️ circular variable reference +- *13* ???*14*[(???*15* | null | [] | ???*16*)] + ⚠️ unknown object +- *14* arguments[3] + ⚠️ function calls are not analysed yet +- *15* l + ⚠️ pattern without value +- *16* f + ⚠️ circular variable reference +- *17* ???*18*[(???*24* | null | [] | ???*25*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* ???*19*( + {}, + b, + { + "defaultChecked": ???*21*, + "defaultValue": ???*22*, + "value": ???*23*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *19* ???*20*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *20* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *21* unsupported expression + ⚠️ This value might have side effects +- *22* unsupported expression + ⚠️ This value might have side effects +- *23* unsupported expression + ⚠️ This value might have side effects +- *24* l + ⚠️ pattern without value +- *25* f + ⚠️ circular variable reference +- *26* (???*27* ? ???*28* : ???*30*) + ⚠️ nested operation +- *27* k + ⚠️ circular variable reference +- *28* ???*29*["__html"] + ⚠️ unknown object +- *29* k + ⚠️ circular variable reference +- *30* unsupported expression + ⚠️ This value might have side effects +- *31* ???*32*["__html"] + ⚠️ unknown object +- *32* ???*33*[(???*34* | null | [] | ???*35*)] + ⚠️ unknown object +- *33* arguments[3] + ⚠️ function calls are not analysed yet +- *34* l + ⚠️ pattern without value +- *35* f + ⚠️ circular variable reference +- *36* ???*37*["__html"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *37* ???*38*[(???*44* | null | [] | ???*45*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *38* ???*39*( + {}, + b, + { + "defaultChecked": ???*41*, + "defaultValue": ???*42*, + "value": ???*43*, + "checked": ((null != c) ? c : a["_wrapperState"]["initialChecked"]) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *39* ???*40*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *40* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects +- *41* unsupported expression + ⚠️ This value might have side effects +- *42* unsupported expression + ⚠️ This value might have side effects +- *43* unsupported expression + ⚠️ This value might have side effects +- *44* l + ⚠️ pattern without value +- *45* f + ⚠️ circular variable reference +- *46* unsupported expression + ⚠️ This value might have side effects + +k#647 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#716 = ???*0* +- *0* ???*1*["alternate"] + ⚠️ unknown object +- *1* ???*2*[d] + ⚠️ unknown object +- *2* ???*3*["deletions"] + ⚠️ unknown object +- *3* arguments[1] + ⚠️ function calls are not analysed yet + +k#721 = (???*0* | ???*2*) +- *0* ???*1*["updateQueue"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* ???*3*["style"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["memoizedProps"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* unsupported expression + ⚠️ This value might have side effects + +k#762 = ???*0* +- *0* k + ⚠️ pattern without value + +k#764 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#789 = ???*0* +- *0* k + ⚠️ pattern without value + +k#792 = ???*0* +- *0* k + ⚠️ pattern without value + +k#794 = ???*0* +- *0* k + ⚠️ pattern without value + +k#796 = ???*0* +- *0* k + ⚠️ pattern without value + +k#797 = ???*0* +- *0* k + ⚠️ pattern without value + +k#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#883 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +k#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +k#953 = ???*0* +- *0* arguments[8] + ⚠️ function calls are not analysed yet + +k#960 = ???*0* +- *0* arguments[8] + ⚠️ function calls are not analysed yet + +k#979 = (???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* unknown new expression + ⚠️ This value might have side effects + +ka = /^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/ + +kb = (...) => ( + | undefined + | "http://www.w3.org/2000/svg" + | "http://www.w3.org/1998/Math/MathML" + | "http://www.w3.org/1999/xhtml" +) + +kc = (null | ???*0*) +- *0* ???*1*["inject"](vl) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects + +kd = ( + | null + | (???*0* ? (???*5* | ???*7*) : (???*9* | ???*10* | ???*12*)) + | ???*13* +) +- *0* (3 === (???*1* | ???*3*)) + ⚠️ nested operation +- *1* ???*2*["nodeType"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ???*4*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *5* ???*6*["parentNode"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* arguments[2] + ⚠️ function calls are not analysed yet +- *10* ???*11*["target"] + ⚠️ unknown object +- *11* a + ⚠️ circular variable reference +- *12* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* unknown new expression + ⚠️ This value might have side effects + +ke = (...) => ( + | undefined + | ((("compositionend" === a) || (!(ae) && ge(a, b))) ? ???*0* : null) + | null + | b["char"] + | FreeVar(String)["fromCharCode"](b["which"]) + | ((de && ("ko" !== b["locale"])) ? null : b["data"]) +) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +kf = (???*0* + ???*6*) +- *0* ???*1*() + ⚠️ nested operation +- *1* ???*2*["toUpperCase"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* ???*3*[0] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*[(0 | ???*5*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ") + ⚠️ nested operation +- *5* updated with update expression + ⚠️ This value might have side effects +- *6* ???*7*(1) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *7* ???*8*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* ???*9*[(0 | ???*10*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *9* "abort auxClick cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel"["split"](" ") + ⚠️ nested operation +- *10* updated with update expression + ⚠️ This value might have side effects + +kg = [] + +kh = (...) => undefined + +ki = (...) => c(*anonymous function 67764*) + +kj = (...) => ($i(a, b, f) | b["child"]) + +kk = (...) => undefined + +kl = (...) => null + +l#123 = ???*0* +- *0* ???*1*["call"](FreeVar(arguments), 3) + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* ???*2*["slice"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* ???*3*["prototype"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Array) + ⚠️ unknown global + ⚠️ This value might have side effects + +l#128 = (null | ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +l#275 = ( + | ???*0* + | null[(0 | ???*7*)][(???*8* | ???*9* | 0)]["currentTarget"] + | ???*10* +) +- *0* ???*1*["currentTarget"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* ???*2*[(???*5* | ???*6* | 0)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* ???*3*[(0 | ???*4*)] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* arguments[0] + ⚠️ function calls are not analysed yet +- *4* updated with update expression + ⚠️ This value might have side effects +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* updated with update expression + ⚠️ This value might have side effects +- *7* updated with update expression + ⚠️ This value might have side effects +- *8* unsupported expression + ⚠️ This value might have side effects +- *9* updated with update expression + ⚠️ This value might have side effects +- *10* ???*11*["currentTarget"] + ⚠️ unknown object +- *11* ???*12*["listener"] + ⚠️ unknown object +- *12* h + ⚠️ circular variable reference + +l#311 = ???*0* +- *0* ???*1*["stateNode"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +l#36 = ???*0* +- *0* l + ⚠️ pattern without value + +l#39 = ???*0* +- *0* l + ⚠️ pattern without value + +l#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#42 = ???*0* +- *0* l + ⚠️ pattern without value + +l#43 = ???*0* +- *0* l + ⚠️ pattern without value + +l#431 = (...) => (???*0* | b) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +l#449 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#459 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#543 = ???*0* +- *0* l + ⚠️ pattern without value + +l#601 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#639 = (???*0* | null | [] | ???*1*) +- *0* l + ⚠️ pattern without value +- *1* f + ⚠️ circular variable reference + +l#673 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +l#720 = ???*0* +- *0* l + ⚠️ pattern without value + +l#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#764 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +l#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +la = {} + +lb = (...) => (((null == a) || ("http://www.w3.org/1999/xhtml" === a)) ? kb(b) : ((("http://www.w3.org/2000/svg" === a) && ("foreignObject" === b)) ? "http://www.w3.org/1999/xhtml" : a)) + +lc = (null | ???*0*) +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects + +ld = ( + | null + | ???*0* + | (???*1* ? (null["value"] | ???*2* | ???*17*) : (null["textContent"] | ???*19* | ???*34*)) +) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* ???*3*["value"] + ⚠️ unknown object +- *3* (???*4* ? (???*9* | ???*11*) : (???*13* | ???*14* | ???*16*)) + ⚠️ nested operation +- *4* (3 === (???*5* | ???*7*)) + ⚠️ nested operation +- *5* ???*6*["nodeType"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *8* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *9* ???*10*["parentNode"] + ⚠️ unknown object +- *10* arguments[2] + ⚠️ function calls are not analysed yet +- *11* ???*12*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *12* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *13* arguments[2] + ⚠️ function calls are not analysed yet +- *14* ???*15*["target"] + ⚠️ unknown object +- *15* a + ⚠️ circular variable reference +- *16* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *17* ???*18*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *18* unknown new expression + ⚠️ This value might have side effects +- *19* ???*20*["textContent"] + ⚠️ unknown object +- *20* (???*21* ? (???*26* | ???*28*) : (???*30* | ???*31* | ???*33*)) + ⚠️ nested operation +- *21* (3 === (???*22* | ???*24*)) + ⚠️ nested operation +- *22* ???*23*["nodeType"] + ⚠️ unknown object +- *23* arguments[2] + ⚠️ function calls are not analysed yet +- *24* ???*25*["nodeType"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *25* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *26* ???*27*["parentNode"] + ⚠️ unknown object +- *27* arguments[2] + ⚠️ function calls are not analysed yet +- *28* ???*29*["parentNode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *29* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *30* arguments[2] + ⚠️ function calls are not analysed yet +- *31* ???*32*["target"] + ⚠️ unknown object +- *32* a + ⚠️ circular variable reference +- *33* FreeVar(window) + ⚠️ unknown global + ⚠️ This value might have side effects +- *34* ???*35*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *35* unknown new expression + ⚠️ This value might have side effects + +le = { + "color": true, + "date": true, + "datetime": true, + "datetime-local": true, + "email": true, + "month": true, + "number": true, + "password": true, + "range": true, + "search": true, + "tel": true, + "text": true, + "time": true, + "url": true, + "week": true +} + +lf = "abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange resize seeked seeking stalled suspend timeupdate volumechange waiting"["split"](" ") + +lg = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +lh = (...) => (1 | ???*0* | ???*1* | a) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* Ck + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +li = (...) => a + +lj = (...) => undefined + +lk = (...) => undefined + +ll = (???*0* ? ???*3* : (...) => undefined) +- *0* ("function" === ???*1*) + ⚠️ nested operation +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects +- *3* FreeVar(reportError) + ⚠️ unknown global + ⚠️ This value might have side effects + +m#125 = ???*0* +- *0* m + ⚠️ pattern without value + +m#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +m#431 = (...) => (???*0* | b) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +m#449 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +m#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +m#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +m#601 = (???*0* | ("function" === ???*2*)) +- *0* ???*1*["getDerivedStateFromProps"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet +- *2* typeof(???*3*) + ⚠️ nested operation +- *3* ???*4*["getDerivedStateFromProps"] + ⚠️ unknown object +- *4* arguments[2] + ⚠️ function calls are not analysed yet + +m#673 = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +m#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +m#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +m#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +m#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +m#919 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ma = {} + +mb = (???*0* | ???*1* | ???*2*) +- *0* mb + ⚠️ pattern without value +- *1* mb + ⚠️ circular variable reference +- *2* ???*3*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *3* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +mc = (...) => undefined + +md = (null | ???*0* | ???*18*) +- *0* ???*1*((???*12* | 0 | ???*13*), ???*14*) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["slice"] + ⚠️ unknown object +- *2* (???*3* ? (null["value"] | ???*4* | ???*6*) : (null["textContent"] | ???*8* | ???*10*)) + ⚠️ nested operation +- *3* unsupported expression + ⚠️ This value might have side effects +- *4* ???*5*["value"] + ⚠️ unknown object +- *5* (??? ? (??? | ???) : (??? | ??? | ???)) + ⚠️ nested operation +- *6* ???*7*["value"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* unknown new expression + ⚠️ This value might have side effects +- *8* ???*9*["textContent"] + ⚠️ unknown object +- *9* (??? ? (??? | ???) : (??? | ??? | ???)) + ⚠️ nested operation +- *10* ???*11*["textContent"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *11* unknown new expression + ⚠️ This value might have side effects +- *12* a + ⚠️ pattern without value +- *13* updated with update expression + ⚠️ This value might have side effects +- *14* (???*15* ? ???*16* : ???*17*) + ⚠️ nested operation +- *15* unsupported expression + ⚠️ This value might have side effects +- *16* unsupported expression + ⚠️ This value might have side effects +- *17* unsupported expression + ⚠️ This value might have side effects +- *18* unsupported expression + ⚠️ This value might have side effects + +me = (...) => (("input" === b) ? !(!(le[a["type"]])) : (("textarea" === b) ? !(0) : !(1))) + +mf = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +mg = (null | ???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* [][???*2*] + ⚠️ unknown array prototype methods or values +- *2* unsupported expression + ⚠️ This value might have side effects + +mh = (...) => undefined + +mi = (...) => undefined + +mj = (...) => b["child"] + +mk = ???*0* +- *0* ???*1*["ceil"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +ml = (...) => undefined + +n#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +n#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +n#431 = (...) => l + +n#449 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +n#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +n#601 = ???*0* +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +n#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +n#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +n#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +n#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +na#292 = ( + | (...) => (undefined | b) + | (...) => (undefined | te(b)) + | (...) => (undefined | te(qe)) + | (...) => (undefined | te(b)) + | ???*0* +) +- *0* ( + | (...) => (undefined | b) + | (...) => (undefined | te(b)) + | (...) => (undefined | te(qe)) + | (...) => (undefined | te(b)) + | ???*1* + )(a, d) + ⚠️ non-function callee +- *1* ???*2*(a, d) + ⚠️ unknown callee +- *2* na + ⚠️ circular variable reference + +na#860 = ???*0* +- *0* na + ⚠️ pattern without value + +na#903 = ???*0* +- *0* na + ⚠️ pattern without value + +na#907 = ???*0* +- *0* na + ⚠️ pattern without value + +nb = ???*0* +- *0* ???*1*(*anonymous function 13608*) + ⚠️ unknown callee +- *1* *anonymous function 13449* + ⚠️ no value of this variable analysed + +nc = (...) => ((0 === a) ? 32 : ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +nd = (...) => (md | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +ne = (...) => undefined + +nf = (...) => undefined + +ng = (0 | ???*0* | ???*1*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet +- *1* [][???*2*] + ⚠️ unknown array prototype methods or values +- *2* unsupported expression + ⚠️ This value might have side effects + +nh = { + "isMounted": (...) => (???*0* ? (Vb(a) === a) : !(1)), + "enqueueSetState": (...) => undefined, + "enqueueReplaceState": (...) => undefined, + "enqueueForceUpdate": (...) => undefined +} +- *0* unsupported expression + ⚠️ This value might have side effects + +ni = (...) => undefined + +nj = {"dehydrated": null, "treeContext": null, "retryLane": 0} + +nk = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"] + +nl = (...) => undefined + +oa = (...) => (!(0) | !(1) | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +ob = (...) => (undefined | FreeVar(undefined)) + +oc = (???*0* ? ???*2* : (...) => ???*4*) +- *0* ???*1*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *2* ???*3*["clz32"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* ((0 === a) ? 32 : ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects + +od = (...) => ((???*0* || (13 === a)) ? a : 0) +- *0* unsupported expression + ⚠️ This value might have side effects + +oe = (...) => d + +of = `__reactEvents$${???*0*}` +- *0* ???*1*["slice"](2) + ⚠️ unknown callee object +- *1* ???*2*(36) + ⚠️ unknown callee +- *2* ???*3*["toString"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +og = [] + +oh = (...) => (("function" === typeof(a["shouldComponentUpdate"])) ? a["shouldComponentUpdate"](d, f, g) : ((b["prototype"] && b["prototype"]["isPureReactComponent"]) ? (!(Ie(c, d)) || !(Ie(e, f))) : !(0))) + +oi = (...) => (undefined | !(He(a, c)) | !(0)) + +oj = (...) => {"baseLanes": a, "cachePool": null, "transitions": null} + +ok = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentOwner"] + +ol = (...) => !(( + || !(a) + || ((1 !== a["nodeType"]) && (9 !== a["nodeType"]) && (11 !== a["nodeType"])) +)) + +p = (...) => `Minified React error #${a}; visit ${b} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.` + +pa = (...) => (undefined | !(1) | !(0) | !(c["acceptsBooleans"]) | (("data-" !== a) && ("aria-" !== a))) + +pb = { + "animationIterationCount": true, + "aspectRatio": true, + "borderImageOutset": true, + "borderImageSlice": true, + "borderImageWidth": true, + "boxFlex": true, + "boxFlexGroup": true, + "boxOrdinalGroup": true, + "columnCount": true, + "columns": true, + "flex": true, + "flexGrow": true, + "flexPositive": true, + "flexShrink": true, + "flexNegative": true, + "flexOrder": true, + "gridArea": true, + "gridRow": true, + "gridRowEnd": true, + "gridRowSpan": true, + "gridRowStart": true, + "gridColumn": true, + "gridColumnEnd": true, + "gridColumnSpan": true, + "gridColumnStart": true, + "fontWeight": true, + "lineClamp": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "tabSize": true, + "widows": true, + "zIndex": true, + "zoom": true, + "fillOpacity": true, + "floodOpacity": true, + "stopOpacity": true, + "strokeDasharray": true, + "strokeDashoffset": true, + "strokeMiterlimit": true, + "strokeOpacity": true, + "strokeWidth": true +} + +pc = ???*0* +- *0* ???*1*["log"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +pd = (...) => !(0) + +pe = (null | ???*0*) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +pf = (...) => undefined + +pg = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +ph = (...) => b + +pi = (...) => undefined + +pj = (...) => (???*0* | (f ? ???*1* : rj(b, g)) | sj(a, b, g, d, h, e, c) | d) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects +- *1* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +pk = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentBatchConfig"] + +pl = (...) => !(( + || !(a) + || ( + && (1 !== a["nodeType"]) + && (9 !== a["nodeType"]) + && (11 !== a["nodeType"]) + && ( + || (8 !== a["nodeType"]) + || (" react-mount-point-unstable " !== a["nodeValue"]) + ) + ) +)) + +q#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +q#431 = (...) => (???*0* | q(a, d(b["_payload"]), c) | null) +- *0* b + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +q#494 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +q#601 = (("function" === ???*0*) | ???*7*) +- *0* typeof((???*1* | ???*3*)) + ⚠️ nested operation +- *1* ???*2*["getDerivedStateFromProps"] + ⚠️ unknown object +- *2* arguments[2] + ⚠️ function calls are not analysed yet +- *3* ("function" === ???*4*) + ⚠️ nested operation +- *4* typeof(???*5*) + ⚠️ nested operation +- *5* ???*6*["getDerivedStateFromProps"] + ⚠️ unknown object +- *6* arguments[2] + ⚠️ function calls are not analysed yet +- *7* ???*8*["pendingProps"] + ⚠️ unknown object +- *8* arguments[1] + ⚠️ function calls are not analysed yet + +q#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +q#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +q#768 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +q#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +q#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +qa = (...) => (!(0) | !(1) | !(b) | (!(1) === b) | FreeVar(isNaN)(b) | (FreeVar(isNaN)(b) || ???*0*)) +- *0* unsupported expression + ⚠️ This value might have side effects + +qb = ["Webkit", "ms", "Moz", "O"] + +qc = ???*0* +- *0* ???*1*["LN2"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *1* FreeVar(Math) + ⚠️ unknown global + ⚠️ This value might have side effects + +qd = (...) => !(1) + +qe = (null | ???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +qf = (...) => undefined + +qg = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +qh = (...) => undefined + +qi = (...) => [b["memoizedState"], a] + +qj = (...) => a + +qk = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ql = (...) => undefined + +r#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +r#431 = (...) => ( + | ((null !== e) ? null : h(a, b, c, d)) + | ((c["key"] === e) ? k(a, b, c, d) : null) + | ((c["key"] === e) ? l(a, b, c, d) : null) + | ???*0* + | ((null !== e) ? null : m(a, b, c, d, null)) + | null +) +- *0* r(a, b, e(c["_payload"]), d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +r#601 = ???*0* +- *0* ???*1*["memoizedState"] + ⚠️ unknown object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +r#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +r#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +r#778 = ???*0* +- *0* r + ⚠️ pattern without value + +r#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +r#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ra = /[\-:]([a-z])/g + +rb = (...) => (((null == b) || ("boolean" === typeof(b)) || ("" === b)) ? "" : ((c || ("number" !== typeof(b)) || (0 === b) || (pb["hasOwnProperty"](a) && pb[a])) ? b["trim"]() : `${b}px`)) + +rc = (64 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +rd = (...) => b + +re = (...) => undefined + +rf = `_reactListening${???*0*}` +- *0* ???*1*["slice"](2) + ⚠️ unknown callee object +- *1* ???*2*(36) + ⚠️ unknown callee +- *2* ???*3*["toString"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +rg = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +rh = (...) => undefined + +ri = (...) => (undefined | FreeVar(undefined)) + +rj = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +rk = (0 | ???*0* | ???*1*) +- *0* unsupported assign operation + ⚠️ This value might have side effects +- *1* unsupported expression + ⚠️ This value might have side effects + +rl = (...) => (g | k) + +sa = (...) => a[1]["toUpperCase"]() + +sb = (...) => undefined + +sc = (4194304 | ???*0*) +- *0* unsupported assign operation + ⚠️ This value might have side effects + +sd = { + "eventPhase": 0, + "bubbles": 0, + "cancelable": 0, + "timeStamp": (...) => (a["timeStamp"] || FreeVar(Date)["now"]()), + "defaultPrevented": 0, + "isTrusted": 0 +} + +se = (...) => undefined + +sf = (...) => undefined + +sg = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +sh = (...) => (b["ref"] | b | a) + +si = (...) => di()["memoizedState"] + +sj = (...) => (???*0* | f | tj(a, b, g, null) | tj(a, b, g, d) | b) +- *0* tj(a, b, g, d) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +sk = (0 | ???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* unsupported assign operation + ⚠️ This value might have side effects + +sl = (...) => hl(g) + +t#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +t#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +t#431 = (...) => l + +t#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +t#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +t#724 = ???*0* +- *0* t + ⚠️ pattern without value + +t#726 = ???*0* +- *0* t + ⚠️ pattern without value + +t#729 = ???*0* +- *0* t + ⚠️ pattern without value + +t#733 = ???*0* +- *0* t + ⚠️ pattern without value + +t#736 = ???*0* +- *0* t + ⚠️ pattern without value + +t#738 = ???*0* +- *0* t + ⚠️ pattern without value + +t#744 = ???*0* +- *0* t + ⚠️ pattern without value + +t#750 = ???*0* +- *0* t + ⚠️ pattern without value + +t#753 = ???*0* +- *0* t + ⚠️ pattern without value + +t#843 = ???*0* +- *0* unknown new expression + ⚠️ This value might have side effects + +t#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ta = (...) => undefined + +tb = ???*0* +- *0* ???*1*( + {"menuitem": !(0)}, + { + "area": !(0), + "base": !(0), + "br": !(0), + "col": !(0), + "embed": !(0), + "hr": !(0), + "img": !(0), + "input": !(0), + "keygen": !(0), + "link": !(0), + "meta": !(0), + "param": !(0), + "source": !(0), + "track": !(0), + "wbr": !(0) + } + ) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +tc = (...) => (undefined | 1 | 2 | 4 | 8 | 16 | 32 | ???*0* | 134217728 | 268435456 | 536870912 | 1073741824 | a) +- *0* unsupported expression + ⚠️ This value might have side effects + +td = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +te = (...) => (undefined | a) + +tf = (...) => {"instance": a, "listener": b, "currentTarget": c} + +tg = (...) => undefined + +th = (...) => undefined + +ti = (...) => undefined + +tj = (...) => a + +tk = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +tl = { + "usingClientEntryPoint": false, + "Events": [ + (...) => (( + || !(a) + || ((5 !== a["tag"]) && (6 !== a["tag"]) && (13 !== a["tag"]) && (3 !== a["tag"])) + ) ? null : a), + (...) => (undefined | a["stateNode"]), + (...) => (a[Pf] || null), + (...) => undefined, + (...) => undefined, + (...) => (undefined | a(b)) + ] +} + +u#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +u#449 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +u#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +u#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +u#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +u#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ua = module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"] + +ub = (...) => undefined + +uc = (...) => (0 | b | d) + +ud = ???*0* +- *0* ???*1*({}, sd, {"view": 0, "detail": 0}) + ⚠️ unknown callee + ⚠️ This value might have side effects +- *1* ???*2*["assign"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *2* FreeVar(Object) + ⚠️ unknown global + ⚠️ This value might have side effects + +ue = (...) => (undefined | a["stateNode"]) + +uf = `__reactContainer$${???*0*}` +- *0* ???*1*["slice"](2) + ⚠️ unknown callee object +- *1* ???*2*(36) + ⚠️ unknown callee +- *2* ???*3*["toString"] + ⚠️ unknown object +- *3* ???*4*() + ⚠️ nested operation +- *4* ???["random"] + ⚠️ unknown object + ⚠️ This value might have side effects + +ug = (...) => undefined + +uh = (...) => b(a["_payload"]) + +ui = (...) => (undefined | FreeVar(undefined)) + +uj = (...) => undefined + +uk = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ul = { + "findFiberByHostInstance": (...) => (b | c | null), + "bundleType": 0, + "version": "18.2.0", + "rendererPackageName": "react-dom" +} + +v = (...) => undefined + +va = ???*0* +- *0* ???*1*["for"]("react.element") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +vb = (...) => (undefined | ("string" === typeof(b["is"])) | !(1) | !(0)) + +vc = (...) => (undefined | (b + 250) | (b + 5000) | ???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +vd = (...) => ???*0* +- *0* unsupported expression + ⚠️ This value might have side effects + +ve = (...) => (undefined | b) + +vf = (...) => (null | (a ? a : null)) + +vg = (...) => undefined + +vh = (...) => J + +vi = (...) => ti(8390656, 8, a, b) + +vj = (...) => undefined + +vk = null + +vl = { + "bundleType": (0 | ???*0*), + "version": ("18.2.0" | ???*1*), + "rendererPackageName": ("react-dom" | ???*2*), + "rendererConfig": (???*3* | ???*4*), + "overrideHookState": null, + "overrideHookStateDeletePath": null, + "overrideHookStateRenamePath": null, + "overrideProps": null, + "overridePropsDeletePath": null, + "overridePropsRenamePath": null, + "setErrorHandler": null, + "setSuspenseHandler": null, + "scheduleUpdate": null, + "currentDispatcherRef": module["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"]["ReactCurrentDispatcher"], + "findHostInstanceByFiber": (...) => ((null === a) ? null : a["stateNode"]), + "findFiberByHostInstance": ((...) => (b | c | null) | ???*5* | (...) => null), + "findHostInstancesForRefresh": null, + "scheduleRefresh": null, + "scheduleRoot": null, + "setRefreshHandler": null, + "getCurrentFiber": null, + "reconcilerVersion": "18.2.0-next-9e3b772b8-20220608" +} +- *0* unknown mutation + ⚠️ This value might have side effects +- *1* unknown mutation + ⚠️ This value might have side effects +- *2* unknown mutation + ⚠️ This value might have side effects +- *3* FreeVar(undefined) + ⚠️ unknown global + ⚠️ This value might have side effects +- *4* unknown mutation + ⚠️ This value might have side effects +- *5* unknown mutation + ⚠️ This value might have side effects + +w#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +w#449 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +w#454 = (???*0* | ???*1*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* updated with update expression + ⚠️ This value might have side effects + +w#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +w#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +w#883 = ((???*0* ? ???*1* : 1)["current"] | null["current"] | ???*6*) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* (???*2* ? ???*3* : 4) + ⚠️ nested operation +- *2* unsupported expression + ⚠️ This value might have side effects +- *3* (???*4* ? 16 : 536870912) + ⚠️ nested operation +- *4* (0 !== ???*5*) + ⚠️ nested operation +- *5* unsupported expression + ⚠️ This value might have side effects +- *6* ???*7*["current"] + ⚠️ unknown object +- *7* arguments[0] + ⚠️ function calls are not analysed yet + +wa = ???*0* +- *0* ???*1*["for"]("react.portal") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +wb = (null | ???*0*) +- *0* unknown new expression + ⚠️ This value might have side effects + +wc = (...) => undefined + +wd = (???*0* | ???*1* | 0) +- *0* wd + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +we = (false | ???*0* | ???*1* | ("function" === ???*2*) | !(???*6*)) +- *0* xe + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* typeof(???*3*) + ⚠️ nested operation +- *3* ???*4*["oninput"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects +- *6* ???*7*["documentMode"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *7* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +wf = (...) => undefined + +wg = (...) => undefined + +wh = (...) => c + +wi = (...) => ui(4, 2, a, b) + +wj = (...) => undefined + +wk = (false | true) + +wl = ???*0* +- *0* FreeVar(__REACT_DEVTOOLS_GLOBAL_HOOK__) + ⚠️ unknown global + ⚠️ This value might have side effects + +x#292 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x#449 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x#454 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +x#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +xa = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +xb = (...) => ((3 === a["nodeType"]) ? a["parentNode"] : a) + +xc = (...) => ((0 !== a) ? a : (???*0* ? 1073741824 : 0)) +- *0* unsupported expression + ⚠️ This value might have side effects + +xd = (???*0* | ???*1*) +- *0* xd + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects + +xe = (???*0* | ???*1* | ("function" === ???*2*) | false) +- *0* xe + ⚠️ pattern without value +- *1* unsupported expression + ⚠️ This value might have side effects +- *2* typeof(???*3*) + ⚠️ nested operation +- *3* ???*4*["oninput"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *4* ???*5*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *5* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +xf = /\r\n?/g + +xg = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +xh = (...) => a + +xi = (...) => ui(4, 4, a, b) + +xj = (...) => undefined + +xk = (null | ???*0* | ???*1*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet +- *1* ???*2*["value"] + ⚠️ unknown object +- *2* arguments[1] + ⚠️ function calls are not analysed yet + +y#404 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +y#431 = (...) => (???*0* | y(a, b, c, f(d["_payload"]), e) | null) +- *0* h(b, a, ("" + d), e) + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +y#601 = ???*0* +- *0* ???*1*["getDerivedStateFromProps"] + ⚠️ unknown object +- *1* arguments[2] + ⚠️ function calls are not analysed yet + +y#673 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +y#721 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +y#843 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +y#883 = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +ya = ???*0* +- *0* ???*1*["for"]("react.fragment") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +yb = (null | (...) => undefined) + +yc = (...) => a + +yd = (???*0* | ???*1*) +- *0* yd + ⚠️ pattern without value +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +ye = (???*0* | ("function" === ???*1*)) +- *0* unsupported expression + ⚠️ This value might have side effects +- *1* typeof(???*2*) + ⚠️ nested operation +- *2* ???*3*["oninput"] + ⚠️ unknown object + ⚠️ This value might have side effects +- *3* ???*4*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *4* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +yf = /\u0000|\uFFFD/g + +yg = ???*0* +- *0* max number of linking steps reached + ⚠️ This value might have side effects + +yh = (...) => (Ah(c["children"], e, f, b) | ???*0* | qj(c, e, f, b) | b) +- *0* a + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +yi = (...) => (undefined | ???*0*) +- *0* *anonymous function 69020* + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +yj = (...) => b["child"] + +yk = (0 | ???*0* | null["finishedLanes"]) +- *0* ???*1*["finishedLanes"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet + +z = {} + +za = ???*0* +- *0* ???*1*["for"]("react.strict_mode") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(Symbol) + ⚠️ unknown global + ⚠️ This value might have side effects + +zb = (null | ???*0*) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +zc = (...) => b + +zd = (...) => Pd + +ze = ???*0* +- *0* ???*1*["createElement"]("div") + ⚠️ unknown callee object + ⚠️ This value might have side effects +- *1* FreeVar(document) + ⚠️ unknown global + ⚠️ This value might have side effects + +zf = (...) => (("string" === typeof(a)) ? a : a)["replace"](xf, "\n")["replace"](yf, "") + +zg = (null | [???*0*]) +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +zh = (...) => b + +zi = (...) => ui(4, 4, yi["bind"](null, b, a), c) + +zj = (...) => (???*0* | pj(a, b, c) | ((null !== a) ? a["sibling"] : null) | yj(a, b, c) | null | $i(a, b, c)) +- *0* null + ⚠️ sequence with side effects + ⚠️ This value might have side effects + +zk = (0 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph-effects.snapshot new file mode 100644 index 0000000000000..f0b6438b9d9a6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph-effects.snapshot @@ -0,0 +1,614 @@ +[ + Member { + obj: MemberCall( + 3, + Variable( + ( + "r", + #3, + ), + ), + Constant( + Str( + Atom( + "keys", + ), + ), + ), + [], + ), + prop: Constant( + Str( + Atom( + "map", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 34..46#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "r", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "keys", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 34..40#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "r", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "keys", + ), + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Call, + ), + ], + span: 34..42#0, + in_try: false, + }, + MemberCall { + obj: MemberCall( + 3, + Variable( + ( + "r", + #3, + ), + ), + Constant( + Str( + Atom( + "keys", + ), + ), + ), + [], + ), + prop: Constant( + Str( + Atom( + "map", + ), + ), + ), + args: [ + Value( + Variable( + ( + "r", + #3, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Return, + ), + ReturnStmt( + Arg, + ), + Expr( + Call, + ), + ], + span: 34..49#0, + in_try: false, + }, + Member { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "context", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 70..85#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 70..77#1, + in_try: false, + }, + MemberCall { + obj: FreeVar( + "require", + ), + prop: Constant( + Str( + Atom( + "context", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "./test", + ), + ), + ), + ), + Value( + Constant( + False, + ), + ), + Value( + Constant( + Regex( + "\\.test\\.js$", + "", + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 70..117#0, + in_try: false, + }, + Call { + func: Variable( + ( + "importAll", + #2, + ), + ), + args: [ + Value( + Variable( + ( + "context", + #2, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 133..151#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "context", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 164..179#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "context", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "resolve", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "./a", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 3, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 164..186#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph-explained.snapshot new file mode 100644 index 0000000000000..48173a9ed48e1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph-explained.snapshot @@ -0,0 +1,9 @@ +a = context["resolve"]("./a") + +context = FreeVar(require)["context"]("./test", false, /\.test\.js$/) + +importAll = (...) => r["keys"]()["map"](r) + +items = importAll(context) + +r = arguments[0] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph.snapshot new file mode 100644 index 0000000000000..a775c4237bb41 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/graph.snapshot @@ -0,0 +1,133 @@ +[ + ( + "a", + MemberCall( + 4, + Variable( + ( + "context", + #2, + ), + ), + Constant( + Str( + Atom( + "resolve", + ), + ), + ), + [ + Constant( + Str( + Word( + "./a", + ), + ), + ), + ], + ), + ), + ( + "context", + MemberCall( + 6, + FreeVar( + "require", + ), + Constant( + Str( + Atom( + "context", + ), + ), + ), + [ + Constant( + Str( + Word( + "./test", + ), + ), + ), + Constant( + False, + ), + Constant( + Regex( + "\\.test\\.js$", + "", + ), + ), + ], + ), + ), + ( + "importAll", + Function( + 7, + 1, + MemberCall( + 6, + MemberCall( + 3, + Variable( + ( + "r", + #3, + ), + ), + Constant( + Str( + Atom( + "keys", + ), + ), + ), + [], + ), + Constant( + Str( + Atom( + "map", + ), + ), + ), + [ + Variable( + ( + "r", + #3, + ), + ), + ], + ), + ), + ), + ( + "items", + Call( + 3, + Variable( + ( + "importAll", + #2, + ), + ), + [ + Variable( + ( + "context", + #2, + ), + ), + ], + ), + ), + ( + "r", + Argument( + 1, + 0, + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/input.js new file mode 100644 index 0000000000000..1569104623852 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/input.js @@ -0,0 +1,8 @@ +function importAll(r) { + return r.keys().map(r); +} + +const context = require.context('./test', false, /\.test\.js$/); +const items = importAll(context); + +const a = context.resolve("./a"); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/resolved-effects.snapshot new file mode 100644 index 0000000000000..6474685303239 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/resolved-effects.snapshot @@ -0,0 +1,22 @@ +0 -> 3 member call = ???*0*["keys"]() +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 4 member call = ???*0*()["map"](???*2*) +- *0* ???*1*["keys"] + ⚠️ unknown object +- *1* arguments[0] + ⚠️ function calls are not analysed yet +- *2* arguments[0] + ⚠️ function calls are not analysed yet + +0 -> 6 free var = FreeVar(require) + +0 -> 7 member call = require*0*["context"]("./test", false, /\.test\.js$/) +- *0* require: The require method from CommonJS + +0 -> 8 call = (...) => r["keys"]()["map"](r)(require.context(...)*0*) +- *0* require.context(...): The require.context(...) method from webpack: https://webpack.js.org/api/module-methods/#requirecontext + +0 -> 10 member call = require.context(...)*0*["resolve"]("./a") +- *0* require.context(...): The require.context(...) method from webpack: https://webpack.js.org/api/module-methods/#requirecontext diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/resolved-explained.snapshot new file mode 100644 index 0000000000000..5d80894bf3efa --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/require-context/resolved-explained.snapshot @@ -0,0 +1,12 @@ +a = "[context: ./test]/a" + +context = require.context(...)*0* +- *0* require.context(...): The require.context(...) method from webpack: https://webpack.js.org/api/module-methods/#requirecontext + +importAll = (...) => r["keys"]()["map"](r) + +items = [module<[context: ./test]/a, {}>, module<[context: ./test]/b, {}>, module<[context: ./test]/c, {}>] + +r = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph-effects.snapshot new file mode 100644 index 0000000000000..fe51488c7066f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph-effects.snapshot @@ -0,0 +1 @@ +[] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph-explained.snapshot new file mode 100644 index 0000000000000..34548b5e96c1d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph-explained.snapshot @@ -0,0 +1,8 @@ +x = (1 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +y = ???*0* +- *0* 2 + ⚠️ sequence with side effects + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph.snapshot new file mode 100644 index 0000000000000..ee959590ae130 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/graph.snapshot @@ -0,0 +1,38 @@ +[ + ( + "x", + Alternatives( + 3, + [ + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + Unknown { + original_value: None, + reason: "updated with update expression", + has_side_effects: true, + }, + ], + ), + ), + ( + "y", + Unknown { + original_value: Some( + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + reason: "sequence with side effects", + has_side_effects: true, + }, + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/input.js new file mode 100644 index 0000000000000..e98df8ef9c0ed --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/input.js @@ -0,0 +1,2 @@ +let x = 1; +const y = (x++, 2); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/resolved-effects.snapshot new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/resolved-explained.snapshot new file mode 100644 index 0000000000000..34548b5e96c1d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/sequences/resolved-explained.snapshot @@ -0,0 +1,8 @@ +x = (1 | ???*0*) +- *0* updated with update expression + ⚠️ This value might have side effects + +y = ???*0* +- *0* 2 + ⚠️ sequence with side effects + ⚠️ This value might have side effects diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph-effects.snapshot new file mode 100644 index 0000000000000..21b1b5afe10ae --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph-effects.snapshot @@ -0,0 +1,302 @@ +[ + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 25..32#1, + in_try: true, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "packages/not-found", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Block, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 25..54#0, + in_try: true, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 78..85#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "packages/found", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Try, + ), + TryStmt( + Handler, + ), + CatchClause( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Call, + ), + ], + span: 78..103#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "pkg", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "fn", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 108..114#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "pkg", + #2, + ), + ), + prop: Constant( + Str( + Atom( + "fn", + ), + ), + ), + args: [], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 108..116#0, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph-explained.snapshot new file mode 100644 index 0000000000000..29b028e14f7fb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph-explained.snapshot @@ -0,0 +1,7 @@ +e = ???*0* +- *0* e + ⚠️ pattern without value + +pkg = (???*0* | FreeVar(require)("packages/not-found") | FreeVar(require)("packages/found")) +- *0* pkg + ⚠️ pattern without value diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph.snapshot new file mode 100644 index 0000000000000..73c67670ecfbb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/graph.snapshot @@ -0,0 +1,67 @@ +[ + ( + "e", + Unknown { + original_value: Some( + Variable( + ( + "e", + #4, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + ), + ( + "pkg", + Alternatives( + 8, + [ + Unknown { + original_value: Some( + Variable( + ( + "pkg", + #2, + ), + ), + ), + reason: "pattern without value", + has_side_effects: false, + }, + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "packages/not-found", + ), + ), + ), + ], + ), + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "packages/found", + ), + ), + ), + ], + ), + ], + ), + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/input.js new file mode 100644 index 0000000000000..22bce88ce1160 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/input.js @@ -0,0 +1,9 @@ +let pkg; + +try { + pkg = require("packages/not-found"); +} catch (e) { + pkg = require("packages/found"); +} + +pkg.fn(); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/resolved-effects.snapshot new file mode 100644 index 0000000000000..0b23c63359957 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/resolved-effects.snapshot @@ -0,0 +1,13 @@ +0 -> 1 free var = FreeVar(require) + +0 -> 2 call = require*0*("packages/not-found") +- *0* require: The require method from CommonJS + +0 -> 3 free var = FreeVar(require) + +0 -> 4 call = require*0*("packages/found") +- *0* require: The require method from CommonJS + +0 -> 6 member call = (???*0* | module | module)["fn"]() +- *0* pkg + ⚠️ pattern without value diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/resolved-explained.snapshot new file mode 100644 index 0000000000000..d3ce954449366 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/try/resolved-explained.snapshot @@ -0,0 +1,7 @@ +e = ???*0* +- *0* e + ⚠️ pattern without value + +pkg = (???*0* | module | module) +- *0* pkg + ⚠️ pattern without value diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph-effects.snapshot new file mode 100644 index 0000000000000..f7e6dde551beb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph-effects.snapshot @@ -0,0 +1,2756 @@ +[ + Member { + obj: Variable( + ( + "exports", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "id", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 46..56#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "exports", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "ids", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 66..77#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "exports", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "modules", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 89..104#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "__webpack_require__", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "r", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 259..280#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "__webpack_require__", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "r", + ), + ), + ), + args: [ + Value( + Variable( + ( + "__webpack_exports__", + #4, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 259..301#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "__webpack_require__", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "d", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 327..348#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "__webpack_require__", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "d", + ), + ), + ), + args: [ + Value( + Variable( + ( + "__webpack_exports__", + #4, + ), + ), + ), + Value( + Object { + total_nodes: 3, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "default", + ), + ), + ), + Variable( + ( + "*arrow function 389*", + #0, + ), + ), + ), + ], + mutable: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 327..426#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 515..522#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "fs/promises", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 2, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 515..537#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "promises_namespaceObject", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "readFile", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Await, + ), + AwaitExpr( + Arg, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Seq, + ), + SeqExpr( + Exprs( + 1, + ), + ), + Expr( + Member, + ), + ], + span: 828..861#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "promises_namespaceObject", + #4, + ), + ), + prop: Constant( + Str( + Atom( + "readFile", + ), + ), + ), + args: [ + Value( + Constant( + Str( + Word( + "./hello.txt", + ), + ), + ), + ), + Value( + Constant( + Str( + Word( + "utf-8", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 0, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Await, + ), + AwaitExpr( + Arg, + ), + Expr( + Call, + ), + ], + span: 824..916#0, + in_try: false, + }, + Member { + obj: MemberCall( + 4, + Variable( + ( + "res", + #5, + ), + ), + Constant( + Str( + Atom( + "status", + ), + ), + ), + [ + Constant( + Num( + ConstantNumber( + 200.0, + ), + ), + ), + ], + ), + prop: Constant( + Str( + Atom( + "json", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 965..985#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "res", + #5, + ), + ), + prop: Constant( + Str( + Atom( + "status", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 965..975#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "res", + #5, + ), + ), + prop: Constant( + Str( + Atom( + "status", + ), + ), + ), + args: [ + Value( + Constant( + Num( + ConstantNumber( + 200.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Call, + ), + ], + span: 965..980#0, + in_try: false, + }, + MemberCall { + obj: MemberCall( + 4, + Variable( + ( + "res", + #5, + ), + ), + Constant( + Str( + Atom( + "status", + ), + ), + ), + [ + Constant( + Num( + ConstantNumber( + 200.0, + ), + ), + ), + ], + ), + prop: Constant( + Str( + Atom( + "json", + ), + ), + ), + args: [ + Value( + Object { + total_nodes: 5, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "users", + ), + ), + ), + Variable( + ( + "users", + #4, + ), + ), + ), + KeyValue( + Constant( + Str( + Atom( + "hello", + ), + ), + ), + Variable( + ( + "hello", + #5, + ), + ), + ), + ], + mutable: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 3, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Right, + ), + Expr( + Object, + ), + ObjectLit( + Props( + 0, + ), + ), + PropOrSpread( + Prop, + ), + Prop( + KeyValue, + ), + KeyValueProp( + Value, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Fn, + ), + FnDecl( + Function, + ), + Function( + Body, + ), + BlockStmt( + Stmts( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 965..1032#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "require", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Ident, + ), + ], + span: 1113..1120#1, + in_try: false, + }, + Call { + func: FreeVar( + "require", + ), + args: [ + Value( + Constant( + Str( + Word( + "../../webpack-api-runtime.js", + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 4, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 1113..1152#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "__webpack_require__", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "C", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Member, + ), + ], + span: 1156..1177#0, + in_try: false, + }, + MemberCall { + obj: Variable( + ( + "__webpack_require__", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "C", + ), + ), + ), + args: [ + Value( + Variable( + ( + "exports", + #3, + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 5, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + ], + span: 1156..1186#0, + in_try: false, + }, + Member { + obj: Variable( + ( + "__webpack_require__", + #3, + ), + ), + prop: Constant( + Str( + Atom( + "s", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Args( + 0, + ), + ), + ExprOrSpread( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 1252..1273#0, + in_try: false, + }, + Call { + func: Variable( + ( + "__webpack_require__", + #3, + ), + ), + args: [ + Value( + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 6, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + Expr, + ), + Expr( + Call, + ), + ], + span: 1231..1286#0, + in_try: false, + }, + Call { + func: Variable( + ( + "__webpack_exec__", + #3, + ), + ), + args: [ + Value( + Constant( + Num( + ConstantNumber( + 5166.0, + ), + ), + ), + ), + ], + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 7, + ), + ), + Stmt( + Decl, + ), + Decl( + Var, + ), + VarDecl( + Decls( + 0, + ), + ), + VarDeclarator( + Init, + ), + Expr( + Call, + ), + ], + span: 1316..1338#0, + in_try: false, + }, + Member { + obj: FreeVar( + "module", + ), + prop: Constant( + Str( + Atom( + "exports", + ), + ), + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 8, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + ], + span: 1342..1356#0, + in_try: false, + }, + FreeVar { + var: FreeVar( + "module", + ), + ast_path: [ + Program( + Script, + ), + Script( + Body( + 1, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Call, + ), + CallExpr( + Callee, + ), + Callee( + Expr, + ), + Expr( + Paren, + ), + ParenExpr( + Expr, + ), + Expr( + Arrow, + ), + ArrowExpr( + Body, + ), + BlockStmtOrExpr( + BlockStmt, + ), + BlockStmt( + Stmts( + 8, + ), + ), + Stmt( + Expr, + ), + ExprStmt( + Expr, + ), + Expr( + Assign, + ), + AssignExpr( + Left, + ), + AssignTarget( + Simple, + ), + SimpleAssignTarget( + Member, + ), + MemberExpr( + Obj, + ), + Expr( + Ident, + ), + ], + span: 1342..1348#1, + in_try: false, + }, +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph-explained.snapshot new file mode 100644 index 0000000000000..836fc1c8e4127 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph-explained.snapshot @@ -0,0 +1,35 @@ +*arrow function 1213* = (...) => __webpack_require__(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +*arrow function 131* = (...) => undefined + +*arrow function 389* = (...) => handler + +__unused_webpack_module = arguments[0] + +__webpack_exec__ = *arrow function 1213* + +__webpack_exports__#3 = __webpack_exec__(5166) + +__webpack_exports__#4 = arguments[1] + +__webpack_require__#3 = FreeVar(require)("../../webpack-api-runtime.js") + +__webpack_require__#4 = arguments[2] + +_req = arguments[0] + +exports = {} + +handler = (...) => undefined + +hello = promises_namespaceObject["readFile"]("./hello.txt", "utf-8") + +moduleId = arguments[0] + +promises_namespaceObject = FreeVar(require)("fs/promises") + +res = arguments[1] + +users = [{"id": 1}, {"id": 2}, {"id": 3}] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph.snapshot new file mode 100644 index 0000000000000..f47d0e025751c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/graph.snapshot @@ -0,0 +1,284 @@ +[ + ( + "*arrow function 1213*", + Function( + 4, + 1213, + Call( + 3, + Variable( + ( + "__webpack_require__", + #3, + ), + ), + [ + Unknown { + original_value: None, + reason: "unsupported expression", + has_side_effects: true, + }, + ], + ), + ), + ), + ( + "*arrow function 131*", + Function( + 2, + 131, + Constant( + Undefined, + ), + ), + ), + ( + "*arrow function 389*", + Function( + 2, + 389, + Variable( + ( + "handler", + #4, + ), + ), + ), + ), + ( + "__unused_webpack_module", + Argument( + 131, + 0, + ), + ), + ( + "__webpack_exec__", + Variable( + ( + "*arrow function 1213*", + #0, + ), + ), + ), + ( + "__webpack_exports__#3", + Call( + 3, + Variable( + ( + "__webpack_exec__", + #3, + ), + ), + [ + Constant( + Num( + ConstantNumber( + 5166.0, + ), + ), + ), + ], + ), + ), + ( + "__webpack_exports__#4", + Argument( + 131, + 1, + ), + ), + ( + "__webpack_require__#3", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "../../webpack-api-runtime.js", + ), + ), + ), + ], + ), + ), + ( + "__webpack_require__#4", + Argument( + 131, + 2, + ), + ), + ( + "_req", + Argument( + 760, + 0, + ), + ), + ( + "exports", + Object { + total_nodes: 1, + parts: [], + mutable: true, + }, + ), + ( + "handler", + Function( + 2, + 760, + Constant( + Undefined, + ), + ), + ), + ( + "hello", + MemberCall( + 5, + Variable( + ( + "promises_namespaceObject", + #4, + ), + ), + Constant( + Str( + Atom( + "readFile", + ), + ), + ), + [ + Constant( + Str( + Word( + "./hello.txt", + ), + ), + ), + Constant( + Str( + Word( + "utf-8", + ), + ), + ), + ], + ), + ), + ( + "moduleId", + Argument( + 1213, + 0, + ), + ), + ( + "promises_namespaceObject", + Call( + 3, + FreeVar( + "require", + ), + [ + Constant( + Str( + Word( + "fs/promises", + ), + ), + ), + ], + ), + ), + ( + "res", + Argument( + 760, + 1, + ), + ), + ( + "users", + Array { + total_nodes: 10, + items: [ + Object { + total_nodes: 3, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "id", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 1.0, + ), + ), + ), + ), + ], + mutable: true, + }, + Object { + total_nodes: 3, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "id", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 2.0, + ), + ), + ), + ), + ], + mutable: true, + }, + Object { + total_nodes: 3, + parts: [ + KeyValue( + Constant( + Str( + Atom( + "id", + ), + ), + ), + Constant( + Num( + ConstantNumber( + 3.0, + ), + ), + ), + ), + ], + mutable: true, + }, + ], + mutable: true, + }, + ), +] diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/input.js b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/input.js new file mode 100644 index 0000000000000..836672779472d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/input.js @@ -0,0 +1,55 @@ +"use strict"; +(() => { + var exports = {}; + exports.id = 829; + exports.ids = [829]; + exports.modules = { + /***/ 5166: /***/ ( + __unused_webpack_module, + __webpack_exports__, + __webpack_require__ + ) => { + // ESM COMPAT FLAG + __webpack_require__.r(__webpack_exports__); + + // EXPORTS + __webpack_require__.d(__webpack_exports__, { + default: () => /* binding */ handler, + }); // CONCATENATED MODULE: external "fs/promises" + + const promises_namespaceObject = require("fs/promises"); // CONCATENATED MODULE: ./pages/api/users.ts + // Fake users data + const users = [ + { + id: 1, + }, + { + id: 2, + }, + { + id: 3, + }, + ]; + async function handler(_req, res) { + const hello = await (0, promises_namespaceObject.readFile)( + "./hello.txt", + "utf-8" + ); + // Get data from your database + res.status(200).json({ + users, + hello, + }); + } + + /***/ + }, + }; + // load runtime + var __webpack_require__ = require("../../webpack-api-runtime.js"); + __webpack_require__.C(exports); + var __webpack_exec__ = (moduleId) => + __webpack_require__((__webpack_require__.s = moduleId)); + var __webpack_exports__ = __webpack_exec__(5166); + module.exports = __webpack_exports__; +})(); diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/resolved-effects.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/resolved-effects.snapshot new file mode 100644 index 0000000000000..c7b2b99fdd454 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/resolved-effects.snapshot @@ -0,0 +1,50 @@ +0 -> 5 member call = ???*0*["r"](???*1*) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 7 member call = ???*0*["d"](???*1*, {"default": (...) => handler}) +- *0* arguments[2] + ⚠️ function calls are not analysed yet +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 8 free var = FreeVar(require) + +0 -> 9 call = require*0*("fs/promises") +- *0* require: The require method from CommonJS + +0 -> 11 member call = module["readFile"]("./hello.txt", "utf-8") + +0 -> 14 member call = ???*0*["status"](200) +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 15 member call = ???*0*["json"]( + { + "users": [{"id": 1}, {"id": 2}, {"id": 3}], + "hello": module["readFile"]("./hello.txt", "utf-8") + } +) +- *0* ???*1*["status"](200) + ⚠️ unknown callee object +- *1* arguments[1] + ⚠️ function calls are not analysed yet + +0 -> 16 free var = FreeVar(require) + +0 -> 17 call = require*0*("../../webpack-api-runtime.js") +- *0* require: The require method from CommonJS + +0 -> 19 member call = module<../../webpack-api-runtime.js, {}>["C"]({}) + +0 -> 21 call = module<../../webpack-api-runtime.js, {}>(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 22 call = (...) => __webpack_require__(???*0*)(5166) +- *0* unsupported expression + ⚠️ This value might have side effects + +0 -> 24 free var = FreeVar(module) diff --git a/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/resolved-explained.snapshot b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/resolved-explained.snapshot new file mode 100644 index 0000000000000..d9dae5649e4ff --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/analyzer/graph/webpack-target-node/resolved-explained.snapshot @@ -0,0 +1,51 @@ +*arrow function 1213* = (...) => __webpack_require__(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +*arrow function 131* = (...) => undefined + +*arrow function 389* = (...) => handler + +__unused_webpack_module = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +__webpack_exec__ = (...) => __webpack_require__(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +__webpack_exports__#3 = module<../../webpack-api-runtime.js, {}>(???*0*) +- *0* unsupported expression + ⚠️ This value might have side effects + +__webpack_exports__#4 = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +__webpack_require__#3 = module<../../webpack-api-runtime.js, {}> + +__webpack_require__#4 = ???*0* +- *0* arguments[2] + ⚠️ function calls are not analysed yet + +_req = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +exports = {} + +handler = (...) => undefined + +hello = module["readFile"]("./hello.txt", "utf-8") + +moduleId = ???*0* +- *0* arguments[0] + ⚠️ function calls are not analysed yet + +promises_namespaceObject = module + +res = ???*0* +- *0* arguments[1] + ⚠️ function calls are not analysed yet + +users = [{"id": 1}, {"id": 2}, {"id": 3}] diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/1/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/1/input.js new file mode 100644 index 0000000000000..573d14eb90927 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/1/input.js @@ -0,0 +1,18 @@ +import { upper } from "module"; +export let foobar = "foo"; +export const foo = foobar; +const bar = "bar"; +foobar += bar; +let foobarCopy = foobar; +foobar += "foo"; +console.log(foobarCopy); +foobarCopy += "Unused"; +function internal() { + return upper(foobar); +} +export function external1() { + return internal() + foobar; +} +export function external2() { + foobar += "."; +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/1/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/1/output.md new file mode 100644 index 0000000000000..812f1ef7c0759 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/1/output.md @@ -0,0 +1,1017 @@ +# Items + +Count: 18 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { upper } from "module"; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { upper } from "module"; + +``` + +- Hoisted +- Declares: `upper` + +## Item 3: Stmt 1, `VarDeclarator(0)` + +```js +export let foobar = "foo"; + +``` + +- Declares: `foobar` +- Write: `foobar` + +## Item 4: Stmt 2, `VarDeclarator(0)` + +```js +export const foo = foobar; + +``` + +- Declares: `foo` +- Reads: `foobar` +- Write: `foo` + +## Item 5: Stmt 3, `VarDeclarator(0)` + +```js +const bar = "bar"; + +``` + +- Declares: `bar` +- Write: `bar` + +## Item 6: Stmt 4, `Normal` + +```js +foobar += bar; + +``` + +- Reads: `bar`, `foobar` +- Write: `foobar` + +## Item 7: Stmt 5, `VarDeclarator(0)` + +```js +let foobarCopy = foobar; + +``` + +- Declares: `foobarCopy` +- Reads: `foobar` +- Write: `foobarCopy` + +## Item 8: Stmt 6, `Normal` + +```js +foobar += "foo"; + +``` + +- Reads: `foobar` +- Write: `foobar` + +## Item 9: Stmt 7, `Normal` + +```js +console.log(foobarCopy); + +``` + +- Side effects +- Reads: `foobarCopy` + +## Item 10: Stmt 8, `Normal` + +```js +foobarCopy += "Unused"; + +``` + +- Reads: `foobarCopy` +- Write: `foobarCopy` + +## Item 11: Stmt 9, `Normal` + +```js +function internal() { + return upper(foobar); +} + +``` + +- Hoisted +- Declares: `internal` +- Reads (eventual): `upper`, `foobar` +- Write: `internal` + +## Item 12: Stmt 10, `Normal` + +```js +export function external1() { + return internal() + foobar; +} + +``` + +- Hoisted +- Declares: `external1` +- Reads (eventual): `internal`, `foobar` +- Write: `external1` + +## Item 13: Stmt 11, `Normal` + +```js +export function external2() { + foobar += "."; +} + +``` + +- Hoisted +- Declares: `external2` +- Write: `external2` +- Write (eventual): `foobar` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export foobar"]; + Item16; + Item16["export foo"]; + Item17; + Item17["export external1"]; + Item18; + Item18["export external2"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export foobar"]; + Item16; + Item16["export foo"]; + Item17; + Item17["export external1"]; + Item18; + Item18["export external2"]; + Item4 --> Item3; + Item6 --> Item5; + Item6 --> Item3; + Item6 -.-> Item4; + Item7 --> Item6; + Item7 --> Item3; + Item8 --> Item6; + Item8 --> Item3; + Item8 -.-> Item4; + Item8 -.-> Item7; + Item9 --> Item7; + Item9 --> Item1; + Item9 -.-> Item2; + Item9 -.-> Item8; + Item9 -.-> Item4; + Item9 -.-> Item11; + Item10 --> Item7; + Item10 -.-> Item9; + Item15 --> Item8; + Item15 --> Item3; + Item16 --> Item4; + Item17 --> Item12; + Item18 --> Item13; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export foobar"]; + Item16; + Item16["export foo"]; + Item17; + Item17["export external1"]; + Item18; + Item18["export external2"]; + Item4 --> Item3; + Item6 --> Item5; + Item6 --> Item3; + Item6 -.-> Item4; + Item7 --> Item6; + Item7 --> Item3; + Item8 --> Item6; + Item8 --> Item3; + Item8 -.-> Item4; + Item8 -.-> Item7; + Item9 --> Item7; + Item9 --> Item1; + Item9 -.-> Item2; + Item9 -.-> Item8; + Item9 -.-> Item4; + Item9 -.-> Item11; + Item10 --> Item7; + Item10 -.-> Item9; + Item15 --> Item8; + Item15 --> Item3; + Item16 --> Item4; + Item17 --> Item12; + Item18 --> Item13; + Item11 --> Item2; + Item11 --> Item8; + Item11 --> Item3; + Item12 --> Item11; + Item12 --> Item8; + Item12 --> Item3; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item13 -.-> Item15; + Item13 --> Item3; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export foobar"]; + Item16; + Item16["export foo"]; + Item17; + Item17["export external1"]; + Item18; + Item18["export external2"]; + Item4 --> Item3; + Item6 --> Item5; + Item6 --> Item3; + Item6 -.-> Item4; + Item7 --> Item6; + Item7 --> Item3; + Item8 --> Item6; + Item8 --> Item3; + Item8 -.-> Item4; + Item8 -.-> Item7; + Item9 --> Item7; + Item9 --> Item1; + Item9 -.-> Item2; + Item9 -.-> Item8; + Item9 -.-> Item4; + Item9 -.-> Item11; + Item10 --> Item7; + Item10 -.-> Item9; + Item15 --> Item8; + Item15 --> Item3; + Item16 --> Item4; + Item17 --> Item12; + Item18 --> Item13; + Item11 --> Item2; + Item11 --> Item8; + Item11 --> Item3; + Item12 --> Item11; + Item12 --> Item8; + Item12 --> Item3; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item13 -.-> Item15; + Item13 --> Item3; + Item14 --> Item1; + Item14 --> Item9; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportBinding(0))]"]; + N1["Items: [ItemId(0, ImportOfModule)]"]; + N2["Items: [ItemId(3, VarDeclarator(0))]"]; + N3["Items: [ItemId(1, VarDeclarator(0))]"]; + N4["Items: [ItemId(2, VarDeclarator(0))]"]; + N5["Items: [ItemId(Export(("foo", #2), "foo"))]"]; + N6["Items: [ItemId(4, Normal)]"]; + N7["Items: [ItemId(5, VarDeclarator(0))]"]; + N8["Items: [ItemId(6, Normal)]"]; + N9["Items: [ItemId(9, Normal)]"]; + N10["Items: [ItemId(10, Normal)]"]; + N11["Items: [ItemId(Export(("external1", #2), "external1"))]"]; + N12["Items: [ItemId(Export(("foobar", #2), "foobar"))]"]; + N13["Items: [ItemId(11, Normal)]"]; + N14["Items: [ItemId(Export(("external2", #2), "external2"))]"]; + N15["Items: [ItemId(7, Normal)]"]; + N16["Items: [ItemId(ModuleEvaluation)]"]; + N17["Items: [ItemId(8, Normal)]"]; + N4 --> N3; + N6 --> N2; + N6 --> N3; + N6 -.-> N4; + N7 --> N6; + N7 --> N3; + N8 --> N6; + N8 --> N3; + N8 -.-> N4; + N8 -.-> N7; + N15 --> N7; + N15 --> N1; + N15 -.-> N0; + N15 -.-> N8; + N15 -.-> N4; + N15 -.-> N9; + N17 --> N7; + N17 -.-> N15; + N12 --> N8; + N12 --> N3; + N5 --> N4; + N11 --> N10; + N14 --> N13; + N9 --> N0; + N9 --> N8; + N9 --> N3; + N10 --> N9; + N10 --> N8; + N10 --> N3; + N13 -.-> N4; + N13 -.-> N7; + N13 -.-> N12; + N13 --> N3; + N16 --> N1; + N16 --> N15; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 16, + Export( + "external1", + ): 11, + Exports: 18, + Export( + "foo", + ): 5, + Export( + "foobar", + ): 12, + Export( + "external2", + ): 14, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { upper } from "module"; +export { upper } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "module"; + +``` +## Part 2 +```js +const bar = "bar"; +export { bar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +let foobar = "foo"; +export { foobar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const foo = foobar; +export { foo } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { foo }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { bar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +foobar += bar; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +let foobarCopy = foobar; +export { foobarCopy } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +foobar += "foo"; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { upper } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function internal() { + return upper(foobar); +} +export { internal } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { internal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +function external1() { + return internal() + foobar; +} +export { external1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { external1 }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { foobar }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +function external2() { + foobar += "."; +} +export { external2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { external2 }; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +console.log(foobarCopy); + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +"module evaluation"; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +foobarCopy += "Unused"; + +``` +## Part 18 +```js +export { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foo" +}; +export { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external1" +}; +export { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foobar" +}; +export { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external2" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 15, + Export( + "external1", + ): 11, + Exports: 18, + Export( + "foo", + ): 17, + Export( + "foobar", + ): 8, + Export( + "external2", + ): 5, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { upper } from "module"; +export { upper } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "module"; + +``` +## Part 2 +```js +const bar = "bar"; +export { bar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +let foobar = "foo"; +export { foobar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +function external2() { + foobar += "."; +} +export { external2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { external2 }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { bar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +foobar += bar; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +foobar += "foo"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { foobar }; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { upper } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function internal() { + return upper(foobar); +} +export { internal } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { internal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +function external1() { + return internal() + foobar; +} +export { external1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { external1 }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +let foobarCopy = foobar; +export { foobarCopy } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +foobarCopy += "Unused"; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +console.log(foobarCopy); + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const foo = foobar; +export { foo } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { foo }; + +``` +## Part 18 +```js +export { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external2" +}; +export { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foobar" +}; +export { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external1" +}; +export { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foo" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/2/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/2/input.js new file mode 100644 index 0000000000000..bb2d024d08d44 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/2/input.js @@ -0,0 +1,19 @@ +export function external1() { + return internal() + foobar; +} +import { upper } from "module"; +export let foobar = "foo"; +export const foo = foobar; +const bar = "bar"; +foobar += bar; +let foobarCopy = foobar; +foobar += "foo"; +console.log(foobarCopy); +foobarCopy += "Unused"; +function internal() { + return upper(foobar); +} +export function external2() { + foobar += "."; +} +import "other"; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/2/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/2/output.md new file mode 100644 index 0000000000000..a8a32cb90bbd2 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/2/output.md @@ -0,0 +1,1077 @@ +# Items + +Count: 19 + +## Item 1: Stmt 0, `Normal` + +```js +export function external1() { + return internal() + foobar; +} + +``` + +- Hoisted +- Declares: `external1` +- Reads (eventual): `internal`, `foobar` +- Write: `external1` + +## Item 2: Stmt 1, `ImportOfModule` + +```js +import { upper } from "module"; + +``` + +- Hoisted +- Side effects + +## Item 3: Stmt 1, `ImportBinding(0)` + +```js +import { upper } from "module"; + +``` + +- Hoisted +- Declares: `upper` + +## Item 4: Stmt 2, `VarDeclarator(0)` + +```js +export let foobar = "foo"; + +``` + +- Declares: `foobar` +- Write: `foobar` + +## Item 5: Stmt 3, `VarDeclarator(0)` + +```js +export const foo = foobar; + +``` + +- Declares: `foo` +- Reads: `foobar` +- Write: `foo` + +## Item 6: Stmt 4, `VarDeclarator(0)` + +```js +const bar = "bar"; + +``` + +- Declares: `bar` +- Write: `bar` + +## Item 7: Stmt 5, `Normal` + +```js +foobar += bar; + +``` + +- Reads: `bar`, `foobar` +- Write: `foobar` + +## Item 8: Stmt 6, `VarDeclarator(0)` + +```js +let foobarCopy = foobar; + +``` + +- Declares: `foobarCopy` +- Reads: `foobar` +- Write: `foobarCopy` + +## Item 9: Stmt 7, `Normal` + +```js +foobar += "foo"; + +``` + +- Reads: `foobar` +- Write: `foobar` + +## Item 10: Stmt 8, `Normal` + +```js +console.log(foobarCopy); + +``` + +- Side effects +- Reads: `foobarCopy` + +## Item 11: Stmt 9, `Normal` + +```js +foobarCopy += "Unused"; + +``` + +- Reads: `foobarCopy` +- Write: `foobarCopy` + +## Item 12: Stmt 10, `Normal` + +```js +function internal() { + return upper(foobar); +} + +``` + +- Hoisted +- Declares: `internal` +- Reads (eventual): `upper`, `foobar` +- Write: `internal` + +## Item 13: Stmt 11, `Normal` + +```js +export function external2() { + foobar += "."; +} + +``` + +- Hoisted +- Declares: `external2` +- Write: `external2` +- Write (eventual): `foobar` + +## Item 14: Stmt 12, `ImportOfModule` + +```js +import "other"; + +``` + +- Hoisted +- Side effects + +# Phase 1 +```mermaid +graph TD + Item3; + Item1; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item2; + Item15; + Item15["ModuleEvaluation"]; + Item16; + Item16["export external1"]; + Item17; + Item17["export foobar"]; + Item18; + Item18["export foo"]; + Item19; + Item19["export external2"]; + Item2 --> Item1; +``` +# Phase 2 +```mermaid +graph TD + Item3; + Item1; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item2; + Item15; + Item15["ModuleEvaluation"]; + Item16; + Item16["export external1"]; + Item17; + Item17["export foobar"]; + Item18; + Item18["export foo"]; + Item19; + Item19["export external2"]; + Item2 --> Item1; + Item6 --> Item5; + Item8 --> Item7; + Item8 --> Item5; + Item8 -.-> Item6; + Item9 --> Item8; + Item9 --> Item5; + Item10 --> Item8; + Item10 --> Item5; + Item10 -.-> Item6; + Item10 -.-> Item9; + Item11 --> Item9; + Item11 --> Item1; + Item11 --> Item2; + Item11 -.-> Item13; + Item11 -.-> Item10; + Item11 -.-> Item6; + Item11 -.-> Item4; + Item12 --> Item9; + Item12 -.-> Item11; + Item16 --> Item3; + Item17 --> Item10; + Item17 --> Item5; + Item18 --> Item6; + Item19 --> Item14; +``` +# Phase 3 +```mermaid +graph TD + Item3; + Item1; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item2; + Item15; + Item15["ModuleEvaluation"]; + Item16; + Item16["export external1"]; + Item17; + Item17["export foobar"]; + Item18; + Item18["export foo"]; + Item19; + Item19["export external2"]; + Item2 --> Item1; + Item6 --> Item5; + Item8 --> Item7; + Item8 --> Item5; + Item8 -.-> Item6; + Item9 --> Item8; + Item9 --> Item5; + Item10 --> Item8; + Item10 --> Item5; + Item10 -.-> Item6; + Item10 -.-> Item9; + Item11 --> Item9; + Item11 --> Item1; + Item11 --> Item2; + Item11 -.-> Item13; + Item11 -.-> Item10; + Item11 -.-> Item6; + Item11 -.-> Item4; + Item12 --> Item9; + Item12 -.-> Item11; + Item16 --> Item3; + Item17 --> Item10; + Item17 --> Item5; + Item18 --> Item6; + Item19 --> Item14; + Item3 --> Item13; + Item3 --> Item10; + Item3 --> Item5; + Item13 --> Item4; + Item13 --> Item10; + Item13 --> Item5; + Item14 -.-> Item6; + Item14 -.-> Item9; + Item14 -.-> Item17; + Item14 --> Item5; +``` +# Phase 4 +```mermaid +graph TD + Item3; + Item1; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item2; + Item15; + Item15["ModuleEvaluation"]; + Item16; + Item16["export external1"]; + Item17; + Item17["export foobar"]; + Item18; + Item18["export foo"]; + Item19; + Item19["export external2"]; + Item2 --> Item1; + Item6 --> Item5; + Item8 --> Item7; + Item8 --> Item5; + Item8 -.-> Item6; + Item9 --> Item8; + Item9 --> Item5; + Item10 --> Item8; + Item10 --> Item5; + Item10 -.-> Item6; + Item10 -.-> Item9; + Item11 --> Item9; + Item11 --> Item1; + Item11 --> Item2; + Item11 -.-> Item13; + Item11 -.-> Item10; + Item11 -.-> Item6; + Item11 -.-> Item4; + Item12 --> Item9; + Item12 -.-> Item11; + Item16 --> Item3; + Item17 --> Item10; + Item17 --> Item5; + Item18 --> Item6; + Item19 --> Item14; + Item3 --> Item13; + Item3 --> Item10; + Item3 --> Item5; + Item13 --> Item4; + Item13 --> Item10; + Item13 --> Item5; + Item14 -.-> Item6; + Item14 -.-> Item9; + Item14 -.-> Item17; + Item14 --> Item5; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item11; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, ImportBinding(0))]"]; + N1["Items: [ItemId(4, VarDeclarator(0))]"]; + N2["Items: [ItemId(2, VarDeclarator(0))]"]; + N3["Items: [ItemId(3, VarDeclarator(0))]"]; + N4["Items: [ItemId(Export(("foo", #2), "foo"))]"]; + N5["Items: [ItemId(5, Normal)]"]; + N6["Items: [ItemId(6, VarDeclarator(0))]"]; + N7["Items: [ItemId(7, Normal)]"]; + N8["Items: [ItemId(10, Normal)]"]; + N9["Items: [ItemId(0, Normal)]"]; + N10["Items: [ItemId(Export(("external1", #2), "external1"))]"]; + N11["Items: [ItemId(Export(("foobar", #2), "foobar"))]"]; + N12["Items: [ItemId(11, Normal)]"]; + N13["Items: [ItemId(Export(("external2", #2), "external2"))]"]; + N14["Items: [ItemId(1, ImportOfModule)]"]; + N15["Items: [ItemId(12, ImportOfModule)]"]; + N16["Items: [ItemId(8, Normal)]"]; + N17["Items: [ItemId(ModuleEvaluation)]"]; + N18["Items: [ItemId(9, Normal)]"]; + N15 --> N14; + N3 --> N2; + N5 --> N1; + N5 --> N2; + N5 -.-> N3; + N6 --> N5; + N6 --> N2; + N7 --> N5; + N7 --> N2; + N7 -.-> N3; + N7 -.-> N6; + N16 --> N6; + N16 --> N14; + N16 --> N15; + N16 -.-> N8; + N16 -.-> N7; + N16 -.-> N3; + N16 -.-> N0; + N18 --> N6; + N18 -.-> N16; + N10 --> N9; + N11 --> N7; + N11 --> N2; + N4 --> N3; + N13 --> N12; + N9 --> N8; + N9 --> N7; + N9 --> N2; + N8 --> N0; + N8 --> N7; + N8 --> N2; + N12 -.-> N3; + N12 -.-> N6; + N12 -.-> N11; + N12 --> N2; + N17 --> N14; + N17 --> N15; + N17 --> N16; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 17, + Export( + "external1", + ): 10, + Exports: 19, + Export( + "foo", + ): 4, + Export( + "foobar", + ): 11, + Export( + "external2", + ): 13, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { upper } from "module"; +export { upper } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +const bar = "bar"; +export { bar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +let foobar = "foo"; +export { foobar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +const foo = foobar; +export { foo } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { foo }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { bar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +foobar += bar; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +let foobarCopy = foobar; +export { foobarCopy } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +foobar += "foo"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { upper } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function internal() { + return upper(foobar); +} +export { internal } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { internal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +function external1() { + return internal() + foobar; +} +export { external1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +export { external1 }; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { foobar }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function external2() { + foobar += "."; +} +export { external2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { external2 }; + +``` +## Part 14 +```js +import "module"; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "other"; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +console.log(foobarCopy); + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +"module evaluation"; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +foobarCopy += "Unused"; + +``` +## Part 19 +```js +export { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foo" +}; +export { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external1" +}; +export { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foobar" +}; +export { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external2" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 18, + Export( + "external1", + ): 10, + Exports: 19, + Export( + "foo", + ): 14, + Export( + "foobar", + ): 7, + Export( + "external2", + ): 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { upper } from "module"; +export { upper } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +const bar = "bar"; +export { bar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +let foobar = "foo"; +export { foobar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function external2() { + foobar += "."; +} +export { external2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { external2 }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { bar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +foobar += bar; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +foobar += "foo"; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { foobar }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { upper } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function internal() { + return upper(foobar); +} +export { internal } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { internal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +function external1() { + return internal() + foobar; +} +export { external1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +export { external1 }; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +let foobarCopy = foobar; +export { foobarCopy } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +foobarCopy += "Unused"; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +const foo = foobar; +export { foo } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { foo }; + +``` +## Part 15 +```js +import "module"; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "other"; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +console.log(foobarCopy); + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +"module evaluation"; + +``` +## Part 19 +```js +export { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external2" +}; +export { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foobar" +}; +export { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external1" +}; +export { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foo" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/config.json b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/config.json new file mode 100644 index 0000000000000..ca4995f8a4a3c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/config.json @@ -0,0 +1,6 @@ +{ + "exports":[ + ["c1_3"], + ["c1_3", "c2_2"] + ] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/input.js new file mode 100644 index 0000000000000..ac8511ed5874e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/input.js @@ -0,0 +1,38 @@ + + +function d1() { } + + +function d2() { } + +function d3() { } + + + + +export function c1_1() { + return c1_2() +} + +function c1_2() { + return c1_3(d1) +} +export function c1_3() { + return c1_1(d2) +} + + +function c2_1() { + return c2_2(d3) +} + +export function c2_2() { + return c2_3() +} +function c2_3() { + return c2_1() +} + + +c1_3() +c2_2() \ No newline at end of file diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/output.md new file mode 100644 index 0000000000000..87f30191cdae3 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/3/output.md @@ -0,0 +1,847 @@ +# Items + +Count: 15 + +## Item 1: Stmt 0, `Normal` + +```js +function d1() {} + +``` + +- Hoisted +- Declares: `d1` +- Write: `d1` + +## Item 2: Stmt 1, `Normal` + +```js +function d2() {} + +``` + +- Hoisted +- Declares: `d2` +- Write: `d2` + +## Item 3: Stmt 2, `Normal` + +```js +function d3() {} + +``` + +- Hoisted +- Declares: `d3` +- Write: `d3` + +## Item 4: Stmt 3, `Normal` + +```js +export function c1_1() { + return c1_2(); +} + +``` + +- Hoisted +- Declares: `c1_1` +- Reads (eventual): `c1_2` +- Write: `c1_1` + +## Item 5: Stmt 4, `Normal` + +```js +function c1_2() { + return c1_3(d1); +} + +``` + +- Hoisted +- Declares: `c1_2` +- Reads (eventual): `c1_3`, `d1` +- Write: `c1_2` + +## Item 6: Stmt 5, `Normal` + +```js +export function c1_3() { + return c1_1(d2); +} + +``` + +- Hoisted +- Declares: `c1_3` +- Reads (eventual): `c1_1`, `d2` +- Write: `c1_3` + +## Item 7: Stmt 6, `Normal` + +```js +function c2_1() { + return c2_2(d3); +} + +``` + +- Hoisted +- Declares: `c2_1` +- Reads (eventual): `c2_2`, `d3` +- Write: `c2_1` + +## Item 8: Stmt 7, `Normal` + +```js +export function c2_2() { + return c2_3(); +} + +``` + +- Hoisted +- Declares: `c2_2` +- Reads (eventual): `c2_3` +- Write: `c2_2` + +## Item 9: Stmt 8, `Normal` + +```js +function c2_3() { + return c2_1(); +} + +``` + +- Hoisted +- Declares: `c2_3` +- Reads (eventual): `c2_1` +- Write: `c2_3` + +## Item 10: Stmt 9, `Normal` + +```js +c1_3(); + +``` + +- Side effects +- Reads: `c1_3` + +## Item 11: Stmt 10, `Normal` + +```js +c2_2(); + +``` + +- Side effects +- Reads: `c2_2` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item12["ModuleEvaluation"]; + Item13; + Item13["export c1_1"]; + Item14; + Item14["export c1_3"]; + Item15; + Item15["export c2_2"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item12["ModuleEvaluation"]; + Item13; + Item13["export c1_1"]; + Item14; + Item14["export c1_3"]; + Item15; + Item15["export c2_2"]; + Item10 --> Item6; + Item10 -.-> Item5; + Item10 -.-> Item1; + Item10 -.-> Item4; + Item10 -.-> Item2; + Item10 -.-> Item8; + Item10 -.-> Item3; + Item10 -.-> Item9; + Item10 -.-> Item7; + Item11 --> Item8; + Item11 --> Item10; + Item11 -.-> Item5; + Item11 -.-> Item6; + Item11 -.-> Item1; + Item11 -.-> Item4; + Item11 -.-> Item2; + Item11 -.-> Item3; + Item11 -.-> Item9; + Item11 -.-> Item7; + Item13 --> Item4; + Item14 --> Item6; + Item15 --> Item8; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item12["ModuleEvaluation"]; + Item13; + Item13["export c1_1"]; + Item14; + Item14["export c1_3"]; + Item15; + Item15["export c2_2"]; + Item10 --> Item6; + Item10 -.-> Item5; + Item10 -.-> Item1; + Item10 -.-> Item4; + Item10 -.-> Item2; + Item10 -.-> Item8; + Item10 -.-> Item3; + Item10 -.-> Item9; + Item10 -.-> Item7; + Item11 --> Item8; + Item11 --> Item10; + Item11 -.-> Item5; + Item11 -.-> Item6; + Item11 -.-> Item1; + Item11 -.-> Item4; + Item11 -.-> Item2; + Item11 -.-> Item3; + Item11 -.-> Item9; + Item11 -.-> Item7; + Item13 --> Item4; + Item14 --> Item6; + Item15 --> Item8; + Item4 --> Item5; + Item5 --> Item6; + Item5 --> Item1; + Item6 --> Item4; + Item6 --> Item2; + Item7 --> Item8; + Item7 --> Item3; + Item8 --> Item9; + Item9 --> Item7; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item12["ModuleEvaluation"]; + Item13; + Item13["export c1_1"]; + Item14; + Item14["export c1_3"]; + Item15; + Item15["export c2_2"]; + Item10 --> Item6; + Item10 -.-> Item5; + Item10 -.-> Item1; + Item10 -.-> Item4; + Item10 -.-> Item2; + Item10 -.-> Item8; + Item10 -.-> Item3; + Item10 -.-> Item9; + Item10 -.-> Item7; + Item11 --> Item8; + Item11 --> Item10; + Item11 -.-> Item5; + Item11 -.-> Item6; + Item11 -.-> Item1; + Item11 -.-> Item4; + Item11 -.-> Item2; + Item11 -.-> Item3; + Item11 -.-> Item9; + Item11 -.-> Item7; + Item13 --> Item4; + Item14 --> Item6; + Item15 --> Item8; + Item4 --> Item5; + Item5 --> Item6; + Item5 --> Item1; + Item6 --> Item4; + Item6 --> Item2; + Item7 --> Item8; + Item7 --> Item3; + Item8 --> Item9; + Item9 --> Item7; + Item12 --> Item10; + Item12 --> Item11; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(2, Normal)]"]; + N1["Items: [ItemId(6, Normal), ItemId(7, Normal), ItemId(8, Normal)]"]; + N2["Items: [ItemId(Export(("c2_2", #2), "c2_2"))]"]; + N3["Items: [ItemId(1, Normal)]"]; + N4["Items: [ItemId(0, Normal)]"]; + N5["Items: [ItemId(3, Normal), ItemId(4, Normal), ItemId(5, Normal)]"]; + N6["Items: [ItemId(Export(("c1_1", #2), "c1_1"))]"]; + N7["Items: [ItemId(Export(("c1_3", #2), "c1_3"))]"]; + N8["Items: [ItemId(9, Normal)]"]; + N9["Items: [ItemId(10, Normal)]"]; + N10["Items: [ItemId(ModuleEvaluation)]"]; + N8 -.-> N5; + N8 -.-> N4; + N8 -.-> N3; + N8 -.-> N1; + N8 -.-> N0; + N9 -.-> N1; + N9 --> N8; + N9 -.-> N5; + N9 -.-> N4; + N9 -.-> N3; + N9 -.-> N0; + N6 --> N5; + N7 --> N5; + N2 --> N1; + N5 --> N5; + N5 --> N4; + N5 --> N3; + N1 --> N1; + N1 --> N0; + N10 --> N8; + N10 --> N9; +``` +# Entrypoints + +``` +{ + Export( + "c2_2", + ): 2, + Export( + "c1_1", + ): 6, + Export( + "c1_3", + ): 7, + ModuleEvaluation: 10, + Exports: 11, +} +``` + + +# Modules (dev) +## Part 0 +```js +function d3() {} +export { d3 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { d3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function c2_1() { + return c2_2(d3); +} +function c2_2() { + return c2_3(); +} +function c2_3() { + return c2_1(); +} +export { c2_1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { c2_2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { c2_3 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { c2_2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +export { c2_2 }; + +``` +## Part 3 +```js +function d2() {} +export { d2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +function d1() {} +export { d1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { d2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { d1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +function c1_1() { + return c1_2(); +} +function c1_2() { + return c1_3(d1); +} +function c1_3() { + return c1_1(d2); +} +export { c1_1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { c1_2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { c1_3 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { c1_1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { c1_1 }; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { c1_3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { c1_3 }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { c1_3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +c1_3(); + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { c2_2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +c2_2(); + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +"module evaluation"; + +``` +## Part 11 +```js +export { c2_2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export c2_2" +}; +export { c1_1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export c1_1" +}; +export { c1_3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export c1_3" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "c2_2", + ): 2, + Export( + "c1_1", + ): 6, + Export( + "c1_3", + ): 7, + ModuleEvaluation: 10, + Exports: 11, +} +``` + + +# Modules (prod) +## Part 0 +```js +function d3() {} +export { d3 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { d3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function c2_1() { + return c2_2(d3); +} +function c2_2() { + return c2_3(); +} +function c2_3() { + return c2_1(); +} +export { c2_1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { c2_2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { c2_3 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { c2_2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +export { c2_2 }; + +``` +## Part 3 +```js +function d2() {} +export { d2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +function d1() {} +export { d1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { d2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { d1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +function c1_1() { + return c1_2(); +} +function c1_2() { + return c1_3(d1); +} +function c1_3() { + return c1_1(d2); +} +export { c1_1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { c1_2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { c1_3 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { c1_1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { c1_1 }; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { c1_3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { c1_3 }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { c1_3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +c1_3(); + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { c2_2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +c2_2(); + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 11 +```js +export { c2_2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export c2_2" +}; +export { c1_1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export c1_1" +}; +export { c1_3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export c1_3" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "c2_2", + ): 2, + Export( + "c1_1", + ): 6, + Export( + "c1_3", + ): 7, + ModuleEvaluation: 10, + Exports: 11, +} +``` + + +## Merged (c1_3) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { c1_3 }; + +``` +# Entrypoints + +``` +{ + Export( + "c2_2", + ): 2, + Export( + "c1_1", + ): 6, + Export( + "c1_3", + ): 7, + ModuleEvaluation: 10, + Exports: 11, +} +``` + + +## Merged (c1_3,c2_2) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +export { c1_3 }; +export { c2_2 }; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/amphtml-document/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/amphtml-document/input.js new file mode 100644 index 0000000000000..fd849eeea7373 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/amphtml-document/input.js @@ -0,0 +1,34 @@ +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; +import Document, { Html, Head, Main, NextScript } from 'next/document'; +class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx); + return { + ...initialProps, + styles: _jsxs(_Fragment, { + children: [ + initialProps.styles, + _jsx("style", { + dangerouslySetInnerHTML: { + __html: `html { background: hotpink; }` + } + }) + ] + }) + }; + } + render() { + return _jsxs(Html, { + children: [ + _jsx(Head, {}), + _jsxs("body", { + children: [ + _jsx(Main, {}), + _jsx(NextScript, {}) + ] + }) + ] + }); + } +} +export default MyDocument; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/amphtml-document/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/amphtml-document/output.md new file mode 100644 index 0000000000000..41eef0a2bed87 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/amphtml-document/output.md @@ -0,0 +1,800 @@ +# Items + +Count: 14 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; + +``` + +- Hoisted +- Declares: `_jsx` + +## Item 3: Stmt 0, `ImportBinding(1)` + +```js +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; + +``` + +- Hoisted +- Declares: `_jsxs` + +## Item 4: Stmt 0, `ImportBinding(2)` + +```js +import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; + +``` + +- Hoisted +- Declares: `_Fragment` + +## Item 5: Stmt 1, `ImportOfModule` + +```js +import Document, { Html, Head, Main, NextScript } from 'next/document'; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 1, `ImportBinding(0)` + +```js +import Document, { Html, Head, Main, NextScript } from 'next/document'; + +``` + +- Hoisted +- Declares: `Document` + +## Item 7: Stmt 1, `ImportBinding(1)` + +```js +import Document, { Html, Head, Main, NextScript } from 'next/document'; + +``` + +- Hoisted +- Declares: `Html` + +## Item 8: Stmt 1, `ImportBinding(2)` + +```js +import Document, { Html, Head, Main, NextScript } from 'next/document'; + +``` + +- Hoisted +- Declares: `Head` + +## Item 9: Stmt 1, `ImportBinding(3)` + +```js +import Document, { Html, Head, Main, NextScript } from 'next/document'; + +``` + +- Hoisted +- Declares: `Main` + +## Item 10: Stmt 1, `ImportBinding(4)` + +```js +import Document, { Html, Head, Main, NextScript } from 'next/document'; + +``` + +- Hoisted +- Declares: `NextScript` + +## Item 11: Stmt 2, `Normal` + +```js +class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx); + return { + ...initialProps, + styles: _jsxs(_Fragment, { + children: [ + initialProps.styles, + _jsx("style", { + dangerouslySetInnerHTML: { + __html: `html { background: hotpink; }` + } + }) + ] + }) + }; + } + render() { + return _jsxs(Html, { + children: [ + _jsx(Head, {}), + _jsxs("body", { + children: [ + _jsx(Main, {}), + _jsx(NextScript, {}) + ] + }) + ] + }); + } +} + +``` + +- Declares: `MyDocument` +- Reads: `Document`, `_jsxs`, `_Fragment`, `_jsx`, `Html`, `Head`, `Main`, `NextScript` +- Write: `Document`, `MyDocument` + +## Item 12: Stmt 3, `Normal` + +```js +export default MyDocument; + +``` + +- Side effects +- Declares: `__TURBOPACK__default__export__` +- Reads: `MyDocument` +- Write: `__TURBOPACK__default__export__` + +# Phase 1 +```mermaid +graph TD + Item1; + Item3; + Item4; + Item5; + Item2; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export default"]; + Item2 --> Item1; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item3; + Item4; + Item5; + Item2; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export default"]; + Item2 --> Item1; + Item11 --> Item6; + Item11 --> Item4; + Item11 --> Item5; + Item11 --> Item3; + Item11 --> Item7; + Item11 --> Item8; + Item11 --> Item9; + Item11 --> Item10; + Item12 --> Item11; + Item12 --> Item1; + Item12 --> Item2; + Item14 --> Item12; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item3; + Item4; + Item5; + Item2; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export default"]; + Item2 --> Item1; + Item11 --> Item6; + Item11 --> Item4; + Item11 --> Item5; + Item11 --> Item3; + Item11 --> Item7; + Item11 --> Item8; + Item11 --> Item9; + Item11 --> Item10; + Item12 --> Item11; + Item12 --> Item1; + Item12 --> Item2; + Item14 --> Item12; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item3; + Item4; + Item5; + Item2; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export default"]; + Item2 --> Item1; + Item11 --> Item6; + Item11 --> Item4; + Item11 --> Item5; + Item11 --> Item3; + Item11 --> Item7; + Item11 --> Item8; + Item11 --> Item9; + Item11 --> Item10; + Item12 --> Item11; + Item12 --> Item1; + Item12 --> Item2; + Item14 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item12; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, ImportBinding(4))]"]; + N1["Items: [ItemId(1, ImportBinding(3))]"]; + N2["Items: [ItemId(1, ImportBinding(2))]"]; + N3["Items: [ItemId(1, ImportBinding(1))]"]; + N4["Items: [ItemId(0, ImportBinding(0))]"]; + N5["Items: [ItemId(0, ImportBinding(2))]"]; + N6["Items: [ItemId(0, ImportBinding(1))]"]; + N7["Items: [ItemId(1, ImportBinding(0))]"]; + N8["Items: [ItemId(2, Normal)]"]; + N9["Items: [ItemId(0, ImportOfModule)]"]; + N10["Items: [ItemId(1, ImportOfModule)]"]; + N11["Items: [ItemId(3, Normal)]"]; + N12["Items: [ItemId(ModuleEvaluation)]"]; + N13["Items: [ItemId(Export(("__TURBOPACK__default__export__", #5), "default"))]"]; + N10 --> N9; + N8 --> N7; + N8 --> N6; + N8 --> N5; + N8 --> N4; + N8 --> N3; + N8 --> N2; + N8 --> N1; + N8 --> N0; + N11 --> N8; + N11 --> N9; + N11 --> N10; + N13 --> N11; + N12 --> N9; + N12 --> N10; + N12 --> N11; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 12, + Export( + "default", + ): 13, + Exports: 14, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { NextScript } from 'next/document'; +export { NextScript } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { Main } from 'next/document'; +export { Main } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { Head } from 'next/document'; +export { Head } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import { Html } from 'next/document'; +export { Html } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import { jsx as _jsx } from "react/jsx-runtime"; +export { _jsx } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import { Fragment as _Fragment } from "react/jsx-runtime"; +export { _Fragment } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import { jsxs as _jsxs } from "react/jsx-runtime"; +export { _jsxs } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import Document from 'next/document'; +export { Document } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { Document } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { _jsxs } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { _Fragment } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { _jsx } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { Html } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { Head } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { Main } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { NextScript } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx); + return { + ...initialProps, + styles: _jsxs(_Fragment, { + children: [ + initialProps.styles, + _jsx("style", { + dangerouslySetInnerHTML: { + __html: `html { background: hotpink; }` + } + }) + ] + }) + }; + } + render() { + return _jsxs(Html, { + children: [ + _jsx(Head, {}), + _jsxs("body", { + children: [ + _jsx(Main, {}), + _jsx(NextScript, {}) + ] + }) + ] + }); + } +} +export { MyDocument } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "react/jsx-runtime"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import 'next/document'; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { MyDocument } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +const __TURBOPACK__default__export__ = MyDocument; +export { __TURBOPACK__default__export__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +"module evaluation"; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { __TURBOPACK__default__export__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +export { __TURBOPACK__default__export__ as default }; + +``` +## Part 14 +```js +export { default } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export default" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 12, + Export( + "default", + ): 13, + Exports: 14, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { NextScript } from 'next/document'; +export { NextScript } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { Main } from 'next/document'; +export { Main } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { Head } from 'next/document'; +export { Head } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import { Html } from 'next/document'; +export { Html } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import { jsx as _jsx } from "react/jsx-runtime"; +export { _jsx } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import { Fragment as _Fragment } from "react/jsx-runtime"; +export { _Fragment } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import { jsxs as _jsxs } from "react/jsx-runtime"; +export { _jsxs } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import Document from 'next/document'; +export { Document } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { Document } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { _jsxs } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { _Fragment } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { _jsx } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { Html } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { Head } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { Main } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { NextScript } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +class MyDocument extends Document { + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx); + return { + ...initialProps, + styles: _jsxs(_Fragment, { + children: [ + initialProps.styles, + _jsx("style", { + dangerouslySetInnerHTML: { + __html: `html { background: hotpink; }` + } + }) + ] + }) + }; + } + render() { + return _jsxs(Html, { + children: [ + _jsx(Head, {}), + _jsxs("body", { + children: [ + _jsx(Main, {}), + _jsx(NextScript, {}) + ] + }) + ] + }); + } +} +export { MyDocument } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "react/jsx-runtime"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import 'next/document'; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { MyDocument } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +const __TURBOPACK__default__export__ = MyDocument; +export { __TURBOPACK__default__export__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +"module evaluation"; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { __TURBOPACK__default__export__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +export { __TURBOPACK__default__export__ as default }; + +``` +## Part 14 +```js +export { default } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export default" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/app-route/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/app-route/input.js new file mode 100644 index 0000000000000..a32837722b8ad --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/app-route/input.js @@ -0,0 +1,31 @@ +import { AppRouteRouteModule } from '../../server/future/route-modules/app-route/module.compiled'; +import { RouteKind } from '../../server/future/route-kind'; +import { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'; +import * as userland from 'VAR_USERLAND'; +// We inject the nextConfigOutput here so that we can use them in the route +// module. +// INJECT:nextConfigOutput +const routeModule = new AppRouteRouteModule({ + definition: { + kind: RouteKind.APP_ROUTE, + page: 'VAR_DEFINITION_PAGE', + pathname: 'VAR_DEFINITION_PATHNAME', + filename: 'VAR_DEFINITION_FILENAME', + bundlePath: 'VAR_DEFINITION_BUNDLE_PATH' + }, + resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH', + nextConfigOutput, + userland +}); +// Pull out the exports that we need to expose from the module. This should +// be eliminated when we've moved the other routes to the new format. These +// are used to hook into the route. +const { requestAsyncStorage, staticGenerationAsyncStorage, serverHooks } = routeModule; +const originalPathname = 'VAR_ORIGINAL_PATHNAME'; +function patchFetch() { + return _patchFetch({ + serverHooks, + staticGenerationAsyncStorage + }); +} +export { routeModule, requestAsyncStorage, staticGenerationAsyncStorage, serverHooks, originalPathname, patchFetch, }; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/app-route/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/app-route/output.md new file mode 100644 index 0000000000000..3c99b727e3757 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/app-route/output.md @@ -0,0 +1,1074 @@ +# Items + +Count: 19 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { AppRouteRouteModule } from '../../server/future/route-modules/app-route/module.compiled'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { AppRouteRouteModule } from '../../server/future/route-modules/app-route/module.compiled'; + +``` + +- Hoisted +- Declares: `AppRouteRouteModule` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import { RouteKind } from '../../server/future/route-kind'; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import { RouteKind } from '../../server/future/route-kind'; + +``` + +- Hoisted +- Declares: `RouteKind` + +## Item 5: Stmt 2, `ImportOfModule` + +```js +import { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 2, `ImportBinding(0)` + +```js +import { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'; + +``` + +- Hoisted +- Declares: `_patchFetch` + +## Item 7: Stmt 3, `ImportOfModule` + +```js +import * as userland from 'VAR_USERLAND'; + +``` + +- Hoisted +- Side effects + +## Item 8: Stmt 3, `ImportBinding(0)` + +```js +import * as userland from 'VAR_USERLAND'; + +``` + +- Hoisted +- Declares: `userland` + +## Item 9: Stmt 4, `VarDeclarator(0)` + +```js +const routeModule = new AppRouteRouteModule({ + definition: { + kind: RouteKind.APP_ROUTE, + page: 'VAR_DEFINITION_PAGE', + pathname: 'VAR_DEFINITION_PATHNAME', + filename: 'VAR_DEFINITION_FILENAME', + bundlePath: 'VAR_DEFINITION_BUNDLE_PATH' + }, + resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH', + nextConfigOutput, + userland +}); + +``` + +- Side effects +- Declares: `routeModule` +- Reads: `AppRouteRouteModule`, `RouteKind`, `userland` +- Write: `RouteKind`, `userland`, `routeModule` + +## Item 10: Stmt 5, `VarDeclarator(0)` + +```js +const { requestAsyncStorage, staticGenerationAsyncStorage, serverHooks } = routeModule; + +``` + +- Declares: `requestAsyncStorage`, `staticGenerationAsyncStorage`, `serverHooks` +- Reads: `routeModule` +- Write: `requestAsyncStorage`, `staticGenerationAsyncStorage`, `serverHooks` + +## Item 11: Stmt 6, `VarDeclarator(0)` + +```js +const originalPathname = 'VAR_ORIGINAL_PATHNAME'; + +``` + +- Declares: `originalPathname` +- Write: `originalPathname` + +## Item 12: Stmt 7, `Normal` + +```js +function patchFetch() { + return _patchFetch({ + serverHooks, + staticGenerationAsyncStorage + }); +} + +``` + +- Hoisted +- Declares: `patchFetch` +- Reads (eventual): `_patchFetch`, `serverHooks`, `staticGenerationAsyncStorage` +- Write: `patchFetch` +- Write (eventual): `serverHooks`, `staticGenerationAsyncStorage` + +# Phase 1 +```mermaid +graph TD + Item1; + Item5; + Item2; + Item6; + Item3; + Item7; + Item4; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export routeModule"]; + Item15; + Item15["export requestAsyncStorage"]; + Item16; + Item16["export staticGenerationAsyncStorage"]; + Item17; + Item17["export serverHooks"]; + Item18; + Item18["export originalPathname"]; + Item19; + Item19["export patchFetch"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item5; + Item2; + Item6; + Item3; + Item7; + Item4; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export routeModule"]; + Item15; + Item15["export requestAsyncStorage"]; + Item16; + Item16["export staticGenerationAsyncStorage"]; + Item17; + Item17["export serverHooks"]; + Item18; + Item18["export originalPathname"]; + Item19; + Item19["export patchFetch"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item9 --> Item5; + Item9 --> Item6; + Item9 --> Item8; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 --> Item4; + Item9 -.-> Item7; + Item10 --> Item9; + Item14 --> Item9; + Item15 --> Item10; + Item16 --> Item10; + Item17 --> Item10; + Item18 --> Item11; + Item19 --> Item12; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item5; + Item2; + Item6; + Item3; + Item7; + Item4; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export routeModule"]; + Item15; + Item15["export requestAsyncStorage"]; + Item16; + Item16["export staticGenerationAsyncStorage"]; + Item17; + Item17["export serverHooks"]; + Item18; + Item18["export originalPathname"]; + Item19; + Item19["export patchFetch"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item9 --> Item5; + Item9 --> Item6; + Item9 --> Item8; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 --> Item4; + Item9 -.-> Item7; + Item10 --> Item9; + Item14 --> Item9; + Item15 --> Item10; + Item16 --> Item10; + Item17 --> Item10; + Item18 --> Item11; + Item19 --> Item12; + Item12 --> Item7; + Item12 --> Item10; + Item12 -.-> Item17; + Item12 -.-> Item16; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item5; + Item2; + Item6; + Item3; + Item7; + Item4; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export routeModule"]; + Item15; + Item15["export requestAsyncStorage"]; + Item16; + Item16["export staticGenerationAsyncStorage"]; + Item17; + Item17["export serverHooks"]; + Item18; + Item18["export originalPathname"]; + Item19; + Item19["export patchFetch"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item9 --> Item5; + Item9 --> Item6; + Item9 --> Item8; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 --> Item4; + Item9 -.-> Item7; + Item10 --> Item9; + Item14 --> Item9; + Item15 --> Item10; + Item16 --> Item10; + Item17 --> Item10; + Item18 --> Item11; + Item19 --> Item12; + Item12 --> Item7; + Item12 --> Item10; + Item12 -.-> Item17; + Item12 -.-> Item16; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item9; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(6, VarDeclarator(0))]"]; + N1["Items: [ItemId(Export(("originalPathname", #2), "originalPathname"))]"]; + N2["Items: [ItemId(2, ImportBinding(0))]"]; + N3["Items: [ItemId(3, ImportBinding(0))]"]; + N4["Items: [ItemId(1, ImportBinding(0))]"]; + N5["Items: [ItemId(0, ImportBinding(0))]"]; + N6["Items: [ItemId(0, ImportOfModule)]"]; + N7["Items: [ItemId(1, ImportOfModule)]"]; + N8["Items: [ItemId(2, ImportOfModule)]"]; + N9["Items: [ItemId(3, ImportOfModule)]"]; + N10["Items: [ItemId(4, VarDeclarator(0))]"]; + N11["Items: [ItemId(ModuleEvaluation)]"]; + N12["Items: [ItemId(Export(("routeModule", #2), "routeModule"))]"]; + N13["Items: [ItemId(5, VarDeclarator(0))]"]; + N14["Items: [ItemId(Export(("serverHooks", #2), "serverHooks"))]"]; + N15["Items: [ItemId(Export(("staticGenerationAsyncStorage", #2), "staticGenerationAsyncStorage"))]"]; + N16["Items: [ItemId(7, Normal)]"]; + N17["Items: [ItemId(Export(("patchFetch", #2), "patchFetch"))]"]; + N18["Items: [ItemId(Export(("requestAsyncStorage", #2), "requestAsyncStorage"))]"]; + N7 --> N6; + N8 --> N6; + N8 --> N7; + N9 --> N6; + N9 --> N7; + N9 --> N8; + N10 --> N5; + N10 --> N4; + N10 --> N3; + N10 --> N6; + N10 --> N7; + N10 --> N8; + N10 --> N9; + N10 -.-> N2; + N13 --> N10; + N12 --> N10; + N18 --> N13; + N15 --> N13; + N14 --> N13; + N1 --> N0; + N17 --> N16; + N16 --> N2; + N16 --> N13; + N16 -.-> N14; + N16 -.-> N15; + N11 --> N6; + N11 --> N7; + N11 --> N8; + N11 --> N9; + N11 --> N10; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 11, + Export( + "serverHooks", + ): 14, + Export( + "patchFetch", + ): 17, + Export( + "staticGenerationAsyncStorage", + ): 15, + Export( + "requestAsyncStorage", + ): 18, + Export( + "routeModule", + ): 12, + Exports: 19, + Export( + "originalPathname", + ): 1, +} +``` + + +# Modules (dev) +## Part 0 +```js +const originalPathname = 'VAR_ORIGINAL_PATHNAME'; +export { originalPathname } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { originalPathname } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { originalPathname as originalPathname }; + +``` +## Part 2 +```js +import { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'; +export { _patchFetch } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import * as userland from 'VAR_USERLAND'; +export { userland } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import { RouteKind } from '../../server/future/route-kind'; +export { RouteKind } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import { AppRouteRouteModule } from '../../server/future/route-modules/app-route/module.compiled'; +export { AppRouteRouteModule } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import '../../server/future/route-modules/app-route/module.compiled'; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import '../../server/future/route-kind'; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import '../../server/lib/patch-fetch'; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import 'VAR_USERLAND'; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { AppRouteRouteModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const routeModule = new AppRouteRouteModule({ + definition: { + kind: RouteKind.APP_ROUTE, + page: 'VAR_DEFINITION_PAGE', + pathname: 'VAR_DEFINITION_PATHNAME', + filename: 'VAR_DEFINITION_FILENAME', + bundlePath: 'VAR_DEFINITION_BUNDLE_PATH' + }, + resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH', + nextConfigOutput, + userland +}); +export { routeModule } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +"module evaluation"; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { routeModule as routeModule }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +const { requestAsyncStorage, staticGenerationAsyncStorage, serverHooks } = routeModule; +export { requestAsyncStorage } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { staticGenerationAsyncStorage } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { serverHooks } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { serverHooks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { serverHooks as serverHooks }; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { staticGenerationAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { staticGenerationAsyncStorage as staticGenerationAsyncStorage }; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { staticGenerationAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { _patchFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { serverHooks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +function patchFetch() { + return _patchFetch({ + serverHooks, + staticGenerationAsyncStorage + }); +} +export { patchFetch } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { patchFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { patchFetch as patchFetch }; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { requestAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { requestAsyncStorage as requestAsyncStorage }; + +``` +## Part 19 +```js +export { originalPathname } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export originalPathname" +}; +export { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export routeModule" +}; +export { serverHooks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export serverHooks" +}; +export { staticGenerationAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export staticGenerationAsyncStorage" +}; +export { patchFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export patchFetch" +}; +export { requestAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export requestAsyncStorage" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 18, + Export( + "patchFetch", + ): 14, + Export( + "serverHooks", + ): 15, + Export( + "staticGenerationAsyncStorage", + ): 16, + Export( + "requestAsyncStorage", + ): 17, + Export( + "routeModule", + ): 11, + Exports: 19, + Export( + "originalPathname", + ): 1, +} +``` + + +# Modules (prod) +## Part 0 +```js +const originalPathname = 'VAR_ORIGINAL_PATHNAME'; +export { originalPathname } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { originalPathname } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { originalPathname as originalPathname }; + +``` +## Part 2 +```js +import { patchFetch as _patchFetch } from '../../server/lib/patch-fetch'; +export { _patchFetch } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import * as userland from 'VAR_USERLAND'; +export { userland } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import { RouteKind } from '../../server/future/route-kind'; +export { RouteKind } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import { AppRouteRouteModule } from '../../server/future/route-modules/app-route/module.compiled'; +export { AppRouteRouteModule } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import '../../server/future/route-modules/app-route/module.compiled'; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import '../../server/future/route-kind'; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import '../../server/lib/patch-fetch'; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import 'VAR_USERLAND'; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { AppRouteRouteModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const routeModule = new AppRouteRouteModule({ + definition: { + kind: RouteKind.APP_ROUTE, + page: 'VAR_DEFINITION_PAGE', + pathname: 'VAR_DEFINITION_PATHNAME', + filename: 'VAR_DEFINITION_FILENAME', + bundlePath: 'VAR_DEFINITION_BUNDLE_PATH' + }, + resolvedPagePath: 'VAR_RESOLVED_PAGE_PATH', + nextConfigOutput, + userland +}); +export { routeModule } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { routeModule as routeModule }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +const { requestAsyncStorage, staticGenerationAsyncStorage, serverHooks } = routeModule; +export { requestAsyncStorage } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { staticGenerationAsyncStorage } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { serverHooks } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { staticGenerationAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { _patchFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { serverHooks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +function patchFetch() { + return _patchFetch({ + serverHooks, + staticGenerationAsyncStorage + }); +} +export { patchFetch } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { patchFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { patchFetch as patchFetch }; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { serverHooks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { serverHooks as serverHooks }; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { staticGenerationAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { staticGenerationAsyncStorage as staticGenerationAsyncStorage }; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { requestAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { requestAsyncStorage as requestAsyncStorage }; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +"module evaluation"; + +``` +## Part 19 +```js +export { originalPathname } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export originalPathname" +}; +export { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export routeModule" +}; +export { patchFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export patchFetch" +}; +export { serverHooks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export serverHooks" +}; +export { staticGenerationAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export staticGenerationAsyncStorage" +}; +export { requestAsyncStorage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export requestAsyncStorage" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-fn/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-fn/input.js new file mode 100644 index 0000000000000..1d4bad1ca723e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-fn/input.js @@ -0,0 +1,7 @@ +a = () => {}; + +function a() {} + + +// use a (side effect) +console.log(a); diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-fn/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-fn/output.md new file mode 100644 index 0000000000000..0830dedfe77d6 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-fn/output.md @@ -0,0 +1,220 @@ +# Items + +Count: 4 + +## Item 1: Stmt 0, `Normal` + +```js +a = ()=>{}; + +``` + +- Write: `a` + +## Item 2: Stmt 1, `Normal` + +```js +function a() {} + +``` + +- Hoisted +- Declares: `a` +- Write: `a` + +## Item 3: Stmt 2, `Normal` + +```js +console.log(a); + +``` + +- Side effects +- Reads: `a` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item1 --> Item2; + Item3 --> Item1; + Item3 --> Item2; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item1 --> Item2; + Item3 --> Item1; + Item3 --> Item2; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item1 --> Item2; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item3; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, Normal)]"]; + N1["Items: [ItemId(0, Normal)]"]; + N2["Items: [ItemId(2, Normal)]"]; + N3["Items: [ItemId(ModuleEvaluation)]"]; + N1 --> N0; + N2 --> N1; + N2 --> N0; + N3 --> N2; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 3, + Exports: 4, +} +``` + + +# Modules (dev) +## Part 0 +```js +function a() {} +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +a = ()=>{}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +console.log(a); + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +## Part 4 +```js + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 3, + Exports: 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +function a() {} +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +a = ()=>{}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +console.log(a); + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +## Part 4 +```js + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-var/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-var/input.js new file mode 100644 index 0000000000000..c1312c195753a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-var/input.js @@ -0,0 +1,6 @@ +a = 1; + +var a; + +// use a (side effect) +console.log(a); diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-var/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-var/output.md new file mode 100644 index 0000000000000..e052d0eef4423 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/assign-before-decl-var/output.md @@ -0,0 +1,209 @@ +# Items + +Count: 4 + +## Item 1: Stmt 0, `Normal` + +```js +a = 1; + +``` + +- Write: `a` + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +var a; + +``` + +- Declares: `a` +- Write: `a` + +## Item 3: Stmt 2, `Normal` + +```js +console.log(a); + +``` + +- Side effects +- Reads: `a` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item1 --> Item2; + Item3 --> Item2; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item1 --> Item2; + Item3 --> Item2; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item1 --> Item2; + Item3 --> Item2; + Item4 --> Item3; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, VarDeclarator(0))]"]; + N1["Items: [ItemId(2, Normal)]"]; + N2["Items: [ItemId(ModuleEvaluation)]"]; + N3["Items: [ItemId(0, Normal)]"]; + N3 --> N0; + N1 --> N0; + N2 --> N1; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 2, + Exports: 4, +} +``` + + +# Modules (dev) +## Part 0 +```js +var a; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +console.log(a); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +a = 1; + +``` +## Part 4 +```js + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 2, + Exports: 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +var a; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +console.log(a); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +a = 1; + +``` +## Part 4 +```js + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/combined-export/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/combined-export/input.js new file mode 100644 index 0000000000000..4b7aee241e63f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/combined-export/input.js @@ -0,0 +1,4 @@ +const a = "a"; +const b = "b"; + +export { a, b }; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/combined-export/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/combined-export/output.md new file mode 100644 index 0000000000000..61ba2ddeabda5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/combined-export/output.md @@ -0,0 +1,239 @@ +# Items + +Count: 5 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +const a = "a"; + +``` + +- Declares: `a` +- Write: `a` + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +const b = "b"; + +``` + +- Declares: `b` +- Write: `b` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export a"]; + Item5; + Item5["export b"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export a"]; + Item5; + Item5["export b"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export a"]; + Item5; + Item5["export b"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export a"]; + Item5; + Item5["export b"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, VarDeclarator(0))]"]; + N1["Items: [ItemId(Export(("b", #2), "b"))]"]; + N2["Items: [ItemId(0, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("a", #2), "a"))]"]; + N4["Items: [ItemId(ModuleEvaluation)]"]; + N3 --> N2; + N1 --> N0; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 4, + Exports: 5, + Export( + "b", + ): 1, + Export( + "a", + ): 3, +} +``` + + +# Modules (dev) +## Part 0 +```js +const b = "b"; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { b as b }; + +``` +## Part 2 +```js +const a = "a"; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { a as a }; + +``` +## Part 4 +```js +"module evaluation"; + +``` +## Part 5 +```js +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 4, + Exports: 5, + Export( + "b", + ): 1, + Export( + "a", + ): 3, +} +``` + + +# Modules (prod) +## Part 0 +```js +const b = "b"; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { b as b }; + +``` +## Part 2 +```js +const a = "a"; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { a as a }; + +``` +## Part 4 +```js +"module evaluation"; + +``` +## Part 5 +```js +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/complex/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/complex/input.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/complex/input.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/complex/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/complex/output.md new file mode 100644 index 0000000000000..aacfd5e3fb231 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/complex/output.md @@ -0,0 +1,1053 @@ +# Items + +Count: 18 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +let dog = "dog"; + +``` + +- Declares: `dog` +- Write: `dog` + +## Item 2: Stmt 1, `Normal` + +```js +dog += "!"; + +``` + +- Reads: `dog` +- Write: `dog` + +## Item 3: Stmt 2, `Normal` + +```js +console.log(dog); + +``` + +- Side effects +- Reads: `dog` + +## Item 4: Stmt 3, `Normal` + +```js +function getDog() { + return dog; +} + +``` + +- Hoisted +- Declares: `getDog` +- Reads (eventual): `dog` +- Write: `getDog` + +## Item 5: Stmt 4, `Normal` + +```js +dog += "!"; + +``` + +- Reads: `dog` +- Write: `dog` + +## Item 6: Stmt 5, `Normal` + +```js +console.log(dog); + +``` + +- Side effects +- Reads: `dog` + +## Item 7: Stmt 6, `Normal` + +```js +function setDog(newDog) { + dog = newDog; +} + +``` + +- Hoisted +- Declares: `setDog` +- Write: `setDog` +- Write (eventual): `dog` + +## Item 8: Stmt 7, `Normal` + +```js +dog += "!"; + +``` + +- Reads: `dog` +- Write: `dog` + +## Item 9: Stmt 8, `Normal` + +```js +console.log(dog); + +``` + +- Side effects +- Reads: `dog` + +## Item 10: Stmt 9, `VarDeclarator(0)` + +```js +export const dogRef = { + initial: dog, + get: getDog, + set: setDog +}; + +``` + +- Declares: `dogRef` +- Reads: `dog`, `getDog`, `setDog` +- Write: `dogRef` + +## Item 11: Stmt 10, `VarDeclarator(0)` + +```js +export let cat = "cat"; + +``` + +- Declares: `cat` +- Write: `cat` + +## Item 12: Stmt 11, `VarDeclarator(0)` + +```js +export const initialCat = cat; + +``` + +- Declares: `initialCat` +- Reads: `cat` +- Write: `initialCat` + +## Item 13: Stmt 12, `Normal` + +```js +export function getChimera() { + return cat + dog; +} + +``` + +- Hoisted +- Declares: `getChimera` +- Reads (eventual): `cat`, `dog` +- Write: `getChimera` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export dogRef"]; + Item16; + Item16["export cat"]; + Item17; + Item17["export initialCat"]; + Item18; + Item18["export getChimera"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export dogRef"]; + Item16; + Item16["export cat"]; + Item17; + Item17["export initialCat"]; + Item18; + Item18["export getChimera"]; + Item2 --> Item1; + Item3 --> Item2; + Item3 --> Item1; + Item5 --> Item2; + Item5 --> Item1; + Item5 -.-> Item3; + Item6 --> Item5; + Item6 --> Item1; + Item6 --> Item3; + Item8 --> Item5; + Item8 --> Item1; + Item8 -.-> Item6; + Item9 --> Item8; + Item9 --> Item1; + Item9 --> Item3; + Item9 --> Item6; + Item10 --> Item8; + Item10 --> Item1; + Item10 --> Item4; + Item10 --> Item7; + Item12 --> Item11; + Item15 --> Item10; + Item16 --> Item11; + Item17 --> Item12; + Item18 --> Item13; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export dogRef"]; + Item16; + Item16["export cat"]; + Item17; + Item17["export initialCat"]; + Item18; + Item18["export getChimera"]; + Item2 --> Item1; + Item3 --> Item2; + Item3 --> Item1; + Item5 --> Item2; + Item5 --> Item1; + Item5 -.-> Item3; + Item6 --> Item5; + Item6 --> Item1; + Item6 --> Item3; + Item8 --> Item5; + Item8 --> Item1; + Item8 -.-> Item6; + Item9 --> Item8; + Item9 --> Item1; + Item9 --> Item3; + Item9 --> Item6; + Item10 --> Item8; + Item10 --> Item1; + Item10 --> Item4; + Item10 --> Item7; + Item12 --> Item11; + Item15 --> Item10; + Item16 --> Item11; + Item17 --> Item12; + Item18 --> Item13; + Item4 --> Item8; + Item4 --> Item1; + Item7 -.-> Item9; + Item7 -.-> Item10; + Item7 --> Item1; + Item13 --> Item11; + Item13 --> Item8; + Item13 --> Item1; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export dogRef"]; + Item16; + Item16["export cat"]; + Item17; + Item17["export initialCat"]; + Item18; + Item18["export getChimera"]; + Item2 --> Item1; + Item3 --> Item2; + Item3 --> Item1; + Item5 --> Item2; + Item5 --> Item1; + Item5 -.-> Item3; + Item6 --> Item5; + Item6 --> Item1; + Item6 --> Item3; + Item8 --> Item5; + Item8 --> Item1; + Item8 -.-> Item6; + Item9 --> Item8; + Item9 --> Item1; + Item9 --> Item3; + Item9 --> Item6; + Item10 --> Item8; + Item10 --> Item1; + Item10 --> Item4; + Item10 --> Item7; + Item12 --> Item11; + Item15 --> Item10; + Item16 --> Item11; + Item17 --> Item12; + Item18 --> Item13; + Item4 --> Item8; + Item4 --> Item1; + Item7 -.-> Item9; + Item7 -.-> Item10; + Item7 --> Item1; + Item13 --> Item11; + Item13 --> Item8; + Item13 --> Item1; + Item14 --> Item3; + Item14 --> Item6; + Item14 --> Item9; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(10, VarDeclarator(0))]"]; + N1["Items: [ItemId(Export(("cat", #2), "cat"))]"]; + N2["Items: [ItemId(11, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("initialCat", #2), "initialCat"))]"]; + N4["Items: [ItemId(0, VarDeclarator(0))]"]; + N5["Items: [ItemId(1, Normal)]"]; + N6["Items: [ItemId(2, Normal)]"]; + N7["Items: [ItemId(4, Normal)]"]; + N8["Items: [ItemId(5, Normal)]"]; + N9["Items: [ItemId(7, Normal)]"]; + N10["Items: [ItemId(12, Normal)]"]; + N11["Items: [ItemId(Export(("getChimera", #2), "getChimera"))]"]; + N12["Items: [ItemId(3, Normal)]"]; + N13["Items: [ItemId(8, Normal)]"]; + N14["Items: [ItemId(ModuleEvaluation)]"]; + N15["Items: [ItemId(6, Normal), ItemId(9, VarDeclarator(0))]"]; + N16["Items: [ItemId(Export(("dogRef", #2), "dogRef"))]"]; + N5 --> N4; + N6 --> N5; + N6 --> N4; + N7 --> N5; + N7 --> N4; + N7 -.-> N6; + N8 --> N7; + N8 --> N4; + N8 --> N6; + N9 --> N7; + N9 --> N4; + N9 -.-> N8; + N13 --> N9; + N13 --> N4; + N13 --> N6; + N13 --> N8; + N15 --> N9; + N15 --> N4; + N15 --> N12; + N15 -.-> N15; + N2 --> N0; + N16 --> N15; + N1 --> N0; + N3 --> N2; + N11 --> N10; + N12 --> N9; + N12 --> N4; + N15 -.-> N13; + N10 --> N0; + N10 --> N9; + N10 --> N4; + N14 --> N6; + N14 --> N8; + N14 --> N13; +``` +# Entrypoints + +``` +{ + Export( + "getChimera", + ): 11, + ModuleEvaluation: 14, + Export( + "initialCat", + ): 3, + Exports: 17, + Export( + "cat", + ): 1, + Export( + "dogRef", + ): 16, +} +``` + + +# Modules (dev) +## Part 0 +```js +let cat = "cat"; +export { cat } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { cat }; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const initialCat = cat; +export { initialCat } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { initialCat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { initialCat }; + +``` +## Part 4 +```js +let dog = "dog"; +export { dog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +dog += "!"; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +console.log(dog); + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +dog += "!"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +console.log(dog); + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +dog += "!"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function getChimera() { + return cat + dog; +} +export { getChimera } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { getChimera } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { getChimera }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +function getDog() { + return dog; +} +export { getDog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +console.log(dog); + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +"module evaluation"; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { getDog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +function setDog(newDog) { + dog = newDog; +} +const dogRef = { + initial: dog, + get: getDog, + set: setDog +}; +export { setDog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { dogRef } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { dogRef } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +export { dogRef }; + +``` +## Part 17 +```js +export { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export cat" +}; +export { initialCat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export initialCat" +}; +export { getChimera } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getChimera" +}; +export { dogRef } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export dogRef" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "getChimera", + ): 10, + ModuleEvaluation: 17, + Export( + "initialCat", + ): 3, + Exports: 18, + Export( + "cat", + ): 1, + Export( + "dogRef", + ): 13, +} +``` + + +# Modules (prod) +## Part 0 +```js +let cat = "cat"; +export { cat } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { cat }; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const initialCat = cat; +export { initialCat } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { initialCat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { initialCat }; + +``` +## Part 4 +```js +let dog = "dog"; +export { dog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +function setDog(newDog) { + dog = newDog; +} +export { setDog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +dog += "!"; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +dog += "!"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +dog += "!"; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function getChimera() { + return cat + dog; +} +export { getChimera } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { getChimera } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +export { getChimera }; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +function getDog() { + return dog; +} +export { getDog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { getDog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { setDog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +const dogRef = { + initial: dog, + get: getDog, + set: setDog +}; +export { dogRef } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { dogRef } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { dogRef }; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +console.log(dog); + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +console.log(dog); + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +console.log(dog); + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +"module evaluation"; + +``` +## Part 18 +```js +export { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export cat" +}; +export { initialCat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export initialCat" +}; +export { getChimera } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getChimera" +}; +export { dogRef } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export dogRef" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/export-named/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/export-named/input.js new file mode 100644 index 0000000000000..7ae3e218f9eb8 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/export-named/input.js @@ -0,0 +1 @@ +export { cat as fakeCat } from "./lib"; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/export-named/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/export-named/output.md new file mode 100644 index 0000000000000..46e62c868ed1b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/export-named/output.md @@ -0,0 +1,200 @@ +# Items + +Count: 4 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +export { cat as fakeCat } from "./lib"; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +export { cat as fakeCat } from "./lib"; + +``` + +- Hoisted +- Declares: `__TURBOPACK__reexport__cat__` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export fakeCat"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export fakeCat"]; + Item4 --> Item2; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export fakeCat"]; + Item4 --> Item2; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export fakeCat"]; + Item4 --> Item2; + Item3 --> Item1; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportOfModule)]"]; + N1["Items: [ItemId(ModuleEvaluation)]"]; + N2["Items: [ItemId(0, ImportBinding(0))]"]; + N3["Items: [ItemId(Export(("__TURBOPACK__reexport__cat__", #3), "fakeCat"))]"]; + N3 --> N2; + N1 --> N0; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 1, + Export( + "fakeCat", + ): 3, + Exports: 4, +} +``` + + +# Modules (dev) +## Part 0 +```js +import "./lib"; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +## Part 2 +```js +import { cat as __TURBOPACK__reexport__cat__ } from "./lib"; +export { __TURBOPACK__reexport__cat__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { __TURBOPACK__reexport__cat__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { __TURBOPACK__reexport__cat__ as fakeCat }; + +``` +## Part 4 +```js +export { fakeCat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export fakeCat" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 1, + Export( + "fakeCat", + ): 3, + Exports: 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +import "./lib"; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +## Part 2 +```js +import { cat as __TURBOPACK__reexport__cat__ } from "./lib"; +export { __TURBOPACK__reexport__cat__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { __TURBOPACK__reexport__cat__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { __TURBOPACK__reexport__cat__ as fakeCat }; + +``` +## Part 4 +```js +export { fakeCat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export fakeCat" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-1/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-1/input.js new file mode 100644 index 0000000000000..f2974f26f1c70 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-1/input.js @@ -0,0 +1,57 @@ +let source; +const eventCallbacks = []; +function getSocketProtocol(assetPrefix) { + let protocol = location.protocol; + try { + protocol = new URL(assetPrefix).protocol; + } catch (_) {} + return protocol === "http:" ? "ws" : "wss"; +} +export function addMessageListener(cb) { + eventCallbacks.push(cb); +} +export function sendMessage(data) { + if (!source || source.readyState !== source.OPEN) return; + return source.send(data); +} +export function connectHMR(options) { + const { timeout = 5 * 1000 } = options; + function init() { + if (source) source.close(); + console.log("[HMR] connecting..."); + function handleOnline() { + const connected = { + type: "turbopack-connected" + }; + eventCallbacks.forEach((cb)=>{ + cb(connected); + }); + if (options.log) console.log("[HMR] connected"); + } + function handleMessage(event) { + const message = { + type: "turbopack-message", + data: JSON.parse(event.data) + }; + eventCallbacks.forEach((cb)=>{ + cb(message); + }); + } + function handleDisconnect() { + source.close(); + setTimeout(init, timeout); + } + const { hostname, port } = location; + const protocol = getSocketProtocol(options.assetPrefix || ""); + const assetPrefix = options.assetPrefix.replace(/^\/+/, ""); + let url = `${protocol}://${hostname}:${port}${assetPrefix ? `/${assetPrefix}` : ""}`; + if (assetPrefix.startsWith("http")) { + url = `${protocol}://${assetPrefix.split("://")[1]}`; + } + source = new window.WebSocket(`${url}${options.path}`); + source.onopen = handleOnline; + source.onerror = handleDisconnect; + source.onmessage = handleMessage; + } + init(); +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-1/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-1/output.md new file mode 100644 index 0000000000000..0d27024f76f45 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-1/output.md @@ -0,0 +1,648 @@ +# Items + +Count: 10 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +let source; + +``` + +- Declares: `source` +- Write: `source` + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +const eventCallbacks = []; + +``` + +- Declares: `eventCallbacks` +- Write: `eventCallbacks` + +## Item 3: Stmt 2, `Normal` + +```js +function getSocketProtocol(assetPrefix) { + let protocol = location.protocol; + try { + protocol = new URL(assetPrefix).protocol; + } catch (_) {} + return protocol === "http:" ? "ws" : "wss"; +} + +``` + +- Hoisted +- Declares: `getSocketProtocol` +- Write: `getSocketProtocol` + +## Item 4: Stmt 3, `Normal` + +```js +export function addMessageListener(cb) { + eventCallbacks.push(cb); +} + +``` + +- Hoisted +- Declares: `addMessageListener` +- Reads (eventual): `eventCallbacks` +- Write: `addMessageListener` +- Write (eventual): `eventCallbacks` + +## Item 5: Stmt 4, `Normal` + +```js +export function sendMessage(data) { + if (!source || source.readyState !== source.OPEN) return; + return source.send(data); +} + +``` + +- Hoisted +- Declares: `sendMessage` +- Reads (eventual): `source` +- Write: `sendMessage` +- Write (eventual): `source` + +## Item 6: Stmt 5, `Normal` + +```js +export function connectHMR(options) { + const { timeout = 5 * 1000 } = options; + function init() { + if (source) source.close(); + console.log("[HMR] connecting..."); + function handleOnline() { + const connected = { + type: "turbopack-connected" + }; + eventCallbacks.forEach((cb)=>{ + cb(connected); + }); + if (options.log) console.log("[HMR] connected"); + } + function handleMessage(event) { + const message = { + type: "turbopack-message", + data: JSON.parse(event.data) + }; + eventCallbacks.forEach((cb)=>{ + cb(message); + }); + } + function handleDisconnect() { + source.close(); + setTimeout(init, timeout); + } + const { hostname, port } = location; + const protocol = getSocketProtocol(options.assetPrefix || ""); + const assetPrefix = options.assetPrefix.replace(/^\/+/, ""); + let url = `${protocol}://${hostname}:${port}${assetPrefix ? `/${assetPrefix}` : ""}`; + if (assetPrefix.startsWith("http")) { + url = `${protocol}://${assetPrefix.split("://")[1]}`; + } + source = new window.WebSocket(`${url}${options.path}`); + source.onopen = handleOnline; + source.onerror = handleDisconnect; + source.onmessage = handleMessage; + } + init(); +} + +``` + +- Hoisted +- Declares: `connectHMR` +- Reads (eventual): `source`, `eventCallbacks`, `getSocketProtocol` +- Write: `connectHMR` +- Write (eventual): `source`, `eventCallbacks` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item7["ModuleEvaluation"]; + Item8; + Item8["export addMessageListener"]; + Item9; + Item9["export sendMessage"]; + Item10; + Item10["export connectHMR"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item7["ModuleEvaluation"]; + Item8; + Item8["export addMessageListener"]; + Item9; + Item9["export sendMessage"]; + Item10; + Item10["export connectHMR"]; + Item8 --> Item4; + Item9 --> Item5; + Item10 --> Item6; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item7["ModuleEvaluation"]; + Item8; + Item8["export addMessageListener"]; + Item9; + Item9["export sendMessage"]; + Item10; + Item10["export connectHMR"]; + Item8 --> Item4; + Item9 --> Item5; + Item10 --> Item6; + Item4 --> Item2; + Item5 --> Item1; + Item6 --> Item1; + Item6 --> Item2; + Item6 --> Item3; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item7["ModuleEvaluation"]; + Item8; + Item8["export addMessageListener"]; + Item9; + Item9["export sendMessage"]; + Item10; + Item10["export connectHMR"]; + Item8 --> Item4; + Item9 --> Item5; + Item10 --> Item6; + Item4 --> Item2; + Item5 --> Item1; + Item6 --> Item1; + Item6 --> Item2; + Item6 --> Item3; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(2, Normal)]"]; + N1["Items: [ItemId(0, VarDeclarator(0))]"]; + N2["Items: [ItemId(1, VarDeclarator(0))]"]; + N3["Items: [ItemId(5, Normal)]"]; + N4["Items: [ItemId(Export(("connectHMR", #2), "connectHMR"))]"]; + N5["Items: [ItemId(4, Normal)]"]; + N6["Items: [ItemId(Export(("sendMessage", #2), "sendMessage"))]"]; + N7["Items: [ItemId(3, Normal)]"]; + N8["Items: [ItemId(Export(("addMessageListener", #2), "addMessageListener"))]"]; + N9["Items: [ItemId(ModuleEvaluation)]"]; + N8 --> N7; + N6 --> N5; + N4 --> N3; + N7 --> N2; + N5 --> N1; + N3 --> N1; + N3 --> N2; + N3 --> N0; +``` +# Entrypoints + +``` +{ + Export( + "connectHMR", + ): 4, + ModuleEvaluation: 9, + Export( + "addMessageListener", + ): 8, + Exports: 10, + Export( + "sendMessage", + ): 6, +} +``` + + +# Modules (dev) +## Part 0 +```js +function getSocketProtocol(assetPrefix) { + let protocol = location.protocol; + try { + protocol = new URL(assetPrefix).protocol; + } catch (_) {} + return protocol === "http:" ? "ws" : "wss"; +} +export { getSocketProtocol } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +let source; +export { source } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +const eventCallbacks = []; +export { eventCallbacks } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { getSocketProtocol } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { source } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { eventCallbacks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function connectHMR(options) { + const { timeout = 5 * 1000 } = options; + function init() { + if (source) source.close(); + console.log("[HMR] connecting..."); + function handleOnline() { + const connected = { + type: "turbopack-connected" + }; + eventCallbacks.forEach((cb)=>{ + cb(connected); + }); + if (options.log) console.log("[HMR] connected"); + } + function handleMessage(event) { + const message = { + type: "turbopack-message", + data: JSON.parse(event.data) + }; + eventCallbacks.forEach((cb)=>{ + cb(message); + }); + } + function handleDisconnect() { + source.close(); + setTimeout(init, timeout); + } + const { hostname, port } = location; + const protocol = getSocketProtocol(options.assetPrefix || ""); + const assetPrefix = options.assetPrefix.replace(/^\/+/, ""); + let url = `${protocol}://${hostname}:${port}${assetPrefix ? `/${assetPrefix}` : ""}`; + if (assetPrefix.startsWith("http")) { + url = `${protocol}://${assetPrefix.split("://")[1]}`; + } + source = new window.WebSocket(`${url}${options.path}`); + source.onopen = handleOnline; + source.onerror = handleDisconnect; + source.onmessage = handleMessage; + } + init(); +} +export { connectHMR } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { connectHMR } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { connectHMR }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { source } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function sendMessage(data) { + if (!source || source.readyState !== source.OPEN) return; + return source.send(data); +} +export { sendMessage } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { sendMessage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { sendMessage }; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { eventCallbacks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function addMessageListener(cb) { + eventCallbacks.push(cb); +} +export { addMessageListener } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { addMessageListener } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +export { addMessageListener }; + +``` +## Part 9 +```js +"module evaluation"; + +``` +## Part 10 +```js +export { connectHMR } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export connectHMR" +}; +export { sendMessage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export sendMessage" +}; +export { addMessageListener } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export addMessageListener" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "connectHMR", + ): 4, + ModuleEvaluation: 9, + Export( + "addMessageListener", + ): 8, + Exports: 10, + Export( + "sendMessage", + ): 6, +} +``` + + +# Modules (prod) +## Part 0 +```js +function getSocketProtocol(assetPrefix) { + let protocol = location.protocol; + try { + protocol = new URL(assetPrefix).protocol; + } catch (_) {} + return protocol === "http:" ? "ws" : "wss"; +} +export { getSocketProtocol } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +let source; +export { source } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +const eventCallbacks = []; +export { eventCallbacks } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { getSocketProtocol } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { source } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { eventCallbacks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function connectHMR(options) { + const { timeout = 5 * 1000 } = options; + function init() { + if (source) source.close(); + console.log("[HMR] connecting..."); + function handleOnline() { + const connected = { + type: "turbopack-connected" + }; + eventCallbacks.forEach((cb)=>{ + cb(connected); + }); + if (options.log) console.log("[HMR] connected"); + } + function handleMessage(event) { + const message = { + type: "turbopack-message", + data: JSON.parse(event.data) + }; + eventCallbacks.forEach((cb)=>{ + cb(message); + }); + } + function handleDisconnect() { + source.close(); + setTimeout(init, timeout); + } + const { hostname, port } = location; + const protocol = getSocketProtocol(options.assetPrefix || ""); + const assetPrefix = options.assetPrefix.replace(/^\/+/, ""); + let url = `${protocol}://${hostname}:${port}${assetPrefix ? `/${assetPrefix}` : ""}`; + if (assetPrefix.startsWith("http")) { + url = `${protocol}://${assetPrefix.split("://")[1]}`; + } + source = new window.WebSocket(`${url}${options.path}`); + source.onopen = handleOnline; + source.onerror = handleDisconnect; + source.onmessage = handleMessage; + } + init(); +} +export { connectHMR } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { connectHMR } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { connectHMR }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { source } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function sendMessage(data) { + if (!source || source.readyState !== source.OPEN) return; + return source.send(data); +} +export { sendMessage } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { sendMessage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { sendMessage }; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { eventCallbacks } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function addMessageListener(cb) { + eventCallbacks.push(cb); +} +export { addMessageListener } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { addMessageListener } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +export { addMessageListener }; + +``` +## Part 9 +```js +"module evaluation"; + +``` +## Part 10 +```js +export { connectHMR } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export connectHMR" +}; +export { sendMessage } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export sendMessage" +}; +export { addMessageListener } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export addMessageListener" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-2/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-2/input.js new file mode 100644 index 0000000000000..d0e0a6793cecb --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-2/input.js @@ -0,0 +1,98 @@ +import React from 'react'; +import { DynamicServerError } from '../../client/components/hooks-server-context'; +import { StaticGenBailoutError } from '../../client/components/static-generation-bailout'; +import { getPathname } from '../../lib/url'; +const hasPostpone = typeof React.unstable_postpone === 'function'; +export function createPrerenderState(isDebugSkeleton) { + return { + isDebugSkeleton, + dynamicAccesses: [] + }; +} +export function markCurrentScopeAsDynamic(store, expression) { + const pathname = getPathname(store.urlPathname); + if (store.isUnstableCacheCallback) { + return; + } else if (store.dynamicShouldError) { + throw new StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); + } else if (store.prerenderState) { + postponeWithTracking(store.prerenderState, expression, pathname); + } else { + store.revalidate = 0; + if (store.isStaticGeneration) { + const err = new DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); + store.dynamicUsageDescription = expression; + store.dynamicUsageStack = err.stack; + throw err; + } + } +} +export function trackDynamicDataAccessed(store, expression) { + const pathname = getPathname(store.urlPathname); + if (store.isUnstableCacheCallback) { + throw new Error(`Route ${pathname} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`); + } else if (store.dynamicShouldError) { + throw new StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); + } else if (store.prerenderState) { + postponeWithTracking(store.prerenderState, expression, pathname); + } else { + store.revalidate = 0; + if (store.isStaticGeneration) { + const err = new DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); + store.dynamicUsageDescription = expression; + store.dynamicUsageStack = err.stack; + throw err; + } + } +} +export function Postpone({ reason, prerenderState, pathname }) { + postponeWithTracking(prerenderState, reason, pathname); +} +export function trackDynamicFetch(store, expression) { + if (!store.prerenderState || store.isUnstableCacheCallback) return; + postponeWithTracking(store.prerenderState, expression, store.urlPathname); +} +function postponeWithTracking(prerenderState, expression, pathname) { + assertPostpone(); + const reason = `Route ${pathname} needs to bail out of prerendering at this point because it used ${expression}. ` + `React throws this special object to indicate where. It should not be caught by ` + `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`; + prerenderState.dynamicAccesses.push({ + stack: prerenderState.isDebugSkeleton ? new Error().stack : undefined, + expression + }); + React.unstable_postpone(reason); +} +export function usedDynamicAPIs(prerenderState) { + return prerenderState.dynamicAccesses.length > 0; +} +export function formatDynamicAPIAccesses(prerenderState) { + return prerenderState.dynamicAccesses.filter((access)=>typeof access.stack === 'string' && access.stack.length > 0).map(({ expression, stack })=>{ + stack = stack.split('\n').slice(4).filter((line)=>{ + if (line.includes('node_modules/next/')) { + return false; + } + if (line.includes(' ()')) { + return false; + } + if (line.includes(' (node:')) { + return false; + } + return true; + }).join('\n'); + return `Dynamic API Usage Debug - ${expression}:\n${stack}`; + }); +} +function assertPostpone() { + if (!hasPostpone) { + throw new Error(`Invariant: React.unstable_postpone is not defined. This suggests the wrong version of React was loaded. This is a bug in Next.js`); + } +} +export function createPostponedAbortSignal(reason) { + assertPostpone(); + const controller = new AbortController(); + try { + React.unstable_postpone(reason); + } catch (x) { + controller.abort(x); + } + return controller.signal; +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-2/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-2/output.md new file mode 100644 index 0000000000000..e2da7b2f36d97 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-2/output.md @@ -0,0 +1,1674 @@ +# Items + +Count: 28 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import React from 'react'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import React from 'react'; + +``` + +- Hoisted +- Declares: `React` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import { DynamicServerError } from '../../client/components/hooks-server-context'; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import { DynamicServerError } from '../../client/components/hooks-server-context'; + +``` + +- Hoisted +- Declares: `DynamicServerError` + +## Item 5: Stmt 2, `ImportOfModule` + +```js +import { StaticGenBailoutError } from '../../client/components/static-generation-bailout'; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 2, `ImportBinding(0)` + +```js +import { StaticGenBailoutError } from '../../client/components/static-generation-bailout'; + +``` + +- Hoisted +- Declares: `StaticGenBailoutError` + +## Item 7: Stmt 3, `ImportOfModule` + +```js +import { getPathname } from '../../lib/url'; + +``` + +- Hoisted +- Side effects + +## Item 8: Stmt 3, `ImportBinding(0)` + +```js +import { getPathname } from '../../lib/url'; + +``` + +- Hoisted +- Declares: `getPathname` + +## Item 9: Stmt 4, `VarDeclarator(0)` + +```js +const hasPostpone = typeof React.unstable_postpone === 'function'; + +``` + +- Declares: `hasPostpone` +- Reads: `React` +- Write: `React`, `hasPostpone` + +## Item 10: Stmt 5, `Normal` + +```js +export function createPrerenderState(isDebugSkeleton) { + return { + isDebugSkeleton, + dynamicAccesses: [] + }; +} + +``` + +- Hoisted +- Declares: `createPrerenderState` +- Write: `createPrerenderState` + +## Item 11: Stmt 6, `Normal` + +```js +export function markCurrentScopeAsDynamic(store, expression) { + const pathname = getPathname(store.urlPathname); + if (store.isUnstableCacheCallback) { + return; + } else if (store.dynamicShouldError) { + throw new StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); + } else if (store.prerenderState) { + postponeWithTracking(store.prerenderState, expression, pathname); + } else { + store.revalidate = 0; + if (store.isStaticGeneration) { + const err = new DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); + store.dynamicUsageDescription = expression; + store.dynamicUsageStack = err.stack; + throw err; + } + } +} + +``` + +- Hoisted +- Declares: `markCurrentScopeAsDynamic` +- Reads (eventual): `getPathname`, `StaticGenBailoutError`, `postponeWithTracking`, `DynamicServerError` +- Write: `markCurrentScopeAsDynamic` + +## Item 12: Stmt 7, `Normal` + +```js +export function trackDynamicDataAccessed(store, expression) { + const pathname = getPathname(store.urlPathname); + if (store.isUnstableCacheCallback) { + throw new Error(`Route ${pathname} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`); + } else if (store.dynamicShouldError) { + throw new StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); + } else if (store.prerenderState) { + postponeWithTracking(store.prerenderState, expression, pathname); + } else { + store.revalidate = 0; + if (store.isStaticGeneration) { + const err = new DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); + store.dynamicUsageDescription = expression; + store.dynamicUsageStack = err.stack; + throw err; + } + } +} + +``` + +- Hoisted +- Declares: `trackDynamicDataAccessed` +- Reads (eventual): `getPathname`, `StaticGenBailoutError`, `postponeWithTracking`, `DynamicServerError` +- Write: `trackDynamicDataAccessed` + +## Item 13: Stmt 8, `Normal` + +```js +export function Postpone({ reason, prerenderState, pathname }) { + postponeWithTracking(prerenderState, reason, pathname); +} + +``` + +- Hoisted +- Declares: `Postpone` +- Reads (eventual): `postponeWithTracking` +- Write: `Postpone` + +## Item 14: Stmt 9, `Normal` + +```js +export function trackDynamicFetch(store, expression) { + if (!store.prerenderState || store.isUnstableCacheCallback) return; + postponeWithTracking(store.prerenderState, expression, store.urlPathname); +} + +``` + +- Hoisted +- Declares: `trackDynamicFetch` +- Reads (eventual): `postponeWithTracking` +- Write: `trackDynamicFetch` + +## Item 15: Stmt 10, `Normal` + +```js +function postponeWithTracking(prerenderState, expression, pathname) { + assertPostpone(); + const reason = `Route ${pathname} needs to bail out of prerendering at this point because it used ${expression}. ` + `React throws this special object to indicate where. It should not be caught by ` + `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`; + prerenderState.dynamicAccesses.push({ + stack: prerenderState.isDebugSkeleton ? new Error().stack : undefined, + expression + }); + React.unstable_postpone(reason); +} + +``` + +- Hoisted +- Declares: `postponeWithTracking` +- Reads (eventual): `assertPostpone`, `React` +- Write: `postponeWithTracking` +- Write (eventual): `React` + +## Item 16: Stmt 11, `Normal` + +```js +export function usedDynamicAPIs(prerenderState) { + return prerenderState.dynamicAccesses.length > 0; +} + +``` + +- Hoisted +- Declares: `usedDynamicAPIs` +- Write: `usedDynamicAPIs` + +## Item 17: Stmt 12, `Normal` + +```js +export function formatDynamicAPIAccesses(prerenderState) { + return prerenderState.dynamicAccesses.filter((access)=>typeof access.stack === 'string' && access.stack.length > 0).map(({ expression, stack })=>{ + stack = stack.split('\n').slice(4).filter((line)=>{ + if (line.includes('node_modules/next/')) { + return false; + } + if (line.includes(' ()')) { + return false; + } + if (line.includes(' (node:')) { + return false; + } + return true; + }).join('\n'); + return `Dynamic API Usage Debug - ${expression}:\n${stack}`; + }); +} + +``` + +- Hoisted +- Declares: `formatDynamicAPIAccesses` +- Write: `formatDynamicAPIAccesses` + +## Item 18: Stmt 13, `Normal` + +```js +function assertPostpone() { + if (!hasPostpone) { + throw new Error(`Invariant: React.unstable_postpone is not defined. This suggests the wrong version of React was loaded. This is a bug in Next.js`); + } +} + +``` + +- Hoisted +- Declares: `assertPostpone` +- Reads (eventual): `hasPostpone` +- Write: `assertPostpone` + +## Item 19: Stmt 14, `Normal` + +```js +export function createPostponedAbortSignal(reason) { + assertPostpone(); + const controller = new AbortController(); + try { + React.unstable_postpone(reason); + } catch (x) { + controller.abort(x); + } + return controller.signal; +} + +``` + +- Hoisted +- Declares: `createPostponedAbortSignal` +- Reads (eventual): `assertPostpone`, `React` +- Write: `createPostponedAbortSignal` +- Write (eventual): `React` + +# Phase 1 +```mermaid +graph TD + Item1; + Item5; + Item2; + Item6; + Item3; + Item7; + Item4; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item20["ModuleEvaluation"]; + Item21; + Item21["export createPrerenderState"]; + Item22; + Item22["export markCurrentScopeAsDynamic"]; + Item23; + Item23["export trackDynamicDataAccessed"]; + Item24; + Item24["export Postpone"]; + Item25; + Item25["export trackDynamicFetch"]; + Item26; + Item26["export usedDynamicAPIs"]; + Item27; + Item27["export formatDynamicAPIAccesses"]; + Item28; + Item28["export createPostponedAbortSignal"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item5; + Item2; + Item6; + Item3; + Item7; + Item4; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item20["ModuleEvaluation"]; + Item21; + Item21["export createPrerenderState"]; + Item22; + Item22["export markCurrentScopeAsDynamic"]; + Item23; + Item23["export trackDynamicDataAccessed"]; + Item24; + Item24["export Postpone"]; + Item25; + Item25["export trackDynamicFetch"]; + Item26; + Item26["export usedDynamicAPIs"]; + Item27; + Item27["export formatDynamicAPIAccesses"]; + Item28; + Item28["export createPostponedAbortSignal"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item9 --> Item5; + Item21 --> Item10; + Item22 --> Item11; + Item23 --> Item12; + Item24 --> Item13; + Item25 --> Item14; + Item26 --> Item16; + Item27 --> Item17; + Item28 --> Item19; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item5; + Item2; + Item6; + Item3; + Item7; + Item4; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item20["ModuleEvaluation"]; + Item21; + Item21["export createPrerenderState"]; + Item22; + Item22["export markCurrentScopeAsDynamic"]; + Item23; + Item23["export trackDynamicDataAccessed"]; + Item24; + Item24["export Postpone"]; + Item25; + Item25["export trackDynamicFetch"]; + Item26; + Item26["export usedDynamicAPIs"]; + Item27; + Item27["export formatDynamicAPIAccesses"]; + Item28; + Item28["export createPostponedAbortSignal"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item9 --> Item5; + Item21 --> Item10; + Item22 --> Item11; + Item23 --> Item12; + Item24 --> Item13; + Item25 --> Item14; + Item26 --> Item16; + Item27 --> Item17; + Item28 --> Item19; + Item11 --> Item8; + Item11 --> Item7; + Item11 --> Item15; + Item11 --> Item6; + Item12 --> Item8; + Item12 --> Item7; + Item12 --> Item15; + Item12 --> Item6; + Item13 --> Item15; + Item14 --> Item15; + Item15 --> Item18; + Item15 --> Item9; + Item15 --> Item5; + Item18 --> Item9; + Item19 --> Item18; + Item19 --> Item9; + Item19 --> Item5; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item5; + Item2; + Item6; + Item3; + Item7; + Item4; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item20["ModuleEvaluation"]; + Item21; + Item21["export createPrerenderState"]; + Item22; + Item22["export markCurrentScopeAsDynamic"]; + Item23; + Item23["export trackDynamicDataAccessed"]; + Item24; + Item24["export Postpone"]; + Item25; + Item25["export trackDynamicFetch"]; + Item26; + Item26["export usedDynamicAPIs"]; + Item27; + Item27["export formatDynamicAPIAccesses"]; + Item28; + Item28["export createPostponedAbortSignal"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item9 --> Item5; + Item21 --> Item10; + Item22 --> Item11; + Item23 --> Item12; + Item24 --> Item13; + Item25 --> Item14; + Item26 --> Item16; + Item27 --> Item17; + Item28 --> Item19; + Item11 --> Item8; + Item11 --> Item7; + Item11 --> Item15; + Item11 --> Item6; + Item12 --> Item8; + Item12 --> Item7; + Item12 --> Item15; + Item12 --> Item6; + Item13 --> Item15; + Item14 --> Item15; + Item15 --> Item18; + Item15 --> Item9; + Item15 --> Item5; + Item18 --> Item9; + Item19 --> Item18; + Item19 --> Item9; + Item19 --> Item5; + Item20 --> Item1; + Item20 --> Item2; + Item20 --> Item3; + Item20 --> Item4; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, ImportBinding(0))]"]; + N1["Items: [ItemId(2, ImportBinding(0))]"]; + N2["Items: [ItemId(3, ImportBinding(0))]"]; + N3["Items: [ItemId(12, Normal)]"]; + N4["Items: [ItemId(Export(("formatDynamicAPIAccesses", #2), "formatDynamicAPIAccesses"))]"]; + N5["Items: [ItemId(11, Normal)]"]; + N6["Items: [ItemId(Export(("usedDynamicAPIs", #2), "usedDynamicAPIs"))]"]; + N7["Items: [ItemId(5, Normal)]"]; + N8["Items: [ItemId(Export(("createPrerenderState", #2), "createPrerenderState"))]"]; + N9["Items: [ItemId(0, ImportBinding(0))]"]; + N10["Items: [ItemId(4, VarDeclarator(0))]"]; + N11["Items: [ItemId(13, Normal)]"]; + N12["Items: [ItemId(14, Normal)]"]; + N13["Items: [ItemId(Export(("createPostponedAbortSignal", #2), "createPostponedAbortSignal"))]"]; + N14["Items: [ItemId(10, Normal)]"]; + N15["Items: [ItemId(9, Normal)]"]; + N16["Items: [ItemId(Export(("trackDynamicFetch", #2), "trackDynamicFetch"))]"]; + N17["Items: [ItemId(8, Normal)]"]; + N18["Items: [ItemId(Export(("Postpone", #2), "Postpone"))]"]; + N19["Items: [ItemId(7, Normal)]"]; + N20["Items: [ItemId(Export(("trackDynamicDataAccessed", #2), "trackDynamicDataAccessed"))]"]; + N21["Items: [ItemId(6, Normal)]"]; + N22["Items: [ItemId(Export(("markCurrentScopeAsDynamic", #2), "markCurrentScopeAsDynamic"))]"]; + N23["Items: [ItemId(0, ImportOfModule)]"]; + N24["Items: [ItemId(1, ImportOfModule)]"]; + N25["Items: [ItemId(2, ImportOfModule)]"]; + N26["Items: [ItemId(3, ImportOfModule)]"]; + N27["Items: [ItemId(ModuleEvaluation)]"]; + N24 --> N23; + N25 --> N23; + N25 --> N24; + N26 --> N23; + N26 --> N24; + N26 --> N25; + N10 --> N9; + N8 --> N7; + N22 --> N21; + N20 --> N19; + N18 --> N17; + N16 --> N15; + N6 --> N5; + N4 --> N3; + N13 --> N12; + N21 --> N2; + N21 --> N1; + N21 --> N14; + N21 --> N0; + N19 --> N2; + N19 --> N1; + N19 --> N14; + N19 --> N0; + N17 --> N14; + N15 --> N14; + N14 --> N11; + N14 --> N10; + N14 --> N9; + N11 --> N10; + N12 --> N11; + N12 --> N10; + N12 --> N9; + N27 --> N23; + N27 --> N24; + N27 --> N25; + N27 --> N26; +``` +# Entrypoints + +``` +{ + Export( + "createPrerenderState", + ): 8, + ModuleEvaluation: 27, + Export( + "markCurrentScopeAsDynamic", + ): 22, + Export( + "usedDynamicAPIs", + ): 6, + Export( + "trackDynamicFetch", + ): 16, + Export( + "Postpone", + ): 18, + Export( + "trackDynamicDataAccessed", + ): 20, + Export( + "createPostponedAbortSignal", + ): 13, + Export( + "formatDynamicAPIAccesses", + ): 4, + Exports: 28, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { DynamicServerError } from '../../client/components/hooks-server-context'; +export { DynamicServerError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { StaticGenBailoutError } from '../../client/components/static-generation-bailout'; +export { StaticGenBailoutError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { getPathname } from '../../lib/url'; +export { getPathname } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +function formatDynamicAPIAccesses(prerenderState) { + return prerenderState.dynamicAccesses.filter((access)=>typeof access.stack === 'string' && access.stack.length > 0).map(({ expression, stack })=>{ + stack = stack.split('\n').slice(4).filter((line)=>{ + if (line.includes('node_modules/next/')) { + return false; + } + if (line.includes(' ()')) { + return false; + } + if (line.includes(' (node:')) { + return false; + } + return true; + }).join('\n'); + return `Dynamic API Usage Debug - ${expression}:\n${stack}`; + }); +} +export { formatDynamicAPIAccesses } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { formatDynamicAPIAccesses } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { formatDynamicAPIAccesses }; + +``` +## Part 5 +```js +function usedDynamicAPIs(prerenderState) { + return prerenderState.dynamicAccesses.length > 0; +} +export { usedDynamicAPIs } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { usedDynamicAPIs } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { usedDynamicAPIs }; + +``` +## Part 7 +```js +function createPrerenderState(isDebugSkeleton) { + return { + isDebugSkeleton, + dynamicAccesses: [] + }; +} +export { createPrerenderState } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { createPrerenderState } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +export { createPrerenderState }; + +``` +## Part 9 +```js +import React from 'react'; +export { React } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { React } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +const hasPostpone = typeof React.unstable_postpone === 'function'; +export { hasPostpone } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { hasPostpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +function assertPostpone() { + if (!hasPostpone) { + throw new Error(`Invariant: React.unstable_postpone is not defined. This suggests the wrong version of React was loaded. This is a bug in Next.js`); + } +} +export { assertPostpone } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { React } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { assertPostpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +function createPostponedAbortSignal(reason) { + assertPostpone(); + const controller = new AbortController(); + try { + React.unstable_postpone(reason); + } catch (x) { + controller.abort(x); + } + return controller.signal; +} +export { createPostponedAbortSignal } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { createPostponedAbortSignal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { createPostponedAbortSignal }; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { React } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { assertPostpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +function postponeWithTracking(prerenderState, expression, pathname) { + assertPostpone(); + const reason = `Route ${pathname} needs to bail out of prerendering at this point because it used ${expression}. ` + `React throws this special object to indicate where. It should not be caught by ` + `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`; + prerenderState.dynamicAccesses.push({ + stack: prerenderState.isDebugSkeleton ? new Error().stack : undefined, + expression + }); + React.unstable_postpone(reason); +} +export { postponeWithTracking } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { postponeWithTracking } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +function trackDynamicFetch(store, expression) { + if (!store.prerenderState || store.isUnstableCacheCallback) return; + postponeWithTracking(store.prerenderState, expression, store.urlPathname); +} +export { trackDynamicFetch } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { trackDynamicFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +export { trackDynamicFetch }; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { postponeWithTracking } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +function Postpone({ reason, prerenderState, pathname }) { + postponeWithTracking(prerenderState, reason, pathname); +} +export { Postpone } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import { Postpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +export { Postpone }; + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { DynamicServerError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { getPathname } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { StaticGenBailoutError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { postponeWithTracking } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +function trackDynamicDataAccessed(store, expression) { + const pathname = getPathname(store.urlPathname); + if (store.isUnstableCacheCallback) { + throw new Error(`Route ${pathname} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`); + } else if (store.dynamicShouldError) { + throw new StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); + } else if (store.prerenderState) { + postponeWithTracking(store.prerenderState, expression, pathname); + } else { + store.revalidate = 0; + if (store.isStaticGeneration) { + const err = new DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); + store.dynamicUsageDescription = expression; + store.dynamicUsageStack = err.stack; + throw err; + } + } +} +export { trackDynamicDataAccessed } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import { trackDynamicDataAccessed } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +export { trackDynamicDataAccessed }; + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { DynamicServerError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { getPathname } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { StaticGenBailoutError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { postponeWithTracking } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +function markCurrentScopeAsDynamic(store, expression) { + const pathname = getPathname(store.urlPathname); + if (store.isUnstableCacheCallback) { + return; + } else if (store.dynamicShouldError) { + throw new StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); + } else if (store.prerenderState) { + postponeWithTracking(store.prerenderState, expression, pathname); + } else { + store.revalidate = 0; + if (store.isStaticGeneration) { + const err = new DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); + store.dynamicUsageDescription = expression; + store.dynamicUsageStack = err.stack; + throw err; + } + } +} +export { markCurrentScopeAsDynamic } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import { markCurrentScopeAsDynamic } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +export { markCurrentScopeAsDynamic }; + +``` +## Part 23 +```js +import 'react'; + +``` +## Part 24 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import '../../client/components/hooks-server-context'; + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import '../../client/components/static-generation-bailout'; + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import '../../lib/url'; + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +"module evaluation"; + +``` +## Part 28 +```js +export { formatDynamicAPIAccesses } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export formatDynamicAPIAccesses" +}; +export { usedDynamicAPIs } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export usedDynamicAPIs" +}; +export { createPrerenderState } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export createPrerenderState" +}; +export { createPostponedAbortSignal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export createPostponedAbortSignal" +}; +export { trackDynamicFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export trackDynamicFetch" +}; +export { Postpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export Postpone" +}; +export { trackDynamicDataAccessed } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export trackDynamicDataAccessed" +}; +export { markCurrentScopeAsDynamic } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export markCurrentScopeAsDynamic" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "createPrerenderState", + ): 8, + ModuleEvaluation: 27, + Export( + "markCurrentScopeAsDynamic", + ): 22, + Export( + "usedDynamicAPIs", + ): 6, + Export( + "trackDynamicFetch", + ): 16, + Export( + "Postpone", + ): 18, + Export( + "trackDynamicDataAccessed", + ): 20, + Export( + "createPostponedAbortSignal", + ): 13, + Export( + "formatDynamicAPIAccesses", + ): 4, + Exports: 28, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { DynamicServerError } from '../../client/components/hooks-server-context'; +export { DynamicServerError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { StaticGenBailoutError } from '../../client/components/static-generation-bailout'; +export { StaticGenBailoutError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { getPathname } from '../../lib/url'; +export { getPathname } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +function formatDynamicAPIAccesses(prerenderState) { + return prerenderState.dynamicAccesses.filter((access)=>typeof access.stack === 'string' && access.stack.length > 0).map(({ expression, stack })=>{ + stack = stack.split('\n').slice(4).filter((line)=>{ + if (line.includes('node_modules/next/')) { + return false; + } + if (line.includes(' ()')) { + return false; + } + if (line.includes(' (node:')) { + return false; + } + return true; + }).join('\n'); + return `Dynamic API Usage Debug - ${expression}:\n${stack}`; + }); +} +export { formatDynamicAPIAccesses } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { formatDynamicAPIAccesses } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { formatDynamicAPIAccesses }; + +``` +## Part 5 +```js +function usedDynamicAPIs(prerenderState) { + return prerenderState.dynamicAccesses.length > 0; +} +export { usedDynamicAPIs } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { usedDynamicAPIs } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { usedDynamicAPIs }; + +``` +## Part 7 +```js +function createPrerenderState(isDebugSkeleton) { + return { + isDebugSkeleton, + dynamicAccesses: [] + }; +} +export { createPrerenderState } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { createPrerenderState } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +export { createPrerenderState }; + +``` +## Part 9 +```js +import React from 'react'; +export { React } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { React } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +const hasPostpone = typeof React.unstable_postpone === 'function'; +export { hasPostpone } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { hasPostpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +function assertPostpone() { + if (!hasPostpone) { + throw new Error(`Invariant: React.unstable_postpone is not defined. This suggests the wrong version of React was loaded. This is a bug in Next.js`); + } +} +export { assertPostpone } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { React } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { assertPostpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +function createPostponedAbortSignal(reason) { + assertPostpone(); + const controller = new AbortController(); + try { + React.unstable_postpone(reason); + } catch (x) { + controller.abort(x); + } + return controller.signal; +} +export { createPostponedAbortSignal } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { createPostponedAbortSignal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { createPostponedAbortSignal }; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { React } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { assertPostpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +function postponeWithTracking(prerenderState, expression, pathname) { + assertPostpone(); + const reason = `Route ${pathname} needs to bail out of prerendering at this point because it used ${expression}. ` + `React throws this special object to indicate where. It should not be caught by ` + `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error`; + prerenderState.dynamicAccesses.push({ + stack: prerenderState.isDebugSkeleton ? new Error().stack : undefined, + expression + }); + React.unstable_postpone(reason); +} +export { postponeWithTracking } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { postponeWithTracking } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +function trackDynamicFetch(store, expression) { + if (!store.prerenderState || store.isUnstableCacheCallback) return; + postponeWithTracking(store.prerenderState, expression, store.urlPathname); +} +export { trackDynamicFetch } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { trackDynamicFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +export { trackDynamicFetch }; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { postponeWithTracking } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +function Postpone({ reason, prerenderState, pathname }) { + postponeWithTracking(prerenderState, reason, pathname); +} +export { Postpone } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import { Postpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +export { Postpone }; + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { DynamicServerError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { getPathname } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { StaticGenBailoutError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { postponeWithTracking } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +function trackDynamicDataAccessed(store, expression) { + const pathname = getPathname(store.urlPathname); + if (store.isUnstableCacheCallback) { + throw new Error(`Route ${pathname} used "${expression}" inside a function cached with "unstable_cache(...)". Accessing Dynamic data sources inside a cache scope is not supported. If you need this data inside a cached function use "${expression}" outside of the cached function and pass the required dynamic data in as an argument. See more info here: https://nextjs.org/docs/app/api-reference/functions/unstable_cache`); + } else if (store.dynamicShouldError) { + throw new StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); + } else if (store.prerenderState) { + postponeWithTracking(store.prerenderState, expression, pathname); + } else { + store.revalidate = 0; + if (store.isStaticGeneration) { + const err = new DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); + store.dynamicUsageDescription = expression; + store.dynamicUsageStack = err.stack; + throw err; + } + } +} +export { trackDynamicDataAccessed } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import { trackDynamicDataAccessed } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +export { trackDynamicDataAccessed }; + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { DynamicServerError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { getPathname } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { StaticGenBailoutError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { postponeWithTracking } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +function markCurrentScopeAsDynamic(store, expression) { + const pathname = getPathname(store.urlPathname); + if (store.isUnstableCacheCallback) { + return; + } else if (store.dynamicShouldError) { + throw new StaticGenBailoutError(`Route ${pathname} with \`dynamic = "error"\` couldn't be rendered statically because it used \`${expression}\`. See more info here: https://nextjs.org/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering`); + } else if (store.prerenderState) { + postponeWithTracking(store.prerenderState, expression, pathname); + } else { + store.revalidate = 0; + if (store.isStaticGeneration) { + const err = new DynamicServerError(`Route ${pathname} couldn't be rendered statically because it used ${expression}. See more info here: https://nextjs.org/docs/messages/dynamic-server-error`); + store.dynamicUsageDescription = expression; + store.dynamicUsageStack = err.stack; + throw err; + } + } +} +export { markCurrentScopeAsDynamic } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import { markCurrentScopeAsDynamic } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +export { markCurrentScopeAsDynamic }; + +``` +## Part 23 +```js +import 'react'; + +``` +## Part 24 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import '../../client/components/hooks-server-context'; + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import '../../client/components/static-generation-bailout'; + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import '../../lib/url'; + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +"module evaluation"; + +``` +## Part 28 +```js +export { formatDynamicAPIAccesses } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export formatDynamicAPIAccesses" +}; +export { usedDynamicAPIs } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export usedDynamicAPIs" +}; +export { createPrerenderState } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export createPrerenderState" +}; +export { createPostponedAbortSignal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export createPostponedAbortSignal" +}; +export { trackDynamicFetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export trackDynamicFetch" +}; +export { Postpone } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export Postpone" +}; +export { trackDynamicDataAccessed } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export trackDynamicDataAccessed" +}; +export { markCurrentScopeAsDynamic } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export markCurrentScopeAsDynamic" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-3/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-3/input.js new file mode 100644 index 0000000000000..441b34ae57bca --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-3/input.js @@ -0,0 +1,172 @@ +import { createConnection } from "node:net"; +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; +import { getProperError } from "./error"; +export function structuredError(e) { + e = getProperError(e); + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : [] + }; +} +function createIpc(port) { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue = []; + const recvPromiseResolveQueue = []; + function pushPacket(packet) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8"))); + } else { + packetQueue.push(packet); + } + } + let state = { + type: "waiting" + }; + let buffer = Buffer.alloc(0); + socket.once("connect", ()=>{ + socket.on("data", (chunk)=>{ + buffer = Buffer.concat([ + buffer, + chunk + ]); + loop: while(true){ + switch(state.type){ + case "waiting": + { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { + type: "packet", + length + }; + } else { + break loop; + } + break; + } + case "packet": + { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { + type: "waiting" + }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + socket.once("close", ()=>{ + process.exit(0); + }); + function send(message) { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + return new Promise((resolve, reject)=>{ + socket.write(packet, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + function sendReady() { + const length = Buffer.from([ + 0, + 0, + 0, + 0 + ]); + return new Promise((resolve, reject)=>{ + socket.write(length, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + return { + async recv () { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")); + } + const result = await new Promise((resolve)=>{ + recvPromiseResolveQueue.push((result)=>{ + resolve(result); + }); + }); + return result; + }, + send (message) { + return send(message); + }, + sendReady, + async sendError (error) { + try { + await send({ + type: "error", + ...structuredError(error) + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + process.exit(1); + } + process.exit(0); + } + }; +} +const PORT = process.argv[2]; +export const IPC = createIpc(parseInt(PORT, 10)); +process.on("uncaughtException", (err)=>{ + IPC.sendError(err); +}); +const improveConsole = (name, stream, addStack)=>{ + const original = console[name]; + const stdio = process[stream]; + console[name] = (...args)=>{ + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; +improveConsole("error", "stderr", true); +improveConsole("warn", "stderr", true); +improveConsole("count", "stdout", true); +improveConsole("trace", "stderr", false); +improveConsole("log", "stdout", true); +improveConsole("group", "stdout", true); +improveConsole("groupCollapsed", "stdout", true); +improveConsole("table", "stdout", true); +improveConsole("debug", "stdout", true); +improveConsole("info", "stdout", true); +improveConsole("dir", "stdout", true); +improveConsole("dirxml", "stdout", true); +improveConsole("timeEnd", "stdout", true); +improveConsole("timeLog", "stdout", true); +improveConsole("timeStamp", "stdout", true); +improveConsole("assert", "stderr", true); diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-3/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-3/output.md new file mode 100644 index 0000000000000..de4f99770472e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/failed-3/output.md @@ -0,0 +1,4984 @@ +# Items + +Count: 31 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { createConnection } from "node:net"; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { createConnection } from "node:net"; + +``` + +- Hoisted +- Declares: `createConnection` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; + +``` + +- Hoisted +- Declares: `parseStackTrace` + +## Item 5: Stmt 2, `ImportOfModule` + +```js +import { getProperError } from "./error"; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 2, `ImportBinding(0)` + +```js +import { getProperError } from "./error"; + +``` + +- Hoisted +- Declares: `getProperError` + +## Item 7: Stmt 3, `Normal` + +```js +export function structuredError(e) { + e = getProperError(e); + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : [] + }; +} + +``` + +- Hoisted +- Declares: `structuredError` +- Reads (eventual): `getProperError`, `parseStackTrace` +- Write: `structuredError` + +## Item 8: Stmt 4, `Normal` + +```js +function createIpc(port) { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue = []; + const recvPromiseResolveQueue = []; + function pushPacket(packet) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8"))); + } else { + packetQueue.push(packet); + } + } + let state = { + type: "waiting" + }; + let buffer = Buffer.alloc(0); + socket.once("connect", ()=>{ + socket.on("data", (chunk)=>{ + buffer = Buffer.concat([ + buffer, + chunk + ]); + loop: while(true){ + switch(state.type){ + case "waiting": + { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { + type: "packet", + length + }; + } else { + break loop; + } + break; + } + case "packet": + { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { + type: "waiting" + }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + socket.once("close", ()=>{ + process.exit(0); + }); + function send(message) { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + return new Promise((resolve, reject)=>{ + socket.write(packet, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + function sendReady() { + const length = Buffer.from([ + 0, + 0, + 0, + 0 + ]); + return new Promise((resolve, reject)=>{ + socket.write(length, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + return { + async recv () { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")); + } + const result = await new Promise((resolve)=>{ + recvPromiseResolveQueue.push((result)=>{ + resolve(result); + }); + }); + return result; + }, + send (message) { + return send(message); + }, + sendReady, + async sendError (error) { + try { + await send({ + type: "error", + ...structuredError(error) + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + process.exit(1); + } + process.exit(0); + } + }; +} + +``` + +- Hoisted +- Declares: `createIpc` +- Reads (eventual): `createConnection`, `loop`, `structuredError` +- Write: `createIpc` + +## Item 9: Stmt 5, `VarDeclarator(0)` + +```js +const PORT = process.argv[2]; + +``` + +- Side effects +- Declares: `PORT` +- Write: `PORT` + +## Item 10: Stmt 6, `VarDeclarator(0)` + +```js +export const IPC = createIpc(parseInt(PORT, 10)); + +``` + +- Side effects +- Declares: `IPC` +- Reads: `createIpc`, `PORT` +- Write: `IPC` + +## Item 11: Stmt 7, `Normal` + +```js +process.on("uncaughtException", (err)=>{ + IPC.sendError(err); +}); + +``` + +- Side effects +- Reads: `IPC` +- Write: `IPC` + +## Item 12: Stmt 8, `VarDeclarator(0)` + +```js +const improveConsole = (name, stream, addStack)=>{ + const original = console[name]; + const stdio = process[stream]; + console[name] = (...args)=>{ + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; + +``` + +- Side effects +- Declares: `improveConsole` +- Write: `improveConsole` + +## Item 13: Stmt 9, `Normal` + +```js +improveConsole("error", "stderr", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 14: Stmt 10, `Normal` + +```js +improveConsole("warn", "stderr", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 15: Stmt 11, `Normal` + +```js +improveConsole("count", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 16: Stmt 12, `Normal` + +```js +improveConsole("trace", "stderr", false); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 17: Stmt 13, `Normal` + +```js +improveConsole("log", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 18: Stmt 14, `Normal` + +```js +improveConsole("group", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 19: Stmt 15, `Normal` + +```js +improveConsole("groupCollapsed", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 20: Stmt 16, `Normal` + +```js +improveConsole("table", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 21: Stmt 17, `Normal` + +```js +improveConsole("debug", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 22: Stmt 18, `Normal` + +```js +improveConsole("info", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 23: Stmt 19, `Normal` + +```js +improveConsole("dir", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 24: Stmt 20, `Normal` + +```js +improveConsole("dirxml", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 25: Stmt 21, `Normal` + +```js +improveConsole("timeEnd", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 26: Stmt 22, `Normal` + +```js +improveConsole("timeLog", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 27: Stmt 23, `Normal` + +```js +improveConsole("timeStamp", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 28: Stmt 24, `Normal` + +```js +improveConsole("assert", "stderr", true); + +``` + +- Side effects +- Reads: `improveConsole` + +# Phase 1 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item29["ModuleEvaluation"]; + Item30; + Item30["export structuredError"]; + Item31; + Item31["export IPC"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item29["ModuleEvaluation"]; + Item30; + Item30["export structuredError"]; + Item31; + Item31["export IPC"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 -.-> Item6; + Item9 -.-> Item5; + Item9 -.-> Item4; + Item9 -.-> Item7; + Item10 --> Item8; + Item10 --> Item9; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item3; + Item10 -.-> Item6; + Item10 -.-> Item5; + Item10 -.-> Item4; + Item10 -.-> Item7; + Item11 --> Item10; + Item11 --> Item1; + Item11 --> Item2; + Item11 --> Item3; + Item11 --> Item9; + Item11 -.-> Item6; + Item11 -.-> Item5; + Item11 -.-> Item4; + Item11 -.-> Item7; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item11; + Item12 -.-> Item6; + Item12 -.-> Item5; + Item12 -.-> Item4; + Item12 -.-> Item7; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item9; + Item13 --> Item10; + Item13 --> Item11; + Item13 -.-> Item6; + Item13 -.-> Item5; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item14 --> Item12; + Item14 --> Item1; + Item14 --> Item2; + Item14 --> Item3; + Item14 --> Item9; + Item14 --> Item10; + Item14 --> Item11; + Item14 --> Item13; + Item14 -.-> Item6; + Item14 -.-> Item5; + Item14 -.-> Item4; + Item14 -.-> Item7; + Item15 --> Item12; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item11; + Item15 --> Item13; + Item15 --> Item14; + Item15 -.-> Item6; + Item15 -.-> Item5; + Item15 -.-> Item4; + Item15 -.-> Item7; + Item16 --> Item12; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item9; + Item16 --> Item10; + Item16 --> Item11; + Item16 --> Item13; + Item16 --> Item14; + Item16 --> Item15; + Item16 -.-> Item6; + Item16 -.-> Item5; + Item16 -.-> Item4; + Item16 -.-> Item7; + Item17 --> Item12; + Item17 --> Item1; + Item17 --> Item2; + Item17 --> Item3; + Item17 --> Item9; + Item17 --> Item10; + Item17 --> Item11; + Item17 --> Item13; + Item17 --> Item14; + Item17 --> Item15; + Item17 --> Item16; + Item17 -.-> Item6; + Item17 -.-> Item5; + Item17 -.-> Item4; + Item17 -.-> Item7; + Item18 --> Item12; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item11; + Item18 --> Item13; + Item18 --> Item14; + Item18 --> Item15; + Item18 --> Item16; + Item18 --> Item17; + Item18 -.-> Item6; + Item18 -.-> Item5; + Item18 -.-> Item4; + Item18 -.-> Item7; + Item19 --> Item12; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item9; + Item19 --> Item10; + Item19 --> Item11; + Item19 --> Item13; + Item19 --> Item14; + Item19 --> Item15; + Item19 --> Item16; + Item19 --> Item17; + Item19 --> Item18; + Item19 -.-> Item6; + Item19 -.-> Item5; + Item19 -.-> Item4; + Item19 -.-> Item7; + Item20 --> Item12; + Item20 --> Item1; + Item20 --> Item2; + Item20 --> Item3; + Item20 --> Item9; + Item20 --> Item10; + Item20 --> Item11; + Item20 --> Item13; + Item20 --> Item14; + Item20 --> Item15; + Item20 --> Item16; + Item20 --> Item17; + Item20 --> Item18; + Item20 --> Item19; + Item20 -.-> Item6; + Item20 -.-> Item5; + Item20 -.-> Item4; + Item20 -.-> Item7; + Item21 --> Item12; + Item21 --> Item1; + Item21 --> Item2; + Item21 --> Item3; + Item21 --> Item9; + Item21 --> Item10; + Item21 --> Item11; + Item21 --> Item13; + Item21 --> Item14; + Item21 --> Item15; + Item21 --> Item16; + Item21 --> Item17; + Item21 --> Item18; + Item21 --> Item19; + Item21 --> Item20; + Item21 -.-> Item6; + Item21 -.-> Item5; + Item21 -.-> Item4; + Item21 -.-> Item7; + Item22 --> Item12; + Item22 --> Item1; + Item22 --> Item2; + Item22 --> Item3; + Item22 --> Item9; + Item22 --> Item10; + Item22 --> Item11; + Item22 --> Item13; + Item22 --> Item14; + Item22 --> Item15; + Item22 --> Item16; + Item22 --> Item17; + Item22 --> Item18; + Item22 --> Item19; + Item22 --> Item20; + Item22 --> Item21; + Item22 -.-> Item6; + Item22 -.-> Item5; + Item22 -.-> Item4; + Item22 -.-> Item7; + Item23 --> Item12; + Item23 --> Item1; + Item23 --> Item2; + Item23 --> Item3; + Item23 --> Item9; + Item23 --> Item10; + Item23 --> Item11; + Item23 --> Item13; + Item23 --> Item14; + Item23 --> Item15; + Item23 --> Item16; + Item23 --> Item17; + Item23 --> Item18; + Item23 --> Item19; + Item23 --> Item20; + Item23 --> Item21; + Item23 --> Item22; + Item23 -.-> Item6; + Item23 -.-> Item5; + Item23 -.-> Item4; + Item23 -.-> Item7; + Item24 --> Item12; + Item24 --> Item1; + Item24 --> Item2; + Item24 --> Item3; + Item24 --> Item9; + Item24 --> Item10; + Item24 --> Item11; + Item24 --> Item13; + Item24 --> Item14; + Item24 --> Item15; + Item24 --> Item16; + Item24 --> Item17; + Item24 --> Item18; + Item24 --> Item19; + Item24 --> Item20; + Item24 --> Item21; + Item24 --> Item22; + Item24 --> Item23; + Item24 -.-> Item6; + Item24 -.-> Item5; + Item24 -.-> Item4; + Item24 -.-> Item7; + Item25 --> Item12; + Item25 --> Item1; + Item25 --> Item2; + Item25 --> Item3; + Item25 --> Item9; + Item25 --> Item10; + Item25 --> Item11; + Item25 --> Item13; + Item25 --> Item14; + Item25 --> Item15; + Item25 --> Item16; + Item25 --> Item17; + Item25 --> Item18; + Item25 --> Item19; + Item25 --> Item20; + Item25 --> Item21; + Item25 --> Item22; + Item25 --> Item23; + Item25 --> Item24; + Item25 -.-> Item6; + Item25 -.-> Item5; + Item25 -.-> Item4; + Item25 -.-> Item7; + Item26 --> Item12; + Item26 --> Item1; + Item26 --> Item2; + Item26 --> Item3; + Item26 --> Item9; + Item26 --> Item10; + Item26 --> Item11; + Item26 --> Item13; + Item26 --> Item14; + Item26 --> Item15; + Item26 --> Item16; + Item26 --> Item17; + Item26 --> Item18; + Item26 --> Item19; + Item26 --> Item20; + Item26 --> Item21; + Item26 --> Item22; + Item26 --> Item23; + Item26 --> Item24; + Item26 --> Item25; + Item26 -.-> Item6; + Item26 -.-> Item5; + Item26 -.-> Item4; + Item26 -.-> Item7; + Item27 --> Item12; + Item27 --> Item1; + Item27 --> Item2; + Item27 --> Item3; + Item27 --> Item9; + Item27 --> Item10; + Item27 --> Item11; + Item27 --> Item13; + Item27 --> Item14; + Item27 --> Item15; + Item27 --> Item16; + Item27 --> Item17; + Item27 --> Item18; + Item27 --> Item19; + Item27 --> Item20; + Item27 --> Item21; + Item27 --> Item22; + Item27 --> Item23; + Item27 --> Item24; + Item27 --> Item25; + Item27 --> Item26; + Item27 -.-> Item6; + Item27 -.-> Item5; + Item27 -.-> Item4; + Item27 -.-> Item7; + Item28 --> Item12; + Item28 --> Item1; + Item28 --> Item2; + Item28 --> Item3; + Item28 --> Item9; + Item28 --> Item10; + Item28 --> Item11; + Item28 --> Item13; + Item28 --> Item14; + Item28 --> Item15; + Item28 --> Item16; + Item28 --> Item17; + Item28 --> Item18; + Item28 --> Item19; + Item28 --> Item20; + Item28 --> Item21; + Item28 --> Item22; + Item28 --> Item23; + Item28 --> Item24; + Item28 --> Item25; + Item28 --> Item26; + Item28 --> Item27; + Item28 -.-> Item6; + Item28 -.-> Item5; + Item28 -.-> Item4; + Item28 -.-> Item7; + Item30 --> Item7; + Item31 --> Item11; + Item31 --> Item10; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item29["ModuleEvaluation"]; + Item30; + Item30["export structuredError"]; + Item31; + Item31["export IPC"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 -.-> Item6; + Item9 -.-> Item5; + Item9 -.-> Item4; + Item9 -.-> Item7; + Item10 --> Item8; + Item10 --> Item9; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item3; + Item10 -.-> Item6; + Item10 -.-> Item5; + Item10 -.-> Item4; + Item10 -.-> Item7; + Item11 --> Item10; + Item11 --> Item1; + Item11 --> Item2; + Item11 --> Item3; + Item11 --> Item9; + Item11 -.-> Item6; + Item11 -.-> Item5; + Item11 -.-> Item4; + Item11 -.-> Item7; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item11; + Item12 -.-> Item6; + Item12 -.-> Item5; + Item12 -.-> Item4; + Item12 -.-> Item7; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item9; + Item13 --> Item10; + Item13 --> Item11; + Item13 -.-> Item6; + Item13 -.-> Item5; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item14 --> Item12; + Item14 --> Item1; + Item14 --> Item2; + Item14 --> Item3; + Item14 --> Item9; + Item14 --> Item10; + Item14 --> Item11; + Item14 --> Item13; + Item14 -.-> Item6; + Item14 -.-> Item5; + Item14 -.-> Item4; + Item14 -.-> Item7; + Item15 --> Item12; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item11; + Item15 --> Item13; + Item15 --> Item14; + Item15 -.-> Item6; + Item15 -.-> Item5; + Item15 -.-> Item4; + Item15 -.-> Item7; + Item16 --> Item12; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item9; + Item16 --> Item10; + Item16 --> Item11; + Item16 --> Item13; + Item16 --> Item14; + Item16 --> Item15; + Item16 -.-> Item6; + Item16 -.-> Item5; + Item16 -.-> Item4; + Item16 -.-> Item7; + Item17 --> Item12; + Item17 --> Item1; + Item17 --> Item2; + Item17 --> Item3; + Item17 --> Item9; + Item17 --> Item10; + Item17 --> Item11; + Item17 --> Item13; + Item17 --> Item14; + Item17 --> Item15; + Item17 --> Item16; + Item17 -.-> Item6; + Item17 -.-> Item5; + Item17 -.-> Item4; + Item17 -.-> Item7; + Item18 --> Item12; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item11; + Item18 --> Item13; + Item18 --> Item14; + Item18 --> Item15; + Item18 --> Item16; + Item18 --> Item17; + Item18 -.-> Item6; + Item18 -.-> Item5; + Item18 -.-> Item4; + Item18 -.-> Item7; + Item19 --> Item12; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item9; + Item19 --> Item10; + Item19 --> Item11; + Item19 --> Item13; + Item19 --> Item14; + Item19 --> Item15; + Item19 --> Item16; + Item19 --> Item17; + Item19 --> Item18; + Item19 -.-> Item6; + Item19 -.-> Item5; + Item19 -.-> Item4; + Item19 -.-> Item7; + Item20 --> Item12; + Item20 --> Item1; + Item20 --> Item2; + Item20 --> Item3; + Item20 --> Item9; + Item20 --> Item10; + Item20 --> Item11; + Item20 --> Item13; + Item20 --> Item14; + Item20 --> Item15; + Item20 --> Item16; + Item20 --> Item17; + Item20 --> Item18; + Item20 --> Item19; + Item20 -.-> Item6; + Item20 -.-> Item5; + Item20 -.-> Item4; + Item20 -.-> Item7; + Item21 --> Item12; + Item21 --> Item1; + Item21 --> Item2; + Item21 --> Item3; + Item21 --> Item9; + Item21 --> Item10; + Item21 --> Item11; + Item21 --> Item13; + Item21 --> Item14; + Item21 --> Item15; + Item21 --> Item16; + Item21 --> Item17; + Item21 --> Item18; + Item21 --> Item19; + Item21 --> Item20; + Item21 -.-> Item6; + Item21 -.-> Item5; + Item21 -.-> Item4; + Item21 -.-> Item7; + Item22 --> Item12; + Item22 --> Item1; + Item22 --> Item2; + Item22 --> Item3; + Item22 --> Item9; + Item22 --> Item10; + Item22 --> Item11; + Item22 --> Item13; + Item22 --> Item14; + Item22 --> Item15; + Item22 --> Item16; + Item22 --> Item17; + Item22 --> Item18; + Item22 --> Item19; + Item22 --> Item20; + Item22 --> Item21; + Item22 -.-> Item6; + Item22 -.-> Item5; + Item22 -.-> Item4; + Item22 -.-> Item7; + Item23 --> Item12; + Item23 --> Item1; + Item23 --> Item2; + Item23 --> Item3; + Item23 --> Item9; + Item23 --> Item10; + Item23 --> Item11; + Item23 --> Item13; + Item23 --> Item14; + Item23 --> Item15; + Item23 --> Item16; + Item23 --> Item17; + Item23 --> Item18; + Item23 --> Item19; + Item23 --> Item20; + Item23 --> Item21; + Item23 --> Item22; + Item23 -.-> Item6; + Item23 -.-> Item5; + Item23 -.-> Item4; + Item23 -.-> Item7; + Item24 --> Item12; + Item24 --> Item1; + Item24 --> Item2; + Item24 --> Item3; + Item24 --> Item9; + Item24 --> Item10; + Item24 --> Item11; + Item24 --> Item13; + Item24 --> Item14; + Item24 --> Item15; + Item24 --> Item16; + Item24 --> Item17; + Item24 --> Item18; + Item24 --> Item19; + Item24 --> Item20; + Item24 --> Item21; + Item24 --> Item22; + Item24 --> Item23; + Item24 -.-> Item6; + Item24 -.-> Item5; + Item24 -.-> Item4; + Item24 -.-> Item7; + Item25 --> Item12; + Item25 --> Item1; + Item25 --> Item2; + Item25 --> Item3; + Item25 --> Item9; + Item25 --> Item10; + Item25 --> Item11; + Item25 --> Item13; + Item25 --> Item14; + Item25 --> Item15; + Item25 --> Item16; + Item25 --> Item17; + Item25 --> Item18; + Item25 --> Item19; + Item25 --> Item20; + Item25 --> Item21; + Item25 --> Item22; + Item25 --> Item23; + Item25 --> Item24; + Item25 -.-> Item6; + Item25 -.-> Item5; + Item25 -.-> Item4; + Item25 -.-> Item7; + Item26 --> Item12; + Item26 --> Item1; + Item26 --> Item2; + Item26 --> Item3; + Item26 --> Item9; + Item26 --> Item10; + Item26 --> Item11; + Item26 --> Item13; + Item26 --> Item14; + Item26 --> Item15; + Item26 --> Item16; + Item26 --> Item17; + Item26 --> Item18; + Item26 --> Item19; + Item26 --> Item20; + Item26 --> Item21; + Item26 --> Item22; + Item26 --> Item23; + Item26 --> Item24; + Item26 --> Item25; + Item26 -.-> Item6; + Item26 -.-> Item5; + Item26 -.-> Item4; + Item26 -.-> Item7; + Item27 --> Item12; + Item27 --> Item1; + Item27 --> Item2; + Item27 --> Item3; + Item27 --> Item9; + Item27 --> Item10; + Item27 --> Item11; + Item27 --> Item13; + Item27 --> Item14; + Item27 --> Item15; + Item27 --> Item16; + Item27 --> Item17; + Item27 --> Item18; + Item27 --> Item19; + Item27 --> Item20; + Item27 --> Item21; + Item27 --> Item22; + Item27 --> Item23; + Item27 --> Item24; + Item27 --> Item25; + Item27 --> Item26; + Item27 -.-> Item6; + Item27 -.-> Item5; + Item27 -.-> Item4; + Item27 -.-> Item7; + Item28 --> Item12; + Item28 --> Item1; + Item28 --> Item2; + Item28 --> Item3; + Item28 --> Item9; + Item28 --> Item10; + Item28 --> Item11; + Item28 --> Item13; + Item28 --> Item14; + Item28 --> Item15; + Item28 --> Item16; + Item28 --> Item17; + Item28 --> Item18; + Item28 --> Item19; + Item28 --> Item20; + Item28 --> Item21; + Item28 --> Item22; + Item28 --> Item23; + Item28 --> Item24; + Item28 --> Item25; + Item28 --> Item26; + Item28 --> Item27; + Item28 -.-> Item6; + Item28 -.-> Item5; + Item28 -.-> Item4; + Item28 -.-> Item7; + Item30 --> Item7; + Item31 --> Item11; + Item31 --> Item10; + Item7 --> Item6; + Item7 --> Item5; + Item8 --> Item4; + Item8 --> Item7; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item29["ModuleEvaluation"]; + Item30; + Item30["export structuredError"]; + Item31; + Item31["export IPC"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 -.-> Item6; + Item9 -.-> Item5; + Item9 -.-> Item4; + Item9 -.-> Item7; + Item10 --> Item8; + Item10 --> Item9; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item3; + Item10 -.-> Item6; + Item10 -.-> Item5; + Item10 -.-> Item4; + Item10 -.-> Item7; + Item11 --> Item10; + Item11 --> Item1; + Item11 --> Item2; + Item11 --> Item3; + Item11 --> Item9; + Item11 -.-> Item6; + Item11 -.-> Item5; + Item11 -.-> Item4; + Item11 -.-> Item7; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item11; + Item12 -.-> Item6; + Item12 -.-> Item5; + Item12 -.-> Item4; + Item12 -.-> Item7; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item9; + Item13 --> Item10; + Item13 --> Item11; + Item13 -.-> Item6; + Item13 -.-> Item5; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item14 --> Item12; + Item14 --> Item1; + Item14 --> Item2; + Item14 --> Item3; + Item14 --> Item9; + Item14 --> Item10; + Item14 --> Item11; + Item14 --> Item13; + Item14 -.-> Item6; + Item14 -.-> Item5; + Item14 -.-> Item4; + Item14 -.-> Item7; + Item15 --> Item12; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item11; + Item15 --> Item13; + Item15 --> Item14; + Item15 -.-> Item6; + Item15 -.-> Item5; + Item15 -.-> Item4; + Item15 -.-> Item7; + Item16 --> Item12; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item9; + Item16 --> Item10; + Item16 --> Item11; + Item16 --> Item13; + Item16 --> Item14; + Item16 --> Item15; + Item16 -.-> Item6; + Item16 -.-> Item5; + Item16 -.-> Item4; + Item16 -.-> Item7; + Item17 --> Item12; + Item17 --> Item1; + Item17 --> Item2; + Item17 --> Item3; + Item17 --> Item9; + Item17 --> Item10; + Item17 --> Item11; + Item17 --> Item13; + Item17 --> Item14; + Item17 --> Item15; + Item17 --> Item16; + Item17 -.-> Item6; + Item17 -.-> Item5; + Item17 -.-> Item4; + Item17 -.-> Item7; + Item18 --> Item12; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item11; + Item18 --> Item13; + Item18 --> Item14; + Item18 --> Item15; + Item18 --> Item16; + Item18 --> Item17; + Item18 -.-> Item6; + Item18 -.-> Item5; + Item18 -.-> Item4; + Item18 -.-> Item7; + Item19 --> Item12; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item9; + Item19 --> Item10; + Item19 --> Item11; + Item19 --> Item13; + Item19 --> Item14; + Item19 --> Item15; + Item19 --> Item16; + Item19 --> Item17; + Item19 --> Item18; + Item19 -.-> Item6; + Item19 -.-> Item5; + Item19 -.-> Item4; + Item19 -.-> Item7; + Item20 --> Item12; + Item20 --> Item1; + Item20 --> Item2; + Item20 --> Item3; + Item20 --> Item9; + Item20 --> Item10; + Item20 --> Item11; + Item20 --> Item13; + Item20 --> Item14; + Item20 --> Item15; + Item20 --> Item16; + Item20 --> Item17; + Item20 --> Item18; + Item20 --> Item19; + Item20 -.-> Item6; + Item20 -.-> Item5; + Item20 -.-> Item4; + Item20 -.-> Item7; + Item21 --> Item12; + Item21 --> Item1; + Item21 --> Item2; + Item21 --> Item3; + Item21 --> Item9; + Item21 --> Item10; + Item21 --> Item11; + Item21 --> Item13; + Item21 --> Item14; + Item21 --> Item15; + Item21 --> Item16; + Item21 --> Item17; + Item21 --> Item18; + Item21 --> Item19; + Item21 --> Item20; + Item21 -.-> Item6; + Item21 -.-> Item5; + Item21 -.-> Item4; + Item21 -.-> Item7; + Item22 --> Item12; + Item22 --> Item1; + Item22 --> Item2; + Item22 --> Item3; + Item22 --> Item9; + Item22 --> Item10; + Item22 --> Item11; + Item22 --> Item13; + Item22 --> Item14; + Item22 --> Item15; + Item22 --> Item16; + Item22 --> Item17; + Item22 --> Item18; + Item22 --> Item19; + Item22 --> Item20; + Item22 --> Item21; + Item22 -.-> Item6; + Item22 -.-> Item5; + Item22 -.-> Item4; + Item22 -.-> Item7; + Item23 --> Item12; + Item23 --> Item1; + Item23 --> Item2; + Item23 --> Item3; + Item23 --> Item9; + Item23 --> Item10; + Item23 --> Item11; + Item23 --> Item13; + Item23 --> Item14; + Item23 --> Item15; + Item23 --> Item16; + Item23 --> Item17; + Item23 --> Item18; + Item23 --> Item19; + Item23 --> Item20; + Item23 --> Item21; + Item23 --> Item22; + Item23 -.-> Item6; + Item23 -.-> Item5; + Item23 -.-> Item4; + Item23 -.-> Item7; + Item24 --> Item12; + Item24 --> Item1; + Item24 --> Item2; + Item24 --> Item3; + Item24 --> Item9; + Item24 --> Item10; + Item24 --> Item11; + Item24 --> Item13; + Item24 --> Item14; + Item24 --> Item15; + Item24 --> Item16; + Item24 --> Item17; + Item24 --> Item18; + Item24 --> Item19; + Item24 --> Item20; + Item24 --> Item21; + Item24 --> Item22; + Item24 --> Item23; + Item24 -.-> Item6; + Item24 -.-> Item5; + Item24 -.-> Item4; + Item24 -.-> Item7; + Item25 --> Item12; + Item25 --> Item1; + Item25 --> Item2; + Item25 --> Item3; + Item25 --> Item9; + Item25 --> Item10; + Item25 --> Item11; + Item25 --> Item13; + Item25 --> Item14; + Item25 --> Item15; + Item25 --> Item16; + Item25 --> Item17; + Item25 --> Item18; + Item25 --> Item19; + Item25 --> Item20; + Item25 --> Item21; + Item25 --> Item22; + Item25 --> Item23; + Item25 --> Item24; + Item25 -.-> Item6; + Item25 -.-> Item5; + Item25 -.-> Item4; + Item25 -.-> Item7; + Item26 --> Item12; + Item26 --> Item1; + Item26 --> Item2; + Item26 --> Item3; + Item26 --> Item9; + Item26 --> Item10; + Item26 --> Item11; + Item26 --> Item13; + Item26 --> Item14; + Item26 --> Item15; + Item26 --> Item16; + Item26 --> Item17; + Item26 --> Item18; + Item26 --> Item19; + Item26 --> Item20; + Item26 --> Item21; + Item26 --> Item22; + Item26 --> Item23; + Item26 --> Item24; + Item26 --> Item25; + Item26 -.-> Item6; + Item26 -.-> Item5; + Item26 -.-> Item4; + Item26 -.-> Item7; + Item27 --> Item12; + Item27 --> Item1; + Item27 --> Item2; + Item27 --> Item3; + Item27 --> Item9; + Item27 --> Item10; + Item27 --> Item11; + Item27 --> Item13; + Item27 --> Item14; + Item27 --> Item15; + Item27 --> Item16; + Item27 --> Item17; + Item27 --> Item18; + Item27 --> Item19; + Item27 --> Item20; + Item27 --> Item21; + Item27 --> Item22; + Item27 --> Item23; + Item27 --> Item24; + Item27 --> Item25; + Item27 --> Item26; + Item27 -.-> Item6; + Item27 -.-> Item5; + Item27 -.-> Item4; + Item27 -.-> Item7; + Item28 --> Item12; + Item28 --> Item1; + Item28 --> Item2; + Item28 --> Item3; + Item28 --> Item9; + Item28 --> Item10; + Item28 --> Item11; + Item28 --> Item13; + Item28 --> Item14; + Item28 --> Item15; + Item28 --> Item16; + Item28 --> Item17; + Item28 --> Item18; + Item28 --> Item19; + Item28 --> Item20; + Item28 --> Item21; + Item28 --> Item22; + Item28 --> Item23; + Item28 --> Item24; + Item28 --> Item25; + Item28 --> Item26; + Item28 --> Item27; + Item28 -.-> Item6; + Item28 -.-> Item5; + Item28 -.-> Item4; + Item28 -.-> Item7; + Item30 --> Item7; + Item31 --> Item11; + Item31 --> Item10; + Item7 --> Item6; + Item7 --> Item5; + Item8 --> Item4; + Item8 --> Item7; + Item29 --> Item1; + Item29 --> Item2; + Item29 --> Item3; + Item29 --> Item9; + Item29 --> Item10; + Item29 --> Item11; + Item29 --> Item12; + Item29 --> Item13; + Item29 --> Item14; + Item29 --> Item15; + Item29 --> Item16; + Item29 --> Item17; + Item29 --> Item18; + Item29 --> Item19; + Item29 --> Item20; + Item29 --> Item21; + Item29 --> Item22; + Item29 --> Item23; + Item29 --> Item24; + Item29 --> Item25; + Item29 --> Item26; + Item29 --> Item27; + Item29 --> Item28; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportBinding(0))]"]; + N1["Items: [ItemId(1, ImportBinding(0))]"]; + N2["Items: [ItemId(2, ImportBinding(0))]"]; + N3["Items: [ItemId(3, Normal)]"]; + N4["Items: [ItemId(4, Normal)]"]; + N5["Items: [ItemId(Export(("structuredError", #2), "structuredError"))]"]; + N6["Items: [ItemId(0, ImportOfModule)]"]; + N7["Items: [ItemId(1, ImportOfModule)]"]; + N8["Items: [ItemId(2, ImportOfModule)]"]; + N9["Items: [ItemId(5, VarDeclarator(0))]"]; + N10["Items: [ItemId(6, VarDeclarator(0))]"]; + N11["Items: [ItemId(7, Normal)]"]; + N12["Items: [ItemId(Export(("IPC", #2), "IPC"))]"]; + N13["Items: [ItemId(8, VarDeclarator(0))]"]; + N14["Items: [ItemId(9, Normal)]"]; + N15["Items: [ItemId(10, Normal)]"]; + N16["Items: [ItemId(11, Normal)]"]; + N17["Items: [ItemId(12, Normal)]"]; + N18["Items: [ItemId(13, Normal)]"]; + N19["Items: [ItemId(14, Normal)]"]; + N20["Items: [ItemId(15, Normal)]"]; + N21["Items: [ItemId(16, Normal)]"]; + N22["Items: [ItemId(17, Normal)]"]; + N23["Items: [ItemId(18, Normal)]"]; + N24["Items: [ItemId(19, Normal)]"]; + N25["Items: [ItemId(20, Normal)]"]; + N26["Items: [ItemId(21, Normal)]"]; + N27["Items: [ItemId(22, Normal)]"]; + N28["Items: [ItemId(23, Normal)]"]; + N29["Items: [ItemId(24, Normal)]"]; + N30["Items: [ItemId(ModuleEvaluation)]"]; + N7 --> N6; + N8 --> N6; + N8 --> N7; + N9 --> N6; + N9 --> N7; + N9 --> N8; + N9 -.-> N2; + N9 -.-> N1; + N9 -.-> N0; + N9 -.-> N3; + N10 --> N4; + N10 --> N9; + N10 --> N6; + N10 --> N7; + N10 --> N8; + N10 -.-> N2; + N10 -.-> N1; + N10 -.-> N0; + N10 -.-> N3; + N11 --> N10; + N11 --> N6; + N11 --> N7; + N11 --> N8; + N11 --> N9; + N11 -.-> N2; + N11 -.-> N1; + N11 -.-> N0; + N11 -.-> N3; + N13 --> N6; + N13 --> N7; + N13 --> N8; + N13 --> N9; + N13 --> N10; + N13 --> N11; + N13 -.-> N2; + N13 -.-> N1; + N13 -.-> N0; + N13 -.-> N3; + N14 --> N13; + N14 --> N6; + N14 --> N7; + N14 --> N8; + N14 --> N9; + N14 --> N10; + N14 --> N11; + N14 -.-> N2; + N14 -.-> N1; + N14 -.-> N0; + N14 -.-> N3; + N15 --> N13; + N15 --> N6; + N15 --> N7; + N15 --> N8; + N15 --> N9; + N15 --> N10; + N15 --> N11; + N15 --> N14; + N15 -.-> N2; + N15 -.-> N1; + N15 -.-> N0; + N15 -.-> N3; + N16 --> N13; + N16 --> N6; + N16 --> N7; + N16 --> N8; + N16 --> N9; + N16 --> N10; + N16 --> N11; + N16 --> N14; + N16 --> N15; + N16 -.-> N2; + N16 -.-> N1; + N16 -.-> N0; + N16 -.-> N3; + N17 --> N13; + N17 --> N6; + N17 --> N7; + N17 --> N8; + N17 --> N9; + N17 --> N10; + N17 --> N11; + N17 --> N14; + N17 --> N15; + N17 --> N16; + N17 -.-> N2; + N17 -.-> N1; + N17 -.-> N0; + N17 -.-> N3; + N18 --> N13; + N18 --> N6; + N18 --> N7; + N18 --> N8; + N18 --> N9; + N18 --> N10; + N18 --> N11; + N18 --> N14; + N18 --> N15; + N18 --> N16; + N18 --> N17; + N18 -.-> N2; + N18 -.-> N1; + N18 -.-> N0; + N18 -.-> N3; + N19 --> N13; + N19 --> N6; + N19 --> N7; + N19 --> N8; + N19 --> N9; + N19 --> N10; + N19 --> N11; + N19 --> N14; + N19 --> N15; + N19 --> N16; + N19 --> N17; + N19 --> N18; + N19 -.-> N2; + N19 -.-> N1; + N19 -.-> N0; + N19 -.-> N3; + N20 --> N13; + N20 --> N6; + N20 --> N7; + N20 --> N8; + N20 --> N9; + N20 --> N10; + N20 --> N11; + N20 --> N14; + N20 --> N15; + N20 --> N16; + N20 --> N17; + N20 --> N18; + N20 --> N19; + N20 -.-> N2; + N20 -.-> N1; + N20 -.-> N0; + N20 -.-> N3; + N21 --> N13; + N21 --> N6; + N21 --> N7; + N21 --> N8; + N21 --> N9; + N21 --> N10; + N21 --> N11; + N21 --> N14; + N21 --> N15; + N21 --> N16; + N21 --> N17; + N21 --> N18; + N21 --> N19; + N21 --> N20; + N21 -.-> N2; + N21 -.-> N1; + N21 -.-> N0; + N21 -.-> N3; + N22 --> N13; + N22 --> N6; + N22 --> N7; + N22 --> N8; + N22 --> N9; + N22 --> N10; + N22 --> N11; + N22 --> N14; + N22 --> N15; + N22 --> N16; + N22 --> N17; + N22 --> N18; + N22 --> N19; + N22 --> N20; + N22 --> N21; + N22 -.-> N2; + N22 -.-> N1; + N22 -.-> N0; + N22 -.-> N3; + N23 --> N13; + N23 --> N6; + N23 --> N7; + N23 --> N8; + N23 --> N9; + N23 --> N10; + N23 --> N11; + N23 --> N14; + N23 --> N15; + N23 --> N16; + N23 --> N17; + N23 --> N18; + N23 --> N19; + N23 --> N20; + N23 --> N21; + N23 --> N22; + N23 -.-> N2; + N23 -.-> N1; + N23 -.-> N0; + N23 -.-> N3; + N24 --> N13; + N24 --> N6; + N24 --> N7; + N24 --> N8; + N24 --> N9; + N24 --> N10; + N24 --> N11; + N24 --> N14; + N24 --> N15; + N24 --> N16; + N24 --> N17; + N24 --> N18; + N24 --> N19; + N24 --> N20; + N24 --> N21; + N24 --> N22; + N24 --> N23; + N24 -.-> N2; + N24 -.-> N1; + N24 -.-> N0; + N24 -.-> N3; + N25 --> N13; + N25 --> N6; + N25 --> N7; + N25 --> N8; + N25 --> N9; + N25 --> N10; + N25 --> N11; + N25 --> N14; + N25 --> N15; + N25 --> N16; + N25 --> N17; + N25 --> N18; + N25 --> N19; + N25 --> N20; + N25 --> N21; + N25 --> N22; + N25 --> N23; + N25 --> N24; + N25 -.-> N2; + N25 -.-> N1; + N25 -.-> N0; + N25 -.-> N3; + N26 --> N13; + N26 --> N6; + N26 --> N7; + N26 --> N8; + N26 --> N9; + N26 --> N10; + N26 --> N11; + N26 --> N14; + N26 --> N15; + N26 --> N16; + N26 --> N17; + N26 --> N18; + N26 --> N19; + N26 --> N20; + N26 --> N21; + N26 --> N22; + N26 --> N23; + N26 --> N24; + N26 --> N25; + N26 -.-> N2; + N26 -.-> N1; + N26 -.-> N0; + N26 -.-> N3; + N27 --> N13; + N27 --> N6; + N27 --> N7; + N27 --> N8; + N27 --> N9; + N27 --> N10; + N27 --> N11; + N27 --> N14; + N27 --> N15; + N27 --> N16; + N27 --> N17; + N27 --> N18; + N27 --> N19; + N27 --> N20; + N27 --> N21; + N27 --> N22; + N27 --> N23; + N27 --> N24; + N27 --> N25; + N27 --> N26; + N27 -.-> N2; + N27 -.-> N1; + N27 -.-> N0; + N27 -.-> N3; + N28 --> N13; + N28 --> N6; + N28 --> N7; + N28 --> N8; + N28 --> N9; + N28 --> N10; + N28 --> N11; + N28 --> N14; + N28 --> N15; + N28 --> N16; + N28 --> N17; + N28 --> N18; + N28 --> N19; + N28 --> N20; + N28 --> N21; + N28 --> N22; + N28 --> N23; + N28 --> N24; + N28 --> N25; + N28 --> N26; + N28 --> N27; + N28 -.-> N2; + N28 -.-> N1; + N28 -.-> N0; + N28 -.-> N3; + N29 --> N13; + N29 --> N6; + N29 --> N7; + N29 --> N8; + N29 --> N9; + N29 --> N10; + N29 --> N11; + N29 --> N14; + N29 --> N15; + N29 --> N16; + N29 --> N17; + N29 --> N18; + N29 --> N19; + N29 --> N20; + N29 --> N21; + N29 --> N22; + N29 --> N23; + N29 --> N24; + N29 --> N25; + N29 --> N26; + N29 --> N27; + N29 --> N28; + N29 -.-> N2; + N29 -.-> N1; + N29 -.-> N0; + N29 -.-> N3; + N5 --> N3; + N12 --> N11; + N12 --> N10; + N3 --> N2; + N3 --> N1; + N4 --> N0; + N4 --> N3; + N30 --> N6; + N30 --> N7; + N30 --> N8; + N30 --> N9; + N30 --> N10; + N30 --> N11; + N30 --> N13; + N30 --> N14; + N30 --> N15; + N30 --> N16; + N30 --> N17; + N30 --> N18; + N30 --> N19; + N30 --> N20; + N30 --> N21; + N30 --> N22; + N30 --> N23; + N30 --> N24; + N30 --> N25; + N30 --> N26; + N30 --> N27; + N30 --> N28; + N30 --> N29; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 30, + Export( + "IPC", + ): 12, + Exports: 31, + Export( + "structuredError", + ): 5, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { createConnection } from "node:net"; +export { createConnection } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; +export { parseStackTrace } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { getProperError } from "./error"; +export { getProperError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { parseStackTrace } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { getProperError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function structuredError(e) { + e = getProperError(e); + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : [] + }; +} +export { structuredError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { createConnection } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function createIpc(port) { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue = []; + const recvPromiseResolveQueue = []; + function pushPacket(packet) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8"))); + } else { + packetQueue.push(packet); + } + } + let state = { + type: "waiting" + }; + let buffer = Buffer.alloc(0); + socket.once("connect", ()=>{ + socket.on("data", (chunk)=>{ + buffer = Buffer.concat([ + buffer, + chunk + ]); + loop: while(true){ + switch(state.type){ + case "waiting": + { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { + type: "packet", + length + }; + } else { + break loop; + } + break; + } + case "packet": + { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { + type: "waiting" + }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + socket.once("close", ()=>{ + process.exit(0); + }); + function send(message) { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + return new Promise((resolve, reject)=>{ + socket.write(packet, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + function sendReady() { + const length = Buffer.from([ + 0, + 0, + 0, + 0 + ]); + return new Promise((resolve, reject)=>{ + socket.write(length, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + return { + async recv () { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")); + } + const result = await new Promise((resolve)=>{ + recvPromiseResolveQueue.push((result)=>{ + resolve(result); + }); + }); + return result; + }, + send (message) { + return send(message); + }, + sendReady, + async sendError (error) { + try { + await send({ + type: "error", + ...structuredError(error) + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + process.exit(1); + } + process.exit(0); + } + }; +} +export { createIpc } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { structuredError }; + +``` +## Part 6 +```js +import "node:net"; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "../compiled/stacktrace-parser"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "./error"; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const PORT = process.argv[2]; +export { PORT } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { createIpc } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { PORT } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +const IPC = createIpc(parseInt(PORT, 10)); +export { IPC } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +process.on("uncaughtException", (err)=>{ + IPC.sendError(err); +}); + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { IPC }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const improveConsole = (name, stream, addStack)=>{ + const original = console[name]; + const stdio = process[stream]; + console[name] = (...args)=>{ + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; +export { improveConsole } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("error", "stderr", true); + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("warn", "stderr", true); + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("count", "stdout", true); + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("trace", "stderr", false); + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("log", "stdout", true); + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("group", "stdout", true); + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("groupCollapsed", "stdout", true); + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("table", "stdout", true); + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("debug", "stdout", true); + +``` +## Part 23 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("info", "stdout", true); + +``` +## Part 24 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("dir", "stdout", true); + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("dirxml", "stdout", true); + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeEnd", "stdout", true); + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeLog", "stdout", true); + +``` +## Part 28 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeStamp", "stdout", true); + +``` +## Part 29 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("assert", "stderr", true); + +``` +## Part 30 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +"module evaluation"; + +``` +## Part 31 +```js +export { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export structuredError" +}; +export { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export IPC" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 30, + Export( + "IPC", + ): 12, + Exports: 31, + Export( + "structuredError", + ): 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { createConnection } from "node:net"; +export { createConnection } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; +export { parseStackTrace } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { getProperError } from "./error"; +export { getProperError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { parseStackTrace } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { getProperError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function structuredError(e) { + e = getProperError(e); + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : [] + }; +} +export { structuredError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { structuredError }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { createConnection } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function createIpc(port) { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue = []; + const recvPromiseResolveQueue = []; + function pushPacket(packet) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8"))); + } else { + packetQueue.push(packet); + } + } + let state = { + type: "waiting" + }; + let buffer = Buffer.alloc(0); + socket.once("connect", ()=>{ + socket.on("data", (chunk)=>{ + buffer = Buffer.concat([ + buffer, + chunk + ]); + loop: while(true){ + switch(state.type){ + case "waiting": + { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { + type: "packet", + length + }; + } else { + break loop; + } + break; + } + case "packet": + { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { + type: "waiting" + }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + socket.once("close", ()=>{ + process.exit(0); + }); + function send(message) { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + return new Promise((resolve, reject)=>{ + socket.write(packet, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + function sendReady() { + const length = Buffer.from([ + 0, + 0, + 0, + 0 + ]); + return new Promise((resolve, reject)=>{ + socket.write(length, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + return { + async recv () { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")); + } + const result = await new Promise((resolve)=>{ + recvPromiseResolveQueue.push((result)=>{ + resolve(result); + }); + }); + return result; + }, + send (message) { + return send(message); + }, + sendReady, + async sendError (error) { + try { + await send({ + type: "error", + ...structuredError(error) + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + process.exit(1); + } + process.exit(0); + } + }; +} +export { createIpc } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "node:net"; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "../compiled/stacktrace-parser"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "./error"; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +const PORT = process.argv[2]; +export { PORT } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { createIpc } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { PORT } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +const IPC = createIpc(parseInt(PORT, 10)); +export { IPC } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +process.on("uncaughtException", (err)=>{ + IPC.sendError(err); +}); + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { IPC }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +const improveConsole = (name, stream, addStack)=>{ + const original = console[name]; + const stdio = process[stream]; + console[name] = (...args)=>{ + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; +export { improveConsole } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("error", "stderr", true); + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("warn", "stderr", true); + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("count", "stdout", true); + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("trace", "stderr", false); + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("log", "stdout", true); + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("group", "stdout", true); + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("groupCollapsed", "stdout", true); + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("table", "stdout", true); + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("debug", "stdout", true); + +``` +## Part 23 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("info", "stdout", true); + +``` +## Part 24 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("dir", "stdout", true); + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("dirxml", "stdout", true); + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeEnd", "stdout", true); + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeLog", "stdout", true); + +``` +## Part 28 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeStamp", "stdout", true); + +``` +## Part 29 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("assert", "stderr", true); + +``` +## Part 30 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 31 +```js +export { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export structuredError" +}; +export { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export IPC" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/grouping/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/grouping/input.js new file mode 100644 index 0000000000000..dcd5db224fab4 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/grouping/input.js @@ -0,0 +1,14 @@ +let x = 1; +x = 2; +x = 3; +console.log(x); +x = 4; +x = 5; +x += 6; +x += 7; +x += 8; +x += 9; + +export { x }; + +export const y = x; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/grouping/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/grouping/output.md new file mode 100644 index 0000000000000..7b7bcbb87484e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/grouping/output.md @@ -0,0 +1,757 @@ +# Items + +Count: 14 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +let x = 1; + +``` + +- Declares: `x` +- Write: `x` + +## Item 2: Stmt 1, `Normal` + +```js +x = 2; + +``` + +- Write: `x` + +## Item 3: Stmt 2, `Normal` + +```js +x = 3; + +``` + +- Write: `x` + +## Item 4: Stmt 3, `Normal` + +```js +console.log(x); + +``` + +- Side effects +- Reads: `x` + +## Item 5: Stmt 4, `Normal` + +```js +x = 4; + +``` + +- Write: `x` + +## Item 6: Stmt 5, `Normal` + +```js +x = 5; + +``` + +- Write: `x` + +## Item 7: Stmt 6, `Normal` + +```js +x += 6; + +``` + +- Reads: `x` +- Write: `x` + +## Item 8: Stmt 7, `Normal` + +```js +x += 7; + +``` + +- Reads: `x` +- Write: `x` + +## Item 9: Stmt 8, `Normal` + +```js +x += 8; + +``` + +- Reads: `x` +- Write: `x` + +## Item 10: Stmt 9, `Normal` + +```js +x += 9; + +``` + +- Reads: `x` +- Write: `x` + +## Item 11: Stmt 11, `VarDeclarator(0)` + +```js +export const y = x; + +``` + +- Declares: `y` +- Reads: `x` +- Write: `y` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item12["ModuleEvaluation"]; + Item13; + Item13["export x"]; + Item14; + Item14["export y"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item12["ModuleEvaluation"]; + Item13; + Item13["export x"]; + Item14; + Item14["export y"]; + Item2 --> Item1; + Item3 --> Item1; + Item4 --> Item3; + Item4 --> Item1; + Item5 -.-> Item4; + Item5 --> Item1; + Item6 -.-> Item4; + Item6 --> Item1; + Item7 --> Item3; + Item7 --> Item6; + Item7 --> Item1; + Item7 -.-> Item4; + Item8 --> Item7; + Item8 --> Item1; + Item8 -.-> Item4; + Item9 --> Item8; + Item9 --> Item1; + Item9 -.-> Item4; + Item10 --> Item9; + Item10 --> Item1; + Item10 -.-> Item4; + Item11 --> Item10; + Item11 --> Item1; + Item13 --> Item10; + Item13 --> Item1; + Item14 --> Item11; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item12["ModuleEvaluation"]; + Item13; + Item13["export x"]; + Item14; + Item14["export y"]; + Item2 --> Item1; + Item3 --> Item1; + Item4 --> Item3; + Item4 --> Item1; + Item5 -.-> Item4; + Item5 --> Item1; + Item6 -.-> Item4; + Item6 --> Item1; + Item7 --> Item3; + Item7 --> Item6; + Item7 --> Item1; + Item7 -.-> Item4; + Item8 --> Item7; + Item8 --> Item1; + Item8 -.-> Item4; + Item9 --> Item8; + Item9 --> Item1; + Item9 -.-> Item4; + Item10 --> Item9; + Item10 --> Item1; + Item10 -.-> Item4; + Item11 --> Item10; + Item11 --> Item1; + Item13 --> Item10; + Item13 --> Item1; + Item14 --> Item11; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item12["ModuleEvaluation"]; + Item13; + Item13["export x"]; + Item14; + Item14["export y"]; + Item2 --> Item1; + Item3 --> Item1; + Item4 --> Item3; + Item4 --> Item1; + Item5 -.-> Item4; + Item5 --> Item1; + Item6 -.-> Item4; + Item6 --> Item1; + Item7 --> Item3; + Item7 --> Item6; + Item7 --> Item1; + Item7 -.-> Item4; + Item8 --> Item7; + Item8 --> Item1; + Item8 -.-> Item4; + Item9 --> Item8; + Item9 --> Item1; + Item9 -.-> Item4; + Item10 --> Item9; + Item10 --> Item1; + Item10 -.-> Item4; + Item11 --> Item10; + Item11 --> Item1; + Item13 --> Item10; + Item13 --> Item1; + Item14 --> Item11; + Item12 --> Item4; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, VarDeclarator(0))]"]; + N1["Items: [ItemId(2, Normal)]"]; + N2["Items: [ItemId(3, Normal)]"]; + N3["Items: [ItemId(ModuleEvaluation)]"]; + N4["Items: [ItemId(5, Normal)]"]; + N5["Items: [ItemId(6, Normal)]"]; + N6["Items: [ItemId(7, Normal)]"]; + N7["Items: [ItemId(8, Normal)]"]; + N8["Items: [ItemId(9, Normal)]"]; + N9["Items: [ItemId(Export(("x", #2), "x"))]"]; + N10["Items: [ItemId(11, VarDeclarator(0))]"]; + N11["Items: [ItemId(Export(("y", #2), "y"))]"]; + N12["Items: [ItemId(4, Normal)]"]; + N13["Items: [ItemId(1, Normal)]"]; + N13 --> N0; + N1 --> N0; + N2 --> N1; + N2 --> N0; + N12 -.-> N2; + N12 --> N0; + N4 -.-> N2; + N4 --> N0; + N5 --> N1; + N5 --> N4; + N5 --> N0; + N5 -.-> N2; + N6 --> N5; + N6 --> N0; + N6 -.-> N2; + N7 --> N6; + N7 --> N0; + N7 -.-> N2; + N8 --> N7; + N8 --> N0; + N8 -.-> N2; + N10 --> N8; + N10 --> N0; + N9 --> N8; + N9 --> N0; + N11 --> N10; + N3 --> N2; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 3, + Exports: 14, + Export( + "y", + ): 11, + Export( + "x", + ): 9, +} +``` + + +# Modules (dev) +## Part 0 +```js +let x = 1; +export { x } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x = 3; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +console.log(x); + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x = 5; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x += 6; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x += 7; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x += 8; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x += 9; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { x as x }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const y = x; +export { y } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { y } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { y }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x = 4; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x = 2; + +``` +## Part 14 +```js +export { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export x" +}; +export { y } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export y" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 12, + Exports: 14, + Export( + "y", + ): 9, + Export( + "x", + ): 10, +} +``` + + +# Modules (prod) +## Part 0 +```js +let x = 1; +export { x } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x = 5; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x = 4; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x = 3; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x += 6; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x += 7; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x += 8; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x += 9; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const y = x; +export { y } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { y } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { y }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { x as x }; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +console.log(x); + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +"module evaluation"; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +x = 2; + +``` +## Part 14 +```js +export { y } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export y" +}; +export { x } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export x" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-evaluate/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-evaluate/input.js new file mode 100644 index 0000000000000..3a98dcf8f5bdd --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-evaluate/input.js @@ -0,0 +1,94 @@ +import { IPC } from "./index"; +const ipc = IPC; +const queue = []; +export const run = async (moduleFactory)=>{ + let nextId = 1; + const requests = new Map(); + const internalIpc = { + sendInfo: (message)=>ipc.send({ + type: "info", + data: message + }), + sendRequest: (message)=>{ + const id = nextId++; + let resolve, reject; + const promise = new Promise((res, rej)=>{ + resolve = res; + reject = rej; + }); + requests.set(id, { + resolve, + reject + }); + return ipc.send({ + type: "request", + id, + data: message + }).then(()=>promise); + }, + sendError: (error)=>{ + return ipc.sendError(error); + } + }; + let getValue; + try { + const module = await moduleFactory(); + if (typeof module.init === "function") { + await module.init(); + } + getValue = module.default; + await ipc.sendReady(); + } catch (err) { + await ipc.sendReady(); + await ipc.sendError(err); + } + let isRunning = false; + const run = async ()=>{ + while(queue.length > 0){ + const args = queue.shift(); + try { + const value = await getValue(internalIpc, ...args); + await ipc.send({ + type: "end", + data: value === undefined ? undefined : JSON.stringify(value, null, 2), + duration: 0 + }); + } catch (e) { + await ipc.sendError(e); + } + } + isRunning = false; + }; + while(true){ + const msg = await ipc.recv(); + switch(msg.type){ + case "evaluate": + { + queue.push(msg.args); + if (!isRunning) { + isRunning = true; + run(); + } + break; + } + case "result": + { + const request = requests.get(msg.id); + if (request) { + requests.delete(msg.id); + if (msg.error) { + request.reject(new Error(msg.error)); + } else { + request.resolve(msg.data); + } + } + break; + } + default: + { + console.error("unexpected message type", msg.type); + process.exit(1); + } + } + } +}; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-evaluate/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-evaluate/output.md new file mode 100644 index 0000000000000..bd16595f615f3 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-evaluate/output.md @@ -0,0 +1,638 @@ +# Items + +Count: 7 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { IPC } from "./index"; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { IPC } from "./index"; + +``` + +- Hoisted +- Declares: `IPC` + +## Item 3: Stmt 1, `VarDeclarator(0)` + +```js +const ipc = IPC; + +``` + +- Declares: `ipc` +- Reads: `IPC` +- Write: `ipc` + +## Item 4: Stmt 2, `VarDeclarator(0)` + +```js +const queue = []; + +``` + +- Declares: `queue` +- Write: `queue` + +## Item 5: Stmt 3, `VarDeclarator(0)` + +```js +export const run = async (moduleFactory)=>{ + let nextId = 1; + const requests = new Map(); + const internalIpc = { + sendInfo: (message)=>ipc.send({ + type: "info", + data: message + }), + sendRequest: (message)=>{ + const id = nextId++; + let resolve, reject; + const promise = new Promise((res, rej)=>{ + resolve = res; + reject = rej; + }); + requests.set(id, { + resolve, + reject + }); + return ipc.send({ + type: "request", + id, + data: message + }).then(()=>promise); + }, + sendError: (error)=>{ + return ipc.sendError(error); + } + }; + let getValue; + try { + const module = await moduleFactory(); + if (typeof module.init === "function") { + await module.init(); + } + getValue = module.default; + await ipc.sendReady(); + } catch (err) { + await ipc.sendReady(); + await ipc.sendError(err); + } + let isRunning = false; + const run = async ()=>{ + while(queue.length > 0){ + const args = queue.shift(); + try { + const value = await getValue(internalIpc, ...args); + await ipc.send({ + type: "end", + data: value === undefined ? undefined : JSON.stringify(value, null, 2), + duration: 0 + }); + } catch (e) { + await ipc.sendError(e); + } + } + isRunning = false; + }; + while(true){ + const msg = await ipc.recv(); + switch(msg.type){ + case "evaluate": + { + queue.push(msg.args); + if (!isRunning) { + isRunning = true; + run(); + } + break; + } + case "result": + { + const request = requests.get(msg.id); + if (request) { + requests.delete(msg.id); + if (msg.error) { + request.reject(new Error(msg.error)); + } else { + request.resolve(msg.data); + } + } + break; + } + default: + { + console.error("unexpected message type", msg.type); + process.exit(1); + } + } + } +}; + +``` + +- Side effects +- Declares: `run` +- Reads: `ipc`, `queue` +- Write: `ipc`, `queue`, `run` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export run"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export run"]; + Item3 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item5 --> Item1; + Item7 --> Item5; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export run"]; + Item3 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item5 --> Item1; + Item7 --> Item5; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export run"]; + Item3 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item5 --> Item1; + Item7 --> Item5; + Item6 --> Item1; + Item6 --> Item5; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportOfModule)]"]; + N1["Items: [ItemId(2, VarDeclarator(0))]"]; + N2["Items: [ItemId(0, ImportBinding(0))]"]; + N3["Items: [ItemId(1, VarDeclarator(0))]"]; + N4["Items: [ItemId(3, VarDeclarator(0))]"]; + N5["Items: [ItemId(ModuleEvaluation)]"]; + N6["Items: [ItemId(Export(("run", #2), "run"))]"]; + N3 --> N2; + N4 --> N3; + N4 --> N1; + N4 --> N0; + N6 --> N4; + N5 --> N0; + N5 --> N4; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 5, + Exports: 7, + Export( + "run", + ): 6, +} +``` + + +# Modules (dev) +## Part 0 +```js +import "./index"; + +``` +## Part 1 +```js +const queue = []; +export { queue } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { IPC } from "./index"; +export { IPC } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +const ipc = IPC; +export { ipc } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { ipc } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { queue } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const run = async (moduleFactory)=>{ + let nextId = 1; + const requests = new Map(); + const internalIpc = { + sendInfo: (message)=>ipc.send({ + type: "info", + data: message + }), + sendRequest: (message)=>{ + const id = nextId++; + let resolve, reject; + const promise = new Promise((res, rej)=>{ + resolve = res; + reject = rej; + }); + requests.set(id, { + resolve, + reject + }); + return ipc.send({ + type: "request", + id, + data: message + }).then(()=>promise); + }, + sendError: (error)=>{ + return ipc.sendError(error); + } + }; + let getValue; + try { + const module = await moduleFactory(); + if (typeof module.init === "function") { + await module.init(); + } + getValue = module.default; + await ipc.sendReady(); + } catch (err) { + await ipc.sendReady(); + await ipc.sendError(err); + } + let isRunning = false; + const run = async ()=>{ + while(queue.length > 0){ + const args = queue.shift(); + try { + const value = await getValue(internalIpc, ...args); + await ipc.send({ + type: "end", + data: value === undefined ? undefined : JSON.stringify(value, null, 2), + duration: 0 + }); + } catch (e) { + await ipc.sendError(e); + } + } + isRunning = false; + }; + while(true){ + const msg = await ipc.recv(); + switch(msg.type){ + case "evaluate": + { + queue.push(msg.args); + if (!isRunning) { + isRunning = true; + run(); + } + break; + } + case "result": + { + const request = requests.get(msg.id); + if (request) { + requests.delete(msg.id); + if (msg.error) { + request.reject(new Error(msg.error)); + } else { + request.resolve(msg.data); + } + } + break; + } + default: + { + console.error("unexpected message type", msg.type); + process.exit(1); + } + } + } +}; +export { run } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +"module evaluation"; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { run } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { run }; + +``` +## Part 7 +```js +export { run } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export run" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 5, + Exports: 7, + Export( + "run", + ): 6, +} +``` + + +# Modules (prod) +## Part 0 +```js +import "./index"; + +``` +## Part 1 +```js +const queue = []; +export { queue } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { IPC } from "./index"; +export { IPC } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +const ipc = IPC; +export { ipc } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { ipc } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { queue } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const run = async (moduleFactory)=>{ + let nextId = 1; + const requests = new Map(); + const internalIpc = { + sendInfo: (message)=>ipc.send({ + type: "info", + data: message + }), + sendRequest: (message)=>{ + const id = nextId++; + let resolve, reject; + const promise = new Promise((res, rej)=>{ + resolve = res; + reject = rej; + }); + requests.set(id, { + resolve, + reject + }); + return ipc.send({ + type: "request", + id, + data: message + }).then(()=>promise); + }, + sendError: (error)=>{ + return ipc.sendError(error); + } + }; + let getValue; + try { + const module = await moduleFactory(); + if (typeof module.init === "function") { + await module.init(); + } + getValue = module.default; + await ipc.sendReady(); + } catch (err) { + await ipc.sendReady(); + await ipc.sendError(err); + } + let isRunning = false; + const run = async ()=>{ + while(queue.length > 0){ + const args = queue.shift(); + try { + const value = await getValue(internalIpc, ...args); + await ipc.send({ + type: "end", + data: value === undefined ? undefined : JSON.stringify(value, null, 2), + duration: 0 + }); + } catch (e) { + await ipc.sendError(e); + } + } + isRunning = false; + }; + while(true){ + const msg = await ipc.recv(); + switch(msg.type){ + case "evaluate": + { + queue.push(msg.args); + if (!isRunning) { + isRunning = true; + run(); + } + break; + } + case "result": + { + const request = requests.get(msg.id); + if (request) { + requests.delete(msg.id); + if (msg.error) { + request.reject(new Error(msg.error)); + } else { + request.resolve(msg.data); + } + } + break; + } + default: + { + console.error("unexpected message type", msg.type); + process.exit(1); + } + } + } +}; +export { run } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +"module evaluation"; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { run } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { run }; + +``` +## Part 7 +```js +export { run } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export run" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-index/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-index/input.js new file mode 100644 index 0000000000000..441b34ae57bca --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-index/input.js @@ -0,0 +1,172 @@ +import { createConnection } from "node:net"; +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; +import { getProperError } from "./error"; +export function structuredError(e) { + e = getProperError(e); + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : [] + }; +} +function createIpc(port) { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue = []; + const recvPromiseResolveQueue = []; + function pushPacket(packet) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8"))); + } else { + packetQueue.push(packet); + } + } + let state = { + type: "waiting" + }; + let buffer = Buffer.alloc(0); + socket.once("connect", ()=>{ + socket.on("data", (chunk)=>{ + buffer = Buffer.concat([ + buffer, + chunk + ]); + loop: while(true){ + switch(state.type){ + case "waiting": + { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { + type: "packet", + length + }; + } else { + break loop; + } + break; + } + case "packet": + { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { + type: "waiting" + }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + socket.once("close", ()=>{ + process.exit(0); + }); + function send(message) { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + return new Promise((resolve, reject)=>{ + socket.write(packet, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + function sendReady() { + const length = Buffer.from([ + 0, + 0, + 0, + 0 + ]); + return new Promise((resolve, reject)=>{ + socket.write(length, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + return { + async recv () { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")); + } + const result = await new Promise((resolve)=>{ + recvPromiseResolveQueue.push((result)=>{ + resolve(result); + }); + }); + return result; + }, + send (message) { + return send(message); + }, + sendReady, + async sendError (error) { + try { + await send({ + type: "error", + ...structuredError(error) + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + process.exit(1); + } + process.exit(0); + } + }; +} +const PORT = process.argv[2]; +export const IPC = createIpc(parseInt(PORT, 10)); +process.on("uncaughtException", (err)=>{ + IPC.sendError(err); +}); +const improveConsole = (name, stream, addStack)=>{ + const original = console[name]; + const stdio = process[stream]; + console[name] = (...args)=>{ + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; +improveConsole("error", "stderr", true); +improveConsole("warn", "stderr", true); +improveConsole("count", "stdout", true); +improveConsole("trace", "stderr", false); +improveConsole("log", "stdout", true); +improveConsole("group", "stdout", true); +improveConsole("groupCollapsed", "stdout", true); +improveConsole("table", "stdout", true); +improveConsole("debug", "stdout", true); +improveConsole("info", "stdout", true); +improveConsole("dir", "stdout", true); +improveConsole("dirxml", "stdout", true); +improveConsole("timeEnd", "stdout", true); +improveConsole("timeLog", "stdout", true); +improveConsole("timeStamp", "stdout", true); +improveConsole("assert", "stderr", true); diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-index/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-index/output.md new file mode 100644 index 0000000000000..de4f99770472e --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/ipc-index/output.md @@ -0,0 +1,4984 @@ +# Items + +Count: 31 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { createConnection } from "node:net"; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { createConnection } from "node:net"; + +``` + +- Hoisted +- Declares: `createConnection` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; + +``` + +- Hoisted +- Declares: `parseStackTrace` + +## Item 5: Stmt 2, `ImportOfModule` + +```js +import { getProperError } from "./error"; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 2, `ImportBinding(0)` + +```js +import { getProperError } from "./error"; + +``` + +- Hoisted +- Declares: `getProperError` + +## Item 7: Stmt 3, `Normal` + +```js +export function structuredError(e) { + e = getProperError(e); + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : [] + }; +} + +``` + +- Hoisted +- Declares: `structuredError` +- Reads (eventual): `getProperError`, `parseStackTrace` +- Write: `structuredError` + +## Item 8: Stmt 4, `Normal` + +```js +function createIpc(port) { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue = []; + const recvPromiseResolveQueue = []; + function pushPacket(packet) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8"))); + } else { + packetQueue.push(packet); + } + } + let state = { + type: "waiting" + }; + let buffer = Buffer.alloc(0); + socket.once("connect", ()=>{ + socket.on("data", (chunk)=>{ + buffer = Buffer.concat([ + buffer, + chunk + ]); + loop: while(true){ + switch(state.type){ + case "waiting": + { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { + type: "packet", + length + }; + } else { + break loop; + } + break; + } + case "packet": + { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { + type: "waiting" + }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + socket.once("close", ()=>{ + process.exit(0); + }); + function send(message) { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + return new Promise((resolve, reject)=>{ + socket.write(packet, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + function sendReady() { + const length = Buffer.from([ + 0, + 0, + 0, + 0 + ]); + return new Promise((resolve, reject)=>{ + socket.write(length, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + return { + async recv () { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")); + } + const result = await new Promise((resolve)=>{ + recvPromiseResolveQueue.push((result)=>{ + resolve(result); + }); + }); + return result; + }, + send (message) { + return send(message); + }, + sendReady, + async sendError (error) { + try { + await send({ + type: "error", + ...structuredError(error) + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + process.exit(1); + } + process.exit(0); + } + }; +} + +``` + +- Hoisted +- Declares: `createIpc` +- Reads (eventual): `createConnection`, `loop`, `structuredError` +- Write: `createIpc` + +## Item 9: Stmt 5, `VarDeclarator(0)` + +```js +const PORT = process.argv[2]; + +``` + +- Side effects +- Declares: `PORT` +- Write: `PORT` + +## Item 10: Stmt 6, `VarDeclarator(0)` + +```js +export const IPC = createIpc(parseInt(PORT, 10)); + +``` + +- Side effects +- Declares: `IPC` +- Reads: `createIpc`, `PORT` +- Write: `IPC` + +## Item 11: Stmt 7, `Normal` + +```js +process.on("uncaughtException", (err)=>{ + IPC.sendError(err); +}); + +``` + +- Side effects +- Reads: `IPC` +- Write: `IPC` + +## Item 12: Stmt 8, `VarDeclarator(0)` + +```js +const improveConsole = (name, stream, addStack)=>{ + const original = console[name]; + const stdio = process[stream]; + console[name] = (...args)=>{ + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; + +``` + +- Side effects +- Declares: `improveConsole` +- Write: `improveConsole` + +## Item 13: Stmt 9, `Normal` + +```js +improveConsole("error", "stderr", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 14: Stmt 10, `Normal` + +```js +improveConsole("warn", "stderr", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 15: Stmt 11, `Normal` + +```js +improveConsole("count", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 16: Stmt 12, `Normal` + +```js +improveConsole("trace", "stderr", false); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 17: Stmt 13, `Normal` + +```js +improveConsole("log", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 18: Stmt 14, `Normal` + +```js +improveConsole("group", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 19: Stmt 15, `Normal` + +```js +improveConsole("groupCollapsed", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 20: Stmt 16, `Normal` + +```js +improveConsole("table", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 21: Stmt 17, `Normal` + +```js +improveConsole("debug", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 22: Stmt 18, `Normal` + +```js +improveConsole("info", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 23: Stmt 19, `Normal` + +```js +improveConsole("dir", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 24: Stmt 20, `Normal` + +```js +improveConsole("dirxml", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 25: Stmt 21, `Normal` + +```js +improveConsole("timeEnd", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 26: Stmt 22, `Normal` + +```js +improveConsole("timeLog", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 27: Stmt 23, `Normal` + +```js +improveConsole("timeStamp", "stdout", true); + +``` + +- Side effects +- Reads: `improveConsole` + +## Item 28: Stmt 24, `Normal` + +```js +improveConsole("assert", "stderr", true); + +``` + +- Side effects +- Reads: `improveConsole` + +# Phase 1 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item29["ModuleEvaluation"]; + Item30; + Item30["export structuredError"]; + Item31; + Item31["export IPC"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item29["ModuleEvaluation"]; + Item30; + Item30["export structuredError"]; + Item31; + Item31["export IPC"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 -.-> Item6; + Item9 -.-> Item5; + Item9 -.-> Item4; + Item9 -.-> Item7; + Item10 --> Item8; + Item10 --> Item9; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item3; + Item10 -.-> Item6; + Item10 -.-> Item5; + Item10 -.-> Item4; + Item10 -.-> Item7; + Item11 --> Item10; + Item11 --> Item1; + Item11 --> Item2; + Item11 --> Item3; + Item11 --> Item9; + Item11 -.-> Item6; + Item11 -.-> Item5; + Item11 -.-> Item4; + Item11 -.-> Item7; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item11; + Item12 -.-> Item6; + Item12 -.-> Item5; + Item12 -.-> Item4; + Item12 -.-> Item7; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item9; + Item13 --> Item10; + Item13 --> Item11; + Item13 -.-> Item6; + Item13 -.-> Item5; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item14 --> Item12; + Item14 --> Item1; + Item14 --> Item2; + Item14 --> Item3; + Item14 --> Item9; + Item14 --> Item10; + Item14 --> Item11; + Item14 --> Item13; + Item14 -.-> Item6; + Item14 -.-> Item5; + Item14 -.-> Item4; + Item14 -.-> Item7; + Item15 --> Item12; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item11; + Item15 --> Item13; + Item15 --> Item14; + Item15 -.-> Item6; + Item15 -.-> Item5; + Item15 -.-> Item4; + Item15 -.-> Item7; + Item16 --> Item12; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item9; + Item16 --> Item10; + Item16 --> Item11; + Item16 --> Item13; + Item16 --> Item14; + Item16 --> Item15; + Item16 -.-> Item6; + Item16 -.-> Item5; + Item16 -.-> Item4; + Item16 -.-> Item7; + Item17 --> Item12; + Item17 --> Item1; + Item17 --> Item2; + Item17 --> Item3; + Item17 --> Item9; + Item17 --> Item10; + Item17 --> Item11; + Item17 --> Item13; + Item17 --> Item14; + Item17 --> Item15; + Item17 --> Item16; + Item17 -.-> Item6; + Item17 -.-> Item5; + Item17 -.-> Item4; + Item17 -.-> Item7; + Item18 --> Item12; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item11; + Item18 --> Item13; + Item18 --> Item14; + Item18 --> Item15; + Item18 --> Item16; + Item18 --> Item17; + Item18 -.-> Item6; + Item18 -.-> Item5; + Item18 -.-> Item4; + Item18 -.-> Item7; + Item19 --> Item12; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item9; + Item19 --> Item10; + Item19 --> Item11; + Item19 --> Item13; + Item19 --> Item14; + Item19 --> Item15; + Item19 --> Item16; + Item19 --> Item17; + Item19 --> Item18; + Item19 -.-> Item6; + Item19 -.-> Item5; + Item19 -.-> Item4; + Item19 -.-> Item7; + Item20 --> Item12; + Item20 --> Item1; + Item20 --> Item2; + Item20 --> Item3; + Item20 --> Item9; + Item20 --> Item10; + Item20 --> Item11; + Item20 --> Item13; + Item20 --> Item14; + Item20 --> Item15; + Item20 --> Item16; + Item20 --> Item17; + Item20 --> Item18; + Item20 --> Item19; + Item20 -.-> Item6; + Item20 -.-> Item5; + Item20 -.-> Item4; + Item20 -.-> Item7; + Item21 --> Item12; + Item21 --> Item1; + Item21 --> Item2; + Item21 --> Item3; + Item21 --> Item9; + Item21 --> Item10; + Item21 --> Item11; + Item21 --> Item13; + Item21 --> Item14; + Item21 --> Item15; + Item21 --> Item16; + Item21 --> Item17; + Item21 --> Item18; + Item21 --> Item19; + Item21 --> Item20; + Item21 -.-> Item6; + Item21 -.-> Item5; + Item21 -.-> Item4; + Item21 -.-> Item7; + Item22 --> Item12; + Item22 --> Item1; + Item22 --> Item2; + Item22 --> Item3; + Item22 --> Item9; + Item22 --> Item10; + Item22 --> Item11; + Item22 --> Item13; + Item22 --> Item14; + Item22 --> Item15; + Item22 --> Item16; + Item22 --> Item17; + Item22 --> Item18; + Item22 --> Item19; + Item22 --> Item20; + Item22 --> Item21; + Item22 -.-> Item6; + Item22 -.-> Item5; + Item22 -.-> Item4; + Item22 -.-> Item7; + Item23 --> Item12; + Item23 --> Item1; + Item23 --> Item2; + Item23 --> Item3; + Item23 --> Item9; + Item23 --> Item10; + Item23 --> Item11; + Item23 --> Item13; + Item23 --> Item14; + Item23 --> Item15; + Item23 --> Item16; + Item23 --> Item17; + Item23 --> Item18; + Item23 --> Item19; + Item23 --> Item20; + Item23 --> Item21; + Item23 --> Item22; + Item23 -.-> Item6; + Item23 -.-> Item5; + Item23 -.-> Item4; + Item23 -.-> Item7; + Item24 --> Item12; + Item24 --> Item1; + Item24 --> Item2; + Item24 --> Item3; + Item24 --> Item9; + Item24 --> Item10; + Item24 --> Item11; + Item24 --> Item13; + Item24 --> Item14; + Item24 --> Item15; + Item24 --> Item16; + Item24 --> Item17; + Item24 --> Item18; + Item24 --> Item19; + Item24 --> Item20; + Item24 --> Item21; + Item24 --> Item22; + Item24 --> Item23; + Item24 -.-> Item6; + Item24 -.-> Item5; + Item24 -.-> Item4; + Item24 -.-> Item7; + Item25 --> Item12; + Item25 --> Item1; + Item25 --> Item2; + Item25 --> Item3; + Item25 --> Item9; + Item25 --> Item10; + Item25 --> Item11; + Item25 --> Item13; + Item25 --> Item14; + Item25 --> Item15; + Item25 --> Item16; + Item25 --> Item17; + Item25 --> Item18; + Item25 --> Item19; + Item25 --> Item20; + Item25 --> Item21; + Item25 --> Item22; + Item25 --> Item23; + Item25 --> Item24; + Item25 -.-> Item6; + Item25 -.-> Item5; + Item25 -.-> Item4; + Item25 -.-> Item7; + Item26 --> Item12; + Item26 --> Item1; + Item26 --> Item2; + Item26 --> Item3; + Item26 --> Item9; + Item26 --> Item10; + Item26 --> Item11; + Item26 --> Item13; + Item26 --> Item14; + Item26 --> Item15; + Item26 --> Item16; + Item26 --> Item17; + Item26 --> Item18; + Item26 --> Item19; + Item26 --> Item20; + Item26 --> Item21; + Item26 --> Item22; + Item26 --> Item23; + Item26 --> Item24; + Item26 --> Item25; + Item26 -.-> Item6; + Item26 -.-> Item5; + Item26 -.-> Item4; + Item26 -.-> Item7; + Item27 --> Item12; + Item27 --> Item1; + Item27 --> Item2; + Item27 --> Item3; + Item27 --> Item9; + Item27 --> Item10; + Item27 --> Item11; + Item27 --> Item13; + Item27 --> Item14; + Item27 --> Item15; + Item27 --> Item16; + Item27 --> Item17; + Item27 --> Item18; + Item27 --> Item19; + Item27 --> Item20; + Item27 --> Item21; + Item27 --> Item22; + Item27 --> Item23; + Item27 --> Item24; + Item27 --> Item25; + Item27 --> Item26; + Item27 -.-> Item6; + Item27 -.-> Item5; + Item27 -.-> Item4; + Item27 -.-> Item7; + Item28 --> Item12; + Item28 --> Item1; + Item28 --> Item2; + Item28 --> Item3; + Item28 --> Item9; + Item28 --> Item10; + Item28 --> Item11; + Item28 --> Item13; + Item28 --> Item14; + Item28 --> Item15; + Item28 --> Item16; + Item28 --> Item17; + Item28 --> Item18; + Item28 --> Item19; + Item28 --> Item20; + Item28 --> Item21; + Item28 --> Item22; + Item28 --> Item23; + Item28 --> Item24; + Item28 --> Item25; + Item28 --> Item26; + Item28 --> Item27; + Item28 -.-> Item6; + Item28 -.-> Item5; + Item28 -.-> Item4; + Item28 -.-> Item7; + Item30 --> Item7; + Item31 --> Item11; + Item31 --> Item10; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item29["ModuleEvaluation"]; + Item30; + Item30["export structuredError"]; + Item31; + Item31["export IPC"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 -.-> Item6; + Item9 -.-> Item5; + Item9 -.-> Item4; + Item9 -.-> Item7; + Item10 --> Item8; + Item10 --> Item9; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item3; + Item10 -.-> Item6; + Item10 -.-> Item5; + Item10 -.-> Item4; + Item10 -.-> Item7; + Item11 --> Item10; + Item11 --> Item1; + Item11 --> Item2; + Item11 --> Item3; + Item11 --> Item9; + Item11 -.-> Item6; + Item11 -.-> Item5; + Item11 -.-> Item4; + Item11 -.-> Item7; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item11; + Item12 -.-> Item6; + Item12 -.-> Item5; + Item12 -.-> Item4; + Item12 -.-> Item7; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item9; + Item13 --> Item10; + Item13 --> Item11; + Item13 -.-> Item6; + Item13 -.-> Item5; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item14 --> Item12; + Item14 --> Item1; + Item14 --> Item2; + Item14 --> Item3; + Item14 --> Item9; + Item14 --> Item10; + Item14 --> Item11; + Item14 --> Item13; + Item14 -.-> Item6; + Item14 -.-> Item5; + Item14 -.-> Item4; + Item14 -.-> Item7; + Item15 --> Item12; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item11; + Item15 --> Item13; + Item15 --> Item14; + Item15 -.-> Item6; + Item15 -.-> Item5; + Item15 -.-> Item4; + Item15 -.-> Item7; + Item16 --> Item12; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item9; + Item16 --> Item10; + Item16 --> Item11; + Item16 --> Item13; + Item16 --> Item14; + Item16 --> Item15; + Item16 -.-> Item6; + Item16 -.-> Item5; + Item16 -.-> Item4; + Item16 -.-> Item7; + Item17 --> Item12; + Item17 --> Item1; + Item17 --> Item2; + Item17 --> Item3; + Item17 --> Item9; + Item17 --> Item10; + Item17 --> Item11; + Item17 --> Item13; + Item17 --> Item14; + Item17 --> Item15; + Item17 --> Item16; + Item17 -.-> Item6; + Item17 -.-> Item5; + Item17 -.-> Item4; + Item17 -.-> Item7; + Item18 --> Item12; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item11; + Item18 --> Item13; + Item18 --> Item14; + Item18 --> Item15; + Item18 --> Item16; + Item18 --> Item17; + Item18 -.-> Item6; + Item18 -.-> Item5; + Item18 -.-> Item4; + Item18 -.-> Item7; + Item19 --> Item12; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item9; + Item19 --> Item10; + Item19 --> Item11; + Item19 --> Item13; + Item19 --> Item14; + Item19 --> Item15; + Item19 --> Item16; + Item19 --> Item17; + Item19 --> Item18; + Item19 -.-> Item6; + Item19 -.-> Item5; + Item19 -.-> Item4; + Item19 -.-> Item7; + Item20 --> Item12; + Item20 --> Item1; + Item20 --> Item2; + Item20 --> Item3; + Item20 --> Item9; + Item20 --> Item10; + Item20 --> Item11; + Item20 --> Item13; + Item20 --> Item14; + Item20 --> Item15; + Item20 --> Item16; + Item20 --> Item17; + Item20 --> Item18; + Item20 --> Item19; + Item20 -.-> Item6; + Item20 -.-> Item5; + Item20 -.-> Item4; + Item20 -.-> Item7; + Item21 --> Item12; + Item21 --> Item1; + Item21 --> Item2; + Item21 --> Item3; + Item21 --> Item9; + Item21 --> Item10; + Item21 --> Item11; + Item21 --> Item13; + Item21 --> Item14; + Item21 --> Item15; + Item21 --> Item16; + Item21 --> Item17; + Item21 --> Item18; + Item21 --> Item19; + Item21 --> Item20; + Item21 -.-> Item6; + Item21 -.-> Item5; + Item21 -.-> Item4; + Item21 -.-> Item7; + Item22 --> Item12; + Item22 --> Item1; + Item22 --> Item2; + Item22 --> Item3; + Item22 --> Item9; + Item22 --> Item10; + Item22 --> Item11; + Item22 --> Item13; + Item22 --> Item14; + Item22 --> Item15; + Item22 --> Item16; + Item22 --> Item17; + Item22 --> Item18; + Item22 --> Item19; + Item22 --> Item20; + Item22 --> Item21; + Item22 -.-> Item6; + Item22 -.-> Item5; + Item22 -.-> Item4; + Item22 -.-> Item7; + Item23 --> Item12; + Item23 --> Item1; + Item23 --> Item2; + Item23 --> Item3; + Item23 --> Item9; + Item23 --> Item10; + Item23 --> Item11; + Item23 --> Item13; + Item23 --> Item14; + Item23 --> Item15; + Item23 --> Item16; + Item23 --> Item17; + Item23 --> Item18; + Item23 --> Item19; + Item23 --> Item20; + Item23 --> Item21; + Item23 --> Item22; + Item23 -.-> Item6; + Item23 -.-> Item5; + Item23 -.-> Item4; + Item23 -.-> Item7; + Item24 --> Item12; + Item24 --> Item1; + Item24 --> Item2; + Item24 --> Item3; + Item24 --> Item9; + Item24 --> Item10; + Item24 --> Item11; + Item24 --> Item13; + Item24 --> Item14; + Item24 --> Item15; + Item24 --> Item16; + Item24 --> Item17; + Item24 --> Item18; + Item24 --> Item19; + Item24 --> Item20; + Item24 --> Item21; + Item24 --> Item22; + Item24 --> Item23; + Item24 -.-> Item6; + Item24 -.-> Item5; + Item24 -.-> Item4; + Item24 -.-> Item7; + Item25 --> Item12; + Item25 --> Item1; + Item25 --> Item2; + Item25 --> Item3; + Item25 --> Item9; + Item25 --> Item10; + Item25 --> Item11; + Item25 --> Item13; + Item25 --> Item14; + Item25 --> Item15; + Item25 --> Item16; + Item25 --> Item17; + Item25 --> Item18; + Item25 --> Item19; + Item25 --> Item20; + Item25 --> Item21; + Item25 --> Item22; + Item25 --> Item23; + Item25 --> Item24; + Item25 -.-> Item6; + Item25 -.-> Item5; + Item25 -.-> Item4; + Item25 -.-> Item7; + Item26 --> Item12; + Item26 --> Item1; + Item26 --> Item2; + Item26 --> Item3; + Item26 --> Item9; + Item26 --> Item10; + Item26 --> Item11; + Item26 --> Item13; + Item26 --> Item14; + Item26 --> Item15; + Item26 --> Item16; + Item26 --> Item17; + Item26 --> Item18; + Item26 --> Item19; + Item26 --> Item20; + Item26 --> Item21; + Item26 --> Item22; + Item26 --> Item23; + Item26 --> Item24; + Item26 --> Item25; + Item26 -.-> Item6; + Item26 -.-> Item5; + Item26 -.-> Item4; + Item26 -.-> Item7; + Item27 --> Item12; + Item27 --> Item1; + Item27 --> Item2; + Item27 --> Item3; + Item27 --> Item9; + Item27 --> Item10; + Item27 --> Item11; + Item27 --> Item13; + Item27 --> Item14; + Item27 --> Item15; + Item27 --> Item16; + Item27 --> Item17; + Item27 --> Item18; + Item27 --> Item19; + Item27 --> Item20; + Item27 --> Item21; + Item27 --> Item22; + Item27 --> Item23; + Item27 --> Item24; + Item27 --> Item25; + Item27 --> Item26; + Item27 -.-> Item6; + Item27 -.-> Item5; + Item27 -.-> Item4; + Item27 -.-> Item7; + Item28 --> Item12; + Item28 --> Item1; + Item28 --> Item2; + Item28 --> Item3; + Item28 --> Item9; + Item28 --> Item10; + Item28 --> Item11; + Item28 --> Item13; + Item28 --> Item14; + Item28 --> Item15; + Item28 --> Item16; + Item28 --> Item17; + Item28 --> Item18; + Item28 --> Item19; + Item28 --> Item20; + Item28 --> Item21; + Item28 --> Item22; + Item28 --> Item23; + Item28 --> Item24; + Item28 --> Item25; + Item28 --> Item26; + Item28 --> Item27; + Item28 -.-> Item6; + Item28 -.-> Item5; + Item28 -.-> Item4; + Item28 -.-> Item7; + Item30 --> Item7; + Item31 --> Item11; + Item31 --> Item10; + Item7 --> Item6; + Item7 --> Item5; + Item8 --> Item4; + Item8 --> Item7; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item29["ModuleEvaluation"]; + Item30; + Item30["export structuredError"]; + Item31; + Item31["export IPC"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item1; + Item9 --> Item2; + Item9 --> Item3; + Item9 -.-> Item6; + Item9 -.-> Item5; + Item9 -.-> Item4; + Item9 -.-> Item7; + Item10 --> Item8; + Item10 --> Item9; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item3; + Item10 -.-> Item6; + Item10 -.-> Item5; + Item10 -.-> Item4; + Item10 -.-> Item7; + Item11 --> Item10; + Item11 --> Item1; + Item11 --> Item2; + Item11 --> Item3; + Item11 --> Item9; + Item11 -.-> Item6; + Item11 -.-> Item5; + Item11 -.-> Item4; + Item11 -.-> Item7; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item11; + Item12 -.-> Item6; + Item12 -.-> Item5; + Item12 -.-> Item4; + Item12 -.-> Item7; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item9; + Item13 --> Item10; + Item13 --> Item11; + Item13 -.-> Item6; + Item13 -.-> Item5; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item14 --> Item12; + Item14 --> Item1; + Item14 --> Item2; + Item14 --> Item3; + Item14 --> Item9; + Item14 --> Item10; + Item14 --> Item11; + Item14 --> Item13; + Item14 -.-> Item6; + Item14 -.-> Item5; + Item14 -.-> Item4; + Item14 -.-> Item7; + Item15 --> Item12; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item11; + Item15 --> Item13; + Item15 --> Item14; + Item15 -.-> Item6; + Item15 -.-> Item5; + Item15 -.-> Item4; + Item15 -.-> Item7; + Item16 --> Item12; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item9; + Item16 --> Item10; + Item16 --> Item11; + Item16 --> Item13; + Item16 --> Item14; + Item16 --> Item15; + Item16 -.-> Item6; + Item16 -.-> Item5; + Item16 -.-> Item4; + Item16 -.-> Item7; + Item17 --> Item12; + Item17 --> Item1; + Item17 --> Item2; + Item17 --> Item3; + Item17 --> Item9; + Item17 --> Item10; + Item17 --> Item11; + Item17 --> Item13; + Item17 --> Item14; + Item17 --> Item15; + Item17 --> Item16; + Item17 -.-> Item6; + Item17 -.-> Item5; + Item17 -.-> Item4; + Item17 -.-> Item7; + Item18 --> Item12; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item11; + Item18 --> Item13; + Item18 --> Item14; + Item18 --> Item15; + Item18 --> Item16; + Item18 --> Item17; + Item18 -.-> Item6; + Item18 -.-> Item5; + Item18 -.-> Item4; + Item18 -.-> Item7; + Item19 --> Item12; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item9; + Item19 --> Item10; + Item19 --> Item11; + Item19 --> Item13; + Item19 --> Item14; + Item19 --> Item15; + Item19 --> Item16; + Item19 --> Item17; + Item19 --> Item18; + Item19 -.-> Item6; + Item19 -.-> Item5; + Item19 -.-> Item4; + Item19 -.-> Item7; + Item20 --> Item12; + Item20 --> Item1; + Item20 --> Item2; + Item20 --> Item3; + Item20 --> Item9; + Item20 --> Item10; + Item20 --> Item11; + Item20 --> Item13; + Item20 --> Item14; + Item20 --> Item15; + Item20 --> Item16; + Item20 --> Item17; + Item20 --> Item18; + Item20 --> Item19; + Item20 -.-> Item6; + Item20 -.-> Item5; + Item20 -.-> Item4; + Item20 -.-> Item7; + Item21 --> Item12; + Item21 --> Item1; + Item21 --> Item2; + Item21 --> Item3; + Item21 --> Item9; + Item21 --> Item10; + Item21 --> Item11; + Item21 --> Item13; + Item21 --> Item14; + Item21 --> Item15; + Item21 --> Item16; + Item21 --> Item17; + Item21 --> Item18; + Item21 --> Item19; + Item21 --> Item20; + Item21 -.-> Item6; + Item21 -.-> Item5; + Item21 -.-> Item4; + Item21 -.-> Item7; + Item22 --> Item12; + Item22 --> Item1; + Item22 --> Item2; + Item22 --> Item3; + Item22 --> Item9; + Item22 --> Item10; + Item22 --> Item11; + Item22 --> Item13; + Item22 --> Item14; + Item22 --> Item15; + Item22 --> Item16; + Item22 --> Item17; + Item22 --> Item18; + Item22 --> Item19; + Item22 --> Item20; + Item22 --> Item21; + Item22 -.-> Item6; + Item22 -.-> Item5; + Item22 -.-> Item4; + Item22 -.-> Item7; + Item23 --> Item12; + Item23 --> Item1; + Item23 --> Item2; + Item23 --> Item3; + Item23 --> Item9; + Item23 --> Item10; + Item23 --> Item11; + Item23 --> Item13; + Item23 --> Item14; + Item23 --> Item15; + Item23 --> Item16; + Item23 --> Item17; + Item23 --> Item18; + Item23 --> Item19; + Item23 --> Item20; + Item23 --> Item21; + Item23 --> Item22; + Item23 -.-> Item6; + Item23 -.-> Item5; + Item23 -.-> Item4; + Item23 -.-> Item7; + Item24 --> Item12; + Item24 --> Item1; + Item24 --> Item2; + Item24 --> Item3; + Item24 --> Item9; + Item24 --> Item10; + Item24 --> Item11; + Item24 --> Item13; + Item24 --> Item14; + Item24 --> Item15; + Item24 --> Item16; + Item24 --> Item17; + Item24 --> Item18; + Item24 --> Item19; + Item24 --> Item20; + Item24 --> Item21; + Item24 --> Item22; + Item24 --> Item23; + Item24 -.-> Item6; + Item24 -.-> Item5; + Item24 -.-> Item4; + Item24 -.-> Item7; + Item25 --> Item12; + Item25 --> Item1; + Item25 --> Item2; + Item25 --> Item3; + Item25 --> Item9; + Item25 --> Item10; + Item25 --> Item11; + Item25 --> Item13; + Item25 --> Item14; + Item25 --> Item15; + Item25 --> Item16; + Item25 --> Item17; + Item25 --> Item18; + Item25 --> Item19; + Item25 --> Item20; + Item25 --> Item21; + Item25 --> Item22; + Item25 --> Item23; + Item25 --> Item24; + Item25 -.-> Item6; + Item25 -.-> Item5; + Item25 -.-> Item4; + Item25 -.-> Item7; + Item26 --> Item12; + Item26 --> Item1; + Item26 --> Item2; + Item26 --> Item3; + Item26 --> Item9; + Item26 --> Item10; + Item26 --> Item11; + Item26 --> Item13; + Item26 --> Item14; + Item26 --> Item15; + Item26 --> Item16; + Item26 --> Item17; + Item26 --> Item18; + Item26 --> Item19; + Item26 --> Item20; + Item26 --> Item21; + Item26 --> Item22; + Item26 --> Item23; + Item26 --> Item24; + Item26 --> Item25; + Item26 -.-> Item6; + Item26 -.-> Item5; + Item26 -.-> Item4; + Item26 -.-> Item7; + Item27 --> Item12; + Item27 --> Item1; + Item27 --> Item2; + Item27 --> Item3; + Item27 --> Item9; + Item27 --> Item10; + Item27 --> Item11; + Item27 --> Item13; + Item27 --> Item14; + Item27 --> Item15; + Item27 --> Item16; + Item27 --> Item17; + Item27 --> Item18; + Item27 --> Item19; + Item27 --> Item20; + Item27 --> Item21; + Item27 --> Item22; + Item27 --> Item23; + Item27 --> Item24; + Item27 --> Item25; + Item27 --> Item26; + Item27 -.-> Item6; + Item27 -.-> Item5; + Item27 -.-> Item4; + Item27 -.-> Item7; + Item28 --> Item12; + Item28 --> Item1; + Item28 --> Item2; + Item28 --> Item3; + Item28 --> Item9; + Item28 --> Item10; + Item28 --> Item11; + Item28 --> Item13; + Item28 --> Item14; + Item28 --> Item15; + Item28 --> Item16; + Item28 --> Item17; + Item28 --> Item18; + Item28 --> Item19; + Item28 --> Item20; + Item28 --> Item21; + Item28 --> Item22; + Item28 --> Item23; + Item28 --> Item24; + Item28 --> Item25; + Item28 --> Item26; + Item28 --> Item27; + Item28 -.-> Item6; + Item28 -.-> Item5; + Item28 -.-> Item4; + Item28 -.-> Item7; + Item30 --> Item7; + Item31 --> Item11; + Item31 --> Item10; + Item7 --> Item6; + Item7 --> Item5; + Item8 --> Item4; + Item8 --> Item7; + Item29 --> Item1; + Item29 --> Item2; + Item29 --> Item3; + Item29 --> Item9; + Item29 --> Item10; + Item29 --> Item11; + Item29 --> Item12; + Item29 --> Item13; + Item29 --> Item14; + Item29 --> Item15; + Item29 --> Item16; + Item29 --> Item17; + Item29 --> Item18; + Item29 --> Item19; + Item29 --> Item20; + Item29 --> Item21; + Item29 --> Item22; + Item29 --> Item23; + Item29 --> Item24; + Item29 --> Item25; + Item29 --> Item26; + Item29 --> Item27; + Item29 --> Item28; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportBinding(0))]"]; + N1["Items: [ItemId(1, ImportBinding(0))]"]; + N2["Items: [ItemId(2, ImportBinding(0))]"]; + N3["Items: [ItemId(3, Normal)]"]; + N4["Items: [ItemId(4, Normal)]"]; + N5["Items: [ItemId(Export(("structuredError", #2), "structuredError"))]"]; + N6["Items: [ItemId(0, ImportOfModule)]"]; + N7["Items: [ItemId(1, ImportOfModule)]"]; + N8["Items: [ItemId(2, ImportOfModule)]"]; + N9["Items: [ItemId(5, VarDeclarator(0))]"]; + N10["Items: [ItemId(6, VarDeclarator(0))]"]; + N11["Items: [ItemId(7, Normal)]"]; + N12["Items: [ItemId(Export(("IPC", #2), "IPC"))]"]; + N13["Items: [ItemId(8, VarDeclarator(0))]"]; + N14["Items: [ItemId(9, Normal)]"]; + N15["Items: [ItemId(10, Normal)]"]; + N16["Items: [ItemId(11, Normal)]"]; + N17["Items: [ItemId(12, Normal)]"]; + N18["Items: [ItemId(13, Normal)]"]; + N19["Items: [ItemId(14, Normal)]"]; + N20["Items: [ItemId(15, Normal)]"]; + N21["Items: [ItemId(16, Normal)]"]; + N22["Items: [ItemId(17, Normal)]"]; + N23["Items: [ItemId(18, Normal)]"]; + N24["Items: [ItemId(19, Normal)]"]; + N25["Items: [ItemId(20, Normal)]"]; + N26["Items: [ItemId(21, Normal)]"]; + N27["Items: [ItemId(22, Normal)]"]; + N28["Items: [ItemId(23, Normal)]"]; + N29["Items: [ItemId(24, Normal)]"]; + N30["Items: [ItemId(ModuleEvaluation)]"]; + N7 --> N6; + N8 --> N6; + N8 --> N7; + N9 --> N6; + N9 --> N7; + N9 --> N8; + N9 -.-> N2; + N9 -.-> N1; + N9 -.-> N0; + N9 -.-> N3; + N10 --> N4; + N10 --> N9; + N10 --> N6; + N10 --> N7; + N10 --> N8; + N10 -.-> N2; + N10 -.-> N1; + N10 -.-> N0; + N10 -.-> N3; + N11 --> N10; + N11 --> N6; + N11 --> N7; + N11 --> N8; + N11 --> N9; + N11 -.-> N2; + N11 -.-> N1; + N11 -.-> N0; + N11 -.-> N3; + N13 --> N6; + N13 --> N7; + N13 --> N8; + N13 --> N9; + N13 --> N10; + N13 --> N11; + N13 -.-> N2; + N13 -.-> N1; + N13 -.-> N0; + N13 -.-> N3; + N14 --> N13; + N14 --> N6; + N14 --> N7; + N14 --> N8; + N14 --> N9; + N14 --> N10; + N14 --> N11; + N14 -.-> N2; + N14 -.-> N1; + N14 -.-> N0; + N14 -.-> N3; + N15 --> N13; + N15 --> N6; + N15 --> N7; + N15 --> N8; + N15 --> N9; + N15 --> N10; + N15 --> N11; + N15 --> N14; + N15 -.-> N2; + N15 -.-> N1; + N15 -.-> N0; + N15 -.-> N3; + N16 --> N13; + N16 --> N6; + N16 --> N7; + N16 --> N8; + N16 --> N9; + N16 --> N10; + N16 --> N11; + N16 --> N14; + N16 --> N15; + N16 -.-> N2; + N16 -.-> N1; + N16 -.-> N0; + N16 -.-> N3; + N17 --> N13; + N17 --> N6; + N17 --> N7; + N17 --> N8; + N17 --> N9; + N17 --> N10; + N17 --> N11; + N17 --> N14; + N17 --> N15; + N17 --> N16; + N17 -.-> N2; + N17 -.-> N1; + N17 -.-> N0; + N17 -.-> N3; + N18 --> N13; + N18 --> N6; + N18 --> N7; + N18 --> N8; + N18 --> N9; + N18 --> N10; + N18 --> N11; + N18 --> N14; + N18 --> N15; + N18 --> N16; + N18 --> N17; + N18 -.-> N2; + N18 -.-> N1; + N18 -.-> N0; + N18 -.-> N3; + N19 --> N13; + N19 --> N6; + N19 --> N7; + N19 --> N8; + N19 --> N9; + N19 --> N10; + N19 --> N11; + N19 --> N14; + N19 --> N15; + N19 --> N16; + N19 --> N17; + N19 --> N18; + N19 -.-> N2; + N19 -.-> N1; + N19 -.-> N0; + N19 -.-> N3; + N20 --> N13; + N20 --> N6; + N20 --> N7; + N20 --> N8; + N20 --> N9; + N20 --> N10; + N20 --> N11; + N20 --> N14; + N20 --> N15; + N20 --> N16; + N20 --> N17; + N20 --> N18; + N20 --> N19; + N20 -.-> N2; + N20 -.-> N1; + N20 -.-> N0; + N20 -.-> N3; + N21 --> N13; + N21 --> N6; + N21 --> N7; + N21 --> N8; + N21 --> N9; + N21 --> N10; + N21 --> N11; + N21 --> N14; + N21 --> N15; + N21 --> N16; + N21 --> N17; + N21 --> N18; + N21 --> N19; + N21 --> N20; + N21 -.-> N2; + N21 -.-> N1; + N21 -.-> N0; + N21 -.-> N3; + N22 --> N13; + N22 --> N6; + N22 --> N7; + N22 --> N8; + N22 --> N9; + N22 --> N10; + N22 --> N11; + N22 --> N14; + N22 --> N15; + N22 --> N16; + N22 --> N17; + N22 --> N18; + N22 --> N19; + N22 --> N20; + N22 --> N21; + N22 -.-> N2; + N22 -.-> N1; + N22 -.-> N0; + N22 -.-> N3; + N23 --> N13; + N23 --> N6; + N23 --> N7; + N23 --> N8; + N23 --> N9; + N23 --> N10; + N23 --> N11; + N23 --> N14; + N23 --> N15; + N23 --> N16; + N23 --> N17; + N23 --> N18; + N23 --> N19; + N23 --> N20; + N23 --> N21; + N23 --> N22; + N23 -.-> N2; + N23 -.-> N1; + N23 -.-> N0; + N23 -.-> N3; + N24 --> N13; + N24 --> N6; + N24 --> N7; + N24 --> N8; + N24 --> N9; + N24 --> N10; + N24 --> N11; + N24 --> N14; + N24 --> N15; + N24 --> N16; + N24 --> N17; + N24 --> N18; + N24 --> N19; + N24 --> N20; + N24 --> N21; + N24 --> N22; + N24 --> N23; + N24 -.-> N2; + N24 -.-> N1; + N24 -.-> N0; + N24 -.-> N3; + N25 --> N13; + N25 --> N6; + N25 --> N7; + N25 --> N8; + N25 --> N9; + N25 --> N10; + N25 --> N11; + N25 --> N14; + N25 --> N15; + N25 --> N16; + N25 --> N17; + N25 --> N18; + N25 --> N19; + N25 --> N20; + N25 --> N21; + N25 --> N22; + N25 --> N23; + N25 --> N24; + N25 -.-> N2; + N25 -.-> N1; + N25 -.-> N0; + N25 -.-> N3; + N26 --> N13; + N26 --> N6; + N26 --> N7; + N26 --> N8; + N26 --> N9; + N26 --> N10; + N26 --> N11; + N26 --> N14; + N26 --> N15; + N26 --> N16; + N26 --> N17; + N26 --> N18; + N26 --> N19; + N26 --> N20; + N26 --> N21; + N26 --> N22; + N26 --> N23; + N26 --> N24; + N26 --> N25; + N26 -.-> N2; + N26 -.-> N1; + N26 -.-> N0; + N26 -.-> N3; + N27 --> N13; + N27 --> N6; + N27 --> N7; + N27 --> N8; + N27 --> N9; + N27 --> N10; + N27 --> N11; + N27 --> N14; + N27 --> N15; + N27 --> N16; + N27 --> N17; + N27 --> N18; + N27 --> N19; + N27 --> N20; + N27 --> N21; + N27 --> N22; + N27 --> N23; + N27 --> N24; + N27 --> N25; + N27 --> N26; + N27 -.-> N2; + N27 -.-> N1; + N27 -.-> N0; + N27 -.-> N3; + N28 --> N13; + N28 --> N6; + N28 --> N7; + N28 --> N8; + N28 --> N9; + N28 --> N10; + N28 --> N11; + N28 --> N14; + N28 --> N15; + N28 --> N16; + N28 --> N17; + N28 --> N18; + N28 --> N19; + N28 --> N20; + N28 --> N21; + N28 --> N22; + N28 --> N23; + N28 --> N24; + N28 --> N25; + N28 --> N26; + N28 --> N27; + N28 -.-> N2; + N28 -.-> N1; + N28 -.-> N0; + N28 -.-> N3; + N29 --> N13; + N29 --> N6; + N29 --> N7; + N29 --> N8; + N29 --> N9; + N29 --> N10; + N29 --> N11; + N29 --> N14; + N29 --> N15; + N29 --> N16; + N29 --> N17; + N29 --> N18; + N29 --> N19; + N29 --> N20; + N29 --> N21; + N29 --> N22; + N29 --> N23; + N29 --> N24; + N29 --> N25; + N29 --> N26; + N29 --> N27; + N29 --> N28; + N29 -.-> N2; + N29 -.-> N1; + N29 -.-> N0; + N29 -.-> N3; + N5 --> N3; + N12 --> N11; + N12 --> N10; + N3 --> N2; + N3 --> N1; + N4 --> N0; + N4 --> N3; + N30 --> N6; + N30 --> N7; + N30 --> N8; + N30 --> N9; + N30 --> N10; + N30 --> N11; + N30 --> N13; + N30 --> N14; + N30 --> N15; + N30 --> N16; + N30 --> N17; + N30 --> N18; + N30 --> N19; + N30 --> N20; + N30 --> N21; + N30 --> N22; + N30 --> N23; + N30 --> N24; + N30 --> N25; + N30 --> N26; + N30 --> N27; + N30 --> N28; + N30 --> N29; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 30, + Export( + "IPC", + ): 12, + Exports: 31, + Export( + "structuredError", + ): 5, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { createConnection } from "node:net"; +export { createConnection } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; +export { parseStackTrace } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { getProperError } from "./error"; +export { getProperError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { parseStackTrace } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { getProperError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function structuredError(e) { + e = getProperError(e); + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : [] + }; +} +export { structuredError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { createConnection } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function createIpc(port) { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue = []; + const recvPromiseResolveQueue = []; + function pushPacket(packet) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8"))); + } else { + packetQueue.push(packet); + } + } + let state = { + type: "waiting" + }; + let buffer = Buffer.alloc(0); + socket.once("connect", ()=>{ + socket.on("data", (chunk)=>{ + buffer = Buffer.concat([ + buffer, + chunk + ]); + loop: while(true){ + switch(state.type){ + case "waiting": + { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { + type: "packet", + length + }; + } else { + break loop; + } + break; + } + case "packet": + { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { + type: "waiting" + }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + socket.once("close", ()=>{ + process.exit(0); + }); + function send(message) { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + return new Promise((resolve, reject)=>{ + socket.write(packet, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + function sendReady() { + const length = Buffer.from([ + 0, + 0, + 0, + 0 + ]); + return new Promise((resolve, reject)=>{ + socket.write(length, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + return { + async recv () { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")); + } + const result = await new Promise((resolve)=>{ + recvPromiseResolveQueue.push((result)=>{ + resolve(result); + }); + }); + return result; + }, + send (message) { + return send(message); + }, + sendReady, + async sendError (error) { + try { + await send({ + type: "error", + ...structuredError(error) + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + process.exit(1); + } + process.exit(0); + } + }; +} +export { createIpc } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { structuredError }; + +``` +## Part 6 +```js +import "node:net"; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "../compiled/stacktrace-parser"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "./error"; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const PORT = process.argv[2]; +export { PORT } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { createIpc } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { PORT } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +const IPC = createIpc(parseInt(PORT, 10)); +export { IPC } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +process.on("uncaughtException", (err)=>{ + IPC.sendError(err); +}); + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { IPC }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const improveConsole = (name, stream, addStack)=>{ + const original = console[name]; + const stdio = process[stream]; + console[name] = (...args)=>{ + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; +export { improveConsole } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("error", "stderr", true); + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("warn", "stderr", true); + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("count", "stdout", true); + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("trace", "stderr", false); + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("log", "stdout", true); + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("group", "stdout", true); + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("groupCollapsed", "stdout", true); + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("table", "stdout", true); + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("debug", "stdout", true); + +``` +## Part 23 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("info", "stdout", true); + +``` +## Part 24 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("dir", "stdout", true); + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("dirxml", "stdout", true); + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeEnd", "stdout", true); + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeLog", "stdout", true); + +``` +## Part 28 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeStamp", "stdout", true); + +``` +## Part 29 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("assert", "stderr", true); + +``` +## Part 30 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +"module evaluation"; + +``` +## Part 31 +```js +export { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export structuredError" +}; +export { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export IPC" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 30, + Export( + "IPC", + ): 12, + Exports: 31, + Export( + "structuredError", + ): 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { createConnection } from "node:net"; +export { createConnection } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; +export { parseStackTrace } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { getProperError } from "./error"; +export { getProperError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { parseStackTrace } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { getProperError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function structuredError(e) { + e = getProperError(e); + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack) : [] + }; +} +export { structuredError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { structuredError }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { createConnection } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function createIpc(port) { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue = []; + const recvPromiseResolveQueue = []; + function pushPacket(packet) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8"))); + } else { + packetQueue.push(packet); + } + } + let state = { + type: "waiting" + }; + let buffer = Buffer.alloc(0); + socket.once("connect", ()=>{ + socket.on("data", (chunk)=>{ + buffer = Buffer.concat([ + buffer, + chunk + ]); + loop: while(true){ + switch(state.type){ + case "waiting": + { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { + type: "packet", + length + }; + } else { + break loop; + } + break; + } + case "packet": + { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { + type: "waiting" + }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + socket.once("close", ()=>{ + process.exit(0); + }); + function send(message) { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + return new Promise((resolve, reject)=>{ + socket.write(packet, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + function sendReady() { + const length = Buffer.from([ + 0, + 0, + 0, + 0 + ]); + return new Promise((resolve, reject)=>{ + socket.write(length, (err)=>{ + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + return { + async recv () { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")); + } + const result = await new Promise((resolve)=>{ + recvPromiseResolveQueue.push((result)=>{ + resolve(result); + }); + }); + return result; + }, + send (message) { + return send(message); + }, + sendReady, + async sendError (error) { + try { + await send({ + type: "error", + ...structuredError(error) + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + process.exit(1); + } + process.exit(0); + } + }; +} +export { createIpc } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "node:net"; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "../compiled/stacktrace-parser"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "./error"; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +const PORT = process.argv[2]; +export { PORT } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { createIpc } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { PORT } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +const IPC = createIpc(parseInt(PORT, 10)); +export { IPC } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +process.on("uncaughtException", (err)=>{ + IPC.sendError(err); +}); + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { IPC }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +const improveConsole = (name, stream, addStack)=>{ + const original = console[name]; + const stdio = process[stream]; + console[name] = (...args)=>{ + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; +export { improveConsole } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("error", "stderr", true); + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("warn", "stderr", true); + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("count", "stdout", true); + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("trace", "stderr", false); + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("log", "stdout", true); + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("group", "stdout", true); + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("groupCollapsed", "stdout", true); + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("table", "stdout", true); + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("debug", "stdout", true); + +``` +## Part 23 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("info", "stdout", true); + +``` +## Part 24 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("dir", "stdout", true); + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("dirxml", "stdout", true); + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeEnd", "stdout", true); + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeLog", "stdout", true); + +``` +## Part 28 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("timeStamp", "stdout", true); + +``` +## Part 29 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { improveConsole } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +improveConsole("assert", "stderr", true); + +``` +## Part 30 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 31 +```js +export { structuredError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export structuredError" +}; +export { IPC } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export IPC" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 19 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/let-bug-1/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/let-bug-1/input.js new file mode 100644 index 0000000000000..2f8e8f3d19740 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/let-bug-1/input.js @@ -0,0 +1,44 @@ +let clientComponentLoadStart = 0; +let clientComponentLoadTimes = 0; +let clientComponentLoadCount = 0; +export function wrapClientComponentLoader(ComponentMod) { + if (!('performance' in globalThis)) { + return ComponentMod.__next_app__; + } + return { + require: (...args)=>{ + const startTime = performance.now(); + if (clientComponentLoadStart === 0) { + clientComponentLoadStart = startTime; + } + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.require(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + }, + loadChunk: (...args)=>{ + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.loadChunk(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + } + }; +} +export function getClientComponentLoaderMetrics(options = {}) { + const metrics = clientComponentLoadStart === 0 ? undefined : { + clientComponentLoadStart, + clientComponentLoadTimes, + clientComponentLoadCount + }; + if (options.reset) { + clientComponentLoadStart = 0; + clientComponentLoadTimes = 0; + clientComponentLoadCount = 0; + } + return metrics; +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/let-bug-1/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/let-bug-1/output.md new file mode 100644 index 0000000000000..cc06bf3abb693 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/let-bug-1/output.md @@ -0,0 +1,545 @@ +# Items + +Count: 8 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +let clientComponentLoadStart = 0; + +``` + +- Declares: `clientComponentLoadStart` +- Write: `clientComponentLoadStart` + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +let clientComponentLoadTimes = 0; + +``` + +- Declares: `clientComponentLoadTimes` +- Write: `clientComponentLoadTimes` + +## Item 3: Stmt 2, `VarDeclarator(0)` + +```js +let clientComponentLoadCount = 0; + +``` + +- Declares: `clientComponentLoadCount` +- Write: `clientComponentLoadCount` + +## Item 4: Stmt 3, `Normal` + +```js +export function wrapClientComponentLoader(ComponentMod) { + if (!('performance' in globalThis)) { + return ComponentMod.__next_app__; + } + return { + require: (...args)=>{ + const startTime = performance.now(); + if (clientComponentLoadStart === 0) { + clientComponentLoadStart = startTime; + } + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.require(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + }, + loadChunk: (...args)=>{ + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.loadChunk(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + } + }; +} + +``` + +- Hoisted +- Declares: `wrapClientComponentLoader` +- Reads (eventual): `clientComponentLoadStart` +- Write: `wrapClientComponentLoader` +- Write (eventual): `clientComponentLoadStart`, `clientComponentLoadCount`, `clientComponentLoadTimes` + +## Item 5: Stmt 4, `Normal` + +```js +export function getClientComponentLoaderMetrics(options = {}) { + const metrics = clientComponentLoadStart === 0 ? undefined : { + clientComponentLoadStart, + clientComponentLoadTimes, + clientComponentLoadCount + }; + if (options.reset) { + clientComponentLoadStart = 0; + clientComponentLoadTimes = 0; + clientComponentLoadCount = 0; + } + return metrics; +} + +``` + +- Hoisted +- Declares: `getClientComponentLoaderMetrics` +- Reads (eventual): `clientComponentLoadStart`, `clientComponentLoadTimes`, `clientComponentLoadCount` +- Write: `getClientComponentLoaderMetrics` +- Write (eventual): `clientComponentLoadStart`, `clientComponentLoadTimes`, `clientComponentLoadCount` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export wrapClientComponentLoader"]; + Item8; + Item8["export getClientComponentLoaderMetrics"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export wrapClientComponentLoader"]; + Item8; + Item8["export getClientComponentLoaderMetrics"]; + Item7 --> Item4; + Item8 --> Item5; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export wrapClientComponentLoader"]; + Item8; + Item8["export getClientComponentLoaderMetrics"]; + Item7 --> Item4; + Item8 --> Item5; + Item4 --> Item1; + Item4 --> Item3; + Item4 --> Item2; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export wrapClientComponentLoader"]; + Item8; + Item8["export getClientComponentLoaderMetrics"]; + Item7 --> Item4; + Item8 --> Item5; + Item4 --> Item1; + Item4 --> Item3; + Item4 --> Item2; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, VarDeclarator(0))]"]; + N1["Items: [ItemId(2, VarDeclarator(0))]"]; + N2["Items: [ItemId(0, VarDeclarator(0))]"]; + N3["Items: [ItemId(4, Normal)]"]; + N4["Items: [ItemId(Export(("getClientComponentLoaderMetrics", #2), "getClientComponentLoaderMetrics"))]"]; + N5["Items: [ItemId(3, Normal)]"]; + N6["Items: [ItemId(Export(("wrapClientComponentLoader", #2), "wrapClientComponentLoader"))]"]; + N7["Items: [ItemId(ModuleEvaluation)]"]; + N6 --> N5; + N4 --> N3; + N5 --> N2; + N5 --> N1; + N5 --> N0; + N3 --> N2; + N3 --> N0; + N3 --> N1; +``` +# Entrypoints + +``` +{ + Export( + "getClientComponentLoaderMetrics", + ): 4, + ModuleEvaluation: 7, + Exports: 8, + Export( + "wrapClientComponentLoader", + ): 6, +} +``` + + +# Modules (dev) +## Part 0 +```js +let clientComponentLoadTimes = 0; +export { clientComponentLoadTimes } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +let clientComponentLoadCount = 0; +export { clientComponentLoadCount } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +let clientComponentLoadStart = 0; +export { clientComponentLoadStart } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { clientComponentLoadCount } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { clientComponentLoadStart } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { clientComponentLoadTimes } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function getClientComponentLoaderMetrics(options = {}) { + const metrics = clientComponentLoadStart === 0 ? undefined : { + clientComponentLoadStart, + clientComponentLoadTimes, + clientComponentLoadCount + }; + if (options.reset) { + clientComponentLoadStart = 0; + clientComponentLoadTimes = 0; + clientComponentLoadCount = 0; + } + return metrics; +} +export { getClientComponentLoaderMetrics } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { getClientComponentLoaderMetrics } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { getClientComponentLoaderMetrics }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { clientComponentLoadTimes } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { clientComponentLoadStart } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { clientComponentLoadCount } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function wrapClientComponentLoader(ComponentMod) { + if (!('performance' in globalThis)) { + return ComponentMod.__next_app__; + } + return { + require: (...args)=>{ + const startTime = performance.now(); + if (clientComponentLoadStart === 0) { + clientComponentLoadStart = startTime; + } + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.require(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + }, + loadChunk: (...args)=>{ + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.loadChunk(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + } + }; +} +export { wrapClientComponentLoader } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { wrapClientComponentLoader } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { wrapClientComponentLoader }; + +``` +## Part 7 +```js +"module evaluation"; + +``` +## Part 8 +```js +export { getClientComponentLoaderMetrics } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getClientComponentLoaderMetrics" +}; +export { wrapClientComponentLoader } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export wrapClientComponentLoader" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "getClientComponentLoaderMetrics", + ): 4, + ModuleEvaluation: 7, + Exports: 8, + Export( + "wrapClientComponentLoader", + ): 6, +} +``` + + +# Modules (prod) +## Part 0 +```js +let clientComponentLoadTimes = 0; +export { clientComponentLoadTimes } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +let clientComponentLoadCount = 0; +export { clientComponentLoadCount } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +let clientComponentLoadStart = 0; +export { clientComponentLoadStart } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { clientComponentLoadCount } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { clientComponentLoadStart } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { clientComponentLoadTimes } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function getClientComponentLoaderMetrics(options = {}) { + const metrics = clientComponentLoadStart === 0 ? undefined : { + clientComponentLoadStart, + clientComponentLoadTimes, + clientComponentLoadCount + }; + if (options.reset) { + clientComponentLoadStart = 0; + clientComponentLoadTimes = 0; + clientComponentLoadCount = 0; + } + return metrics; +} +export { getClientComponentLoaderMetrics } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { getClientComponentLoaderMetrics } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { getClientComponentLoaderMetrics }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { clientComponentLoadTimes } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { clientComponentLoadStart } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { clientComponentLoadCount } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function wrapClientComponentLoader(ComponentMod) { + if (!('performance' in globalThis)) { + return ComponentMod.__next_app__; + } + return { + require: (...args)=>{ + const startTime = performance.now(); + if (clientComponentLoadStart === 0) { + clientComponentLoadStart = startTime; + } + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.require(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + }, + loadChunk: (...args)=>{ + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.loadChunk(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + } + }; +} +export { wrapClientComponentLoader } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { wrapClientComponentLoader } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { wrapClientComponentLoader }; + +``` +## Part 7 +```js +"module evaluation"; + +``` +## Part 8 +```js +export { getClientComponentLoaderMetrics } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getClientComponentLoaderMetrics" +}; +export { wrapClientComponentLoader } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export wrapClientComponentLoader" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/logger/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/logger/input.js new file mode 100644 index 0000000000000..831bb0474831b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/logger/input.js @@ -0,0 +1,44 @@ +let clientComponentLoadStart = 0; +let clientComponentLoadTimes = 0; +let clientComponentLoadCount = 0; +export function wrapClientComponentLoader(ComponentMod) { + if (!('performance' in globalThis)) { + return ComponentMod.__next_app__; + } + return { + require: (...args)=>{ + if (clientComponentLoadStart === 0) { + clientComponentLoadStart = performance.now(); + } + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.require(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + }, + loadChunk: (...args)=>{ + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.loadChunk(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + } + }; +} +export function getClientComponentLoaderMetrics(options = {}) { + const metrics = clientComponentLoadStart === 0 ? undefined : { + clientComponentLoadStart, + clientComponentLoadTimes, + clientComponentLoadCount + }; + if (options.reset) { + clientComponentLoadStart = 0; + clientComponentLoadTimes = 0; + clientComponentLoadCount = 0; + } + return metrics; +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/logger/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/logger/output.md new file mode 100644 index 0000000000000..31feb044292c8 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/logger/output.md @@ -0,0 +1,545 @@ +# Items + +Count: 8 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +let clientComponentLoadStart = 0; + +``` + +- Declares: `clientComponentLoadStart` +- Write: `clientComponentLoadStart` + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +let clientComponentLoadTimes = 0; + +``` + +- Declares: `clientComponentLoadTimes` +- Write: `clientComponentLoadTimes` + +## Item 3: Stmt 2, `VarDeclarator(0)` + +```js +let clientComponentLoadCount = 0; + +``` + +- Declares: `clientComponentLoadCount` +- Write: `clientComponentLoadCount` + +## Item 4: Stmt 3, `Normal` + +```js +export function wrapClientComponentLoader(ComponentMod) { + if (!('performance' in globalThis)) { + return ComponentMod.__next_app__; + } + return { + require: (...args)=>{ + if (clientComponentLoadStart === 0) { + clientComponentLoadStart = performance.now(); + } + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.require(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + }, + loadChunk: (...args)=>{ + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.loadChunk(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + } + }; +} + +``` + +- Hoisted +- Declares: `wrapClientComponentLoader` +- Reads (eventual): `clientComponentLoadStart` +- Write: `wrapClientComponentLoader` +- Write (eventual): `clientComponentLoadStart`, `clientComponentLoadCount`, `clientComponentLoadTimes` + +## Item 5: Stmt 4, `Normal` + +```js +export function getClientComponentLoaderMetrics(options = {}) { + const metrics = clientComponentLoadStart === 0 ? undefined : { + clientComponentLoadStart, + clientComponentLoadTimes, + clientComponentLoadCount + }; + if (options.reset) { + clientComponentLoadStart = 0; + clientComponentLoadTimes = 0; + clientComponentLoadCount = 0; + } + return metrics; +} + +``` + +- Hoisted +- Declares: `getClientComponentLoaderMetrics` +- Reads (eventual): `clientComponentLoadStart`, `clientComponentLoadTimes`, `clientComponentLoadCount` +- Write: `getClientComponentLoaderMetrics` +- Write (eventual): `clientComponentLoadStart`, `clientComponentLoadTimes`, `clientComponentLoadCount` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export wrapClientComponentLoader"]; + Item8; + Item8["export getClientComponentLoaderMetrics"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export wrapClientComponentLoader"]; + Item8; + Item8["export getClientComponentLoaderMetrics"]; + Item7 --> Item4; + Item8 --> Item5; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export wrapClientComponentLoader"]; + Item8; + Item8["export getClientComponentLoaderMetrics"]; + Item7 --> Item4; + Item8 --> Item5; + Item4 --> Item1; + Item4 --> Item3; + Item4 --> Item2; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export wrapClientComponentLoader"]; + Item8; + Item8["export getClientComponentLoaderMetrics"]; + Item7 --> Item4; + Item8 --> Item5; + Item4 --> Item1; + Item4 --> Item3; + Item4 --> Item2; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, VarDeclarator(0))]"]; + N1["Items: [ItemId(2, VarDeclarator(0))]"]; + N2["Items: [ItemId(0, VarDeclarator(0))]"]; + N3["Items: [ItemId(4, Normal)]"]; + N4["Items: [ItemId(Export(("getClientComponentLoaderMetrics", #2), "getClientComponentLoaderMetrics"))]"]; + N5["Items: [ItemId(3, Normal)]"]; + N6["Items: [ItemId(Export(("wrapClientComponentLoader", #2), "wrapClientComponentLoader"))]"]; + N7["Items: [ItemId(ModuleEvaluation)]"]; + N6 --> N5; + N4 --> N3; + N5 --> N2; + N5 --> N1; + N5 --> N0; + N3 --> N2; + N3 --> N0; + N3 --> N1; +``` +# Entrypoints + +``` +{ + Export( + "getClientComponentLoaderMetrics", + ): 4, + ModuleEvaluation: 7, + Exports: 8, + Export( + "wrapClientComponentLoader", + ): 6, +} +``` + + +# Modules (dev) +## Part 0 +```js +let clientComponentLoadTimes = 0; +export { clientComponentLoadTimes } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +let clientComponentLoadCount = 0; +export { clientComponentLoadCount } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +let clientComponentLoadStart = 0; +export { clientComponentLoadStart } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { clientComponentLoadCount } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { clientComponentLoadStart } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { clientComponentLoadTimes } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function getClientComponentLoaderMetrics(options = {}) { + const metrics = clientComponentLoadStart === 0 ? undefined : { + clientComponentLoadStart, + clientComponentLoadTimes, + clientComponentLoadCount + }; + if (options.reset) { + clientComponentLoadStart = 0; + clientComponentLoadTimes = 0; + clientComponentLoadCount = 0; + } + return metrics; +} +export { getClientComponentLoaderMetrics } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { getClientComponentLoaderMetrics } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { getClientComponentLoaderMetrics }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { clientComponentLoadTimes } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { clientComponentLoadStart } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { clientComponentLoadCount } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function wrapClientComponentLoader(ComponentMod) { + if (!('performance' in globalThis)) { + return ComponentMod.__next_app__; + } + return { + require: (...args)=>{ + if (clientComponentLoadStart === 0) { + clientComponentLoadStart = performance.now(); + } + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.require(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + }, + loadChunk: (...args)=>{ + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.loadChunk(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + } + }; +} +export { wrapClientComponentLoader } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { wrapClientComponentLoader } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { wrapClientComponentLoader }; + +``` +## Part 7 +```js +"module evaluation"; + +``` +## Part 8 +```js +export { getClientComponentLoaderMetrics } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getClientComponentLoaderMetrics" +}; +export { wrapClientComponentLoader } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export wrapClientComponentLoader" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "getClientComponentLoaderMetrics", + ): 4, + ModuleEvaluation: 7, + Exports: 8, + Export( + "wrapClientComponentLoader", + ): 6, +} +``` + + +# Modules (prod) +## Part 0 +```js +let clientComponentLoadTimes = 0; +export { clientComponentLoadTimes } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +let clientComponentLoadCount = 0; +export { clientComponentLoadCount } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +let clientComponentLoadStart = 0; +export { clientComponentLoadStart } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { clientComponentLoadCount } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { clientComponentLoadStart } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { clientComponentLoadTimes } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function getClientComponentLoaderMetrics(options = {}) { + const metrics = clientComponentLoadStart === 0 ? undefined : { + clientComponentLoadStart, + clientComponentLoadTimes, + clientComponentLoadCount + }; + if (options.reset) { + clientComponentLoadStart = 0; + clientComponentLoadTimes = 0; + clientComponentLoadCount = 0; + } + return metrics; +} +export { getClientComponentLoaderMetrics } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { getClientComponentLoaderMetrics } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { getClientComponentLoaderMetrics }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { clientComponentLoadTimes } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { clientComponentLoadStart } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { clientComponentLoadCount } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function wrapClientComponentLoader(ComponentMod) { + if (!('performance' in globalThis)) { + return ComponentMod.__next_app__; + } + return { + require: (...args)=>{ + if (clientComponentLoadStart === 0) { + clientComponentLoadStart = performance.now(); + } + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.require(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + }, + loadChunk: (...args)=>{ + const startTime = performance.now(); + try { + clientComponentLoadCount += 1; + return ComponentMod.__next_app__.loadChunk(...args); + } finally{ + clientComponentLoadTimes += performance.now() - startTime; + } + } + }; +} +export { wrapClientComponentLoader } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { wrapClientComponentLoader } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { wrapClientComponentLoader }; + +``` +## Part 7 +```js +"module evaluation"; + +``` +## Part 8 +```js +export { getClientComponentLoaderMetrics } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getClientComponentLoaderMetrics" +}; +export { wrapClientComponentLoader } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export wrapClientComponentLoader" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/mui-sys/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/mui-sys/input.js new file mode 100644 index 0000000000000..ed24f234dc66f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/mui-sys/input.js @@ -0,0 +1,85 @@ +import style from './style'; +import compose from './compose'; +import { createUnaryUnit, getValue } from './spacing'; +import { handleBreakpoints } from './breakpoints'; +import responsivePropType from './responsivePropType'; +export const gap = props => { + if (props.gap !== undefined && props.gap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'gap'); + + const styleFromPropValue = propValue => ({ + gap: getValue(transformer, propValue) + }); + + return handleBreakpoints(props, props.gap, styleFromPropValue); + } + + return null; +}; +gap.propTypes = process.env.NODE_ENV !== 'production' ? { + gap: responsivePropType +} : {}; +gap.filterProps = ['gap']; +export const columnGap = props => { + if (props.columnGap !== undefined && props.columnGap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'columnGap'); + + const styleFromPropValue = propValue => ({ + columnGap: getValue(transformer, propValue) + }); + + return handleBreakpoints(props, props.columnGap, styleFromPropValue); + } + + return null; +}; +columnGap.propTypes = process.env.NODE_ENV !== 'production' ? { + columnGap: responsivePropType +} : {}; +columnGap.filterProps = ['columnGap']; +export const rowGap = props => { + if (props.rowGap !== undefined && props.rowGap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'rowGap'); + + const styleFromPropValue = propValue => ({ + rowGap: getValue(transformer, propValue) + }); + + return handleBreakpoints(props, props.rowGap, styleFromPropValue); + } + + return null; +}; +rowGap.propTypes = process.env.NODE_ENV !== 'production' ? { + rowGap: responsivePropType +} : {}; +rowGap.filterProps = ['rowGap']; +export const gridColumn = style({ + prop: 'gridColumn' +}); +export const gridRow = style({ + prop: 'gridRow' +}); +export const gridAutoFlow = style({ + prop: 'gridAutoFlow' +}); +export const gridAutoColumns = style({ + prop: 'gridAutoColumns' +}); +export const gridAutoRows = style({ + prop: 'gridAutoRows' +}); +export const gridTemplateColumns = style({ + prop: 'gridTemplateColumns' +}); +export const gridTemplateRows = style({ + prop: 'gridTemplateRows' +}); +export const gridTemplateAreas = style({ + prop: 'gridTemplateAreas' +}); +export const gridArea = style({ + prop: 'gridArea' +}); +const grid = compose(gap, columnGap, rowGap, gridColumn, gridRow, gridAutoFlow, gridAutoColumns, gridAutoRows, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridArea); +export default grid; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/mui-sys/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/mui-sys/output.md new file mode 100644 index 0000000000000..0ff6fe58205f5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/mui-sys/output.md @@ -0,0 +1,3335 @@ +# Items + +Count: 45 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import style from './style'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import style from './style'; + +``` + +- Hoisted +- Declares: `style` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import compose from './compose'; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import compose from './compose'; + +``` + +- Hoisted +- Declares: `compose` + +## Item 5: Stmt 2, `ImportOfModule` + +```js +import { createUnaryUnit, getValue } from './spacing'; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 2, `ImportBinding(0)` + +```js +import { createUnaryUnit, getValue } from './spacing'; + +``` + +- Hoisted +- Declares: `createUnaryUnit` + +## Item 7: Stmt 2, `ImportBinding(1)` + +```js +import { createUnaryUnit, getValue } from './spacing'; + +``` + +- Hoisted +- Declares: `getValue` + +## Item 8: Stmt 3, `ImportOfModule` + +```js +import { handleBreakpoints } from './breakpoints'; + +``` + +- Hoisted +- Side effects + +## Item 9: Stmt 3, `ImportBinding(0)` + +```js +import { handleBreakpoints } from './breakpoints'; + +``` + +- Hoisted +- Declares: `handleBreakpoints` + +## Item 10: Stmt 4, `ImportOfModule` + +```js +import responsivePropType from './responsivePropType'; + +``` + +- Hoisted +- Side effects + +## Item 11: Stmt 4, `ImportBinding(0)` + +```js +import responsivePropType from './responsivePropType'; + +``` + +- Hoisted +- Declares: `responsivePropType` + +## Item 12: Stmt 5, `VarDeclarator(0)` + +```js +export const gap = (props)=>{ + if (props.gap !== undefined && props.gap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'gap'); + const styleFromPropValue = (propValue)=>({ + gap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.gap, styleFromPropValue); + } + return null; +}; + +``` + +- Side effects +- Declares: `gap` +- Reads: `createUnaryUnit`, `getValue`, `handleBreakpoints` +- Write: `gap` + +## Item 13: Stmt 6, `Normal` + +```js +gap.propTypes = process.env.NODE_ENV !== 'production' ? { + gap: responsivePropType +} : {}; + +``` + +- Side effects +- Reads: `gap`, `responsivePropType` +- Write: `gap` + +## Item 14: Stmt 7, `Normal` + +```js +gap.filterProps = [ + 'gap' +]; + +``` + +- Reads: `gap` +- Write: `gap` + +## Item 15: Stmt 8, `VarDeclarator(0)` + +```js +export const columnGap = (props)=>{ + if (props.columnGap !== undefined && props.columnGap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'columnGap'); + const styleFromPropValue = (propValue)=>({ + columnGap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.columnGap, styleFromPropValue); + } + return null; +}; + +``` + +- Side effects +- Declares: `columnGap` +- Reads: `createUnaryUnit`, `getValue`, `handleBreakpoints` +- Write: `columnGap` + +## Item 16: Stmt 9, `Normal` + +```js +columnGap.propTypes = process.env.NODE_ENV !== 'production' ? { + columnGap: responsivePropType +} : {}; + +``` + +- Side effects +- Reads: `columnGap`, `responsivePropType` +- Write: `columnGap` + +## Item 17: Stmt 10, `Normal` + +```js +columnGap.filterProps = [ + 'columnGap' +]; + +``` + +- Reads: `columnGap` +- Write: `columnGap` + +## Item 18: Stmt 11, `VarDeclarator(0)` + +```js +export const rowGap = (props)=>{ + if (props.rowGap !== undefined && props.rowGap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'rowGap'); + const styleFromPropValue = (propValue)=>({ + rowGap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.rowGap, styleFromPropValue); + } + return null; +}; + +``` + +- Side effects +- Declares: `rowGap` +- Reads: `createUnaryUnit`, `getValue`, `handleBreakpoints` +- Write: `rowGap` + +## Item 19: Stmt 12, `Normal` + +```js +rowGap.propTypes = process.env.NODE_ENV !== 'production' ? { + rowGap: responsivePropType +} : {}; + +``` + +- Side effects +- Reads: `rowGap`, `responsivePropType` +- Write: `rowGap` + +## Item 20: Stmt 13, `Normal` + +```js +rowGap.filterProps = [ + 'rowGap' +]; + +``` + +- Reads: `rowGap` +- Write: `rowGap` + +## Item 21: Stmt 14, `VarDeclarator(0)` + +```js +export const gridColumn = style({ + prop: 'gridColumn' +}); + +``` + +- Declares: `gridColumn` +- Reads: `style` +- Write: `gridColumn` + +## Item 22: Stmt 15, `VarDeclarator(0)` + +```js +export const gridRow = style({ + prop: 'gridRow' +}); + +``` + +- Declares: `gridRow` +- Reads: `style` +- Write: `gridRow` + +## Item 23: Stmt 16, `VarDeclarator(0)` + +```js +export const gridAutoFlow = style({ + prop: 'gridAutoFlow' +}); + +``` + +- Declares: `gridAutoFlow` +- Reads: `style` +- Write: `gridAutoFlow` + +## Item 24: Stmt 17, `VarDeclarator(0)` + +```js +export const gridAutoColumns = style({ + prop: 'gridAutoColumns' +}); + +``` + +- Declares: `gridAutoColumns` +- Reads: `style` +- Write: `gridAutoColumns` + +## Item 25: Stmt 18, `VarDeclarator(0)` + +```js +export const gridAutoRows = style({ + prop: 'gridAutoRows' +}); + +``` + +- Declares: `gridAutoRows` +- Reads: `style` +- Write: `gridAutoRows` + +## Item 26: Stmt 19, `VarDeclarator(0)` + +```js +export const gridTemplateColumns = style({ + prop: 'gridTemplateColumns' +}); + +``` + +- Declares: `gridTemplateColumns` +- Reads: `style` +- Write: `gridTemplateColumns` + +## Item 27: Stmt 20, `VarDeclarator(0)` + +```js +export const gridTemplateRows = style({ + prop: 'gridTemplateRows' +}); + +``` + +- Declares: `gridTemplateRows` +- Reads: `style` +- Write: `gridTemplateRows` + +## Item 28: Stmt 21, `VarDeclarator(0)` + +```js +export const gridTemplateAreas = style({ + prop: 'gridTemplateAreas' +}); + +``` + +- Declares: `gridTemplateAreas` +- Reads: `style` +- Write: `gridTemplateAreas` + +## Item 29: Stmt 22, `VarDeclarator(0)` + +```js +export const gridArea = style({ + prop: 'gridArea' +}); + +``` + +- Declares: `gridArea` +- Reads: `style` +- Write: `gridArea` + +## Item 30: Stmt 23, `VarDeclarator(0)` + +```js +const grid = compose(gap, columnGap, rowGap, gridColumn, gridRow, gridAutoFlow, gridAutoColumns, gridAutoRows, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridArea); + +``` + +- Declares: `grid` +- Reads: `compose`, `gap`, `columnGap`, `rowGap`, `gridColumn`, `gridRow`, `gridAutoFlow`, `gridAutoColumns`, `gridAutoRows`, `gridTemplateColumns`, `gridTemplateRows`, `gridTemplateAreas`, `gridArea` +- Write: `grid` + +## Item 31: Stmt 24, `Normal` + +```js +export default grid; + +``` + +- Side effects +- Declares: `__TURBOPACK__default__export__` +- Reads: `grid` +- Write: `__TURBOPACK__default__export__` + +# Phase 1 +```mermaid +graph TD + Item1; + Item6; + Item2; + Item7; + Item3; + Item8; + Item9; + Item4; + Item10; + Item5; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item30; + Item31; + Item32; + Item32["ModuleEvaluation"]; + Item33; + Item33["export gap"]; + Item34; + Item34["export columnGap"]; + Item35; + Item35["export rowGap"]; + Item36; + Item36["export gridColumn"]; + Item37; + Item37["export gridRow"]; + Item38; + Item38["export gridAutoFlow"]; + Item39; + Item39["export gridAutoColumns"]; + Item40; + Item40["export gridAutoRows"]; + Item41; + Item41["export gridTemplateColumns"]; + Item42; + Item42["export gridTemplateRows"]; + Item43; + Item43["export gridTemplateAreas"]; + Item44; + Item44["export gridArea"]; + Item45; + Item45["export default"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item6; + Item2; + Item7; + Item3; + Item8; + Item9; + Item4; + Item10; + Item5; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item30; + Item31; + Item32; + Item32["ModuleEvaluation"]; + Item33; + Item33["export gap"]; + Item34; + Item34["export columnGap"]; + Item35; + Item35["export rowGap"]; + Item36; + Item36["export gridColumn"]; + Item37; + Item37["export gridRow"]; + Item38; + Item38["export gridAutoFlow"]; + Item39; + Item39["export gridAutoColumns"]; + Item40; + Item40["export gridAutoRows"]; + Item41; + Item41["export gridTemplateColumns"]; + Item42; + Item42["export gridTemplateRows"]; + Item43; + Item43["export gridTemplateAreas"]; + Item44; + Item44["export gridArea"]; + Item45; + Item45["export default"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item12 --> Item8; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item4; + Item12 --> Item5; + Item13 --> Item12; + Item13 --> Item11; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item14 --> Item13; + Item14 --> Item12; + Item15 --> Item8; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item4; + Item15 --> Item5; + Item15 --> Item12; + Item15 --> Item13; + Item16 --> Item15; + Item16 --> Item11; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item4; + Item16 --> Item5; + Item16 --> Item12; + Item16 --> Item13; + Item17 --> Item16; + Item17 --> Item15; + Item18 --> Item8; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item4; + Item18 --> Item5; + Item18 --> Item12; + Item18 --> Item13; + Item18 --> Item15; + Item18 --> Item16; + Item19 --> Item18; + Item19 --> Item11; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item4; + Item19 --> Item5; + Item19 --> Item12; + Item19 --> Item13; + Item19 --> Item15; + Item19 --> Item16; + Item20 --> Item19; + Item20 --> Item18; + Item21 --> Item6; + Item22 --> Item6; + Item23 --> Item6; + Item24 --> Item6; + Item25 --> Item6; + Item26 --> Item6; + Item27 --> Item6; + Item28 --> Item6; + Item29 --> Item6; + Item30 --> Item7; + Item30 --> Item14; + Item30 --> Item12; + Item30 --> Item17; + Item30 --> Item15; + Item30 --> Item20; + Item30 --> Item18; + Item30 --> Item21; + Item30 --> Item22; + Item30 --> Item23; + Item30 --> Item24; + Item30 --> Item25; + Item30 --> Item26; + Item30 --> Item27; + Item30 --> Item28; + Item30 --> Item29; + Item31 --> Item30; + Item31 --> Item1; + Item31 --> Item2; + Item31 --> Item3; + Item31 --> Item4; + Item31 --> Item5; + Item31 --> Item12; + Item31 --> Item13; + Item31 --> Item15; + Item31 --> Item16; + Item31 --> Item18; + Item31 --> Item19; + Item33 --> Item14; + Item33 --> Item12; + Item34 --> Item17; + Item34 --> Item15; + Item35 --> Item20; + Item35 --> Item18; + Item36 --> Item21; + Item37 --> Item22; + Item38 --> Item23; + Item39 --> Item24; + Item40 --> Item25; + Item41 --> Item26; + Item42 --> Item27; + Item43 --> Item28; + Item44 --> Item29; + Item45 --> Item31; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item6; + Item2; + Item7; + Item3; + Item8; + Item9; + Item4; + Item10; + Item5; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item30; + Item31; + Item32; + Item32["ModuleEvaluation"]; + Item33; + Item33["export gap"]; + Item34; + Item34["export columnGap"]; + Item35; + Item35["export rowGap"]; + Item36; + Item36["export gridColumn"]; + Item37; + Item37["export gridRow"]; + Item38; + Item38["export gridAutoFlow"]; + Item39; + Item39["export gridAutoColumns"]; + Item40; + Item40["export gridAutoRows"]; + Item41; + Item41["export gridTemplateColumns"]; + Item42; + Item42["export gridTemplateRows"]; + Item43; + Item43["export gridTemplateAreas"]; + Item44; + Item44["export gridArea"]; + Item45; + Item45["export default"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item12 --> Item8; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item4; + Item12 --> Item5; + Item13 --> Item12; + Item13 --> Item11; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item14 --> Item13; + Item14 --> Item12; + Item15 --> Item8; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item4; + Item15 --> Item5; + Item15 --> Item12; + Item15 --> Item13; + Item16 --> Item15; + Item16 --> Item11; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item4; + Item16 --> Item5; + Item16 --> Item12; + Item16 --> Item13; + Item17 --> Item16; + Item17 --> Item15; + Item18 --> Item8; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item4; + Item18 --> Item5; + Item18 --> Item12; + Item18 --> Item13; + Item18 --> Item15; + Item18 --> Item16; + Item19 --> Item18; + Item19 --> Item11; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item4; + Item19 --> Item5; + Item19 --> Item12; + Item19 --> Item13; + Item19 --> Item15; + Item19 --> Item16; + Item20 --> Item19; + Item20 --> Item18; + Item21 --> Item6; + Item22 --> Item6; + Item23 --> Item6; + Item24 --> Item6; + Item25 --> Item6; + Item26 --> Item6; + Item27 --> Item6; + Item28 --> Item6; + Item29 --> Item6; + Item30 --> Item7; + Item30 --> Item14; + Item30 --> Item12; + Item30 --> Item17; + Item30 --> Item15; + Item30 --> Item20; + Item30 --> Item18; + Item30 --> Item21; + Item30 --> Item22; + Item30 --> Item23; + Item30 --> Item24; + Item30 --> Item25; + Item30 --> Item26; + Item30 --> Item27; + Item30 --> Item28; + Item30 --> Item29; + Item31 --> Item30; + Item31 --> Item1; + Item31 --> Item2; + Item31 --> Item3; + Item31 --> Item4; + Item31 --> Item5; + Item31 --> Item12; + Item31 --> Item13; + Item31 --> Item15; + Item31 --> Item16; + Item31 --> Item18; + Item31 --> Item19; + Item33 --> Item14; + Item33 --> Item12; + Item34 --> Item17; + Item34 --> Item15; + Item35 --> Item20; + Item35 --> Item18; + Item36 --> Item21; + Item37 --> Item22; + Item38 --> Item23; + Item39 --> Item24; + Item40 --> Item25; + Item41 --> Item26; + Item42 --> Item27; + Item43 --> Item28; + Item44 --> Item29; + Item45 --> Item31; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item6; + Item2; + Item7; + Item3; + Item8; + Item9; + Item4; + Item10; + Item5; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item26; + Item27; + Item28; + Item29; + Item30; + Item31; + Item32; + Item32["ModuleEvaluation"]; + Item33; + Item33["export gap"]; + Item34; + Item34["export columnGap"]; + Item35; + Item35["export rowGap"]; + Item36; + Item36["export gridColumn"]; + Item37; + Item37["export gridRow"]; + Item38; + Item38["export gridAutoFlow"]; + Item39; + Item39["export gridAutoColumns"]; + Item40; + Item40["export gridAutoRows"]; + Item41; + Item41["export gridTemplateColumns"]; + Item42; + Item42["export gridTemplateRows"]; + Item43; + Item43["export gridTemplateAreas"]; + Item44; + Item44["export gridArea"]; + Item45; + Item45["export default"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item12 --> Item8; + Item12 --> Item9; + Item12 --> Item10; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item4; + Item12 --> Item5; + Item13 --> Item12; + Item13 --> Item11; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item14 --> Item13; + Item14 --> Item12; + Item15 --> Item8; + Item15 --> Item9; + Item15 --> Item10; + Item15 --> Item1; + Item15 --> Item2; + Item15 --> Item3; + Item15 --> Item4; + Item15 --> Item5; + Item15 --> Item12; + Item15 --> Item13; + Item16 --> Item15; + Item16 --> Item11; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item4; + Item16 --> Item5; + Item16 --> Item12; + Item16 --> Item13; + Item17 --> Item16; + Item17 --> Item15; + Item18 --> Item8; + Item18 --> Item9; + Item18 --> Item10; + Item18 --> Item1; + Item18 --> Item2; + Item18 --> Item3; + Item18 --> Item4; + Item18 --> Item5; + Item18 --> Item12; + Item18 --> Item13; + Item18 --> Item15; + Item18 --> Item16; + Item19 --> Item18; + Item19 --> Item11; + Item19 --> Item1; + Item19 --> Item2; + Item19 --> Item3; + Item19 --> Item4; + Item19 --> Item5; + Item19 --> Item12; + Item19 --> Item13; + Item19 --> Item15; + Item19 --> Item16; + Item20 --> Item19; + Item20 --> Item18; + Item21 --> Item6; + Item22 --> Item6; + Item23 --> Item6; + Item24 --> Item6; + Item25 --> Item6; + Item26 --> Item6; + Item27 --> Item6; + Item28 --> Item6; + Item29 --> Item6; + Item30 --> Item7; + Item30 --> Item14; + Item30 --> Item12; + Item30 --> Item17; + Item30 --> Item15; + Item30 --> Item20; + Item30 --> Item18; + Item30 --> Item21; + Item30 --> Item22; + Item30 --> Item23; + Item30 --> Item24; + Item30 --> Item25; + Item30 --> Item26; + Item30 --> Item27; + Item30 --> Item28; + Item30 --> Item29; + Item31 --> Item30; + Item31 --> Item1; + Item31 --> Item2; + Item31 --> Item3; + Item31 --> Item4; + Item31 --> Item5; + Item31 --> Item12; + Item31 --> Item13; + Item31 --> Item15; + Item31 --> Item16; + Item31 --> Item18; + Item31 --> Item19; + Item33 --> Item14; + Item33 --> Item12; + Item34 --> Item17; + Item34 --> Item15; + Item35 --> Item20; + Item35 --> Item18; + Item36 --> Item21; + Item37 --> Item22; + Item38 --> Item23; + Item39 --> Item24; + Item40 --> Item25; + Item41 --> Item26; + Item42 --> Item27; + Item43 --> Item28; + Item44 --> Item29; + Item45 --> Item31; + Item32 --> Item1; + Item32 --> Item2; + Item32 --> Item3; + Item32 --> Item4; + Item32 --> Item5; + Item32 --> Item12; + Item32 --> Item13; + Item32 --> Item15; + Item32 --> Item16; + Item32 --> Item18; + Item32 --> Item19; + Item32 --> Item31; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, ImportBinding(0))]"]; + N1["Items: [ItemId(0, ImportBinding(0))]"]; + N2["Items: [ItemId(22, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("gridArea", #2), "gridArea"))]"]; + N4["Items: [ItemId(21, VarDeclarator(0))]"]; + N5["Items: [ItemId(Export(("gridTemplateAreas", #2), "gridTemplateAreas"))]"]; + N6["Items: [ItemId(20, VarDeclarator(0))]"]; + N7["Items: [ItemId(Export(("gridTemplateRows", #2), "gridTemplateRows"))]"]; + N8["Items: [ItemId(19, VarDeclarator(0))]"]; + N9["Items: [ItemId(Export(("gridTemplateColumns", #2), "gridTemplateColumns"))]"]; + N10["Items: [ItemId(18, VarDeclarator(0))]"]; + N11["Items: [ItemId(Export(("gridAutoRows", #2), "gridAutoRows"))]"]; + N12["Items: [ItemId(17, VarDeclarator(0))]"]; + N13["Items: [ItemId(Export(("gridAutoColumns", #2), "gridAutoColumns"))]"]; + N14["Items: [ItemId(16, VarDeclarator(0))]"]; + N15["Items: [ItemId(Export(("gridAutoFlow", #2), "gridAutoFlow"))]"]; + N16["Items: [ItemId(15, VarDeclarator(0))]"]; + N17["Items: [ItemId(Export(("gridRow", #2), "gridRow"))]"]; + N18["Items: [ItemId(14, VarDeclarator(0))]"]; + N19["Items: [ItemId(Export(("gridColumn", #2), "gridColumn"))]"]; + N20["Items: [ItemId(4, ImportBinding(0))]"]; + N21["Items: [ItemId(3, ImportBinding(0))]"]; + N22["Items: [ItemId(2, ImportBinding(1))]"]; + N23["Items: [ItemId(2, ImportBinding(0))]"]; + N24["Items: [ItemId(0, ImportOfModule)]"]; + N25["Items: [ItemId(1, ImportOfModule)]"]; + N26["Items: [ItemId(2, ImportOfModule)]"]; + N27["Items: [ItemId(3, ImportOfModule)]"]; + N28["Items: [ItemId(4, ImportOfModule)]"]; + N29["Items: [ItemId(5, VarDeclarator(0))]"]; + N30["Items: [ItemId(6, Normal)]"]; + N31["Items: [ItemId(8, VarDeclarator(0))]"]; + N32["Items: [ItemId(9, Normal)]"]; + N33["Items: [ItemId(11, VarDeclarator(0))]"]; + N34["Items: [ItemId(12, Normal)]"]; + N35["Items: [ItemId(13, Normal)]"]; + N36["Items: [ItemId(Export(("rowGap", #2), "rowGap"))]"]; + N37["Items: [ItemId(10, Normal)]"]; + N38["Items: [ItemId(Export(("columnGap", #2), "columnGap"))]"]; + N39["Items: [ItemId(7, Normal)]"]; + N40["Items: [ItemId(Export(("gap", #2), "gap"))]"]; + N41["Items: [ItemId(23, VarDeclarator(0))]"]; + N42["Items: [ItemId(24, Normal)]"]; + N43["Items: [ItemId(ModuleEvaluation)]"]; + N44["Items: [ItemId(Export(("__TURBOPACK__default__export__", #12), "default"))]"]; + N25 --> N24; + N26 --> N24; + N26 --> N25; + N27 --> N24; + N27 --> N25; + N27 --> N26; + N28 --> N24; + N28 --> N25; + N28 --> N26; + N28 --> N27; + N29 --> N23; + N29 --> N22; + N29 --> N21; + N29 --> N24; + N29 --> N25; + N29 --> N26; + N29 --> N27; + N29 --> N28; + N30 --> N29; + N30 --> N20; + N30 --> N24; + N30 --> N25; + N30 --> N26; + N30 --> N27; + N30 --> N28; + N39 --> N30; + N39 --> N29; + N31 --> N23; + N31 --> N22; + N31 --> N21; + N31 --> N24; + N31 --> N25; + N31 --> N26; + N31 --> N27; + N31 --> N28; + N31 --> N29; + N31 --> N30; + N32 --> N31; + N32 --> N20; + N32 --> N24; + N32 --> N25; + N32 --> N26; + N32 --> N27; + N32 --> N28; + N32 --> N29; + N32 --> N30; + N37 --> N32; + N37 --> N31; + N33 --> N23; + N33 --> N22; + N33 --> N21; + N33 --> N24; + N33 --> N25; + N33 --> N26; + N33 --> N27; + N33 --> N28; + N33 --> N29; + N33 --> N30; + N33 --> N31; + N33 --> N32; + N34 --> N33; + N34 --> N20; + N34 --> N24; + N34 --> N25; + N34 --> N26; + N34 --> N27; + N34 --> N28; + N34 --> N29; + N34 --> N30; + N34 --> N31; + N34 --> N32; + N35 --> N34; + N35 --> N33; + N18 --> N1; + N16 --> N1; + N14 --> N1; + N12 --> N1; + N10 --> N1; + N8 --> N1; + N6 --> N1; + N4 --> N1; + N2 --> N1; + N41 --> N0; + N41 --> N39; + N41 --> N29; + N41 --> N37; + N41 --> N31; + N41 --> N35; + N41 --> N33; + N41 --> N18; + N41 --> N16; + N41 --> N14; + N41 --> N12; + N41 --> N10; + N41 --> N8; + N41 --> N6; + N41 --> N4; + N41 --> N2; + N42 --> N41; + N42 --> N24; + N42 --> N25; + N42 --> N26; + N42 --> N27; + N42 --> N28; + N42 --> N29; + N42 --> N30; + N42 --> N31; + N42 --> N32; + N42 --> N33; + N42 --> N34; + N40 --> N39; + N40 --> N29; + N38 --> N37; + N38 --> N31; + N36 --> N35; + N36 --> N33; + N19 --> N18; + N17 --> N16; + N15 --> N14; + N13 --> N12; + N11 --> N10; + N9 --> N8; + N7 --> N6; + N5 --> N4; + N3 --> N2; + N44 --> N42; + N43 --> N24; + N43 --> N25; + N43 --> N26; + N43 --> N27; + N43 --> N28; + N43 --> N29; + N43 --> N30; + N43 --> N31; + N43 --> N32; + N43 --> N33; + N43 --> N34; + N43 --> N42; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 43, + Export( + "gap", + ): 40, + Export( + "gridTemplateColumns", + ): 9, + Export( + "gridAutoRows", + ): 11, + Export( + "columnGap", + ): 38, + Export( + "gridArea", + ): 3, + Exports: 45, + Export( + "gridAutoFlow", + ): 15, + Export( + "gridColumn", + ): 19, + Export( + "gridAutoColumns", + ): 13, + Export( + "rowGap", + ): 36, + Export( + "gridTemplateRows", + ): 7, + Export( + "gridTemplateAreas", + ): 5, + Export( + "default", + ): 44, + Export( + "gridRow", + ): 17, +} +``` + + +# Modules (dev) +## Part 0 +```js +import compose from './compose'; +export { compose } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import style from './style'; +export { style } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridArea = style({ + prop: 'gridArea' +}); +export { gridArea } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { gridArea } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { gridArea }; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridTemplateAreas = style({ + prop: 'gridTemplateAreas' +}); +export { gridTemplateAreas } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { gridTemplateAreas } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { gridTemplateAreas }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridTemplateRows = style({ + prop: 'gridTemplateRows' +}); +export { gridTemplateRows } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { gridTemplateRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { gridTemplateRows }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridTemplateColumns = style({ + prop: 'gridTemplateColumns' +}); +export { gridTemplateColumns } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { gridTemplateColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { gridTemplateColumns }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridAutoRows = style({ + prop: 'gridAutoRows' +}); +export { gridAutoRows } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { gridAutoRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { gridAutoRows }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridAutoColumns = style({ + prop: 'gridAutoColumns' +}); +export { gridAutoColumns } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { gridAutoColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { gridAutoColumns }; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridAutoFlow = style({ + prop: 'gridAutoFlow' +}); +export { gridAutoFlow } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { gridAutoFlow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +export { gridAutoFlow }; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridRow = style({ + prop: 'gridRow' +}); +export { gridRow } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { gridRow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { gridRow }; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridColumn = style({ + prop: 'gridColumn' +}); +export { gridColumn } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { gridColumn } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +export { gridColumn }; + +``` +## Part 20 +```js +import responsivePropType from './responsivePropType'; +export { responsivePropType } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 21 +```js +import { handleBreakpoints } from './breakpoints'; +export { handleBreakpoints } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 22 +```js +import { getValue } from './spacing'; +export { getValue } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 23 +```js +import { createUnaryUnit } from './spacing'; +export { createUnaryUnit } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 24 +```js +import './style'; + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import './compose'; + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import './spacing'; + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import './breakpoints'; + +``` +## Part 28 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import './responsivePropType'; + +``` +## Part 29 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import { createUnaryUnit } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import { getValue } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { handleBreakpoints } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +const gap = (props)=>{ + if (props.gap !== undefined && props.gap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'gap'); + const styleFromPropValue = (propValue)=>({ + gap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.gap, styleFromPropValue); + } + return null; +}; +export { gap } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 30 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import { responsivePropType } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +gap.propTypes = process.env.NODE_ENV !== 'production' ? { + gap: responsivePropType +} : {}; + +``` +## Part 31 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import { createUnaryUnit } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import { getValue } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { handleBreakpoints } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +const columnGap = (props)=>{ + if (props.columnGap !== undefined && props.columnGap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'columnGap'); + const styleFromPropValue = (propValue)=>({ + columnGap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.columnGap, styleFromPropValue); + } + return null; +}; +export { columnGap } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 32 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { responsivePropType } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +columnGap.propTypes = process.env.NODE_ENV !== 'production' ? { + columnGap: responsivePropType +} : {}; + +``` +## Part 33 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import { createUnaryUnit } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import { getValue } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { handleBreakpoints } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +const rowGap = (props)=>{ + if (props.rowGap !== undefined && props.rowGap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'rowGap'); + const styleFromPropValue = (propValue)=>({ + rowGap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.rowGap, styleFromPropValue); + } + return null; +}; +export { rowGap } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 34 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { responsivePropType } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +rowGap.propTypes = process.env.NODE_ENV !== 'production' ? { + rowGap: responsivePropType +} : {}; + +``` +## Part 35 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +rowGap.filterProps = [ + 'rowGap' +]; + +``` +## Part 36 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 35 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +export { rowGap }; + +``` +## Part 37 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +columnGap.filterProps = [ + 'columnGap' +]; + +``` +## Part 38 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 37 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +export { columnGap }; + +``` +## Part 39 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +gap.filterProps = [ + 'gap' +]; + +``` +## Part 40 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 39 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +export { gap }; + +``` +## Part 41 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 39 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 37 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 35 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { compose } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { gridColumn } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { gridRow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { gridAutoFlow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { gridAutoColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { gridAutoRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { gridTemplateColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { gridTemplateRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { gridTemplateAreas } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { gridArea } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +const grid = compose(gap, columnGap, rowGap, gridColumn, gridRow, gridAutoFlow, gridAutoColumns, gridAutoRows, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridArea); +export { grid } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 42 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 41 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import { grid } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 41 +}; +const __TURBOPACK__default__export__ = grid; +export { __TURBOPACK__default__export__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 43 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 42 +}; +"module evaluation"; + +``` +## Part 44 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 42 +}; +import { __TURBOPACK__default__export__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 42 +}; +export { __TURBOPACK__default__export__ as default }; + +``` +## Part 45 +```js +export { gridArea } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridArea" +}; +export { gridTemplateAreas } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridTemplateAreas" +}; +export { gridTemplateRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridTemplateRows" +}; +export { gridTemplateColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridTemplateColumns" +}; +export { gridAutoRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridAutoRows" +}; +export { gridAutoColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridAutoColumns" +}; +export { gridAutoFlow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridAutoFlow" +}; +export { gridRow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridRow" +}; +export { gridColumn } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridColumn" +}; +export { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export rowGap" +}; +export { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export columnGap" +}; +export { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gap" +}; +export { default } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export default" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 42 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 43, + Export( + "gap", + ): 40, + Export( + "gridTemplateColumns", + ): 9, + Export( + "gridAutoRows", + ): 11, + Export( + "columnGap", + ): 38, + Export( + "gridArea", + ): 3, + Exports: 45, + Export( + "gridAutoFlow", + ): 15, + Export( + "gridColumn", + ): 19, + Export( + "gridAutoColumns", + ): 13, + Export( + "rowGap", + ): 36, + Export( + "gridTemplateRows", + ): 7, + Export( + "gridTemplateAreas", + ): 5, + Export( + "default", + ): 44, + Export( + "gridRow", + ): 17, +} +``` + + +# Modules (prod) +## Part 0 +```js +import compose from './compose'; +export { compose } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import style from './style'; +export { style } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridArea = style({ + prop: 'gridArea' +}); +export { gridArea } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { gridArea } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { gridArea }; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridTemplateAreas = style({ + prop: 'gridTemplateAreas' +}); +export { gridTemplateAreas } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { gridTemplateAreas } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { gridTemplateAreas }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridTemplateRows = style({ + prop: 'gridTemplateRows' +}); +export { gridTemplateRows } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { gridTemplateRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { gridTemplateRows }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridTemplateColumns = style({ + prop: 'gridTemplateColumns' +}); +export { gridTemplateColumns } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { gridTemplateColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { gridTemplateColumns }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridAutoRows = style({ + prop: 'gridAutoRows' +}); +export { gridAutoRows } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { gridAutoRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { gridAutoRows }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridAutoColumns = style({ + prop: 'gridAutoColumns' +}); +export { gridAutoColumns } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { gridAutoColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { gridAutoColumns }; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridAutoFlow = style({ + prop: 'gridAutoFlow' +}); +export { gridAutoFlow } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { gridAutoFlow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +export { gridAutoFlow }; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridRow = style({ + prop: 'gridRow' +}); +export { gridRow } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { gridRow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { gridRow }; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { style } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const gridColumn = style({ + prop: 'gridColumn' +}); +export { gridColumn } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { gridColumn } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +export { gridColumn }; + +``` +## Part 20 +```js +import responsivePropType from './responsivePropType'; +export { responsivePropType } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 21 +```js +import { handleBreakpoints } from './breakpoints'; +export { handleBreakpoints } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 22 +```js +import { getValue } from './spacing'; +export { getValue } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 23 +```js +import { createUnaryUnit } from './spacing'; +export { createUnaryUnit } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 24 +```js +import './style'; + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import './compose'; + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import './spacing'; + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import './breakpoints'; + +``` +## Part 28 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import './responsivePropType'; + +``` +## Part 29 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import { createUnaryUnit } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import { getValue } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { handleBreakpoints } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +const gap = (props)=>{ + if (props.gap !== undefined && props.gap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'gap'); + const styleFromPropValue = (propValue)=>({ + gap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.gap, styleFromPropValue); + } + return null; +}; +export { gap } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 30 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import { responsivePropType } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +gap.propTypes = process.env.NODE_ENV !== 'production' ? { + gap: responsivePropType +} : {}; + +``` +## Part 31 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import { createUnaryUnit } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import { getValue } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { handleBreakpoints } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +const columnGap = (props)=>{ + if (props.columnGap !== undefined && props.columnGap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'columnGap'); + const styleFromPropValue = (propValue)=>({ + columnGap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.columnGap, styleFromPropValue); + } + return null; +}; +export { columnGap } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 32 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { responsivePropType } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +columnGap.propTypes = process.env.NODE_ENV !== 'production' ? { + columnGap: responsivePropType +} : {}; + +``` +## Part 33 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import { createUnaryUnit } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 23 +}; +import { getValue } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { handleBreakpoints } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +const rowGap = (props)=>{ + if (props.rowGap !== undefined && props.rowGap !== null) { + const transformer = createUnaryUnit(props.theme, 'spacing', 8, 'rowGap'); + const styleFromPropValue = (propValue)=>({ + rowGap: getValue(transformer, propValue) + }); + return handleBreakpoints(props, props.rowGap, styleFromPropValue); + } + return null; +}; +export { rowGap } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 34 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { responsivePropType } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +rowGap.propTypes = process.env.NODE_ENV !== 'production' ? { + rowGap: responsivePropType +} : {}; + +``` +## Part 35 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +rowGap.filterProps = [ + 'rowGap' +]; + +``` +## Part 36 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 35 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +export { rowGap }; + +``` +## Part 37 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +columnGap.filterProps = [ + 'columnGap' +]; + +``` +## Part 38 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 37 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +export { columnGap }; + +``` +## Part 39 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +gap.filterProps = [ + 'gap' +]; + +``` +## Part 40 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 39 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +export { gap }; + +``` +## Part 41 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 39 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 37 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 35 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { compose } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { gridColumn } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { gridRow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { gridAutoFlow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { gridAutoColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { gridAutoRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { gridTemplateColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { gridTemplateRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { gridTemplateAreas } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { gridArea } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +const grid = compose(gap, columnGap, rowGap, gridColumn, gridRow, gridAutoFlow, gridAutoColumns, gridAutoRows, gridTemplateColumns, gridTemplateRows, gridTemplateAreas, gridArea); +export { grid } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 42 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 41 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import { grid } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 41 +}; +const __TURBOPACK__default__export__ = grid; +export { __TURBOPACK__default__export__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 43 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 42 +}; +"module evaluation"; + +``` +## Part 44 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 42 +}; +import { __TURBOPACK__default__export__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 42 +}; +export { __TURBOPACK__default__export__ as default }; + +``` +## Part 45 +```js +export { gridArea } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridArea" +}; +export { gridTemplateAreas } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridTemplateAreas" +}; +export { gridTemplateRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridTemplateRows" +}; +export { gridTemplateColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridTemplateColumns" +}; +export { gridAutoRows } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridAutoRows" +}; +export { gridAutoColumns } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridAutoColumns" +}; +export { gridAutoFlow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridAutoFlow" +}; +export { gridRow } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridRow" +}; +export { gridColumn } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gridColumn" +}; +export { rowGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export rowGap" +}; +export { columnGap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export columnGap" +}; +export { gap } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export gap" +}; +export { default } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export default" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 25 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 42 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/multi-export/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/multi-export/input.js new file mode 100644 index 0000000000000..a4afccb3336c0 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/multi-export/input.js @@ -0,0 +1,4 @@ +const dog = "dog"; +const cat = "cat"; + +export { dog as DOG, cat }; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/multi-export/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/multi-export/output.md new file mode 100644 index 0000000000000..9425768ace9ba --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/multi-export/output.md @@ -0,0 +1,239 @@ +# Items + +Count: 5 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +const dog = "dog"; + +``` + +- Declares: `dog` +- Write: `dog` + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +const cat = "cat"; + +``` + +- Declares: `cat` +- Write: `cat` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export DOG"]; + Item5; + Item5["export cat"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export DOG"]; + Item5; + Item5["export cat"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export DOG"]; + Item5; + Item5["export cat"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export DOG"]; + Item5; + Item5["export cat"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, VarDeclarator(0))]"]; + N1["Items: [ItemId(Export(("cat", #2), "cat"))]"]; + N2["Items: [ItemId(0, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("dog", #2), "DOG"))]"]; + N4["Items: [ItemId(ModuleEvaluation)]"]; + N3 --> N2; + N1 --> N0; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 4, + Exports: 5, + Export( + "cat", + ): 1, + Export( + "DOG", + ): 3, +} +``` + + +# Modules (dev) +## Part 0 +```js +const cat = "cat"; +export { cat } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { cat as cat }; + +``` +## Part 2 +```js +const dog = "dog"; +export { dog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { dog as DOG }; + +``` +## Part 4 +```js +"module evaluation"; + +``` +## Part 5 +```js +export { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export cat" +}; +export { DOG } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export DOG" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 4, + Exports: 5, + Export( + "cat", + ): 1, + Export( + "DOG", + ): 3, +} +``` + + +# Modules (prod) +## Part 0 +```js +const cat = "cat"; +export { cat } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { cat as cat }; + +``` +## Part 2 +```js +const dog = "dog"; +export { dog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { dog as DOG }; + +``` +## Part 4 +```js +"module evaluation"; + +``` +## Part 5 +```js +export { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export cat" +}; +export { DOG } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export DOG" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nanoid/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nanoid/input.js new file mode 100644 index 0000000000000..bf12a2b2e4066 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nanoid/input.js @@ -0,0 +1,44 @@ +import crypto from 'crypto' +import { urlAlphabet } from './url-alphabet/index.js' +const POOL_SIZE_MULTIPLIER = 128 +let pool, poolOffset +let fillPool = bytes => { + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER) + crypto.randomFillSync(pool) + poolOffset = 0 + } else if (poolOffset + bytes > pool.length) { + crypto.randomFillSync(pool) + poolOffset = 0 + } + poolOffset += bytes +} +let random = bytes => { + fillPool((bytes -= 0)) + return pool.subarray(poolOffset - bytes, poolOffset) +} +let customRandom = (alphabet, size, getRandom) => { + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1 + let step = Math.ceil((1.6 * mask * size) / alphabet.length) + return () => { + let id = '' + while (true) { + let bytes = getRandom(step) + let i = step + while (i--) { + id += alphabet[bytes[i] & mask] || '' + if (id.length === size) return id + } + } + } +} +let customAlphabet = (alphabet, size) => customRandom(alphabet, size, random) +let nanoid = (size = 21) => { + fillPool((size -= 0)) + let id = '' + for (let i = poolOffset - size; i < poolOffset; i++) { + id += urlAlphabet[pool[i] & 63] + } + return id +} +export { nanoid, customAlphabet, customRandom, urlAlphabet, random } diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nanoid/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nanoid/output.md new file mode 100644 index 0000000000000..1e473a195069b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nanoid/output.md @@ -0,0 +1,1131 @@ +# Items + +Count: 18 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import crypto from 'crypto'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import crypto from 'crypto'; + +``` + +- Hoisted +- Declares: `crypto` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import { urlAlphabet } from './url-alphabet/index.js'; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import { urlAlphabet } from './url-alphabet/index.js'; + +``` + +- Hoisted +- Declares: `urlAlphabet` + +## Item 5: Stmt 2, `VarDeclarator(0)` + +```js +const POOL_SIZE_MULTIPLIER = 128; + +``` + +- Declares: `POOL_SIZE_MULTIPLIER` +- Write: `POOL_SIZE_MULTIPLIER` + +## Item 6: Stmt 3, `VarDeclarator(0)` + +```js +let pool, poolOffset; + +``` + +- Declares: `pool` +- Write: `pool` + +## Item 7: Stmt 3, `VarDeclarator(1)` + +```js +let pool, poolOffset; + +``` + +- Declares: `poolOffset` +- Write: `poolOffset` + +## Item 8: Stmt 4, `VarDeclarator(0)` + +```js +let fillPool = (bytes)=>{ + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER); + crypto.randomFillSync(pool); + poolOffset = 0; + } else if (poolOffset + bytes > pool.length) { + crypto.randomFillSync(pool); + poolOffset = 0; + } + poolOffset += bytes; +}; + +``` + +- Side effects +- Declares: `fillPool` +- Reads: `pool`, `POOL_SIZE_MULTIPLIER`, `crypto`, `poolOffset` +- Write: `pool`, `crypto`, `poolOffset`, `fillPool` + +## Item 9: Stmt 5, `VarDeclarator(0)` + +```js +let random = (bytes)=>{ + fillPool((bytes -= 0)); + return pool.subarray(poolOffset - bytes, poolOffset); +}; + +``` + +- Declares: `random` +- Reads: `fillPool`, `pool`, `poolOffset` +- Write: `pool`, `random` + +## Item 10: Stmt 6, `VarDeclarator(0)` + +```js +let customRandom = (alphabet, size, getRandom)=>{ + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1; + let step = Math.ceil((1.6 * mask * size) / alphabet.length); + return ()=>{ + let id = ''; + while(true){ + let bytes = getRandom(step); + let i = step; + while(i--){ + id += alphabet[bytes[i] & mask] || ''; + if (id.length === size) return id; + } + } + }; +}; + +``` + +- Side effects +- Declares: `customRandom` +- Write: `customRandom` + +## Item 11: Stmt 7, `VarDeclarator(0)` + +```js +let customAlphabet = (alphabet, size)=>customRandom(alphabet, size, random); + +``` + +- Declares: `customAlphabet` +- Reads: `customRandom`, `random` +- Write: `customAlphabet` + +## Item 12: Stmt 8, `VarDeclarator(0)` + +```js +let nanoid = (size = 21)=>{ + fillPool((size -= 0)); + let id = ''; + for(let i = poolOffset - size; i < poolOffset; i++){ + id += urlAlphabet[pool[i] & 63]; + } + return id; +}; + +``` + +- Declares: `nanoid` +- Reads: `fillPool`, `poolOffset`, `urlAlphabet`, `pool` +- Write: `urlAlphabet`, `pool`, `nanoid` + +# Phase 1 +```mermaid +graph TD + Item1; + Item3; + Item2; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export nanoid"]; + Item15; + Item15["export customAlphabet"]; + Item16; + Item16["export customRandom"]; + Item17; + Item17["export urlAlphabet"]; + Item18; + Item18["export random"]; + Item2 --> Item1; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item3; + Item2; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export nanoid"]; + Item15; + Item15["export customAlphabet"]; + Item16; + Item16["export customRandom"]; + Item17; + Item17["export urlAlphabet"]; + Item18; + Item18["export random"]; + Item2 --> Item1; + Item8 --> Item6; + Item8 --> Item5; + Item8 --> Item3; + Item8 --> Item7; + Item8 --> Item1; + Item8 --> Item2; + Item9 --> Item8; + Item9 --> Item6; + Item9 --> Item7; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item8; + Item11 --> Item10; + Item11 --> Item9; + Item12 --> Item8; + Item12 --> Item7; + Item12 --> Item4; + Item12 --> Item9; + Item12 --> Item6; + Item14 --> Item12; + Item15 --> Item11; + Item16 --> Item10; + Item17 --> Item12; + Item17 --> Item4; + Item18 --> Item9; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item3; + Item2; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export nanoid"]; + Item15; + Item15["export customAlphabet"]; + Item16; + Item16["export customRandom"]; + Item17; + Item17["export urlAlphabet"]; + Item18; + Item18["export random"]; + Item2 --> Item1; + Item8 --> Item6; + Item8 --> Item5; + Item8 --> Item3; + Item8 --> Item7; + Item8 --> Item1; + Item8 --> Item2; + Item9 --> Item8; + Item9 --> Item6; + Item9 --> Item7; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item8; + Item11 --> Item10; + Item11 --> Item9; + Item12 --> Item8; + Item12 --> Item7; + Item12 --> Item4; + Item12 --> Item9; + Item12 --> Item6; + Item14 --> Item12; + Item15 --> Item11; + Item16 --> Item10; + Item17 --> Item12; + Item17 --> Item4; + Item18 --> Item9; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item3; + Item2; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item13["ModuleEvaluation"]; + Item14; + Item14["export nanoid"]; + Item15; + Item15["export customAlphabet"]; + Item16; + Item16["export customRandom"]; + Item17; + Item17["export urlAlphabet"]; + Item18; + Item18["export random"]; + Item2 --> Item1; + Item8 --> Item6; + Item8 --> Item5; + Item8 --> Item3; + Item8 --> Item7; + Item8 --> Item1; + Item8 --> Item2; + Item9 --> Item8; + Item9 --> Item6; + Item9 --> Item7; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item8; + Item11 --> Item10; + Item11 --> Item9; + Item12 --> Item8; + Item12 --> Item7; + Item12 --> Item4; + Item12 --> Item9; + Item12 --> Item6; + Item14 --> Item12; + Item15 --> Item11; + Item16 --> Item10; + Item17 --> Item12; + Item17 --> Item4; + Item18 --> Item9; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item8; + Item13 --> Item10; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, ImportBinding(0))]"]; + N1["Items: [ItemId(3, VarDeclarator(1))]"]; + N2["Items: [ItemId(0, ImportBinding(0))]"]; + N3["Items: [ItemId(2, VarDeclarator(0))]"]; + N4["Items: [ItemId(3, VarDeclarator(0))]"]; + N5["Items: [ItemId(0, ImportOfModule)]"]; + N6["Items: [ItemId(1, ImportOfModule)]"]; + N7["Items: [ItemId(4, VarDeclarator(0))]"]; + N8["Items: [ItemId(6, VarDeclarator(0))]"]; + N9["Items: [ItemId(ModuleEvaluation)]"]; + N10["Items: [ItemId(Export(("customRandom", #2), "customRandom"))]"]; + N11["Items: [ItemId(5, VarDeclarator(0))]"]; + N12["Items: [ItemId(Export(("random", #2), "random"))]"]; + N13["Items: [ItemId(8, VarDeclarator(0))]"]; + N14["Items: [ItemId(Export(("urlAlphabet", #2), "urlAlphabet"))]"]; + N15["Items: [ItemId(Export(("nanoid", #2), "nanoid"))]"]; + N16["Items: [ItemId(7, VarDeclarator(0))]"]; + N17["Items: [ItemId(Export(("customAlphabet", #2), "customAlphabet"))]"]; + N6 --> N5; + N7 --> N4; + N7 --> N3; + N7 --> N2; + N7 --> N1; + N7 --> N5; + N7 --> N6; + N11 --> N7; + N11 --> N4; + N11 --> N1; + N8 --> N5; + N8 --> N6; + N8 --> N7; + N16 --> N8; + N16 --> N11; + N13 --> N7; + N13 --> N1; + N13 --> N0; + N13 --> N11; + N13 --> N4; + N15 --> N13; + N17 --> N16; + N10 --> N8; + N14 --> N13; + N14 --> N0; + N12 --> N11; + N9 --> N5; + N9 --> N6; + N9 --> N7; + N9 --> N8; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 9, + Exports: 18, + Export( + "customRandom", + ): 10, + Export( + "urlAlphabet", + ): 14, + Export( + "random", + ): 12, + Export( + "customAlphabet", + ): 17, + Export( + "nanoid", + ): 15, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { urlAlphabet } from './url-alphabet/index.js'; +export { urlAlphabet } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +let poolOffset; +export { poolOffset } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import crypto from 'crypto'; +export { crypto } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +const POOL_SIZE_MULTIPLIER = 128; +export { POOL_SIZE_MULTIPLIER } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +let pool; +export { pool } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import 'crypto'; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import './url-alphabet/index.js'; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { pool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { POOL_SIZE_MULTIPLIER } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { crypto } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { poolOffset } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +let fillPool = (bytes)=>{ + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER); + crypto.randomFillSync(pool); + poolOffset = 0; + } else if (poolOffset + bytes > pool.length) { + crypto.randomFillSync(pool); + poolOffset = 0; + } + poolOffset += bytes; +}; +export { fillPool } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +let customRandom = (alphabet, size, getRandom)=>{ + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1; + let step = Math.ceil((1.6 * mask * size) / alphabet.length); + return ()=>{ + let id = ''; + while(true){ + let bytes = getRandom(step); + let i = step; + while(i--){ + id += alphabet[bytes[i] & mask] || ''; + if (id.length === size) return id; + } + } + }; +}; +export { customRandom } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { customRandom } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { customRandom as customRandom }; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { fillPool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { pool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { poolOffset } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +let random = (bytes)=>{ + fillPool((bytes -= 0)); + return pool.subarray(poolOffset - bytes, poolOffset); +}; +export { random } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +export { random as random }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { fillPool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { poolOffset } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { urlAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { pool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +let nanoid = (size = 21)=>{ + fillPool((size -= 0)); + let id = ''; + for(let i = poolOffset - size; i < poolOffset; i++){ + id += urlAlphabet[pool[i] & 63]; + } + return id; +}; +export { nanoid } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { urlAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { urlAlphabet as urlAlphabet }; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { nanoid } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { nanoid as nanoid }; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { customRandom } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +let customAlphabet = (alphabet, size)=>customRandom(alphabet, size, random); +export { customAlphabet } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { customAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { customAlphabet as customAlphabet }; + +``` +## Part 18 +```js +export { customRandom } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export customRandom" +}; +export { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export random" +}; +export { urlAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export urlAlphabet" +}; +export { nanoid } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export nanoid" +}; +export { customAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export customAlphabet" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 9, + Exports: 18, + Export( + "customRandom", + ): 10, + Export( + "urlAlphabet", + ): 14, + Export( + "random", + ): 12, + Export( + "customAlphabet", + ): 17, + Export( + "nanoid", + ): 15, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { urlAlphabet } from './url-alphabet/index.js'; +export { urlAlphabet } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +let poolOffset; +export { poolOffset } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import crypto from 'crypto'; +export { crypto } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +const POOL_SIZE_MULTIPLIER = 128; +export { POOL_SIZE_MULTIPLIER } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +let pool; +export { pool } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import 'crypto'; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import './url-alphabet/index.js'; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { pool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { POOL_SIZE_MULTIPLIER } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { crypto } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { poolOffset } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +let fillPool = (bytes)=>{ + if (!pool || pool.length < bytes) { + pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER); + crypto.randomFillSync(pool); + poolOffset = 0; + } else if (poolOffset + bytes > pool.length) { + crypto.randomFillSync(pool); + poolOffset = 0; + } + poolOffset += bytes; +}; +export { fillPool } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +let customRandom = (alphabet, size, getRandom)=>{ + let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1; + let step = Math.ceil((1.6 * mask * size) / alphabet.length); + return ()=>{ + let id = ''; + while(true){ + let bytes = getRandom(step); + let i = step; + while(i--){ + id += alphabet[bytes[i] & mask] || ''; + if (id.length === size) return id; + } + } + }; +}; +export { customRandom } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { customRandom } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { customRandom as customRandom }; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { fillPool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { pool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { poolOffset } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +let random = (bytes)=>{ + fillPool((bytes -= 0)); + return pool.subarray(poolOffset - bytes, poolOffset); +}; +export { random } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +export { random as random }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { fillPool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { poolOffset } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { urlAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { pool } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +let nanoid = (size = 21)=>{ + fillPool((size -= 0)); + let id = ''; + for(let i = poolOffset - size; i < poolOffset; i++){ + id += urlAlphabet[pool[i] & 63]; + } + return id; +}; +export { nanoid } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { urlAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { urlAlphabet as urlAlphabet }; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { nanoid } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { nanoid as nanoid }; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { customRandom } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +let customAlphabet = (alphabet, size)=>customRandom(alphabet, size, random); +export { customAlphabet } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { customAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { customAlphabet as customAlphabet }; + +``` +## Part 18 +```js +export { customRandom } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export customRandom" +}; +export { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export random" +}; +export { urlAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export urlAlphabet" +}; +export { nanoid } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export nanoid" +}; +export { customAlphabet } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export customAlphabet" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/next-response/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/next-response/input.js new file mode 100644 index 0000000000000..355cd43370ea1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/next-response/input.js @@ -0,0 +1,122 @@ +import { stringifyCookie } from '../../web/spec-extension/cookies'; +import { NextURL } from '../next-url'; +import { toNodeOutgoingHttpHeaders, validateURL } from '../utils'; +import { ReflectAdapter } from './adapters/reflect'; +import { ResponseCookies } from './cookies'; +const INTERNALS = Symbol('internal response'); +const REDIRECTS = new Set([ + 301, + 302, + 303, + 307, + 308 +]); +function handleMiddlewareField(init, headers) { + var _init_request; + if (init == null ? void 0 : (_init_request = init.request) == null ? void 0 : _init_request.headers) { + if (!(init.request.headers instanceof Headers)) { + throw new Error('request.headers must be an instance of Headers'); + } + const keys = []; + for (const [key, value] of init.request.headers){ + headers.set('x-middleware-request-' + key, value); + keys.push(key); + } + headers.set('x-middleware-override-headers', keys.join(',')); + } +} +/** + * This class extends the [Web `Response` API](https://developer.mozilla.org/docs/Web/API/Response) with additional convenience methods. + * + * Read more: [Next.js Docs: `NextResponse`](https://nextjs.org/docs/app/api-reference/functions/next-response) + */ export class NextResponse extends Response { + constructor(body, init = {}){ + super(body, init); + const headers = this.headers; + const cookies = new ResponseCookies(headers); + const cookiesProxy = new Proxy(cookies, { + get (target, prop, receiver) { + switch(prop){ + case 'delete': + case 'set': + { + return (...args)=>{ + const result = Reflect.apply(target[prop], target, args); + const newHeaders = new Headers(headers); + if (result instanceof ResponseCookies) { + headers.set('x-middleware-set-cookie', result.getAll().map((cookie)=>stringifyCookie(cookie)).join(',')); + } + handleMiddlewareField(init, newHeaders); + return result; + }; + } + default: + return ReflectAdapter.get(target, prop, receiver); + } + } + }); + this[INTERNALS] = { + cookies: cookiesProxy, + url: init.url ? new NextURL(init.url, { + headers: toNodeOutgoingHttpHeaders(headers), + nextConfig: init.nextConfig + }) : undefined + }; + } + [Symbol.for('edge-runtime.inspect.custom')]() { + return { + cookies: this.cookies, + url: this.url, + // rest of props come from Response + body: this.body, + bodyUsed: this.bodyUsed, + headers: Object.fromEntries(this.headers), + ok: this.ok, + redirected: this.redirected, + status: this.status, + statusText: this.statusText, + type: this.type + }; + } + get cookies() { + return this[INTERNALS].cookies; + } + static json(body, init) { + const response = Response.json(body, init); + return new NextResponse(response.body, response); + } + static redirect(url, init) { + const status = typeof init === 'number' ? init : (init == null ? void 0 : init.status) ?? 307; + if (!REDIRECTS.has(status)) { + throw new RangeError('Failed to execute "redirect" on "response": Invalid status code'); + } + const initObj = typeof init === 'object' ? init : {}; + const headers = new Headers(initObj == null ? void 0 : initObj.headers); + headers.set('Location', validateURL(url)); + return new NextResponse(null, { + ...initObj, + headers, + status + }); + } + static rewrite(destination, init) { + const headers = new Headers(init == null ? void 0 : init.headers); + headers.set('x-middleware-rewrite', validateURL(destination)); + handleMiddlewareField(init, headers); + return new NextResponse(null, { + ...init, + headers + }); + } + static next(init) { + const headers = new Headers(init == null ? void 0 : init.headers); + headers.set('x-middleware-next', '1'); + handleMiddlewareField(init, headers); + return new NextResponse(null, { + ...init, + headers + }); + } +} + +//# sourceMappingURL=response.js.map diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/next-response/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/next-response/output.md new file mode 100644 index 0000000000000..42b449b912a94 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/next-response/output.md @@ -0,0 +1,1349 @@ +# Items + +Count: 17 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { stringifyCookie } from '../../web/spec-extension/cookies'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { stringifyCookie } from '../../web/spec-extension/cookies'; + +``` + +- Hoisted +- Declares: `stringifyCookie` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import { NextURL } from '../next-url'; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import { NextURL } from '../next-url'; + +``` + +- Hoisted +- Declares: `NextURL` + +## Item 5: Stmt 2, `ImportOfModule` + +```js +import { toNodeOutgoingHttpHeaders, validateURL } from '../utils'; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 2, `ImportBinding(0)` + +```js +import { toNodeOutgoingHttpHeaders, validateURL } from '../utils'; + +``` + +- Hoisted +- Declares: `toNodeOutgoingHttpHeaders` + +## Item 7: Stmt 2, `ImportBinding(1)` + +```js +import { toNodeOutgoingHttpHeaders, validateURL } from '../utils'; + +``` + +- Hoisted +- Declares: `validateURL` + +## Item 8: Stmt 3, `ImportOfModule` + +```js +import { ReflectAdapter } from './adapters/reflect'; + +``` + +- Hoisted +- Side effects + +## Item 9: Stmt 3, `ImportBinding(0)` + +```js +import { ReflectAdapter } from './adapters/reflect'; + +``` + +- Hoisted +- Declares: `ReflectAdapter` + +## Item 10: Stmt 4, `ImportOfModule` + +```js +import { ResponseCookies } from './cookies'; + +``` + +- Hoisted +- Side effects + +## Item 11: Stmt 4, `ImportBinding(0)` + +```js +import { ResponseCookies } from './cookies'; + +``` + +- Hoisted +- Declares: `ResponseCookies` + +## Item 12: Stmt 5, `VarDeclarator(0)` + +```js +const INTERNALS = Symbol('internal response'); + +``` + +- Side effects +- Declares: `INTERNALS` +- Write: `INTERNALS` + +## Item 13: Stmt 6, `VarDeclarator(0)` + +```js +const REDIRECTS = new Set([ + 301, + 302, + 303, + 307, + 308 +]); + +``` + +- Side effects +- Declares: `REDIRECTS` +- Write: `REDIRECTS` + +## Item 14: Stmt 7, `Normal` + +```js +function handleMiddlewareField(init, headers) { + var _init_request; + if (init == null ? void 0 : (_init_request = init.request) == null ? void 0 : _init_request.headers) { + if (!(init.request.headers instanceof Headers)) { + throw new Error('request.headers must be an instance of Headers'); + } + const keys = []; + for (const [key, value] of init.request.headers){ + headers.set('x-middleware-request-' + key, value); + keys.push(key); + } + headers.set('x-middleware-override-headers', keys.join(',')); + } +} + +``` + +- Hoisted +- Declares: `handleMiddlewareField` +- Write: `handleMiddlewareField` + +## Item 15: Stmt 8, `Normal` + +```js +export class NextResponse extends Response { + constructor(body, init = {}){ + super(body, init); + const headers = this.headers; + const cookies = new ResponseCookies(headers); + const cookiesProxy = new Proxy(cookies, { + get (target, prop, receiver) { + switch(prop){ + case 'delete': + case 'set': + { + return (...args)=>{ + const result = Reflect.apply(target[prop], target, args); + const newHeaders = new Headers(headers); + if (result instanceof ResponseCookies) { + headers.set('x-middleware-set-cookie', result.getAll().map((cookie)=>stringifyCookie(cookie)).join(',')); + } + handleMiddlewareField(init, newHeaders); + return result; + }; + } + default: + return ReflectAdapter.get(target, prop, receiver); + } + } + }); + this[INTERNALS] = { + cookies: cookiesProxy, + url: init.url ? new NextURL(init.url, { + headers: toNodeOutgoingHttpHeaders(headers), + nextConfig: init.nextConfig + }) : undefined + }; + } + [Symbol.for('edge-runtime.inspect.custom')]() { + return { + cookies: this.cookies, + url: this.url, + body: this.body, + bodyUsed: this.bodyUsed, + headers: Object.fromEntries(this.headers), + ok: this.ok, + redirected: this.redirected, + status: this.status, + statusText: this.statusText, + type: this.type + }; + } + get cookies() { + return this[INTERNALS].cookies; + } + static json(body, init) { + const response = Response.json(body, init); + return new NextResponse(response.body, response); + } + static redirect(url, init) { + const status = typeof init === 'number' ? init : (init == null ? void 0 : init.status) ?? 307; + if (!REDIRECTS.has(status)) { + throw new RangeError('Failed to execute "redirect" on "response": Invalid status code'); + } + const initObj = typeof init === 'object' ? init : {}; + const headers = new Headers(initObj == null ? void 0 : initObj.headers); + headers.set('Location', validateURL(url)); + return new NextResponse(null, { + ...initObj, + headers, + status + }); + } + static rewrite(destination, init) { + const headers = new Headers(init == null ? void 0 : init.headers); + headers.set('x-middleware-rewrite', validateURL(destination)); + handleMiddlewareField(init, headers); + return new NextResponse(null, { + ...init, + headers + }); + } + static next(init) { + const headers = new Headers(init == null ? void 0 : init.headers); + headers.set('x-middleware-next', '1'); + handleMiddlewareField(init, headers); + return new NextResponse(null, { + ...init, + headers + }); + } +} + +``` + +- Declares: `NextResponse` +- Reads: `ResponseCookies`, `stringifyCookie`, `handleMiddlewareField`, `ReflectAdapter`, `INTERNALS`, `NextURL`, `toNodeOutgoingHttpHeaders`, `NextResponse`, `REDIRECTS`, `validateURL` +- Write: `ReflectAdapter`, `REDIRECTS`, `NextResponse` + +# Phase 1 +```mermaid +graph TD + Item1; + Item6; + Item2; + Item7; + Item3; + Item8; + Item9; + Item4; + Item10; + Item5; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item16["ModuleEvaluation"]; + Item17; + Item17["export NextResponse"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item6; + Item2; + Item7; + Item3; + Item8; + Item9; + Item4; + Item10; + Item5; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item16["ModuleEvaluation"]; + Item17; + Item17["export NextResponse"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item4; + Item12 --> Item5; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item13 --> Item12; + Item15 --> Item11; + Item15 --> Item6; + Item15 --> Item14; + Item15 --> Item10; + Item15 --> Item12; + Item15 --> Item7; + Item15 --> Item8; + Item15 --> Item13; + Item15 --> Item9; + Item17 --> Item15; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item6; + Item2; + Item7; + Item3; + Item8; + Item9; + Item4; + Item10; + Item5; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item16["ModuleEvaluation"]; + Item17; + Item17["export NextResponse"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item4; + Item12 --> Item5; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item13 --> Item12; + Item15 --> Item11; + Item15 --> Item6; + Item15 --> Item14; + Item15 --> Item10; + Item15 --> Item12; + Item15 --> Item7; + Item15 --> Item8; + Item15 --> Item13; + Item15 --> Item9; + Item17 --> Item15; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item6; + Item2; + Item7; + Item3; + Item8; + Item9; + Item4; + Item10; + Item5; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item16["ModuleEvaluation"]; + Item17; + Item17["export NextResponse"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item12 --> Item1; + Item12 --> Item2; + Item12 --> Item3; + Item12 --> Item4; + Item12 --> Item5; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item13 --> Item12; + Item15 --> Item11; + Item15 --> Item6; + Item15 --> Item14; + Item15 --> Item10; + Item15 --> Item12; + Item15 --> Item7; + Item15 --> Item8; + Item15 --> Item13; + Item15 --> Item9; + Item17 --> Item15; + Item16 --> Item1; + Item16 --> Item2; + Item16 --> Item3; + Item16 --> Item4; + Item16 --> Item5; + Item16 --> Item12; + Item16 --> Item13; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(2, ImportBinding(1))]"]; + N1["Items: [ItemId(2, ImportBinding(0))]"]; + N2["Items: [ItemId(1, ImportBinding(0))]"]; + N3["Items: [ItemId(3, ImportBinding(0))]"]; + N4["Items: [ItemId(7, Normal)]"]; + N5["Items: [ItemId(0, ImportBinding(0))]"]; + N6["Items: [ItemId(4, ImportBinding(0))]"]; + N7["Items: [ItemId(0, ImportOfModule)]"]; + N8["Items: [ItemId(1, ImportOfModule)]"]; + N9["Items: [ItemId(2, ImportOfModule)]"]; + N10["Items: [ItemId(3, ImportOfModule)]"]; + N11["Items: [ItemId(4, ImportOfModule)]"]; + N12["Items: [ItemId(5, VarDeclarator(0))]"]; + N13["Items: [ItemId(6, VarDeclarator(0))]"]; + N14["Items: [ItemId(ModuleEvaluation)]"]; + N15["Items: [ItemId(8, Normal)]"]; + N16["Items: [ItemId(Export(("NextResponse", #2), "NextResponse"))]"]; + N8 --> N7; + N9 --> N7; + N9 --> N8; + N10 --> N7; + N10 --> N8; + N10 --> N9; + N11 --> N7; + N11 --> N8; + N11 --> N9; + N11 --> N10; + N12 --> N7; + N12 --> N8; + N12 --> N9; + N12 --> N10; + N12 --> N11; + N13 --> N7; + N13 --> N8; + N13 --> N9; + N13 --> N10; + N13 --> N11; + N13 --> N12; + N15 --> N6; + N15 --> N5; + N15 --> N4; + N15 --> N3; + N15 --> N12; + N15 --> N2; + N15 --> N1; + N15 --> N13; + N15 --> N0; + N16 --> N15; + N14 --> N7; + N14 --> N8; + N14 --> N9; + N14 --> N10; + N14 --> N11; + N14 --> N12; + N14 --> N13; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 14, + Export( + "NextResponse", + ): 16, + Exports: 17, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { validateURL } from '../utils'; +export { validateURL } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { toNodeOutgoingHttpHeaders } from '../utils'; +export { toNodeOutgoingHttpHeaders } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { NextURL } from '../next-url'; +export { NextURL } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import { ReflectAdapter } from './adapters/reflect'; +export { ReflectAdapter } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +function handleMiddlewareField(init, headers) { + var _init_request; + if (init == null ? void 0 : (_init_request = init.request) == null ? void 0 : _init_request.headers) { + if (!(init.request.headers instanceof Headers)) { + throw new Error('request.headers must be an instance of Headers'); + } + const keys = []; + for (const [key, value] of init.request.headers){ + headers.set('x-middleware-request-' + key, value); + keys.push(key); + } + headers.set('x-middleware-override-headers', keys.join(',')); + } +} +export { handleMiddlewareField } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import { stringifyCookie } from '../../web/spec-extension/cookies'; +export { stringifyCookie } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import { ResponseCookies } from './cookies'; +export { ResponseCookies } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import '../../web/spec-extension/cookies'; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import '../next-url'; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import '../utils'; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import './adapters/reflect'; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import './cookies'; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +const INTERNALS = Symbol('internal response'); +export { INTERNALS } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +const REDIRECTS = new Set([ + 301, + 302, + 303, + 307, + 308 +]); +export { REDIRECTS } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +"module evaluation"; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { ResponseCookies } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { stringifyCookie } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { handleMiddlewareField } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { ReflectAdapter } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { INTERNALS } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { NextURL } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { toNodeOutgoingHttpHeaders } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { validateURL } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { REDIRECTS } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +class NextResponse extends Response { + constructor(body, init = {}){ + super(body, init); + const headers = this.headers; + const cookies = new ResponseCookies(headers); + const cookiesProxy = new Proxy(cookies, { + get (target, prop, receiver) { + switch(prop){ + case 'delete': + case 'set': + { + return (...args)=>{ + const result = Reflect.apply(target[prop], target, args); + const newHeaders = new Headers(headers); + if (result instanceof ResponseCookies) { + headers.set('x-middleware-set-cookie', result.getAll().map((cookie)=>stringifyCookie(cookie)).join(',')); + } + handleMiddlewareField(init, newHeaders); + return result; + }; + } + default: + return ReflectAdapter.get(target, prop, receiver); + } + } + }); + this[INTERNALS] = { + cookies: cookiesProxy, + url: init.url ? new NextURL(init.url, { + headers: toNodeOutgoingHttpHeaders(headers), + nextConfig: init.nextConfig + }) : undefined + }; + } + [Symbol.for('edge-runtime.inspect.custom')]() { + return { + cookies: this.cookies, + url: this.url, + body: this.body, + bodyUsed: this.bodyUsed, + headers: Object.fromEntries(this.headers), + ok: this.ok, + redirected: this.redirected, + status: this.status, + statusText: this.statusText, + type: this.type + }; + } + get cookies() { + return this[INTERNALS].cookies; + } + static json(body, init) { + const response = Response.json(body, init); + return new NextResponse(response.body, response); + } + static redirect(url, init) { + const status = typeof init === 'number' ? init : (init == null ? void 0 : init.status) ?? 307; + if (!REDIRECTS.has(status)) { + throw new RangeError('Failed to execute "redirect" on "response": Invalid status code'); + } + const initObj = typeof init === 'object' ? init : {}; + const headers = new Headers(initObj == null ? void 0 : initObj.headers); + headers.set('Location', validateURL(url)); + return new NextResponse(null, { + ...initObj, + headers, + status + }); + } + static rewrite(destination, init) { + const headers = new Headers(init == null ? void 0 : init.headers); + headers.set('x-middleware-rewrite', validateURL(destination)); + handleMiddlewareField(init, headers); + return new NextResponse(null, { + ...init, + headers + }); + } + static next(init) { + const headers = new Headers(init == null ? void 0 : init.headers); + headers.set('x-middleware-next', '1'); + handleMiddlewareField(init, headers); + return new NextResponse(null, { + ...init, + headers + }); + } +} +export { NextResponse } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { NextResponse } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +export { NextResponse }; + +``` +## Part 17 +```js +export { NextResponse } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export NextResponse" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 14, + Export( + "NextResponse", + ): 16, + Exports: 17, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { validateURL } from '../utils'; +export { validateURL } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { toNodeOutgoingHttpHeaders } from '../utils'; +export { toNodeOutgoingHttpHeaders } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { NextURL } from '../next-url'; +export { NextURL } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import { ReflectAdapter } from './adapters/reflect'; +export { ReflectAdapter } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +function handleMiddlewareField(init, headers) { + var _init_request; + if (init == null ? void 0 : (_init_request = init.request) == null ? void 0 : _init_request.headers) { + if (!(init.request.headers instanceof Headers)) { + throw new Error('request.headers must be an instance of Headers'); + } + const keys = []; + for (const [key, value] of init.request.headers){ + headers.set('x-middleware-request-' + key, value); + keys.push(key); + } + headers.set('x-middleware-override-headers', keys.join(',')); + } +} +export { handleMiddlewareField } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import { stringifyCookie } from '../../web/spec-extension/cookies'; +export { stringifyCookie } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import { ResponseCookies } from './cookies'; +export { ResponseCookies } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import '../../web/spec-extension/cookies'; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import '../next-url'; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import '../utils'; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import './adapters/reflect'; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import './cookies'; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +const INTERNALS = Symbol('internal response'); +export { INTERNALS } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +const REDIRECTS = new Set([ + 301, + 302, + 303, + 307, + 308 +]); +export { REDIRECTS } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +"module evaluation"; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { ResponseCookies } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { stringifyCookie } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { handleMiddlewareField } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { ReflectAdapter } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { INTERNALS } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { NextURL } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { toNodeOutgoingHttpHeaders } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { validateURL } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { REDIRECTS } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +class NextResponse extends Response { + constructor(body, init = {}){ + super(body, init); + const headers = this.headers; + const cookies = new ResponseCookies(headers); + const cookiesProxy = new Proxy(cookies, { + get (target, prop, receiver) { + switch(prop){ + case 'delete': + case 'set': + { + return (...args)=>{ + const result = Reflect.apply(target[prop], target, args); + const newHeaders = new Headers(headers); + if (result instanceof ResponseCookies) { + headers.set('x-middleware-set-cookie', result.getAll().map((cookie)=>stringifyCookie(cookie)).join(',')); + } + handleMiddlewareField(init, newHeaders); + return result; + }; + } + default: + return ReflectAdapter.get(target, prop, receiver); + } + } + }); + this[INTERNALS] = { + cookies: cookiesProxy, + url: init.url ? new NextURL(init.url, { + headers: toNodeOutgoingHttpHeaders(headers), + nextConfig: init.nextConfig + }) : undefined + }; + } + [Symbol.for('edge-runtime.inspect.custom')]() { + return { + cookies: this.cookies, + url: this.url, + body: this.body, + bodyUsed: this.bodyUsed, + headers: Object.fromEntries(this.headers), + ok: this.ok, + redirected: this.redirected, + status: this.status, + statusText: this.statusText, + type: this.type + }; + } + get cookies() { + return this[INTERNALS].cookies; + } + static json(body, init) { + const response = Response.json(body, init); + return new NextResponse(response.body, response); + } + static redirect(url, init) { + const status = typeof init === 'number' ? init : (init == null ? void 0 : init.status) ?? 307; + if (!REDIRECTS.has(status)) { + throw new RangeError('Failed to execute "redirect" on "response": Invalid status code'); + } + const initObj = typeof init === 'object' ? init : {}; + const headers = new Headers(initObj == null ? void 0 : initObj.headers); + headers.set('Location', validateURL(url)); + return new NextResponse(null, { + ...initObj, + headers, + status + }); + } + static rewrite(destination, init) { + const headers = new Headers(init == null ? void 0 : init.headers); + headers.set('x-middleware-rewrite', validateURL(destination)); + handleMiddlewareField(init, headers); + return new NextResponse(null, { + ...init, + headers + }); + } + static next(init) { + const headers = new Headers(init == null ? void 0 : init.headers); + headers.set('x-middleware-next', '1'); + handleMiddlewareField(init, headers); + return new NextResponse(null, { + ...init, + headers + }); + } +} +export { NextResponse } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { NextResponse } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +export { NextResponse }; + +``` +## Part 17 +```js +export { NextResponse } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export NextResponse" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nextjs-tracer/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nextjs-tracer/input.js new file mode 100644 index 0000000000000..3fafa47598599 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nextjs-tracer/input.js @@ -0,0 +1,214 @@ +import { LogSpanAllowList, NextVanillaSpanAllowlist } from './constants'; +let api; +// we want to allow users to use their own version of @opentelemetry/api if they +// want to, so we try to require it first, and if it fails we fall back to the +// version that is bundled with Next.js +// this is because @opentelemetry/api has to be synced with the version of +// @opentelemetry/tracing that is used, and we don't want to force users to use +// the version that is bundled with Next.js. +// the API is ~stable, so this should be fine +if (process.env.NEXT_RUNTIME === 'edge') { + api = require('@opentelemetry/api'); +} else { + try { + api = require('@opentelemetry/api'); + } catch (err) { + api = require('next/dist/compiled/@opentelemetry/api'); + } +} +const { context, propagation, trace, SpanStatusCode, SpanKind, ROOT_CONTEXT } = api; +const isPromise = (p)=>{ + return p !== null && typeof p === 'object' && typeof p.then === 'function'; +}; +export class BubbledError extends Error { + constructor(bubble, result){ + super(); + this.bubble = bubble; + this.result = result; + } +} +export function isBubbledError(error) { + if (typeof error !== 'object' || error === null) return false; + return error instanceof BubbledError; +} +const closeSpanWithError = (span, error)=>{ + if (isBubbledError(error) && error.bubble) { + span.setAttribute('next.bubble', true); + } else { + if (error) { + span.recordException(error); + } + span.setStatus({ + code: SpanStatusCode.ERROR, + message: error == null ? void 0 : error.message + }); + } + span.end(); +}; +/** we use this map to propagate attributes from nested spans to the top span */ const rootSpanAttributesStore = new Map(); +const rootSpanIdKey = api.createContextKey('next.rootSpanId'); +let lastSpanId = 0; +const getSpanId = ()=>lastSpanId++; +const clientTraceDataSetter = { + set (carrier, key, value) { + carrier.push({ + key, + value + }); + } +}; +class NextTracerImpl { + /** + * Returns an instance to the trace with configured name. + * Since wrap / trace can be defined in any place prior to actual trace subscriber initialization, + * This should be lazily evaluated. + */ getTracerInstance() { + return trace.getTracer('next.js', '0.0.1'); + } + getContext() { + return context; + } + getTracePropagationData() { + const activeContext = context.active(); + const entries = []; + propagation.inject(activeContext, entries, clientTraceDataSetter); + return entries; + } + getActiveScopeSpan() { + return trace.getSpan(context == null ? void 0 : context.active()); + } + withPropagatedContext(carrier, fn, getter) { + const activeContext = context.active(); + if (trace.getSpanContext(activeContext)) { + // Active span is already set, too late to propagate. + return fn(); + } + const remoteContext = propagation.extract(activeContext, carrier, getter); + return context.with(remoteContext, fn); + } + trace(...args) { + var _trace_getSpanContext; + const [type, fnOrOptions, fnOrEmpty] = args; + // coerce options form overload + const { fn, options } = typeof fnOrOptions === 'function' ? { + fn: fnOrOptions, + options: {} + } : { + fn: fnOrEmpty, + options: { + ...fnOrOptions + } + }; + const spanName = options.spanName ?? type; + if (!NextVanillaSpanAllowlist.includes(type) && process.env.NEXT_OTEL_VERBOSE !== '1' || options.hideSpan) { + return fn(); + } + // Trying to get active scoped span to assign parent. If option specifies parent span manually, will try to use it. + let spanContext = this.getSpanContext((options == null ? void 0 : options.parentSpan) ?? this.getActiveScopeSpan()); + let isRootSpan = false; + if (!spanContext) { + spanContext = (context == null ? void 0 : context.active()) ?? ROOT_CONTEXT; + isRootSpan = true; + } else if ((_trace_getSpanContext = trace.getSpanContext(spanContext)) == null ? void 0 : _trace_getSpanContext.isRemote) { + isRootSpan = true; + } + const spanId = getSpanId(); + options.attributes = { + 'next.span_name': spanName, + 'next.span_type': type, + ...options.attributes + }; + return context.with(spanContext.setValue(rootSpanIdKey, spanId), ()=>this.getTracerInstance().startActiveSpan(spanName, options, (span)=>{ + const startTime = 'performance' in globalThis && 'measure' in performance ? globalThis.performance.now() : undefined; + const onCleanup = ()=>{ + rootSpanAttributesStore.delete(spanId); + if (startTime && process.env.NEXT_OTEL_PERFORMANCE_PREFIX && LogSpanAllowList.includes(type || '')) { + performance.measure(`${process.env.NEXT_OTEL_PERFORMANCE_PREFIX}:next-${(type.split('.').pop() || '').replace(/[A-Z]/g, (match)=>'-' + match.toLowerCase())}`, { + start: startTime, + end: performance.now() + }); + } + }; + if (isRootSpan) { + rootSpanAttributesStore.set(spanId, new Map(Object.entries(options.attributes ?? {}))); + } + try { + if (fn.length > 1) { + return fn(span, (err)=>closeSpanWithError(span, err)); + } + const result = fn(span); + if (isPromise(result)) { + // If there's error make sure it throws + return result.then((res)=>{ + span.end(); + // Need to pass down the promise result, + // it could be react stream response with error { error, stream } + return res; + }).catch((err)=>{ + closeSpanWithError(span, err); + throw err; + }).finally(onCleanup); + } else { + span.end(); + onCleanup(); + } + return result; + } catch (err) { + closeSpanWithError(span, err); + onCleanup(); + throw err; + } + })); + } + wrap(...args) { + const tracer = this; + const [name, options, fn] = args.length === 3 ? args : [ + args[0], + {}, + args[1] + ]; + if (!NextVanillaSpanAllowlist.includes(name) && process.env.NEXT_OTEL_VERBOSE !== '1') { + return fn; + } + return function() { + let optionsObj = options; + if (typeof optionsObj === 'function' && typeof fn === 'function') { + optionsObj = optionsObj.apply(this, arguments); + } + const lastArgId = arguments.length - 1; + const cb = arguments[lastArgId]; + if (typeof cb === 'function') { + const scopeBoundCb = tracer.getContext().bind(context.active(), cb); + return tracer.trace(name, optionsObj, (_span, done)=>{ + arguments[lastArgId] = function(err) { + done == null ? void 0 : done(err); + return scopeBoundCb.apply(this, arguments); + }; + return fn.apply(this, arguments); + }); + } else { + return tracer.trace(name, optionsObj, ()=>fn.apply(this, arguments)); + } + }; + } + startSpan(...args) { + const [type, options] = args; + const spanContext = this.getSpanContext((options == null ? void 0 : options.parentSpan) ?? this.getActiveScopeSpan()); + return this.getTracerInstance().startSpan(type, options, spanContext); + } + getSpanContext(parentSpan) { + const spanContext = parentSpan ? trace.setSpan(context.active(), parentSpan) : undefined; + return spanContext; + } + getRootSpanAttributes() { + const spanId = context.active().getValue(rootSpanIdKey); + return rootSpanAttributesStore.get(spanId); + } +} +const getTracer = (()=>{ + const tracer = new NextTracerImpl(); + return ()=>tracer; +})(); +export { getTracer, SpanStatusCode, SpanKind }; + +//# sourceMappingURL=tracer.js.map diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nextjs-tracer/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nextjs-tracer/output.md new file mode 100644 index 0000000000000..65f137044256d --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/nextjs-tracer/output.md @@ -0,0 +1,1814 @@ +# Items + +Count: 23 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { LogSpanAllowList, NextVanillaSpanAllowlist } from './constants'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { LogSpanAllowList, NextVanillaSpanAllowlist } from './constants'; + +``` + +- Hoisted +- Declares: `LogSpanAllowList` + +## Item 3: Stmt 0, `ImportBinding(1)` + +```js +import { LogSpanAllowList, NextVanillaSpanAllowlist } from './constants'; + +``` + +- Hoisted +- Declares: `NextVanillaSpanAllowlist` + +## Item 4: Stmt 1, `VarDeclarator(0)` + +```js +let api; + +``` + +- Declares: `api` +- Write: `api` + +## Item 5: Stmt 2, `Normal` + +```js +if (process.env.NEXT_RUNTIME === 'edge') { + api = require('@opentelemetry/api'); +} else { + try { + api = require('@opentelemetry/api'); + } catch (err) { + api = require('next/dist/compiled/@opentelemetry/api'); + } +} + +``` + +- Side effects +- Write: `api` + +## Item 6: Stmt 3, `VarDeclarator(0)` + +```js +const { context, propagation, trace, SpanStatusCode, SpanKind, ROOT_CONTEXT } = api; + +``` + +- Declares: `context`, `propagation`, `trace`, `SpanStatusCode`, `SpanKind`, `ROOT_CONTEXT` +- Reads: `api` +- Write: `context`, `propagation`, `trace`, `SpanStatusCode`, `SpanKind`, `ROOT_CONTEXT` + +## Item 7: Stmt 4, `VarDeclarator(0)` + +```js +const isPromise = (p)=>{ + return p !== null && typeof p === 'object' && typeof p.then === 'function'; +}; + +``` + +- Declares: `isPromise` +- Write: `isPromise` + +## Item 8: Stmt 5, `Normal` + +```js +export class BubbledError extends Error { + constructor(bubble, result){ + super(); + this.bubble = bubble; + this.result = result; + } +} + +``` + +- Declares: `BubbledError` +- Write: `BubbledError` + +## Item 9: Stmt 6, `Normal` + +```js +export function isBubbledError(error) { + if (typeof error !== 'object' || error === null) return false; + return error instanceof BubbledError; +} + +``` + +- Hoisted +- Declares: `isBubbledError` +- Reads (eventual): `BubbledError` +- Write: `isBubbledError` + +## Item 10: Stmt 7, `VarDeclarator(0)` + +```js +const closeSpanWithError = (span, error)=>{ + if (isBubbledError(error) && error.bubble) { + span.setAttribute('next.bubble', true); + } else { + if (error) { + span.recordException(error); + } + span.setStatus({ + code: SpanStatusCode.ERROR, + message: error == null ? void 0 : error.message + }); + } + span.end(); +}; + +``` + +- Declares: `closeSpanWithError` +- Reads: `isBubbledError`, `SpanStatusCode` +- Write: `SpanStatusCode`, `closeSpanWithError` + +## Item 11: Stmt 8, `VarDeclarator(0)` + +```js +const rootSpanAttributesStore = new Map(); + +``` + +- Side effects +- Declares: `rootSpanAttributesStore` +- Write: `rootSpanAttributesStore` + +## Item 12: Stmt 9, `VarDeclarator(0)` + +```js +const rootSpanIdKey = api.createContextKey('next.rootSpanId'); + +``` + +- Declares: `rootSpanIdKey` +- Reads: `api` +- Write: `api`, `rootSpanIdKey` + +## Item 13: Stmt 10, `VarDeclarator(0)` + +```js +let lastSpanId = 0; + +``` + +- Declares: `lastSpanId` +- Write: `lastSpanId` + +## Item 14: Stmt 11, `VarDeclarator(0)` + +```js +const getSpanId = ()=>lastSpanId++; + +``` + +- Declares: `getSpanId` +- Reads: `lastSpanId` +- Write: `getSpanId` + +## Item 15: Stmt 12, `VarDeclarator(0)` + +```js +const clientTraceDataSetter = { + set (carrier, key, value) { + carrier.push({ + key, + value + }); + } +}; + +``` + +- Declares: `clientTraceDataSetter` +- Write: `clientTraceDataSetter` + +## Item 16: Stmt 13, `Normal` + +```js +class NextTracerImpl { + getTracerInstance() { + return trace.getTracer('next.js', '0.0.1'); + } + getContext() { + return context; + } + getTracePropagationData() { + const activeContext = context.active(); + const entries = []; + propagation.inject(activeContext, entries, clientTraceDataSetter); + return entries; + } + getActiveScopeSpan() { + return trace.getSpan(context == null ? void 0 : context.active()); + } + withPropagatedContext(carrier, fn, getter) { + const activeContext = context.active(); + if (trace.getSpanContext(activeContext)) { + return fn(); + } + const remoteContext = propagation.extract(activeContext, carrier, getter); + return context.with(remoteContext, fn); + } + trace(...args) { + var _trace_getSpanContext; + const [type, fnOrOptions, fnOrEmpty] = args; + const { fn, options } = typeof fnOrOptions === 'function' ? { + fn: fnOrOptions, + options: {} + } : { + fn: fnOrEmpty, + options: { + ...fnOrOptions + } + }; + const spanName = options.spanName ?? type; + if (!NextVanillaSpanAllowlist.includes(type) && process.env.NEXT_OTEL_VERBOSE !== '1' || options.hideSpan) { + return fn(); + } + let spanContext = this.getSpanContext((options == null ? void 0 : options.parentSpan) ?? this.getActiveScopeSpan()); + let isRootSpan = false; + if (!spanContext) { + spanContext = (context == null ? void 0 : context.active()) ?? ROOT_CONTEXT; + isRootSpan = true; + } else if ((_trace_getSpanContext = trace.getSpanContext(spanContext)) == null ? void 0 : _trace_getSpanContext.isRemote) { + isRootSpan = true; + } + const spanId = getSpanId(); + options.attributes = { + 'next.span_name': spanName, + 'next.span_type': type, + ...options.attributes + }; + return context.with(spanContext.setValue(rootSpanIdKey, spanId), ()=>this.getTracerInstance().startActiveSpan(spanName, options, (span)=>{ + const startTime = 'performance' in globalThis && 'measure' in performance ? globalThis.performance.now() : undefined; + const onCleanup = ()=>{ + rootSpanAttributesStore.delete(spanId); + if (startTime && process.env.NEXT_OTEL_PERFORMANCE_PREFIX && LogSpanAllowList.includes(type || '')) { + performance.measure(`${process.env.NEXT_OTEL_PERFORMANCE_PREFIX}:next-${(type.split('.').pop() || '').replace(/[A-Z]/g, (match)=>'-' + match.toLowerCase())}`, { + start: startTime, + end: performance.now() + }); + } + }; + if (isRootSpan) { + rootSpanAttributesStore.set(spanId, new Map(Object.entries(options.attributes ?? {}))); + } + try { + if (fn.length > 1) { + return fn(span, (err)=>closeSpanWithError(span, err)); + } + const result = fn(span); + if (isPromise(result)) { + return result.then((res)=>{ + span.end(); + return res; + }).catch((err)=>{ + closeSpanWithError(span, err); + throw err; + }).finally(onCleanup); + } else { + span.end(); + onCleanup(); + } + return result; + } catch (err) { + closeSpanWithError(span, err); + onCleanup(); + throw err; + } + })); + } + wrap(...args) { + const tracer = this; + const [name, options, fn] = args.length === 3 ? args : [ + args[0], + {}, + args[1] + ]; + if (!NextVanillaSpanAllowlist.includes(name) && process.env.NEXT_OTEL_VERBOSE !== '1') { + return fn; + } + return function() { + let optionsObj = options; + if (typeof optionsObj === 'function' && typeof fn === 'function') { + optionsObj = optionsObj.apply(this, arguments); + } + const lastArgId = arguments.length - 1; + const cb = arguments[lastArgId]; + if (typeof cb === 'function') { + const scopeBoundCb = tracer.getContext().bind(context.active(), cb); + return tracer.trace(name, optionsObj, (_span, done)=>{ + arguments[lastArgId] = function(err) { + done == null ? void 0 : done(err); + return scopeBoundCb.apply(this, arguments); + }; + return fn.apply(this, arguments); + }); + } else { + return tracer.trace(name, optionsObj, ()=>fn.apply(this, arguments)); + } + }; + } + startSpan(...args) { + const [type, options] = args; + const spanContext = this.getSpanContext((options == null ? void 0 : options.parentSpan) ?? this.getActiveScopeSpan()); + return this.getTracerInstance().startSpan(type, options, spanContext); + } + getSpanContext(parentSpan) { + const spanContext = parentSpan ? trace.setSpan(context.active(), parentSpan) : undefined; + return spanContext; + } + getRootSpanAttributes() { + const spanId = context.active().getValue(rootSpanIdKey); + return rootSpanAttributesStore.get(spanId); + } +} + +``` + +- Declares: `NextTracerImpl` +- Reads: `trace`, `context`, `propagation`, `clientTraceDataSetter`, `NextVanillaSpanAllowlist`, `ROOT_CONTEXT`, `getSpanId`, `rootSpanIdKey`, `rootSpanAttributesStore`, `LogSpanAllowList`, `closeSpanWithError`, `isPromise` +- Write: `trace`, `context`, `propagation`, `NextVanillaSpanAllowlist`, `rootSpanAttributesStore`, `LogSpanAllowList`, `NextTracerImpl` + +## Item 17: Stmt 14, `VarDeclarator(0)` + +```js +const getTracer = (()=>{ + const tracer = new NextTracerImpl(); + return ()=>tracer; +})(); + +``` + +- Declares: `getTracer` +- Reads: `NextTracerImpl` +- Write: `getTracer` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item18["ModuleEvaluation"]; + Item19; + Item19["export BubbledError"]; + Item20; + Item20["export isBubbledError"]; + Item21; + Item21["export getTracer"]; + Item22; + Item22["export SpanStatusCode"]; + Item23; + Item23["export SpanKind"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item18["ModuleEvaluation"]; + Item19; + Item19["export BubbledError"]; + Item20; + Item20["export isBubbledError"]; + Item21; + Item21["export getTracer"]; + Item22; + Item22["export SpanStatusCode"]; + Item23; + Item23["export SpanKind"]; + Item5 --> Item4; + Item5 --> Item1; + Item6 --> Item5; + Item6 --> Item4; + Item10 --> Item9; + Item10 --> Item6; + Item11 --> Item1; + Item11 --> Item5; + Item11 -.-> Item8; + Item12 --> Item5; + Item12 --> Item4; + Item12 -.-> Item6; + Item14 --> Item13; + Item16 --> Item6; + Item16 --> Item15; + Item16 --> Item3; + Item16 --> Item14; + Item16 --> Item12; + Item16 --> Item11; + Item16 --> Item2; + Item16 --> Item10; + Item16 --> Item7; + Item17 --> Item16; + Item19 --> Item8; + Item20 --> Item9; + Item21 --> Item17; + Item22 --> Item10; + Item22 --> Item6; + Item23 --> Item6; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item18["ModuleEvaluation"]; + Item19; + Item19["export BubbledError"]; + Item20; + Item20["export isBubbledError"]; + Item21; + Item21["export getTracer"]; + Item22; + Item22["export SpanStatusCode"]; + Item23; + Item23["export SpanKind"]; + Item5 --> Item4; + Item5 --> Item1; + Item6 --> Item5; + Item6 --> Item4; + Item10 --> Item9; + Item10 --> Item6; + Item11 --> Item1; + Item11 --> Item5; + Item11 -.-> Item8; + Item12 --> Item5; + Item12 --> Item4; + Item12 -.-> Item6; + Item14 --> Item13; + Item16 --> Item6; + Item16 --> Item15; + Item16 --> Item3; + Item16 --> Item14; + Item16 --> Item12; + Item16 --> Item11; + Item16 --> Item2; + Item16 --> Item10; + Item16 --> Item7; + Item17 --> Item16; + Item19 --> Item8; + Item20 --> Item9; + Item21 --> Item17; + Item22 --> Item10; + Item22 --> Item6; + Item23 --> Item6; + Item9 --> Item8; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item18["ModuleEvaluation"]; + Item19; + Item19["export BubbledError"]; + Item20; + Item20["export isBubbledError"]; + Item21; + Item21["export getTracer"]; + Item22; + Item22["export SpanStatusCode"]; + Item23; + Item23["export SpanKind"]; + Item5 --> Item4; + Item5 --> Item1; + Item6 --> Item5; + Item6 --> Item4; + Item10 --> Item9; + Item10 --> Item6; + Item11 --> Item1; + Item11 --> Item5; + Item11 -.-> Item8; + Item12 --> Item5; + Item12 --> Item4; + Item12 -.-> Item6; + Item14 --> Item13; + Item16 --> Item6; + Item16 --> Item15; + Item16 --> Item3; + Item16 --> Item14; + Item16 --> Item12; + Item16 --> Item11; + Item16 --> Item2; + Item16 --> Item10; + Item16 --> Item7; + Item17 --> Item16; + Item19 --> Item8; + Item20 --> Item9; + Item21 --> Item17; + Item22 --> Item10; + Item22 --> Item6; + Item23 --> Item6; + Item9 --> Item8; + Item18 --> Item1; + Item18 --> Item5; + Item18 --> Item11; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(4, VarDeclarator(0))]"]; + N1["Items: [ItemId(0, ImportBinding(0))]"]; + N2["Items: [ItemId(0, ImportBinding(1))]"]; + N3["Items: [ItemId(12, VarDeclarator(0))]"]; + N4["Items: [ItemId(10, VarDeclarator(0))]"]; + N5["Items: [ItemId(11, VarDeclarator(0))]"]; + N6["Items: [ItemId(5, Normal)]"]; + N7["Items: [ItemId(Export(("BubbledError", #2), "BubbledError"))]"]; + N8["Items: [ItemId(6, Normal)]"]; + N9["Items: [ItemId(Export(("isBubbledError", #2), "isBubbledError"))]"]; + N10["Items: [ItemId(0, ImportOfModule)]"]; + N11["Items: [ItemId(1, VarDeclarator(0))]"]; + N12["Items: [ItemId(2, Normal)]"]; + N13["Items: [ItemId(8, VarDeclarator(0))]"]; + N14["Items: [ItemId(ModuleEvaluation)]"]; + N15["Items: [ItemId(3, VarDeclarator(0))]"]; + N16["Items: [ItemId(Export(("SpanKind", #2), "SpanKind"))]"]; + N17["Items: [ItemId(9, VarDeclarator(0))]"]; + N18["Items: [ItemId(7, VarDeclarator(0))]"]; + N19["Items: [ItemId(Export(("SpanStatusCode", #2), "SpanStatusCode"))]"]; + N20["Items: [ItemId(13, Normal)]"]; + N21["Items: [ItemId(14, VarDeclarator(0))]"]; + N22["Items: [ItemId(Export(("getTracer", #2), "getTracer"))]"]; + N12 --> N11; + N12 --> N10; + N15 --> N12; + N15 --> N11; + N18 --> N8; + N18 --> N15; + N13 --> N10; + N13 --> N12; + N13 -.-> N6; + N17 --> N12; + N17 --> N11; + N17 -.-> N15; + N5 --> N4; + N20 --> N15; + N20 --> N3; + N20 --> N2; + N20 --> N5; + N20 --> N17; + N20 --> N13; + N20 --> N1; + N20 --> N18; + N20 --> N0; + N21 --> N20; + N7 --> N6; + N9 --> N8; + N22 --> N21; + N19 --> N18; + N19 --> N15; + N16 --> N15; + N8 --> N6; + N14 --> N10; + N14 --> N12; + N14 --> N13; +``` +# Entrypoints + +``` +{ + Export( + "isBubbledError", + ): 9, + ModuleEvaluation: 14, + Export( + "SpanKind", + ): 16, + Exports: 23, + Export( + "SpanStatusCode", + ): 19, + Export( + "BubbledError", + ): 7, + Export( + "getTracer", + ): 22, +} +``` + + +# Modules (dev) +## Part 0 +```js +const isPromise = (p)=>{ + return p !== null && typeof p === 'object' && typeof p.then === 'function'; +}; +export { isPromise } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { LogSpanAllowList } from './constants'; +export { LogSpanAllowList } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { NextVanillaSpanAllowlist } from './constants'; +export { NextVanillaSpanAllowlist } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +const clientTraceDataSetter = { + set (carrier, key, value) { + carrier.push({ + key, + value + }); + } +}; +export { clientTraceDataSetter } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +let lastSpanId = 0; +export { lastSpanId } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { lastSpanId } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const getSpanId = ()=>lastSpanId++; +export { getSpanId } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +class BubbledError extends Error { + constructor(bubble, result){ + super(); + this.bubble = bubble; + this.result = result; + } +} +export { BubbledError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { BubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { BubbledError }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { BubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +function isBubbledError(error) { + if (typeof error !== 'object' || error === null) return false; + return error instanceof BubbledError; +} +export { isBubbledError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { isBubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { isBubbledError }; + +``` +## Part 10 +```js +import './constants'; + +``` +## Part 11 +```js +let api; +export { api } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { api } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +if (process.env.NEXT_RUNTIME === 'edge') { + api = require('@opentelemetry/api'); +} else { + try { + api = require('@opentelemetry/api'); + } catch (err) { + api = require('next/dist/compiled/@opentelemetry/api'); + } +} + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +const rootSpanAttributesStore = new Map(); +export { rootSpanAttributesStore } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +"module evaluation"; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { api } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +const { context, propagation, trace, SpanStatusCode, SpanKind, ROOT_CONTEXT } = api; +export { context } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { propagation } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { trace } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { SpanStatusCode } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { SpanKind } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { ROOT_CONTEXT } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { SpanKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +export { SpanKind as SpanKind }; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { api } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +const rootSpanIdKey = api.createContextKey('next.rootSpanId'); +export { rootSpanIdKey } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { isBubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { SpanStatusCode } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +const closeSpanWithError = (span, error)=>{ + if (isBubbledError(error) && error.bubble) { + span.setAttribute('next.bubble', true); + } else { + if (error) { + span.recordException(error); + } + span.setStatus({ + code: SpanStatusCode.ERROR, + message: error == null ? void 0 : error.message + }); + } + span.end(); +}; +export { closeSpanWithError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { SpanStatusCode } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +export { SpanStatusCode as SpanStatusCode }; + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { trace } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { context } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { propagation } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { clientTraceDataSetter } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { NextVanillaSpanAllowlist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { ROOT_CONTEXT } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { getSpanId } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { rootSpanIdKey } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 17 +}; +import { rootSpanAttributesStore } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { LogSpanAllowList } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { closeSpanWithError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { isPromise } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +class NextTracerImpl { + getTracerInstance() { + return trace.getTracer('next.js', '0.0.1'); + } + getContext() { + return context; + } + getTracePropagationData() { + const activeContext = context.active(); + const entries = []; + propagation.inject(activeContext, entries, clientTraceDataSetter); + return entries; + } + getActiveScopeSpan() { + return trace.getSpan(context == null ? void 0 : context.active()); + } + withPropagatedContext(carrier, fn, getter) { + const activeContext = context.active(); + if (trace.getSpanContext(activeContext)) { + return fn(); + } + const remoteContext = propagation.extract(activeContext, carrier, getter); + return context.with(remoteContext, fn); + } + trace(...args) { + var _trace_getSpanContext; + const [type, fnOrOptions, fnOrEmpty] = args; + const { fn, options } = typeof fnOrOptions === 'function' ? { + fn: fnOrOptions, + options: {} + } : { + fn: fnOrEmpty, + options: { + ...fnOrOptions + } + }; + const spanName = options.spanName ?? type; + if (!NextVanillaSpanAllowlist.includes(type) && process.env.NEXT_OTEL_VERBOSE !== '1' || options.hideSpan) { + return fn(); + } + let spanContext = this.getSpanContext((options == null ? void 0 : options.parentSpan) ?? this.getActiveScopeSpan()); + let isRootSpan = false; + if (!spanContext) { + spanContext = (context == null ? void 0 : context.active()) ?? ROOT_CONTEXT; + isRootSpan = true; + } else if ((_trace_getSpanContext = trace.getSpanContext(spanContext)) == null ? void 0 : _trace_getSpanContext.isRemote) { + isRootSpan = true; + } + const spanId = getSpanId(); + options.attributes = { + 'next.span_name': spanName, + 'next.span_type': type, + ...options.attributes + }; + return context.with(spanContext.setValue(rootSpanIdKey, spanId), ()=>this.getTracerInstance().startActiveSpan(spanName, options, (span)=>{ + const startTime = 'performance' in globalThis && 'measure' in performance ? globalThis.performance.now() : undefined; + const onCleanup = ()=>{ + rootSpanAttributesStore.delete(spanId); + if (startTime && process.env.NEXT_OTEL_PERFORMANCE_PREFIX && LogSpanAllowList.includes(type || '')) { + performance.measure(`${process.env.NEXT_OTEL_PERFORMANCE_PREFIX}:next-${(type.split('.').pop() || '').replace(/[A-Z]/g, (match)=>'-' + match.toLowerCase())}`, { + start: startTime, + end: performance.now() + }); + } + }; + if (isRootSpan) { + rootSpanAttributesStore.set(spanId, new Map(Object.entries(options.attributes ?? {}))); + } + try { + if (fn.length > 1) { + return fn(span, (err)=>closeSpanWithError(span, err)); + } + const result = fn(span); + if (isPromise(result)) { + return result.then((res)=>{ + span.end(); + return res; + }).catch((err)=>{ + closeSpanWithError(span, err); + throw err; + }).finally(onCleanup); + } else { + span.end(); + onCleanup(); + } + return result; + } catch (err) { + closeSpanWithError(span, err); + onCleanup(); + throw err; + } + })); + } + wrap(...args) { + const tracer = this; + const [name, options, fn] = args.length === 3 ? args : [ + args[0], + {}, + args[1] + ]; + if (!NextVanillaSpanAllowlist.includes(name) && process.env.NEXT_OTEL_VERBOSE !== '1') { + return fn; + } + return function() { + let optionsObj = options; + if (typeof optionsObj === 'function' && typeof fn === 'function') { + optionsObj = optionsObj.apply(this, arguments); + } + const lastArgId = arguments.length - 1; + const cb = arguments[lastArgId]; + if (typeof cb === 'function') { + const scopeBoundCb = tracer.getContext().bind(context.active(), cb); + return tracer.trace(name, optionsObj, (_span, done)=>{ + arguments[lastArgId] = function(err) { + done == null ? void 0 : done(err); + return scopeBoundCb.apply(this, arguments); + }; + return fn.apply(this, arguments); + }); + } else { + return tracer.trace(name, optionsObj, ()=>fn.apply(this, arguments)); + } + }; + } + startSpan(...args) { + const [type, options] = args; + const spanContext = this.getSpanContext((options == null ? void 0 : options.parentSpan) ?? this.getActiveScopeSpan()); + return this.getTracerInstance().startSpan(type, options, spanContext); + } + getSpanContext(parentSpan) { + const spanContext = parentSpan ? trace.setSpan(context.active(), parentSpan) : undefined; + return spanContext; + } + getRootSpanAttributes() { + const spanId = context.active().getValue(rootSpanIdKey); + return rootSpanAttributesStore.get(spanId); + } +} +export { NextTracerImpl } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import { NextTracerImpl } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +const getTracer = (()=>{ + const tracer = new NextTracerImpl(); + return ()=>tracer; +})(); +export { getTracer } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import { getTracer } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +export { getTracer as getTracer }; + +``` +## Part 23 +```js +export { BubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export BubbledError" +}; +export { isBubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export isBubbledError" +}; +export { SpanKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export SpanKind" +}; +export { SpanStatusCode } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export SpanStatusCode" +}; +export { getTracer } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getTracer" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "isBubbledError", + ): 9, + ModuleEvaluation: 15, + Export( + "SpanKind", + ): 17, + Exports: 23, + Export( + "SpanStatusCode", + ): 19, + Export( + "BubbledError", + ): 7, + Export( + "getTracer", + ): 22, +} +``` + + +# Modules (prod) +## Part 0 +```js +const isPromise = (p)=>{ + return p !== null && typeof p === 'object' && typeof p.then === 'function'; +}; +export { isPromise } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { LogSpanAllowList } from './constants'; +export { LogSpanAllowList } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { NextVanillaSpanAllowlist } from './constants'; +export { NextVanillaSpanAllowlist } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +const clientTraceDataSetter = { + set (carrier, key, value) { + carrier.push({ + key, + value + }); + } +}; +export { clientTraceDataSetter } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +let lastSpanId = 0; +export { lastSpanId } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { lastSpanId } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const getSpanId = ()=>lastSpanId++; +export { getSpanId } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +class BubbledError extends Error { + constructor(bubble, result){ + super(); + this.bubble = bubble; + this.result = result; + } +} +export { BubbledError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { BubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { BubbledError }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { BubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +function isBubbledError(error) { + if (typeof error !== 'object' || error === null) return false; + return error instanceof BubbledError; +} +export { isBubbledError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { isBubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { isBubbledError }; + +``` +## Part 10 +```js +import './constants'; + +``` +## Part 11 +```js +let api; +export { api } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { api } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +if (process.env.NEXT_RUNTIME === 'edge') { + api = require('@opentelemetry/api'); +} else { + try { + api = require('@opentelemetry/api'); + } catch (err) { + api = require('next/dist/compiled/@opentelemetry/api'); + } +} + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { api } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +const rootSpanIdKey = api.createContextKey('next.rootSpanId'); +export { rootSpanIdKey } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +const rootSpanAttributesStore = new Map(); +export { rootSpanAttributesStore } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +"module evaluation"; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +import { api } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 11 +}; +const { context, propagation, trace, SpanStatusCode, SpanKind, ROOT_CONTEXT } = api; +export { context } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { propagation } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { trace } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { SpanStatusCode } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { SpanKind } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; +export { ROOT_CONTEXT } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { SpanKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { SpanKind as SpanKind }; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { isBubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { SpanStatusCode } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +const closeSpanWithError = (span, error)=>{ + if (isBubbledError(error) && error.bubble) { + span.setAttribute('next.bubble', true); + } else { + if (error) { + span.recordException(error); + } + span.setStatus({ + code: SpanStatusCode.ERROR, + message: error == null ? void 0 : error.message + }); + } + span.end(); +}; +export { closeSpanWithError } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { SpanStatusCode } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { SpanStatusCode as SpanStatusCode }; + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { trace } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { context } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { propagation } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { clientTraceDataSetter } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { NextVanillaSpanAllowlist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { ROOT_CONTEXT } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { getSpanId } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { rootSpanIdKey } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { rootSpanAttributesStore } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { LogSpanAllowList } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { closeSpanWithError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { isPromise } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +class NextTracerImpl { + getTracerInstance() { + return trace.getTracer('next.js', '0.0.1'); + } + getContext() { + return context; + } + getTracePropagationData() { + const activeContext = context.active(); + const entries = []; + propagation.inject(activeContext, entries, clientTraceDataSetter); + return entries; + } + getActiveScopeSpan() { + return trace.getSpan(context == null ? void 0 : context.active()); + } + withPropagatedContext(carrier, fn, getter) { + const activeContext = context.active(); + if (trace.getSpanContext(activeContext)) { + return fn(); + } + const remoteContext = propagation.extract(activeContext, carrier, getter); + return context.with(remoteContext, fn); + } + trace(...args) { + var _trace_getSpanContext; + const [type, fnOrOptions, fnOrEmpty] = args; + const { fn, options } = typeof fnOrOptions === 'function' ? { + fn: fnOrOptions, + options: {} + } : { + fn: fnOrEmpty, + options: { + ...fnOrOptions + } + }; + const spanName = options.spanName ?? type; + if (!NextVanillaSpanAllowlist.includes(type) && process.env.NEXT_OTEL_VERBOSE !== '1' || options.hideSpan) { + return fn(); + } + let spanContext = this.getSpanContext((options == null ? void 0 : options.parentSpan) ?? this.getActiveScopeSpan()); + let isRootSpan = false; + if (!spanContext) { + spanContext = (context == null ? void 0 : context.active()) ?? ROOT_CONTEXT; + isRootSpan = true; + } else if ((_trace_getSpanContext = trace.getSpanContext(spanContext)) == null ? void 0 : _trace_getSpanContext.isRemote) { + isRootSpan = true; + } + const spanId = getSpanId(); + options.attributes = { + 'next.span_name': spanName, + 'next.span_type': type, + ...options.attributes + }; + return context.with(spanContext.setValue(rootSpanIdKey, spanId), ()=>this.getTracerInstance().startActiveSpan(spanName, options, (span)=>{ + const startTime = 'performance' in globalThis && 'measure' in performance ? globalThis.performance.now() : undefined; + const onCleanup = ()=>{ + rootSpanAttributesStore.delete(spanId); + if (startTime && process.env.NEXT_OTEL_PERFORMANCE_PREFIX && LogSpanAllowList.includes(type || '')) { + performance.measure(`${process.env.NEXT_OTEL_PERFORMANCE_PREFIX}:next-${(type.split('.').pop() || '').replace(/[A-Z]/g, (match)=>'-' + match.toLowerCase())}`, { + start: startTime, + end: performance.now() + }); + } + }; + if (isRootSpan) { + rootSpanAttributesStore.set(spanId, new Map(Object.entries(options.attributes ?? {}))); + } + try { + if (fn.length > 1) { + return fn(span, (err)=>closeSpanWithError(span, err)); + } + const result = fn(span); + if (isPromise(result)) { + return result.then((res)=>{ + span.end(); + return res; + }).catch((err)=>{ + closeSpanWithError(span, err); + throw err; + }).finally(onCleanup); + } else { + span.end(); + onCleanup(); + } + return result; + } catch (err) { + closeSpanWithError(span, err); + onCleanup(); + throw err; + } + })); + } + wrap(...args) { + const tracer = this; + const [name, options, fn] = args.length === 3 ? args : [ + args[0], + {}, + args[1] + ]; + if (!NextVanillaSpanAllowlist.includes(name) && process.env.NEXT_OTEL_VERBOSE !== '1') { + return fn; + } + return function() { + let optionsObj = options; + if (typeof optionsObj === 'function' && typeof fn === 'function') { + optionsObj = optionsObj.apply(this, arguments); + } + const lastArgId = arguments.length - 1; + const cb = arguments[lastArgId]; + if (typeof cb === 'function') { + const scopeBoundCb = tracer.getContext().bind(context.active(), cb); + return tracer.trace(name, optionsObj, (_span, done)=>{ + arguments[lastArgId] = function(err) { + done == null ? void 0 : done(err); + return scopeBoundCb.apply(this, arguments); + }; + return fn.apply(this, arguments); + }); + } else { + return tracer.trace(name, optionsObj, ()=>fn.apply(this, arguments)); + } + }; + } + startSpan(...args) { + const [type, options] = args; + const spanContext = this.getSpanContext((options == null ? void 0 : options.parentSpan) ?? this.getActiveScopeSpan()); + return this.getTracerInstance().startSpan(type, options, spanContext); + } + getSpanContext(parentSpan) { + const spanContext = parentSpan ? trace.setSpan(context.active(), parentSpan) : undefined; + return spanContext; + } + getRootSpanAttributes() { + const spanId = context.active().getValue(rootSpanIdKey); + return rootSpanAttributesStore.get(spanId); + } +} +export { NextTracerImpl } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import { NextTracerImpl } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +const getTracer = (()=>{ + const tracer = new NextTracerImpl(); + return ()=>tracer; +})(); +export { getTracer } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +import { getTracer } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 21 +}; +export { getTracer as getTracer }; + +``` +## Part 23 +```js +export { BubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export BubbledError" +}; +export { isBubbledError } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export isBubbledError" +}; +export { SpanKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export SpanKind" +}; +export { SpanStatusCode } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export SpanStatusCode" +}; +export { getTracer } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getTracer" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-fetch/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-fetch/input.js new file mode 100644 index 0000000000000..dbdeaab4b2c2a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-fetch/input.js @@ -0,0 +1,9 @@ +import Stream from 'node:stream'; + +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +function fetch(){ + +} + +export default fetch; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-fetch/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-fetch/output.md new file mode 100644 index 0000000000000..1b1df3bc56c2b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-fetch/output.md @@ -0,0 +1,353 @@ +# Items + +Count: 7 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import Stream from 'node:stream'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import Stream from 'node:stream'; + +``` + +- Hoisted +- Declares: `Stream` + +## Item 3: Stmt 1, `VarDeclarator(0)` + +```js +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +``` + +- Declares: `streamDestructionSupported` +- Reads: `Stream` +- Write: `Stream`, `streamDestructionSupported` + +## Item 4: Stmt 2, `Normal` + +```js +function fetch() {} + +``` + +- Hoisted +- Declares: `fetch` +- Write: `fetch` + +## Item 5: Stmt 3, `Normal` + +```js +export default fetch; + +``` + +- Side effects +- Declares: `__TURBOPACK__default__export__` +- Reads: `fetch` +- Write: `__TURBOPACK__default__export__` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export default"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export default"]; + Item3 --> Item2; + Item5 --> Item4; + Item5 --> Item1; + Item7 --> Item5; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export default"]; + Item3 --> Item2; + Item5 --> Item4; + Item5 --> Item1; + Item7 --> Item5; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item6["ModuleEvaluation"]; + Item7; + Item7["export default"]; + Item3 --> Item2; + Item5 --> Item4; + Item5 --> Item1; + Item7 --> Item5; + Item6 --> Item1; + Item6 --> Item5; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportOfModule)]"]; + N1["Items: [ItemId(2, Normal)]"]; + N2["Items: [ItemId(3, Normal)]"]; + N3["Items: [ItemId(ModuleEvaluation)]"]; + N4["Items: [ItemId(Export(("__TURBOPACK__default__export__", #4), "default"))]"]; + N5["Items: [ItemId(0, ImportBinding(0))]"]; + N6["Items: [ItemId(1, VarDeclarator(0))]"]; + N6 --> N5; + N2 --> N1; + N2 --> N0; + N4 --> N2; + N3 --> N0; + N3 --> N2; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 3, + Export( + "default", + ): 4, + Exports: 7, +} +``` + + +# Modules (dev) +## Part 0 +```js +import 'node:stream'; + +``` +## Part 1 +```js +function fetch() {} +export { fetch } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { fetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const __TURBOPACK__default__export__ = fetch; +export { __TURBOPACK__default__export__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { __TURBOPACK__default__export__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { __TURBOPACK__default__export__ as default }; + +``` +## Part 5 +```js +import Stream from 'node:stream'; +export { Stream } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { Stream } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; +export { streamDestructionSupported } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +export { default } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export default" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 3, + Export( + "default", + ): 4, + Exports: 7, +} +``` + + +# Modules (prod) +## Part 0 +```js +import 'node:stream'; + +``` +## Part 1 +```js +function fetch() {} +export { fetch } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { fetch } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const __TURBOPACK__default__export__ = fetch; +export { __TURBOPACK__default__export__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { __TURBOPACK__default__export__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { __TURBOPACK__default__export__ as default }; + +``` +## Part 5 +```js +import Stream from 'node:stream'; +export { Stream } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { Stream } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; +export { streamDestructionSupported } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +export { default } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export default" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-globals/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-globals/input.js new file mode 100644 index 0000000000000..257842725280c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-globals/input.js @@ -0,0 +1,2 @@ +// @ts-ignore +process.turbopack = {}; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-globals/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-globals/output.md new file mode 100644 index 0000000000000..71de679c499ee --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/node-globals/output.md @@ -0,0 +1,121 @@ +# Items + +Count: 2 + +## Item 1: Stmt 0, `Normal` + +```js +process.turbopack = {}; + +``` + +- Side effects + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item2["ModuleEvaluation"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item2["ModuleEvaluation"]; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item2["ModuleEvaluation"]; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item2["ModuleEvaluation"]; + Item2 --> Item1; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, Normal)]"]; + N1["Items: [ItemId(ModuleEvaluation)]"]; + N1 --> N0; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 1, + Exports: 2, +} +``` + + +# Modules (dev) +## Part 0 +```js +process.turbopack = {}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +## Part 2 +```js + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 1, + Exports: 2, +} +``` + + +# Modules (prod) +## Part 0 +```js +process.turbopack = {}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +## Part 2 +```js + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/otel-core/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/otel-core/input.js new file mode 100644 index 0000000000000..0d99a1926bc63 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/otel-core/input.js @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { DEFAULT_ENVIRONMENT, parseEnvironment, } from '../../utils/environment'; +import { _globalThis } from './globalThis'; +/** + * Gets the environment variables + */ +export function getEnv() { + var globalEnv = parseEnvironment(_globalThis); + return Object.assign({}, DEFAULT_ENVIRONMENT, globalEnv); +} +export function getEnvWithoutDefaults() { + return parseEnvironment(_globalThis); +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/otel-core/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/otel-core/output.md new file mode 100644 index 0000000000000..4cea6db192660 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/otel-core/output.md @@ -0,0 +1,515 @@ +# Items + +Count: 10 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { DEFAULT_ENVIRONMENT, parseEnvironment } from '../../utils/environment'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { DEFAULT_ENVIRONMENT, parseEnvironment } from '../../utils/environment'; + +``` + +- Hoisted +- Declares: `DEFAULT_ENVIRONMENT` + +## Item 3: Stmt 0, `ImportBinding(1)` + +```js +import { DEFAULT_ENVIRONMENT, parseEnvironment } from '../../utils/environment'; + +``` + +- Hoisted +- Declares: `parseEnvironment` + +## Item 4: Stmt 1, `ImportOfModule` + +```js +import { _globalThis } from './globalThis'; + +``` + +- Hoisted +- Side effects + +## Item 5: Stmt 1, `ImportBinding(0)` + +```js +import { _globalThis } from './globalThis'; + +``` + +- Hoisted +- Declares: `_globalThis` + +## Item 6: Stmt 2, `Normal` + +```js +export function getEnv() { + var globalEnv = parseEnvironment(_globalThis); + return Object.assign({}, DEFAULT_ENVIRONMENT, globalEnv); +} + +``` + +- Hoisted +- Declares: `getEnv` +- Reads (eventual): `parseEnvironment`, `_globalThis`, `DEFAULT_ENVIRONMENT` +- Write: `getEnv` + +## Item 7: Stmt 3, `Normal` + +```js +export function getEnvWithoutDefaults() { + return parseEnvironment(_globalThis); +} + +``` + +- Hoisted +- Declares: `getEnvWithoutDefaults` +- Reads (eventual): `parseEnvironment`, `_globalThis` +- Write: `getEnvWithoutDefaults` + +# Phase 1 +```mermaid +graph TD + Item1; + Item3; + Item4; + Item2; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export getEnv"]; + Item10; + Item10["export getEnvWithoutDefaults"]; + Item2 --> Item1; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item3; + Item4; + Item2; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export getEnv"]; + Item10; + Item10["export getEnvWithoutDefaults"]; + Item2 --> Item1; + Item9 --> Item6; + Item10 --> Item7; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item3; + Item4; + Item2; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export getEnv"]; + Item10; + Item10["export getEnvWithoutDefaults"]; + Item2 --> Item1; + Item9 --> Item6; + Item10 --> Item7; + Item6 --> Item4; + Item6 --> Item5; + Item6 --> Item3; + Item7 --> Item4; + Item7 --> Item5; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item3; + Item4; + Item2; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export getEnv"]; + Item10; + Item10["export getEnvWithoutDefaults"]; + Item2 --> Item1; + Item9 --> Item6; + Item10 --> Item7; + Item6 --> Item4; + Item6 --> Item5; + Item6 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item8 --> Item1; + Item8 --> Item2; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportBinding(0))]"]; + N1["Items: [ItemId(1, ImportBinding(0))]"]; + N2["Items: [ItemId(0, ImportBinding(1))]"]; + N3["Items: [ItemId(3, Normal)]"]; + N4["Items: [ItemId(Export(("getEnvWithoutDefaults", #2), "getEnvWithoutDefaults"))]"]; + N5["Items: [ItemId(2, Normal)]"]; + N6["Items: [ItemId(Export(("getEnv", #2), "getEnv"))]"]; + N7["Items: [ItemId(0, ImportOfModule)]"]; + N8["Items: [ItemId(1, ImportOfModule)]"]; + N9["Items: [ItemId(ModuleEvaluation)]"]; + N8 --> N7; + N6 --> N5; + N4 --> N3; + N5 --> N2; + N5 --> N1; + N5 --> N0; + N3 --> N2; + N3 --> N1; + N9 --> N7; + N9 --> N8; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 9, + Exports: 10, + Export( + "getEnvWithoutDefaults", + ): 4, + Export( + "getEnv", + ): 6, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { DEFAULT_ENVIRONMENT } from '../../utils/environment'; +export { DEFAULT_ENVIRONMENT } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { _globalThis } from './globalThis'; +export { _globalThis } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { parseEnvironment } from '../../utils/environment'; +export { parseEnvironment } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { _globalThis } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { parseEnvironment } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function getEnvWithoutDefaults() { + return parseEnvironment(_globalThis); +} +export { getEnvWithoutDefaults } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { getEnvWithoutDefaults } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { getEnvWithoutDefaults }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { DEFAULT_ENVIRONMENT } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { parseEnvironment } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { _globalThis } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function getEnv() { + var globalEnv = parseEnvironment(_globalThis); + return Object.assign({}, DEFAULT_ENVIRONMENT, globalEnv); +} +export { getEnv } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { getEnv } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { getEnv }; + +``` +## Part 7 +```js +import '../../utils/environment'; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import './globalThis'; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 10 +```js +export { getEnvWithoutDefaults } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getEnvWithoutDefaults" +}; +export { getEnv } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getEnv" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 9, + Exports: 10, + Export( + "getEnvWithoutDefaults", + ): 4, + Export( + "getEnv", + ): 6, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { DEFAULT_ENVIRONMENT } from '../../utils/environment'; +export { DEFAULT_ENVIRONMENT } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { _globalThis } from './globalThis'; +export { _globalThis } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { parseEnvironment } from '../../utils/environment'; +export { parseEnvironment } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { _globalThis } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { parseEnvironment } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function getEnvWithoutDefaults() { + return parseEnvironment(_globalThis); +} +export { getEnvWithoutDefaults } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { getEnvWithoutDefaults } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { getEnvWithoutDefaults }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { DEFAULT_ENVIRONMENT } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { parseEnvironment } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { _globalThis } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function getEnv() { + var globalEnv = parseEnvironment(_globalThis); + return Object.assign({}, DEFAULT_ENVIRONMENT, globalEnv); +} +export { getEnv } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { getEnv } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { getEnv }; + +``` +## Part 7 +```js +import '../../utils/environment'; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import './globalThis'; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 10 +```js +export { getEnvWithoutDefaults } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getEnvWithoutDefaults" +}; +export { getEnv } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getEnv" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-handler/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-handler/input.js new file mode 100644 index 0000000000000..3fa42f80742e1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-handler/input.js @@ -0,0 +1,9 @@ +import { NextResponse } from "next/server"; + +export const GET = (req) => { + return NextResponse.json({ + pathname: req.nextUrl.pathname, + }); +}; + +export const runtime = "edge"; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-handler/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-handler/output.md new file mode 100644 index 0000000000000..6c90717a68018 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-handler/output.md @@ -0,0 +1,338 @@ +# Items + +Count: 7 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { NextResponse } from "next/server"; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { NextResponse } from "next/server"; + +``` + +- Hoisted +- Declares: `NextResponse` + +## Item 3: Stmt 1, `VarDeclarator(0)` + +```js +export const GET = (req)=>{ + return NextResponse.json({ + pathname: req.nextUrl.pathname + }); +}; + +``` + +- Declares: `GET` +- Reads: `NextResponse` +- Write: `NextResponse`, `GET` + +## Item 4: Stmt 2, `VarDeclarator(0)` + +```js +export const runtime = "edge"; + +``` + +- Declares: `runtime` +- Write: `runtime` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item5["ModuleEvaluation"]; + Item6; + Item6["export GET"]; + Item7; + Item7["export runtime"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item5["ModuleEvaluation"]; + Item6; + Item6["export GET"]; + Item7; + Item7["export runtime"]; + Item3 --> Item2; + Item6 --> Item3; + Item7 --> Item4; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item5["ModuleEvaluation"]; + Item6; + Item6["export GET"]; + Item7; + Item7["export runtime"]; + Item3 --> Item2; + Item6 --> Item3; + Item7 --> Item4; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item5["ModuleEvaluation"]; + Item6; + Item6["export GET"]; + Item7; + Item7["export runtime"]; + Item3 --> Item2; + Item6 --> Item3; + Item7 --> Item4; + Item5 --> Item1; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportOfModule)]"]; + N1["Items: [ItemId(ModuleEvaluation)]"]; + N2["Items: [ItemId(2, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("runtime", #2), "runtime"))]"]; + N4["Items: [ItemId(0, ImportBinding(0))]"]; + N5["Items: [ItemId(1, VarDeclarator(0))]"]; + N6["Items: [ItemId(Export(("GET", #2), "GET"))]"]; + N5 --> N4; + N6 --> N5; + N3 --> N2; + N1 --> N0; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 1, + Exports: 7, + Export( + "runtime", + ): 3, + Export( + "GET", + ): 6, +} +``` + + +# Modules (dev) +## Part 0 +```js +import "next/server"; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +## Part 2 +```js +const runtime = "edge"; +export { runtime } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { runtime } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { runtime }; + +``` +## Part 4 +```js +import { NextResponse } from "next/server"; +export { NextResponse } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { NextResponse } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const GET = (req)=>{ + return NextResponse.json({ + pathname: req.nextUrl.pathname + }); +}; +export { GET } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { GET } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { GET }; + +``` +## Part 7 +```js +export { runtime } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export runtime" +}; +export { GET } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export GET" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 1, + Exports: 7, + Export( + "runtime", + ): 3, + Export( + "GET", + ): 6, +} +``` + + +# Modules (prod) +## Part 0 +```js +import "next/server"; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +## Part 2 +```js +const runtime = "edge"; +export { runtime } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { runtime } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { runtime }; + +``` +## Part 4 +```js +import { NextResponse } from "next/server"; +export { NextResponse } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { NextResponse } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const GET = (req)=>{ + return NextResponse.json({ + pathname: req.nextUrl.pathname + }); +}; +export { GET } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { GET } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { GET }; + +``` +## Part 7 +```js +export { runtime } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export runtime" +}; +export { GET } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export GET" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-kind/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-kind/input.js new file mode 100644 index 0000000000000..0f94568637374 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-kind/input.js @@ -0,0 +1,19 @@ +export var RouteKind; +(function(RouteKind) { + /** + * `PAGES` represents all the React pages that are under `pages/`. + */ RouteKind["PAGES"] = "PAGES"; + /** + * `PAGES_API` represents all the API routes under `pages/api/`. + */ RouteKind["PAGES_API"] = "PAGES_API"; + /** + * `APP_PAGE` represents all the React pages that are under `app/` with the + * filename of `page.{j,t}s{,x}`. + */ RouteKind["APP_PAGE"] = "APP_PAGE"; + /** + * `APP_ROUTE` represents all the API routes and metadata routes that are under `app/` with the + * filename of `route.{j,t}s{,x}`. + */ RouteKind["APP_ROUTE"] = "APP_ROUTE"; +})(RouteKind || (RouteKind = {})); + +//# sourceMappingURL=route-kind.js.map diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-kind/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-kind/output.md new file mode 100644 index 0000000000000..a68471266fca8 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/route-kind/output.md @@ -0,0 +1,242 @@ +# Items + +Count: 4 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +export var RouteKind; + +``` + +- Declares: `RouteKind` +- Write: `RouteKind` + +## Item 2: Stmt 1, `Normal` + +```js +(function(RouteKind) { + RouteKind["PAGES"] = "PAGES"; + RouteKind["PAGES_API"] = "PAGES_API"; + RouteKind["APP_PAGE"] = "APP_PAGE"; + RouteKind["APP_ROUTE"] = "APP_ROUTE"; +})(RouteKind || (RouteKind = {})); + +``` + +- Side effects +- Reads: `RouteKind` +- Write: `RouteKind` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export RouteKind"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export RouteKind"]; + Item2 --> Item1; + Item4 --> Item2; + Item4 --> Item1; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export RouteKind"]; + Item2 --> Item1; + Item4 --> Item2; + Item4 --> Item1; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export RouteKind"]; + Item2 --> Item1; + Item4 --> Item2; + Item4 --> Item1; + Item3 --> Item2; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, VarDeclarator(0))]"]; + N1["Items: [ItemId(1, Normal)]"]; + N2["Items: [ItemId(ModuleEvaluation)]"]; + N3["Items: [ItemId(Export(("RouteKind", #2), "RouteKind"))]"]; + N1 --> N0; + N3 --> N1; + N3 --> N0; + N2 --> N1; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 2, + Export( + "RouteKind", + ): 3, + Exports: 4, +} +``` + + +# Modules (dev) +## Part 0 +```js +var RouteKind; +export { RouteKind } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +(function(RouteKind) { + RouteKind["PAGES"] = "PAGES"; + RouteKind["PAGES_API"] = "PAGES_API"; + RouteKind["APP_PAGE"] = "APP_PAGE"; + RouteKind["APP_ROUTE"] = "APP_ROUTE"; +})(RouteKind || (RouteKind = {})); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { RouteKind }; + +``` +## Part 4 +```js +export { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export RouteKind" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 2, + Export( + "RouteKind", + ): 3, + Exports: 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +var RouteKind; +export { RouteKind } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +(function(RouteKind) { + RouteKind["PAGES"] = "PAGES"; + RouteKind["PAGES_API"] = "PAGES_API"; + RouteKind["APP_PAGE"] = "APP_PAGE"; + RouteKind["APP_ROUTE"] = "APP_ROUTE"; +})(RouteKind || (RouteKind = {})); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { RouteKind }; + +``` +## Part 4 +```js +export { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export RouteKind" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-2/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-2/input.js new file mode 100644 index 0000000000000..74a6147c0837a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-2/input.js @@ -0,0 +1,9 @@ +export const order = []; + +order.push("a"); +const random = Math.random(); +const shared = { random, effect: order.push("b") }; +order.push("c"); + +export const a = { shared, a: "aaaaaaaaaaa" }; +export const b = { shared, b: "bbbbbbbbbbb" }; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-2/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-2/output.md new file mode 100644 index 0000000000000..ba32ef160ce76 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-2/output.md @@ -0,0 +1,670 @@ +# Items + +Count: 11 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +export const order = []; + +``` + +- Declares: `order` +- Write: `order` + +## Item 2: Stmt 1, `Normal` + +```js +order.push("a"); + +``` + +- Side effects +- Reads: `order` +- Write: `order` + +## Item 3: Stmt 2, `VarDeclarator(0)` + +```js +const random = Math.random(); + +``` + +- Side effects +- Declares: `random` +- Write: `random` + +## Item 4: Stmt 3, `VarDeclarator(0)` + +```js +const shared = { + random, + effect: order.push("b") +}; + +``` + +- Declares: `shared` +- Reads: `random`, `order` +- Write: `random`, `order`, `shared` + +## Item 5: Stmt 4, `Normal` + +```js +order.push("c"); + +``` + +- Side effects +- Reads: `order` +- Write: `order` + +## Item 6: Stmt 5, `VarDeclarator(0)` + +```js +export const a = { + shared, + a: "aaaaaaaaaaa" +}; + +``` + +- Declares: `a` +- Reads: `shared` +- Write: `shared`, `a` + +## Item 7: Stmt 6, `VarDeclarator(0)` + +```js +export const b = { + shared, + b: "bbbbbbbbbbb" +}; + +``` + +- Declares: `b` +- Reads: `shared` +- Write: `shared`, `b` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export a"]; + Item11; + Item11["export b"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export a"]; + Item11; + Item11["export b"]; + Item2 --> Item1; + Item3 --> Item2; + Item4 --> Item3; + Item4 --> Item2; + Item4 --> Item1; + Item5 --> Item4; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item6 --> Item4; + Item7 --> Item6; + Item7 --> Item4; + Item9 --> Item5; + Item9 --> Item1; + Item10 --> Item6; + Item11 --> Item7; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export a"]; + Item11; + Item11["export b"]; + Item2 --> Item1; + Item3 --> Item2; + Item4 --> Item3; + Item4 --> Item2; + Item4 --> Item1; + Item5 --> Item4; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item6 --> Item4; + Item7 --> Item6; + Item7 --> Item4; + Item9 --> Item5; + Item9 --> Item1; + Item10 --> Item6; + Item11 --> Item7; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export a"]; + Item11; + Item11["export b"]; + Item2 --> Item1; + Item3 --> Item2; + Item4 --> Item3; + Item4 --> Item2; + Item4 --> Item1; + Item5 --> Item4; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item6 --> Item4; + Item7 --> Item6; + Item7 --> Item4; + Item9 --> Item5; + Item9 --> Item1; + Item10 --> Item6; + Item11 --> Item7; + Item8 --> Item2; + Item8 --> Item3; + Item8 --> Item5; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, VarDeclarator(0))]"]; + N1["Items: [ItemId(1, Normal)]"]; + N2["Items: [ItemId(2, VarDeclarator(0))]"]; + N3["Items: [ItemId(3, VarDeclarator(0))]"]; + N4["Items: [ItemId(5, VarDeclarator(0))]"]; + N5["Items: [ItemId(Export(("a", #2), "a"))]"]; + N6["Items: [ItemId(6, VarDeclarator(0))]"]; + N7["Items: [ItemId(Export(("b", #2), "b"))]"]; + N8["Items: [ItemId(4, Normal)]"]; + N9["Items: [ItemId(ModuleEvaluation)]"]; + N10["Items: [ItemId(Export(("order", #2), "order"))]"]; + N1 --> N0; + N2 --> N1; + N3 --> N2; + N3 --> N1; + N3 --> N0; + N8 --> N3; + N8 --> N0; + N8 --> N1; + N8 --> N2; + N4 --> N3; + N6 --> N4; + N6 --> N3; + N10 --> N8; + N10 --> N0; + N5 --> N4; + N7 --> N6; + N9 --> N1; + N9 --> N2; + N9 --> N8; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 9, + Export( + "order", + ): 10, + Exports: 11, + Export( + "b", + ): 7, + Export( + "a", + ): 5, +} +``` + + +# Modules (dev) +## Part 0 +```js +const order = []; +export { order } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("a"); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const random = Math.random(); +export { random } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const shared = { + random, + effect: order.push("b") +}; +export { shared } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const a = { + shared, + a: "aaaaaaaaaaa" +}; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { a }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const b = { + shared, + b: "bbbbbbbbbbb" +}; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { b }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("c"); + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { order }; + +``` +## Part 11 +```js +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; +export { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export order" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 9, + Export( + "order", + ): 10, + Exports: 11, + Export( + "b", + ): 7, + Export( + "a", + ): 5, +} +``` + + +# Modules (prod) +## Part 0 +```js +const order = []; +export { order } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("a"); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const random = Math.random(); +export { random } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const shared = { + random, + effect: order.push("b") +}; +export { shared } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const a = { + shared, + a: "aaaaaaaaaaa" +}; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { a }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const b = { + shared, + b: "bbbbbbbbbbb" +}; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { b }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("c"); + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { order }; + +``` +## Part 11 +```js +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; +export { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export order" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-and-side-effects/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-and-side-effects/input.js new file mode 100644 index 0000000000000..077dd8009d6cf --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-and-side-effects/input.js @@ -0,0 +1,11 @@ +console.log("Hello"); +const value = externalFunction(); +const value2 = externalObject.propertyWithGetter; +externalObject.propertyWithSetter = 42; +const value3 = /*#__PURE__*/ externalFunction(); + +const shared = { value, value2, value3 }; +console.log(shared); + +export const a = { shared, a: "aaaaaaaaaaa" }; +export const b = { shared, b: "bbbbbbbbbbb" }; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-and-side-effects/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-and-side-effects/output.md new file mode 100644 index 0000000000000..ab65ad9fcbe22 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-and-side-effects/output.md @@ -0,0 +1,826 @@ +# Items + +Count: 12 + +## Item 1: Stmt 0, `Normal` + +```js +console.log("Hello"); + +``` + +- Side effects + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +const value = externalFunction(); + +``` + +- Side effects +- Declares: `value` +- Write: `value` + +## Item 3: Stmt 2, `VarDeclarator(0)` + +```js +const value2 = externalObject.propertyWithGetter; + +``` + +- Side effects +- Declares: `value2` +- Write: `value2` + +## Item 4: Stmt 3, `Normal` + +```js +externalObject.propertyWithSetter = 42; + +``` + +- Side effects + +## Item 5: Stmt 4, `VarDeclarator(0)` + +```js +const value3 = externalFunction(); + +``` + +- Side effects +- Declares: `value3` +- Write: `value3` + +## Item 6: Stmt 5, `VarDeclarator(0)` + +```js +const shared = { + value, + value2, + value3 +}; + +``` + +- Declares: `shared` +- Reads: `value`, `value2`, `value3` +- Write: `value`, `value2`, `value3`, `shared` + +## Item 7: Stmt 6, `Normal` + +```js +console.log(shared); + +``` + +- Side effects +- Reads: `shared` + +## Item 8: Stmt 7, `VarDeclarator(0)` + +```js +export const a = { + shared, + a: "aaaaaaaaaaa" +}; + +``` + +- Declares: `a` +- Reads: `shared` +- Write: `shared`, `a` + +## Item 9: Stmt 8, `VarDeclarator(0)` + +```js +export const b = { + shared, + b: "bbbbbbbbbbb" +}; + +``` + +- Declares: `b` +- Reads: `shared` +- Write: `shared`, `b` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item10["ModuleEvaluation"]; + Item11; + Item11["export a"]; + Item12; + Item12["export b"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item10["ModuleEvaluation"]; + Item11; + Item11["export a"]; + Item12; + Item12["export b"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item2; + Item6 --> Item3; + Item6 --> Item5; + Item7 --> Item6; + Item7 --> Item1; + Item7 --> Item2; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item8 --> Item6; + Item8 -.-> Item7; + Item9 --> Item8; + Item9 --> Item6; + Item9 -.-> Item7; + Item11 --> Item8; + Item12 --> Item9; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item10["ModuleEvaluation"]; + Item11; + Item11["export a"]; + Item12; + Item12["export b"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item2; + Item6 --> Item3; + Item6 --> Item5; + Item7 --> Item6; + Item7 --> Item1; + Item7 --> Item2; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item8 --> Item6; + Item8 -.-> Item7; + Item9 --> Item8; + Item9 --> Item6; + Item9 -.-> Item7; + Item11 --> Item8; + Item12 --> Item9; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item10["ModuleEvaluation"]; + Item11; + Item11["export a"]; + Item12; + Item12["export b"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item2; + Item6 --> Item3; + Item6 --> Item5; + Item7 --> Item6; + Item7 --> Item1; + Item7 --> Item2; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item8 --> Item6; + Item8 -.-> Item7; + Item9 --> Item8; + Item9 --> Item6; + Item9 -.-> Item7; + Item11 --> Item8; + Item12 --> Item9; + Item10 --> Item1; + Item10 --> Item2; + Item10 --> Item3; + Item10 --> Item4; + Item10 --> Item5; + Item10 --> Item7; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, Normal)]"]; + N1["Items: [ItemId(1, VarDeclarator(0))]"]; + N2["Items: [ItemId(2, VarDeclarator(0))]"]; + N3["Items: [ItemId(3, Normal)]"]; + N4["Items: [ItemId(4, VarDeclarator(0))]"]; + N5["Items: [ItemId(5, VarDeclarator(0))]"]; + N6["Items: [ItemId(6, Normal)]"]; + N7["Items: [ItemId(ModuleEvaluation)]"]; + N8["Items: [ItemId(7, VarDeclarator(0))]"]; + N9["Items: [ItemId(Export(("a", #2), "a"))]"]; + N10["Items: [ItemId(8, VarDeclarator(0))]"]; + N11["Items: [ItemId(Export(("b", #2), "b"))]"]; + N1 --> N0; + N2 --> N0; + N2 --> N1; + N3 --> N0; + N3 --> N1; + N3 --> N2; + N4 --> N0; + N4 --> N1; + N4 --> N2; + N4 --> N3; + N5 --> N1; + N5 --> N2; + N5 --> N4; + N6 --> N5; + N6 --> N0; + N6 --> N1; + N6 --> N2; + N6 --> N3; + N6 --> N4; + N8 --> N5; + N8 -.-> N6; + N10 --> N8; + N10 --> N5; + N10 -.-> N6; + N9 --> N8; + N11 --> N10; + N7 --> N0; + N7 --> N1; + N7 --> N2; + N7 --> N3; + N7 --> N4; + N7 --> N6; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 7, + Exports: 12, + Export( + "b", + ): 11, + Export( + "a", + ): 9, +} +``` + + +# Modules (dev) +## Part 0 +```js +console.log("Hello"); + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const value = externalFunction(); +export { value } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const value2 = externalObject.propertyWithGetter; +export { value2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +externalObject.propertyWithSetter = 42; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const value3 = externalFunction(); +export { value3 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { value } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { value2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { value3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const shared = { + value, + value2, + value3 +}; +export { shared } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +console.log(shared); + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +"module evaluation"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +const a = { + shared, + a: "aaaaaaaaaaa" +}; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { a }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +const b = { + shared, + b: "bbbbbbbbbbb" +}; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { b }; + +``` +## Part 12 +```js +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 11, + Exports: 12, + Export( + "b", + ): 9, + Export( + "a", + ): 7, +} +``` + + +# Modules (prod) +## Part 0 +```js +console.log("Hello"); + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const value = externalFunction(); +export { value } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const value2 = externalObject.propertyWithGetter; +export { value2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +externalObject.propertyWithSetter = 42; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const value3 = externalFunction(); +export { value3 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { value } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { value2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { value3 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const shared = { + value, + value2, + value3 +}; +export { shared } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +const a = { + shared, + a: "aaaaaaaaaaa" +}; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { a }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +const b = { + shared, + b: "bbbbbbbbbbb" +}; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { b }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +console.log(shared); + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +"module evaluation"; + +``` +## Part 12 +```js +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-regression/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-regression/input.js new file mode 100644 index 0000000000000..74a6147c0837a --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-regression/input.js @@ -0,0 +1,9 @@ +export const order = []; + +order.push("a"); +const random = Math.random(); +const shared = { random, effect: order.push("b") }; +order.push("c"); + +export const a = { shared, a: "aaaaaaaaaaa" }; +export const b = { shared, b: "bbbbbbbbbbb" }; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-regression/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-regression/output.md new file mode 100644 index 0000000000000..ba32ef160ce76 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/shared-regression/output.md @@ -0,0 +1,670 @@ +# Items + +Count: 11 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +export const order = []; + +``` + +- Declares: `order` +- Write: `order` + +## Item 2: Stmt 1, `Normal` + +```js +order.push("a"); + +``` + +- Side effects +- Reads: `order` +- Write: `order` + +## Item 3: Stmt 2, `VarDeclarator(0)` + +```js +const random = Math.random(); + +``` + +- Side effects +- Declares: `random` +- Write: `random` + +## Item 4: Stmt 3, `VarDeclarator(0)` + +```js +const shared = { + random, + effect: order.push("b") +}; + +``` + +- Declares: `shared` +- Reads: `random`, `order` +- Write: `random`, `order`, `shared` + +## Item 5: Stmt 4, `Normal` + +```js +order.push("c"); + +``` + +- Side effects +- Reads: `order` +- Write: `order` + +## Item 6: Stmt 5, `VarDeclarator(0)` + +```js +export const a = { + shared, + a: "aaaaaaaaaaa" +}; + +``` + +- Declares: `a` +- Reads: `shared` +- Write: `shared`, `a` + +## Item 7: Stmt 6, `VarDeclarator(0)` + +```js +export const b = { + shared, + b: "bbbbbbbbbbb" +}; + +``` + +- Declares: `b` +- Reads: `shared` +- Write: `shared`, `b` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export a"]; + Item11; + Item11["export b"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export a"]; + Item11; + Item11["export b"]; + Item2 --> Item1; + Item3 --> Item2; + Item4 --> Item3; + Item4 --> Item2; + Item4 --> Item1; + Item5 --> Item4; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item6 --> Item4; + Item7 --> Item6; + Item7 --> Item4; + Item9 --> Item5; + Item9 --> Item1; + Item10 --> Item6; + Item11 --> Item7; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export a"]; + Item11; + Item11["export b"]; + Item2 --> Item1; + Item3 --> Item2; + Item4 --> Item3; + Item4 --> Item2; + Item4 --> Item1; + Item5 --> Item4; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item6 --> Item4; + Item7 --> Item6; + Item7 --> Item4; + Item9 --> Item5; + Item9 --> Item1; + Item10 --> Item6; + Item11 --> Item7; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export a"]; + Item11; + Item11["export b"]; + Item2 --> Item1; + Item3 --> Item2; + Item4 --> Item3; + Item4 --> Item2; + Item4 --> Item1; + Item5 --> Item4; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item6 --> Item4; + Item7 --> Item6; + Item7 --> Item4; + Item9 --> Item5; + Item9 --> Item1; + Item10 --> Item6; + Item11 --> Item7; + Item8 --> Item2; + Item8 --> Item3; + Item8 --> Item5; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, VarDeclarator(0))]"]; + N1["Items: [ItemId(1, Normal)]"]; + N2["Items: [ItemId(2, VarDeclarator(0))]"]; + N3["Items: [ItemId(3, VarDeclarator(0))]"]; + N4["Items: [ItemId(5, VarDeclarator(0))]"]; + N5["Items: [ItemId(Export(("a", #2), "a"))]"]; + N6["Items: [ItemId(6, VarDeclarator(0))]"]; + N7["Items: [ItemId(Export(("b", #2), "b"))]"]; + N8["Items: [ItemId(4, Normal)]"]; + N9["Items: [ItemId(ModuleEvaluation)]"]; + N10["Items: [ItemId(Export(("order", #2), "order"))]"]; + N1 --> N0; + N2 --> N1; + N3 --> N2; + N3 --> N1; + N3 --> N0; + N8 --> N3; + N8 --> N0; + N8 --> N1; + N8 --> N2; + N4 --> N3; + N6 --> N4; + N6 --> N3; + N10 --> N8; + N10 --> N0; + N5 --> N4; + N7 --> N6; + N9 --> N1; + N9 --> N2; + N9 --> N8; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 9, + Export( + "order", + ): 10, + Exports: 11, + Export( + "b", + ): 7, + Export( + "a", + ): 5, +} +``` + + +# Modules (dev) +## Part 0 +```js +const order = []; +export { order } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("a"); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const random = Math.random(); +export { random } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const shared = { + random, + effect: order.push("b") +}; +export { shared } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const a = { + shared, + a: "aaaaaaaaaaa" +}; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { a }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const b = { + shared, + b: "bbbbbbbbbbb" +}; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { b }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("c"); + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { order }; + +``` +## Part 11 +```js +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; +export { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export order" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 9, + Export( + "order", + ): 10, + Exports: 11, + Export( + "b", + ): 7, + Export( + "a", + ): 5, +} +``` + + +# Modules (prod) +## Part 0 +```js +const order = []; +export { order } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("a"); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const random = Math.random(); +export { random } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { random } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const shared = { + random, + effect: order.push("b") +}; +export { shared } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const a = { + shared, + a: "aaaaaaaaaaa" +}; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { a }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const b = { + shared, + b: "bbbbbbbbbbb" +}; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { b }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("c"); + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { order }; + +``` +## Part 11 +```js +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; +export { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export order" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple-vars-1/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple-vars-1/input.js new file mode 100644 index 0000000000000..4b7aee241e63f --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple-vars-1/input.js @@ -0,0 +1,4 @@ +const a = "a"; +const b = "b"; + +export { a, b }; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple-vars-1/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple-vars-1/output.md new file mode 100644 index 0000000000000..61ba2ddeabda5 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple-vars-1/output.md @@ -0,0 +1,239 @@ +# Items + +Count: 5 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +const a = "a"; + +``` + +- Declares: `a` +- Write: `a` + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +const b = "b"; + +``` + +- Declares: `b` +- Write: `b` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export a"]; + Item5; + Item5["export b"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export a"]; + Item5; + Item5["export b"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export a"]; + Item5; + Item5["export b"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item3["ModuleEvaluation"]; + Item4; + Item4["export a"]; + Item5; + Item5["export b"]; + Item4 --> Item1; + Item5 --> Item2; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, VarDeclarator(0))]"]; + N1["Items: [ItemId(Export(("b", #2), "b"))]"]; + N2["Items: [ItemId(0, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("a", #2), "a"))]"]; + N4["Items: [ItemId(ModuleEvaluation)]"]; + N3 --> N2; + N1 --> N0; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 4, + Exports: 5, + Export( + "b", + ): 1, + Export( + "a", + ): 3, +} +``` + + +# Modules (dev) +## Part 0 +```js +const b = "b"; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { b as b }; + +``` +## Part 2 +```js +const a = "a"; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { a as a }; + +``` +## Part 4 +```js +"module evaluation"; + +``` +## Part 5 +```js +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 4, + Exports: 5, + Export( + "b", + ): 1, + Export( + "a", + ): 3, +} +``` + + +# Modules (prod) +## Part 0 +```js +const b = "b"; +export { b } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { b as b }; + +``` +## Part 2 +```js +const a = "a"; +export { a } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { a as a }; + +``` +## Part 4 +```js +"module evaluation"; + +``` +## Part 5 +```js +export { b } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export b" +}; +export { a } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export a" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple/input.js new file mode 100644 index 0000000000000..7c7ddcc1369c0 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple/input.js @@ -0,0 +1,5 @@ +const dog = "dog"; +const cat = "cat"; + +export const DOG = dog; +export const CHIMERA = cat + dog; diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple/output.md new file mode 100644 index 0000000000000..154c5d08b08ab --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/simple/output.md @@ -0,0 +1,351 @@ +# Items + +Count: 7 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +const dog = "dog"; + +``` + +- Declares: `dog` +- Write: `dog` + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +const cat = "cat"; + +``` + +- Declares: `cat` +- Write: `cat` + +## Item 3: Stmt 2, `VarDeclarator(0)` + +```js +export const DOG = dog; + +``` + +- Declares: `DOG` +- Reads: `dog` +- Write: `DOG` + +## Item 4: Stmt 3, `VarDeclarator(0)` + +```js +export const CHIMERA = cat + dog; + +``` + +- Declares: `CHIMERA` +- Reads: `cat`, `dog` +- Write: `CHIMERA` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item5["ModuleEvaluation"]; + Item6; + Item6["export DOG"]; + Item7; + Item7["export CHIMERA"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item5["ModuleEvaluation"]; + Item6; + Item6["export DOG"]; + Item7; + Item7["export CHIMERA"]; + Item3 --> Item1; + Item4 --> Item2; + Item4 --> Item1; + Item6 --> Item3; + Item7 --> Item4; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item5["ModuleEvaluation"]; + Item6; + Item6["export DOG"]; + Item7; + Item7["export CHIMERA"]; + Item3 --> Item1; + Item4 --> Item2; + Item4 --> Item1; + Item6 --> Item3; + Item7 --> Item4; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item5["ModuleEvaluation"]; + Item6; + Item6["export DOG"]; + Item7; + Item7["export CHIMERA"]; + Item3 --> Item1; + Item4 --> Item2; + Item4 --> Item1; + Item6 --> Item3; + Item7 --> Item4; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(1, VarDeclarator(0))]"]; + N1["Items: [ItemId(0, VarDeclarator(0))]"]; + N2["Items: [ItemId(3, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("CHIMERA", #2), "CHIMERA"))]"]; + N4["Items: [ItemId(2, VarDeclarator(0))]"]; + N5["Items: [ItemId(Export(("DOG", #2), "DOG"))]"]; + N6["Items: [ItemId(ModuleEvaluation)]"]; + N4 --> N1; + N2 --> N0; + N2 --> N1; + N5 --> N4; + N3 --> N2; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 6, + Exports: 7, + Export( + "CHIMERA", + ): 3, + Export( + "DOG", + ): 5, +} +``` + + +# Modules (dev) +## Part 0 +```js +const cat = "cat"; +export { cat } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +const dog = "dog"; +export { dog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const CHIMERA = cat + dog; +export { CHIMERA } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { CHIMERA } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { CHIMERA }; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const DOG = dog; +export { DOG } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { DOG } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { DOG }; + +``` +## Part 6 +```js +"module evaluation"; + +``` +## Part 7 +```js +export { CHIMERA } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export CHIMERA" +}; +export { DOG } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export DOG" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 6, + Exports: 7, + Export( + "CHIMERA", + ): 3, + Export( + "DOG", + ): 5, +} +``` + + +# Modules (prod) +## Part 0 +```js +const cat = "cat"; +export { cat } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +const dog = "dog"; +export { dog } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { cat } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const CHIMERA = cat + dog; +export { CHIMERA } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { CHIMERA } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { CHIMERA }; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { dog } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const DOG = dog; +export { DOG } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { DOG } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { DOG }; + +``` +## Part 6 +```js +"module evaluation"; + +``` +## Part 7 +```js +export { CHIMERA } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export CHIMERA" +}; +export { DOG } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export DOG" +}; + +``` +## Merged (module eval) +```js +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/template-pages/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/template-pages/input.js new file mode 100644 index 0000000000000..87093f682e655 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/template-pages/input.js @@ -0,0 +1,59 @@ +import { PagesRouteModule } from '../../server/future/route-modules/pages/module.compiled' +import { RouteKind } from '../../server/future/route-kind' +import { hoist } from './helpers' + +// Import the app and document modules. +import Document from 'VAR_MODULE_DOCUMENT' +import App from 'VAR_MODULE_APP' + +// Import the userland code. +import * as userland from 'VAR_USERLAND' + +// Re-export the component (should be the default export). +export default hoist(userland, 'default') + +// Re-export methods. +export const getStaticProps = hoist(userland, 'getStaticProps') +export const getStaticPaths = hoist(userland, 'getStaticPaths') +export const getServerSideProps = hoist(userland, 'getServerSideProps') +export const config = hoist(userland, 'config') +export const reportWebVitals = hoist(userland, 'reportWebVitals') + +// Re-export legacy methods. +export const unstable_getStaticProps = hoist( + userland, + 'unstable_getStaticProps' +) +export const unstable_getStaticPaths = hoist( + userland, + 'unstable_getStaticPaths' +) +export const unstable_getStaticParams = hoist( + userland, + 'unstable_getStaticParams' +) +export const unstable_getServerProps = hoist( + userland, + 'unstable_getServerProps' +) +export const unstable_getServerSideProps = hoist( + userland, + 'unstable_getServerSideProps' +) + +// Create and export the route module that will be consumed. +export const routeModule = new PagesRouteModule({ + definition: { + kind: RouteKind.PAGES, + page: 'VAR_DEFINITION_PAGE', + pathname: 'VAR_DEFINITION_PATHNAME', + // The following aren't used in production. + bundlePath: '', + filename: '', + }, + components: { + App, + Document, + }, + userland, +}) diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/template-pages/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/template-pages/output.md new file mode 100644 index 0000000000000..7d58120819b36 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/template-pages/output.md @@ -0,0 +1,2239 @@ +# Items + +Count: 37 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { PagesRouteModule } from '../../server/future/route-modules/pages/module.compiled'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { PagesRouteModule } from '../../server/future/route-modules/pages/module.compiled'; + +``` + +- Hoisted +- Declares: `PagesRouteModule` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import { RouteKind } from '../../server/future/route-kind'; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import { RouteKind } from '../../server/future/route-kind'; + +``` + +- Hoisted +- Declares: `RouteKind` + +## Item 5: Stmt 2, `ImportOfModule` + +```js +import { hoist } from './helpers'; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 2, `ImportBinding(0)` + +```js +import { hoist } from './helpers'; + +``` + +- Hoisted +- Declares: `hoist` + +## Item 7: Stmt 3, `ImportOfModule` + +```js +import Document from 'VAR_MODULE_DOCUMENT'; + +``` + +- Hoisted +- Side effects + +## Item 8: Stmt 3, `ImportBinding(0)` + +```js +import Document from 'VAR_MODULE_DOCUMENT'; + +``` + +- Hoisted +- Declares: `Document` + +## Item 9: Stmt 4, `ImportOfModule` + +```js +import App from 'VAR_MODULE_APP'; + +``` + +- Hoisted +- Side effects + +## Item 10: Stmt 4, `ImportBinding(0)` + +```js +import App from 'VAR_MODULE_APP'; + +``` + +- Hoisted +- Declares: `App` + +## Item 11: Stmt 5, `ImportOfModule` + +```js +import * as userland from 'VAR_USERLAND'; + +``` + +- Hoisted +- Side effects + +## Item 12: Stmt 5, `ImportBinding(0)` + +```js +import * as userland from 'VAR_USERLAND'; + +``` + +- Hoisted +- Declares: `userland` + +## Item 13: Stmt 6, `Normal` + +```js +export default hoist(userland, 'default'); + +``` + +- Side effects +- Declares: `__TURBOPACK__default__export__` +- Reads: `hoist`, `userland` +- Write: `__TURBOPACK__default__export__` + +## Item 14: Stmt 7, `VarDeclarator(0)` + +```js +export const getStaticProps = hoist(userland, 'getStaticProps'); + +``` + +- Declares: `getStaticProps` +- Reads: `hoist`, `userland` +- Write: `getStaticProps` + +## Item 15: Stmt 8, `VarDeclarator(0)` + +```js +export const getStaticPaths = hoist(userland, 'getStaticPaths'); + +``` + +- Declares: `getStaticPaths` +- Reads: `hoist`, `userland` +- Write: `getStaticPaths` + +## Item 16: Stmt 9, `VarDeclarator(0)` + +```js +export const getServerSideProps = hoist(userland, 'getServerSideProps'); + +``` + +- Declares: `getServerSideProps` +- Reads: `hoist`, `userland` +- Write: `getServerSideProps` + +## Item 17: Stmt 10, `VarDeclarator(0)` + +```js +export const config = hoist(userland, 'config'); + +``` + +- Declares: `config` +- Reads: `hoist`, `userland` +- Write: `config` + +## Item 18: Stmt 11, `VarDeclarator(0)` + +```js +export const reportWebVitals = hoist(userland, 'reportWebVitals'); + +``` + +- Declares: `reportWebVitals` +- Reads: `hoist`, `userland` +- Write: `reportWebVitals` + +## Item 19: Stmt 12, `VarDeclarator(0)` + +```js +export const unstable_getStaticProps = hoist(userland, 'unstable_getStaticProps'); + +``` + +- Declares: `unstable_getStaticProps` +- Reads: `hoist`, `userland` +- Write: `unstable_getStaticProps` + +## Item 20: Stmt 13, `VarDeclarator(0)` + +```js +export const unstable_getStaticPaths = hoist(userland, 'unstable_getStaticPaths'); + +``` + +- Declares: `unstable_getStaticPaths` +- Reads: `hoist`, `userland` +- Write: `unstable_getStaticPaths` + +## Item 21: Stmt 14, `VarDeclarator(0)` + +```js +export const unstable_getStaticParams = hoist(userland, 'unstable_getStaticParams'); + +``` + +- Declares: `unstable_getStaticParams` +- Reads: `hoist`, `userland` +- Write: `unstable_getStaticParams` + +## Item 22: Stmt 15, `VarDeclarator(0)` + +```js +export const unstable_getServerProps = hoist(userland, 'unstable_getServerProps'); + +``` + +- Declares: `unstable_getServerProps` +- Reads: `hoist`, `userland` +- Write: `unstable_getServerProps` + +## Item 23: Stmt 16, `VarDeclarator(0)` + +```js +export const unstable_getServerSideProps = hoist(userland, 'unstable_getServerSideProps'); + +``` + +- Declares: `unstable_getServerSideProps` +- Reads: `hoist`, `userland` +- Write: `unstable_getServerSideProps` + +## Item 24: Stmt 17, `VarDeclarator(0)` + +```js +export const routeModule = new PagesRouteModule({ + definition: { + kind: RouteKind.PAGES, + page: 'VAR_DEFINITION_PAGE', + pathname: 'VAR_DEFINITION_PATHNAME', + bundlePath: '', + filename: '' + }, + components: { + App, + Document + }, + userland +}); + +``` + +- Declares: `routeModule` +- Reads: `PagesRouteModule`, `RouteKind`, `App`, `Document`, `userland` +- Write: `RouteKind`, `App`, `Document`, `userland`, `routeModule` + +# Phase 1 +```mermaid +graph TD + Item1; + Item7; + Item2; + Item8; + Item3; + Item9; + Item4; + Item10; + Item5; + Item11; + Item6; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item25["ModuleEvaluation"]; + Item26; + Item26["export default"]; + Item27; + Item27["export getStaticProps"]; + Item28; + Item28["export getStaticPaths"]; + Item29; + Item29["export getServerSideProps"]; + Item30; + Item30["export config"]; + Item31; + Item31["export reportWebVitals"]; + Item32; + Item32["export unstable_getStaticProps"]; + Item33; + Item33["export unstable_getStaticPaths"]; + Item34; + Item34["export unstable_getStaticParams"]; + Item35; + Item35["export unstable_getServerProps"]; + Item36; + Item36["export unstable_getServerSideProps"]; + Item37; + Item37["export routeModule"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item1; + Item6 --> Item2; + Item6 --> Item3; + Item6 --> Item4; + Item6 --> Item5; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item7; + Item2; + Item8; + Item3; + Item9; + Item4; + Item10; + Item5; + Item11; + Item6; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item25["ModuleEvaluation"]; + Item26; + Item26["export default"]; + Item27; + Item27["export getStaticProps"]; + Item28; + Item28["export getStaticPaths"]; + Item29; + Item29["export getServerSideProps"]; + Item30; + Item30["export config"]; + Item31; + Item31["export reportWebVitals"]; + Item32; + Item32["export unstable_getStaticProps"]; + Item33; + Item33["export unstable_getStaticPaths"]; + Item34; + Item34["export unstable_getStaticParams"]; + Item35; + Item35["export unstable_getServerProps"]; + Item36; + Item36["export unstable_getServerSideProps"]; + Item37; + Item37["export routeModule"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item1; + Item6 --> Item2; + Item6 --> Item3; + Item6 --> Item4; + Item6 --> Item5; + Item13 --> Item9; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item13 --> Item6; + Item14 --> Item9; + Item14 --> Item12; + Item15 --> Item9; + Item15 --> Item12; + Item16 --> Item9; + Item16 --> Item12; + Item17 --> Item9; + Item17 --> Item12; + Item18 --> Item9; + Item18 --> Item12; + Item19 --> Item9; + Item19 --> Item12; + Item20 --> Item9; + Item20 --> Item12; + Item21 --> Item9; + Item21 --> Item12; + Item22 --> Item9; + Item22 --> Item12; + Item23 --> Item9; + Item23 --> Item12; + Item24 --> Item7; + Item24 --> Item8; + Item24 --> Item11; + Item24 --> Item10; + Item24 --> Item12; + Item24 -.-> Item13; + Item24 -.-> Item14; + Item24 -.-> Item15; + Item24 -.-> Item16; + Item24 -.-> Item17; + Item24 -.-> Item18; + Item24 -.-> Item19; + Item24 -.-> Item20; + Item24 -.-> Item21; + Item24 -.-> Item22; + Item24 -.-> Item23; + Item26 --> Item13; + Item27 --> Item14; + Item28 --> Item15; + Item29 --> Item16; + Item30 --> Item17; + Item31 --> Item18; + Item32 --> Item19; + Item33 --> Item20; + Item34 --> Item21; + Item35 --> Item22; + Item36 --> Item23; + Item37 --> Item24; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item7; + Item2; + Item8; + Item3; + Item9; + Item4; + Item10; + Item5; + Item11; + Item6; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item25["ModuleEvaluation"]; + Item26; + Item26["export default"]; + Item27; + Item27["export getStaticProps"]; + Item28; + Item28["export getStaticPaths"]; + Item29; + Item29["export getServerSideProps"]; + Item30; + Item30["export config"]; + Item31; + Item31["export reportWebVitals"]; + Item32; + Item32["export unstable_getStaticProps"]; + Item33; + Item33["export unstable_getStaticPaths"]; + Item34; + Item34["export unstable_getStaticParams"]; + Item35; + Item35["export unstable_getServerProps"]; + Item36; + Item36["export unstable_getServerSideProps"]; + Item37; + Item37["export routeModule"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item1; + Item6 --> Item2; + Item6 --> Item3; + Item6 --> Item4; + Item6 --> Item5; + Item13 --> Item9; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item13 --> Item6; + Item14 --> Item9; + Item14 --> Item12; + Item15 --> Item9; + Item15 --> Item12; + Item16 --> Item9; + Item16 --> Item12; + Item17 --> Item9; + Item17 --> Item12; + Item18 --> Item9; + Item18 --> Item12; + Item19 --> Item9; + Item19 --> Item12; + Item20 --> Item9; + Item20 --> Item12; + Item21 --> Item9; + Item21 --> Item12; + Item22 --> Item9; + Item22 --> Item12; + Item23 --> Item9; + Item23 --> Item12; + Item24 --> Item7; + Item24 --> Item8; + Item24 --> Item11; + Item24 --> Item10; + Item24 --> Item12; + Item24 -.-> Item13; + Item24 -.-> Item14; + Item24 -.-> Item15; + Item24 -.-> Item16; + Item24 -.-> Item17; + Item24 -.-> Item18; + Item24 -.-> Item19; + Item24 -.-> Item20; + Item24 -.-> Item21; + Item24 -.-> Item22; + Item24 -.-> Item23; + Item26 --> Item13; + Item27 --> Item14; + Item28 --> Item15; + Item29 --> Item16; + Item30 --> Item17; + Item31 --> Item18; + Item32 --> Item19; + Item33 --> Item20; + Item34 --> Item21; + Item35 --> Item22; + Item36 --> Item23; + Item37 --> Item24; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item7; + Item2; + Item8; + Item3; + Item9; + Item4; + Item10; + Item5; + Item11; + Item6; + Item12; + Item13; + Item14; + Item15; + Item16; + Item17; + Item18; + Item19; + Item20; + Item21; + Item22; + Item23; + Item24; + Item25; + Item25["ModuleEvaluation"]; + Item26; + Item26["export default"]; + Item27; + Item27["export getStaticProps"]; + Item28; + Item28["export getStaticPaths"]; + Item29; + Item29["export getServerSideProps"]; + Item30; + Item30["export config"]; + Item31; + Item31["export reportWebVitals"]; + Item32; + Item32["export unstable_getStaticProps"]; + Item33; + Item33["export unstable_getStaticPaths"]; + Item34; + Item34["export unstable_getStaticParams"]; + Item35; + Item35["export unstable_getServerProps"]; + Item36; + Item36["export unstable_getServerSideProps"]; + Item37; + Item37["export routeModule"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item4 --> Item1; + Item4 --> Item2; + Item4 --> Item3; + Item5 --> Item1; + Item5 --> Item2; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item1; + Item6 --> Item2; + Item6 --> Item3; + Item6 --> Item4; + Item6 --> Item5; + Item13 --> Item9; + Item13 --> Item12; + Item13 --> Item1; + Item13 --> Item2; + Item13 --> Item3; + Item13 --> Item4; + Item13 --> Item5; + Item13 --> Item6; + Item14 --> Item9; + Item14 --> Item12; + Item15 --> Item9; + Item15 --> Item12; + Item16 --> Item9; + Item16 --> Item12; + Item17 --> Item9; + Item17 --> Item12; + Item18 --> Item9; + Item18 --> Item12; + Item19 --> Item9; + Item19 --> Item12; + Item20 --> Item9; + Item20 --> Item12; + Item21 --> Item9; + Item21 --> Item12; + Item22 --> Item9; + Item22 --> Item12; + Item23 --> Item9; + Item23 --> Item12; + Item24 --> Item7; + Item24 --> Item8; + Item24 --> Item11; + Item24 --> Item10; + Item24 --> Item12; + Item24 -.-> Item13; + Item24 -.-> Item14; + Item24 -.-> Item15; + Item24 -.-> Item16; + Item24 -.-> Item17; + Item24 -.-> Item18; + Item24 -.-> Item19; + Item24 -.-> Item20; + Item24 -.-> Item21; + Item24 -.-> Item22; + Item24 -.-> Item23; + Item26 --> Item13; + Item27 --> Item14; + Item28 --> Item15; + Item29 --> Item16; + Item30 --> Item17; + Item31 --> Item18; + Item32 --> Item19; + Item33 --> Item20; + Item34 --> Item21; + Item35 --> Item22; + Item36 --> Item23; + Item37 --> Item24; + Item25 --> Item1; + Item25 --> Item2; + Item25 --> Item3; + Item25 --> Item4; + Item25 --> Item5; + Item25 --> Item6; + Item25 --> Item13; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(3, ImportBinding(0))]"]; + N1["Items: [ItemId(4, ImportBinding(0))]"]; + N2["Items: [ItemId(1, ImportBinding(0))]"]; + N3["Items: [ItemId(0, ImportBinding(0))]"]; + N4["Items: [ItemId(5, ImportBinding(0))]"]; + N5["Items: [ItemId(2, ImportBinding(0))]"]; + N6["Items: [ItemId(16, VarDeclarator(0))]"]; + N7["Items: [ItemId(Export(("unstable_getServerSideProps", #2), "unstable_getServerSideProps"))]"]; + N8["Items: [ItemId(15, VarDeclarator(0))]"]; + N9["Items: [ItemId(Export(("unstable_getServerProps", #2), "unstable_getServerProps"))]"]; + N10["Items: [ItemId(14, VarDeclarator(0))]"]; + N11["Items: [ItemId(Export(("unstable_getStaticParams", #2), "unstable_getStaticParams"))]"]; + N12["Items: [ItemId(13, VarDeclarator(0))]"]; + N13["Items: [ItemId(Export(("unstable_getStaticPaths", #2), "unstable_getStaticPaths"))]"]; + N14["Items: [ItemId(12, VarDeclarator(0))]"]; + N15["Items: [ItemId(Export(("unstable_getStaticProps", #2), "unstable_getStaticProps"))]"]; + N16["Items: [ItemId(11, VarDeclarator(0))]"]; + N17["Items: [ItemId(Export(("reportWebVitals", #2), "reportWebVitals"))]"]; + N18["Items: [ItemId(10, VarDeclarator(0))]"]; + N19["Items: [ItemId(Export(("config", #2), "config"))]"]; + N20["Items: [ItemId(9, VarDeclarator(0))]"]; + N21["Items: [ItemId(Export(("getServerSideProps", #2), "getServerSideProps"))]"]; + N22["Items: [ItemId(8, VarDeclarator(0))]"]; + N23["Items: [ItemId(Export(("getStaticPaths", #2), "getStaticPaths"))]"]; + N24["Items: [ItemId(7, VarDeclarator(0))]"]; + N25["Items: [ItemId(Export(("getStaticProps", #2), "getStaticProps"))]"]; + N26["Items: [ItemId(0, ImportOfModule)]"]; + N27["Items: [ItemId(1, ImportOfModule)]"]; + N28["Items: [ItemId(2, ImportOfModule)]"]; + N29["Items: [ItemId(3, ImportOfModule)]"]; + N30["Items: [ItemId(4, ImportOfModule)]"]; + N31["Items: [ItemId(5, ImportOfModule)]"]; + N32["Items: [ItemId(6, Normal)]"]; + N33["Items: [ItemId(ModuleEvaluation)]"]; + N34["Items: [ItemId(Export(("__TURBOPACK__default__export__", #3), "default"))]"]; + N35["Items: [ItemId(17, VarDeclarator(0))]"]; + N36["Items: [ItemId(Export(("routeModule", #2), "routeModule"))]"]; + N27 --> N26; + N28 --> N26; + N28 --> N27; + N29 --> N26; + N29 --> N27; + N29 --> N28; + N30 --> N26; + N30 --> N27; + N30 --> N28; + N30 --> N29; + N31 --> N26; + N31 --> N27; + N31 --> N28; + N31 --> N29; + N31 --> N30; + N32 --> N5; + N32 --> N4; + N32 --> N26; + N32 --> N27; + N32 --> N28; + N32 --> N29; + N32 --> N30; + N32 --> N31; + N24 --> N5; + N24 --> N4; + N22 --> N5; + N22 --> N4; + N20 --> N5; + N20 --> N4; + N18 --> N5; + N18 --> N4; + N16 --> N5; + N16 --> N4; + N14 --> N5; + N14 --> N4; + N12 --> N5; + N12 --> N4; + N10 --> N5; + N10 --> N4; + N8 --> N5; + N8 --> N4; + N6 --> N5; + N6 --> N4; + N35 --> N3; + N35 --> N2; + N35 --> N1; + N35 --> N0; + N35 --> N4; + N35 -.-> N32; + N35 -.-> N24; + N35 -.-> N22; + N35 -.-> N20; + N35 -.-> N18; + N35 -.-> N16; + N35 -.-> N14; + N35 -.-> N12; + N35 -.-> N10; + N35 -.-> N8; + N35 -.-> N6; + N34 --> N32; + N25 --> N24; + N23 --> N22; + N21 --> N20; + N19 --> N18; + N17 --> N16; + N15 --> N14; + N13 --> N12; + N11 --> N10; + N9 --> N8; + N7 --> N6; + N36 --> N35; + N33 --> N26; + N33 --> N27; + N33 --> N28; + N33 --> N29; + N33 --> N30; + N33 --> N31; + N33 --> N32; +``` +# Entrypoints + +``` +{ + Export( + "unstable_getServerSideProps", + ): 7, + ModuleEvaluation: 33, + Export( + "default", + ): 34, + Export( + "unstable_getServerProps", + ): 9, + Export( + "reportWebVitals", + ): 17, + Export( + "routeModule", + ): 36, + Export( + "unstable_getStaticParams", + ): 11, + Export( + "config", + ): 19, + Export( + "getStaticProps", + ): 25, + Export( + "unstable_getStaticProps", + ): 15, + Exports: 37, + Export( + "unstable_getStaticPaths", + ): 13, + Export( + "getServerSideProps", + ): 21, + Export( + "getStaticPaths", + ): 23, +} +``` + + +# Modules (dev) +## Part 0 +```js +import Document from 'VAR_MODULE_DOCUMENT'; +export { Document } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import App from 'VAR_MODULE_APP'; +export { App } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { RouteKind } from '../../server/future/route-kind'; +export { RouteKind } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import { PagesRouteModule } from '../../server/future/route-modules/pages/module.compiled'; +export { PagesRouteModule } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import * as userland from 'VAR_USERLAND'; +export { userland } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import { hoist } from './helpers'; +export { hoist } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getServerSideProps = hoist(userland, 'unstable_getServerSideProps'); +export { unstable_getServerSideProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { unstable_getServerSideProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +export { unstable_getServerSideProps }; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getServerProps = hoist(userland, 'unstable_getServerProps'); +export { unstable_getServerProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { unstable_getServerProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { unstable_getServerProps }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getStaticParams = hoist(userland, 'unstable_getStaticParams'); +export { unstable_getStaticParams } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { unstable_getStaticParams } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { unstable_getStaticParams }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getStaticPaths = hoist(userland, 'unstable_getStaticPaths'); +export { unstable_getStaticPaths } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { unstable_getStaticPaths } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { unstable_getStaticPaths }; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getStaticProps = hoist(userland, 'unstable_getStaticProps'); +export { unstable_getStaticProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { unstable_getStaticProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +export { unstable_getStaticProps }; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const reportWebVitals = hoist(userland, 'reportWebVitals'); +export { reportWebVitals } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { reportWebVitals } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { reportWebVitals }; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const config = hoist(userland, 'config'); +export { config } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { config } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +export { config }; + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const getServerSideProps = hoist(userland, 'getServerSideProps'); +export { getServerSideProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import { getServerSideProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +export { getServerSideProps }; + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const getStaticPaths = hoist(userland, 'getStaticPaths'); +export { getStaticPaths } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 23 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { getStaticPaths } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +export { getStaticPaths }; + +``` +## Part 24 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const getStaticProps = hoist(userland, 'getStaticProps'); +export { getStaticProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import { getStaticProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +export { getStaticProps }; + +``` +## Part 26 +```js +import '../../server/future/route-modules/pages/module.compiled'; + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import '../../server/future/route-kind'; + +``` +## Part 28 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import './helpers'; + +``` +## Part 29 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import 'VAR_MODULE_DOCUMENT'; + +``` +## Part 30 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import 'VAR_MODULE_APP'; + +``` +## Part 31 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import 'VAR_USERLAND'; + +``` +## Part 32 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const __TURBOPACK__default__export__ = hoist(userland, 'default'); +export { __TURBOPACK__default__export__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 33 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +"module evaluation"; + +``` +## Part 34 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import { __TURBOPACK__default__export__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +export { __TURBOPACK__default__export__ as default }; + +``` +## Part 35 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import { PagesRouteModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { App } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { Document } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const routeModule = new PagesRouteModule({ + definition: { + kind: RouteKind.PAGES, + page: 'VAR_DEFINITION_PAGE', + pathname: 'VAR_DEFINITION_PATHNAME', + bundlePath: '', + filename: '' + }, + components: { + App, + Document + }, + userland +}); +export { routeModule } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 36 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 35 +}; +import { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 35 +}; +export { routeModule }; + +``` +## Part 37 +```js +export { unstable_getServerSideProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getServerSideProps" +}; +export { unstable_getServerProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getServerProps" +}; +export { unstable_getStaticParams } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getStaticParams" +}; +export { unstable_getStaticPaths } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getStaticPaths" +}; +export { unstable_getStaticProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getStaticProps" +}; +export { reportWebVitals } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export reportWebVitals" +}; +export { config } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export config" +}; +export { getServerSideProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getServerSideProps" +}; +export { getStaticPaths } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getStaticPaths" +}; +export { getStaticProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getStaticProps" +}; +export { default } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export default" +}; +export { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export routeModule" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 27 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + Export( + "unstable_getServerSideProps", + ): 9, + Export( + "default", + ): 35, + ModuleEvaluation: 36, + Export( + "unstable_getServerProps", + ): 11, + Export( + "reportWebVitals", + ): 19, + Export( + "routeModule", + ): 6, + Export( + "unstable_getStaticParams", + ): 13, + Export( + "config", + ): 21, + Export( + "getStaticProps", + ): 27, + Export( + "unstable_getStaticProps", + ): 17, + Exports: 37, + Export( + "unstable_getStaticPaths", + ): 15, + Export( + "getServerSideProps", + ): 23, + Export( + "getStaticPaths", + ): 25, +} +``` + + +# Modules (prod) +## Part 0 +```js +import Document from 'VAR_MODULE_DOCUMENT'; +export { Document } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import App from 'VAR_MODULE_APP'; +export { App } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { RouteKind } from '../../server/future/route-kind'; +export { RouteKind } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import { PagesRouteModule } from '../../server/future/route-modules/pages/module.compiled'; +export { PagesRouteModule } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import * as userland from 'VAR_USERLAND'; +export { userland } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { PagesRouteModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { RouteKind } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { App } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { Document } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const routeModule = new PagesRouteModule({ + definition: { + kind: RouteKind.PAGES, + page: 'VAR_DEFINITION_PAGE', + pathname: 'VAR_DEFINITION_PATHNAME', + bundlePath: '', + filename: '' + }, + components: { + App, + Document + }, + userland +}); +export { routeModule } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +export { routeModule }; + +``` +## Part 7 +```js +import { hoist } from './helpers'; +export { hoist } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getServerSideProps = hoist(userland, 'unstable_getServerSideProps'); +export { unstable_getServerSideProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { unstable_getServerSideProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { unstable_getServerSideProps }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getServerProps = hoist(userland, 'unstable_getServerProps'); +export { unstable_getServerProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { unstable_getServerProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { unstable_getServerProps }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getStaticParams = hoist(userland, 'unstable_getStaticParams'); +export { unstable_getStaticParams } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { unstable_getStaticParams } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +export { unstable_getStaticParams }; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getStaticPaths = hoist(userland, 'unstable_getStaticPaths'); +export { unstable_getStaticPaths } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import { unstable_getStaticPaths } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +export { unstable_getStaticPaths }; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const unstable_getStaticProps = hoist(userland, 'unstable_getStaticProps'); +export { unstable_getStaticProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { unstable_getStaticProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { unstable_getStaticProps }; + +``` +## Part 18 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const reportWebVitals = hoist(userland, 'reportWebVitals'); +export { reportWebVitals } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 19 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +import { reportWebVitals } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 18 +}; +export { reportWebVitals }; + +``` +## Part 20 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const config = hoist(userland, 'config'); +export { config } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 21 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +import { config } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 20 +}; +export { config }; + +``` +## Part 22 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const getServerSideProps = hoist(userland, 'getServerSideProps'); +export { getServerSideProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 23 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +import { getServerSideProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 22 +}; +export { getServerSideProps }; + +``` +## Part 24 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const getStaticPaths = hoist(userland, 'getStaticPaths'); +export { getStaticPaths } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 25 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +import { getStaticPaths } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 24 +}; +export { getStaticPaths }; + +``` +## Part 26 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const getStaticProps = hoist(userland, 'getStaticProps'); +export { getStaticProps } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 27 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +import { getStaticProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 26 +}; +export { getStaticProps }; + +``` +## Part 28 +```js +import '../../server/future/route-modules/pages/module.compiled'; + +``` +## Part 29 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import '../../server/future/route-kind'; + +``` +## Part 30 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import './helpers'; + +``` +## Part 31 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import 'VAR_MODULE_DOCUMENT'; + +``` +## Part 32 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import 'VAR_MODULE_APP'; + +``` +## Part 33 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import 'VAR_USERLAND'; + +``` +## Part 34 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import { hoist } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { userland } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const __TURBOPACK__default__export__ = hoist(userland, 'default'); +export { __TURBOPACK__default__export__ } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 35 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import { __TURBOPACK__default__export__ } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +export { __TURBOPACK__default__export__ as default }; + +``` +## Part 36 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +"module evaluation"; + +``` +## Part 37 +```js +export { routeModule } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export routeModule" +}; +export { unstable_getServerSideProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getServerSideProps" +}; +export { unstable_getServerProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getServerProps" +}; +export { unstable_getStaticParams } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getStaticParams" +}; +export { unstable_getStaticPaths } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getStaticPaths" +}; +export { unstable_getStaticProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export unstable_getStaticProps" +}; +export { reportWebVitals } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export reportWebVitals" +}; +export { config } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export config" +}; +export { getServerSideProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getServerSideProps" +}; +export { getStaticPaths } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getStaticPaths" +}; +export { getStaticProps } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export getStaticProps" +}; +export { default } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export default" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 34 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 33 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 32 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 31 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 30 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 29 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 28 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/config.json b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/config.json new file mode 100644 index 0000000000000..f40e04e58357c --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/config.json @@ -0,0 +1,6 @@ +{ + "exports":[ + ["external1"], + ["external1", "external2"] + ] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/input.js new file mode 100644 index 0000000000000..573d14eb90927 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/input.js @@ -0,0 +1,18 @@ +import { upper } from "module"; +export let foobar = "foo"; +export const foo = foobar; +const bar = "bar"; +foobar += bar; +let foobarCopy = foobar; +foobar += "foo"; +console.log(foobarCopy); +foobarCopy += "Unused"; +function internal() { + return upper(foobar); +} +export function external1() { + return internal() + foobar; +} +export function external2() { + foobar += "."; +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/output.md new file mode 100644 index 0000000000000..21c3aef7db07b --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/test-config-1/output.md @@ -0,0 +1,1081 @@ +# Items + +Count: 18 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { upper } from "module"; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { upper } from "module"; + +``` + +- Hoisted +- Declares: `upper` + +## Item 3: Stmt 1, `VarDeclarator(0)` + +```js +export let foobar = "foo"; + +``` + +- Declares: `foobar` +- Write: `foobar` + +## Item 4: Stmt 2, `VarDeclarator(0)` + +```js +export const foo = foobar; + +``` + +- Declares: `foo` +- Reads: `foobar` +- Write: `foo` + +## Item 5: Stmt 3, `VarDeclarator(0)` + +```js +const bar = "bar"; + +``` + +- Declares: `bar` +- Write: `bar` + +## Item 6: Stmt 4, `Normal` + +```js +foobar += bar; + +``` + +- Reads: `bar`, `foobar` +- Write: `foobar` + +## Item 7: Stmt 5, `VarDeclarator(0)` + +```js +let foobarCopy = foobar; + +``` + +- Declares: `foobarCopy` +- Reads: `foobar` +- Write: `foobarCopy` + +## Item 8: Stmt 6, `Normal` + +```js +foobar += "foo"; + +``` + +- Reads: `foobar` +- Write: `foobar` + +## Item 9: Stmt 7, `Normal` + +```js +console.log(foobarCopy); + +``` + +- Side effects +- Reads: `foobarCopy` + +## Item 10: Stmt 8, `Normal` + +```js +foobarCopy += "Unused"; + +``` + +- Reads: `foobarCopy` +- Write: `foobarCopy` + +## Item 11: Stmt 9, `Normal` + +```js +function internal() { + return upper(foobar); +} + +``` + +- Hoisted +- Declares: `internal` +- Reads (eventual): `upper`, `foobar` +- Write: `internal` + +## Item 12: Stmt 10, `Normal` + +```js +export function external1() { + return internal() + foobar; +} + +``` + +- Hoisted +- Declares: `external1` +- Reads (eventual): `internal`, `foobar` +- Write: `external1` + +## Item 13: Stmt 11, `Normal` + +```js +export function external2() { + foobar += "."; +} + +``` + +- Hoisted +- Declares: `external2` +- Write: `external2` +- Write (eventual): `foobar` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export foobar"]; + Item16; + Item16["export foo"]; + Item17; + Item17["export external1"]; + Item18; + Item18["export external2"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export foobar"]; + Item16; + Item16["export foo"]; + Item17; + Item17["export external1"]; + Item18; + Item18["export external2"]; + Item4 --> Item3; + Item6 --> Item5; + Item6 --> Item3; + Item6 -.-> Item4; + Item7 --> Item6; + Item7 --> Item3; + Item8 --> Item6; + Item8 --> Item3; + Item8 -.-> Item4; + Item8 -.-> Item7; + Item9 --> Item7; + Item9 --> Item1; + Item9 -.-> Item2; + Item9 -.-> Item8; + Item9 -.-> Item4; + Item9 -.-> Item11; + Item10 --> Item7; + Item10 -.-> Item9; + Item15 --> Item8; + Item15 --> Item3; + Item16 --> Item4; + Item17 --> Item12; + Item18 --> Item13; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export foobar"]; + Item16; + Item16["export foo"]; + Item17; + Item17["export external1"]; + Item18; + Item18["export external2"]; + Item4 --> Item3; + Item6 --> Item5; + Item6 --> Item3; + Item6 -.-> Item4; + Item7 --> Item6; + Item7 --> Item3; + Item8 --> Item6; + Item8 --> Item3; + Item8 -.-> Item4; + Item8 -.-> Item7; + Item9 --> Item7; + Item9 --> Item1; + Item9 -.-> Item2; + Item9 -.-> Item8; + Item9 -.-> Item4; + Item9 -.-> Item11; + Item10 --> Item7; + Item10 -.-> Item9; + Item15 --> Item8; + Item15 --> Item3; + Item16 --> Item4; + Item17 --> Item12; + Item18 --> Item13; + Item11 --> Item2; + Item11 --> Item8; + Item11 --> Item3; + Item12 --> Item11; + Item12 --> Item8; + Item12 --> Item3; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item13 -.-> Item15; + Item13 --> Item3; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item9; + Item10; + Item11; + Item12; + Item13; + Item14; + Item14["ModuleEvaluation"]; + Item15; + Item15["export foobar"]; + Item16; + Item16["export foo"]; + Item17; + Item17["export external1"]; + Item18; + Item18["export external2"]; + Item4 --> Item3; + Item6 --> Item5; + Item6 --> Item3; + Item6 -.-> Item4; + Item7 --> Item6; + Item7 --> Item3; + Item8 --> Item6; + Item8 --> Item3; + Item8 -.-> Item4; + Item8 -.-> Item7; + Item9 --> Item7; + Item9 --> Item1; + Item9 -.-> Item2; + Item9 -.-> Item8; + Item9 -.-> Item4; + Item9 -.-> Item11; + Item10 --> Item7; + Item10 -.-> Item9; + Item15 --> Item8; + Item15 --> Item3; + Item16 --> Item4; + Item17 --> Item12; + Item18 --> Item13; + Item11 --> Item2; + Item11 --> Item8; + Item11 --> Item3; + Item12 --> Item11; + Item12 --> Item8; + Item12 --> Item3; + Item13 -.-> Item4; + Item13 -.-> Item7; + Item13 -.-> Item15; + Item13 --> Item3; + Item14 --> Item1; + Item14 --> Item9; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, ImportBinding(0))]"]; + N1["Items: [ItemId(0, ImportOfModule)]"]; + N2["Items: [ItemId(3, VarDeclarator(0))]"]; + N3["Items: [ItemId(1, VarDeclarator(0))]"]; + N4["Items: [ItemId(2, VarDeclarator(0))]"]; + N5["Items: [ItemId(Export(("foo", #2), "foo"))]"]; + N6["Items: [ItemId(4, Normal)]"]; + N7["Items: [ItemId(5, VarDeclarator(0))]"]; + N8["Items: [ItemId(6, Normal)]"]; + N9["Items: [ItemId(9, Normal)]"]; + N10["Items: [ItemId(10, Normal)]"]; + N11["Items: [ItemId(Export(("external1", #2), "external1"))]"]; + N12["Items: [ItemId(Export(("foobar", #2), "foobar"))]"]; + N13["Items: [ItemId(11, Normal)]"]; + N14["Items: [ItemId(Export(("external2", #2), "external2"))]"]; + N15["Items: [ItemId(7, Normal)]"]; + N16["Items: [ItemId(ModuleEvaluation)]"]; + N17["Items: [ItemId(8, Normal)]"]; + N4 --> N3; + N6 --> N2; + N6 --> N3; + N6 -.-> N4; + N7 --> N6; + N7 --> N3; + N8 --> N6; + N8 --> N3; + N8 -.-> N4; + N8 -.-> N7; + N15 --> N7; + N15 --> N1; + N15 -.-> N0; + N15 -.-> N8; + N15 -.-> N4; + N15 -.-> N9; + N17 --> N7; + N17 -.-> N15; + N12 --> N8; + N12 --> N3; + N5 --> N4; + N11 --> N10; + N14 --> N13; + N9 --> N0; + N9 --> N8; + N9 --> N3; + N10 --> N9; + N10 --> N8; + N10 --> N3; + N13 -.-> N4; + N13 -.-> N7; + N13 -.-> N12; + N13 --> N3; + N16 --> N1; + N16 --> N15; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 16, + Export( + "external1", + ): 11, + Exports: 18, + Export( + "foo", + ): 5, + Export( + "foobar", + ): 12, + Export( + "external2", + ): 14, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { upper } from "module"; +export { upper } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "module"; + +``` +## Part 2 +```js +const bar = "bar"; +export { bar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +let foobar = "foo"; +export { foobar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const foo = foobar; +export { foo } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { foo }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { bar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +foobar += bar; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +let foobarCopy = foobar; +export { foobarCopy } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +foobar += "foo"; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { upper } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function internal() { + return upper(foobar); +} +export { internal } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { internal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +function external1() { + return internal() + foobar; +} +export { external1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { external1 }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { foobar }; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +function external2() { + foobar += "."; +} +export { external2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +import { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 13 +}; +export { external2 }; + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +console.log(foobarCopy); + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +"module evaluation"; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +foobarCopy += "Unused"; + +``` +## Part 18 +```js +export { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foo" +}; +export { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external1" +}; +export { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foobar" +}; +export { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external2" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 15 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 15, + Export( + "external1", + ): 11, + Exports: 18, + Export( + "foo", + ): 17, + Export( + "foobar", + ): 8, + Export( + "external2", + ): 5, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { upper } from "module"; +export { upper } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "module"; + +``` +## Part 2 +```js +const bar = "bar"; +export { bar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +let foobar = "foo"; +export { foobar } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +function external2() { + foobar += "."; +} +export { external2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { external2 }; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { bar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +foobar += bar; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +foobar += "foo"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { foobar }; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { upper } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function internal() { + return upper(foobar); +} +export { internal } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { internal } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +function external1() { + return internal() + foobar; +} +export { external1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 11 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { external1 }; + +``` +## Part 12 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +let foobarCopy = foobar; +export { foobarCopy } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 13 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +foobarCopy += "Unused"; + +``` +## Part 14 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import { foobarCopy } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 12 +}; +console.log(foobarCopy); + +``` +## Part 15 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +## Part 16 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +const foo = foobar; +export { foo } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 17 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +import { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 16 +}; +export { foo }; + +``` +## Part 18 +```js +export { external2 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external2" +}; +export { foobar } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foobar" +}; +export { external1 } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export external1" +}; +export { foo } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export foo" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 14 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 15, + Export( + "external1", + ): 11, + Exports: 18, + Export( + "foo", + ): 17, + Export( + "foobar", + ): 8, + Export( + "external2", + ): 5, +} +``` + + +## Merged (external1) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +export { external1 }; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 15, + Export( + "external1", + ): 11, + Exports: 18, + Export( + "foo", + ): 17, + Export( + "foobar", + ): 8, + Export( + "external2", + ): 5, +} +``` + + +## Merged (external1,external2) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 10 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { external1 }; +export { external2 }; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/tla-1/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/tla-1/input.js new file mode 100644 index 0000000000000..de355e58250b1 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/tla-1/input.js @@ -0,0 +1,7 @@ +await Promise.resolve(); + +export const effects = []; + +export function effect(name) { + effects.push(name); +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/tla-1/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/tla-1/output.md new file mode 100644 index 0000000000000..b0379dd7c18db --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/tla-1/output.md @@ -0,0 +1,307 @@ +# Items + +Count: 6 + +## Item 1: Stmt 0, `Normal` + +```js +await Promise.resolve(); + +``` + +- Side effects + +## Item 2: Stmt 1, `VarDeclarator(0)` + +```js +export const effects = []; + +``` + +- Declares: `effects` +- Write: `effects` + +## Item 3: Stmt 2, `Normal` + +```js +export function effect(name) { + effects.push(name); +} + +``` + +- Hoisted +- Declares: `effect` +- Reads (eventual): `effects` +- Write: `effect` +- Write (eventual): `effects` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item5; + Item5["export effects"]; + Item6; + Item6["export effect"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item5; + Item5["export effects"]; + Item6; + Item6["export effect"]; + Item5 --> Item2; + Item6 --> Item3; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item5; + Item5["export effects"]; + Item6; + Item6["export effect"]; + Item5 --> Item2; + Item6 --> Item3; + Item3 --> Item2; + Item3 -.-> Item5; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item4["ModuleEvaluation"]; + Item5; + Item5["export effects"]; + Item6; + Item6["export effect"]; + Item5 --> Item2; + Item6 --> Item3; + Item3 --> Item2; + Item3 -.-> Item5; + Item4 --> Item1; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, Normal)]"]; + N1["Items: [ItemId(ModuleEvaluation)]"]; + N2["Items: [ItemId(1, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("effects", #2), "effects"))]"]; + N4["Items: [ItemId(2, Normal)]"]; + N5["Items: [ItemId(Export(("effect", #2), "effect"))]"]; + N3 --> N2; + N5 --> N4; + N4 --> N2; + N4 -.-> N3; + N1 --> N0; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 1, + Export( + "effect", + ): 5, + Exports: 6, + Export( + "effects", + ): 3, +} +``` + + +# Modules (dev) +## Part 0 +```js +await Promise.resolve(); + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +## Part 2 +```js +const effects = []; +export { effects } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { effects } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { effects }; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { effects } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function effect(name) { + effects.push(name); +} +export { effect } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import { effect } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +export { effect }; + +``` +## Part 6 +```js +export { effects } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export effects" +}; +export { effect } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export effect" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 1, + Export( + "effect", + ): 4, + Exports: 6, + Export( + "effects", + ): 5, +} +``` + + +# Modules (prod) +## Part 0 +```js +await Promise.resolve(); + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` +## Part 2 +```js +const effects = []; +export { effects } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { effects } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +function effect(name) { + effects.push(name); +} +export { effect } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { effect } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { effect }; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { effects } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { effects }; + +``` +## Part 6 +```js +export { effect } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export effect" +}; +export { effects } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export effects" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/typeof-1/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/typeof-1/input.js new file mode 100644 index 0000000000000..fd7505a005999 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/typeof-1/input.js @@ -0,0 +1,10 @@ +import { NextResponse } from 'next/server' +import { ClientComponent } from '../../ClientComponent' +import { MyModuleClientComponent } from 'my-module/MyModuleClientComponent' + +export function GET() { + return NextResponse.json({ + clientComponent: typeof ClientComponent, + myModuleClientComponent: typeof MyModuleClientComponent, + }) +} diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/typeof-1/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/typeof-1/output.md new file mode 100644 index 0000000000000..8026566746197 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/typeof-1/output.md @@ -0,0 +1,467 @@ +# Items + +Count: 9 + +## Item 1: Stmt 0, `ImportOfModule` + +```js +import { NextResponse } from 'next/server'; + +``` + +- Hoisted +- Side effects + +## Item 2: Stmt 0, `ImportBinding(0)` + +```js +import { NextResponse } from 'next/server'; + +``` + +- Hoisted +- Declares: `NextResponse` + +## Item 3: Stmt 1, `ImportOfModule` + +```js +import { ClientComponent } from '../../ClientComponent'; + +``` + +- Hoisted +- Side effects + +## Item 4: Stmt 1, `ImportBinding(0)` + +```js +import { ClientComponent } from '../../ClientComponent'; + +``` + +- Hoisted +- Declares: `ClientComponent` + +## Item 5: Stmt 2, `ImportOfModule` + +```js +import { MyModuleClientComponent } from 'my-module/MyModuleClientComponent'; + +``` + +- Hoisted +- Side effects + +## Item 6: Stmt 2, `ImportBinding(0)` + +```js +import { MyModuleClientComponent } from 'my-module/MyModuleClientComponent'; + +``` + +- Hoisted +- Declares: `MyModuleClientComponent` + +## Item 7: Stmt 3, `Normal` + +```js +export function GET() { + return NextResponse.json({ + clientComponent: typeof ClientComponent, + myModuleClientComponent: typeof MyModuleClientComponent + }); +} + +``` + +- Hoisted +- Declares: `GET` +- Reads (eventual): `NextResponse`, `ClientComponent`, `MyModuleClientComponent` +- Write: `GET` +- Write (eventual): `NextResponse` + +# Phase 1 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export GET"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export GET"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item7; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export GET"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item7; + Item7 --> Item4; + Item7 --> Item5; + Item7 --> Item6; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item4; + Item2; + Item5; + Item3; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export GET"]; + Item2 --> Item1; + Item3 --> Item1; + Item3 --> Item2; + Item9 --> Item7; + Item7 --> Item4; + Item7 --> Item5; + Item7 --> Item6; + Item8 --> Item1; + Item8 --> Item2; + Item8 --> Item3; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(2, ImportBinding(0))]"]; + N1["Items: [ItemId(1, ImportBinding(0))]"]; + N2["Items: [ItemId(0, ImportBinding(0))]"]; + N3["Items: [ItemId(3, Normal)]"]; + N4["Items: [ItemId(Export(("GET", #2), "GET"))]"]; + N5["Items: [ItemId(0, ImportOfModule)]"]; + N6["Items: [ItemId(1, ImportOfModule)]"]; + N7["Items: [ItemId(2, ImportOfModule)]"]; + N8["Items: [ItemId(ModuleEvaluation)]"]; + N6 --> N5; + N7 --> N5; + N7 --> N6; + N4 --> N3; + N3 --> N2; + N3 --> N1; + N3 --> N0; + N8 --> N5; + N8 --> N6; + N8 --> N7; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 8, + Exports: 9, + Export( + "GET", + ): 4, +} +``` + + +# Modules (dev) +## Part 0 +```js +import { MyModuleClientComponent } from 'my-module/MyModuleClientComponent'; +export { MyModuleClientComponent } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { ClientComponent } from '../../ClientComponent'; +export { ClientComponent } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { NextResponse } from 'next/server'; +export { NextResponse } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { MyModuleClientComponent } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { NextResponse } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { ClientComponent } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function GET() { + return NextResponse.json({ + clientComponent: typeof ClientComponent, + myModuleClientComponent: typeof MyModuleClientComponent + }); +} +export { GET } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { GET } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { GET }; + +``` +## Part 5 +```js +import 'next/server'; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import '../../ClientComponent'; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import 'my-module/MyModuleClientComponent'; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +"module evaluation"; + +``` +## Part 9 +```js +export { GET } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export GET" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 8, + Exports: 9, + Export( + "GET", + ): 4, +} +``` + + +# Modules (prod) +## Part 0 +```js +import { MyModuleClientComponent } from 'my-module/MyModuleClientComponent'; +export { MyModuleClientComponent } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import { ClientComponent } from '../../ClientComponent'; +export { ClientComponent } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 2 +```js +import { NextResponse } from 'next/server'; +export { NextResponse } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { MyModuleClientComponent } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { NextResponse } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { ClientComponent } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +function GET() { + return NextResponse.json({ + clientComponent: typeof ClientComponent, + myModuleClientComponent: typeof MyModuleClientComponent + }); +} +export { GET } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +import { GET } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 3 +}; +export { GET }; + +``` +## Part 5 +```js +import 'next/server'; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import '../../ClientComponent'; + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import 'my-module/MyModuleClientComponent'; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +"module evaluation"; + +``` +## Part 9 +```js +export { GET } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export GET" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 7 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/write-order/input.js b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/write-order/input.js new file mode 100644 index 0000000000000..afc7c9f573e75 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/write-order/input.js @@ -0,0 +1,11 @@ +export const order = []; + +export function func() { + order.push("d"); +} + +order.push("a"); +const x1 = externalFunction(); +const x2 = externalFunction(); +export const shared = { effect: order.push("b") }; +order.push("c"); diff --git a/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/write-order/output.md b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/write-order/output.md new file mode 100644 index 0000000000000..e10ee1c106434 --- /dev/null +++ b/turbopack/crates/turbopack-ecmascript/tests/tree-shaker/analyzer/write-order/output.md @@ -0,0 +1,673 @@ +# Items + +Count: 11 + +## Item 1: Stmt 0, `VarDeclarator(0)` + +```js +export const order = []; + +``` + +- Declares: `order` +- Write: `order` + +## Item 2: Stmt 1, `Normal` + +```js +export function func() { + order.push("d"); +} + +``` + +- Hoisted +- Declares: `func` +- Reads (eventual): `order` +- Write: `func` +- Write (eventual): `order` + +## Item 3: Stmt 2, `Normal` + +```js +order.push("a"); + +``` + +- Side effects +- Reads: `order` +- Write: `order` + +## Item 4: Stmt 3, `VarDeclarator(0)` + +```js +const x1 = externalFunction(); + +``` + +- Side effects +- Declares: `x1` +- Write: `x1` + +## Item 5: Stmt 4, `VarDeclarator(0)` + +```js +const x2 = externalFunction(); + +``` + +- Side effects +- Declares: `x2` +- Write: `x2` + +## Item 6: Stmt 5, `VarDeclarator(0)` + +```js +export const shared = { + effect: order.push("b") +}; + +``` + +- Declares: `shared` +- Reads: `order` +- Write: `order`, `shared` + +## Item 7: Stmt 6, `Normal` + +```js +order.push("c"); + +``` + +- Side effects +- Reads: `order` +- Write: `order` + +# Phase 1 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export func"]; + Item11; + Item11["export shared"]; +``` +# Phase 2 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export func"]; + Item11; + Item11["export shared"]; + Item3 --> Item1; + Item4 --> Item3; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item3; + Item6 --> Item1; + Item7 --> Item6; + Item7 --> Item1; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item9 --> Item7; + Item9 --> Item1; + Item10 --> Item2; + Item11 --> Item6; +``` +# Phase 3 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export func"]; + Item11; + Item11["export shared"]; + Item3 --> Item1; + Item4 --> Item3; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item3; + Item6 --> Item1; + Item7 --> Item6; + Item7 --> Item1; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item9 --> Item7; + Item9 --> Item1; + Item10 --> Item2; + Item11 --> Item6; + Item2 --> Item7; + Item2 --> Item1; + Item2 -.-> Item9; +``` +# Phase 4 +```mermaid +graph TD + Item1; + Item2; + Item3; + Item4; + Item5; + Item6; + Item7; + Item8; + Item8["ModuleEvaluation"]; + Item9; + Item9["export order"]; + Item10; + Item10["export func"]; + Item11; + Item11["export shared"]; + Item3 --> Item1; + Item4 --> Item3; + Item5 --> Item3; + Item5 --> Item4; + Item6 --> Item3; + Item6 --> Item1; + Item7 --> Item6; + Item7 --> Item1; + Item7 --> Item3; + Item7 --> Item4; + Item7 --> Item5; + Item9 --> Item7; + Item9 --> Item1; + Item10 --> Item2; + Item11 --> Item6; + Item2 --> Item7; + Item2 --> Item1; + Item2 -.-> Item9; + Item8 --> Item3; + Item8 --> Item4; + Item8 --> Item5; + Item8 --> Item7; +``` +# Final +```mermaid +graph TD + N0["Items: [ItemId(0, VarDeclarator(0))]"]; + N1["Items: [ItemId(2, Normal)]"]; + N2["Items: [ItemId(5, VarDeclarator(0))]"]; + N3["Items: [ItemId(Export(("shared", #2), "shared"))]"]; + N4["Items: [ItemId(3, VarDeclarator(0))]"]; + N5["Items: [ItemId(4, VarDeclarator(0))]"]; + N6["Items: [ItemId(6, Normal)]"]; + N7["Items: [ItemId(ModuleEvaluation)]"]; + N8["Items: [ItemId(Export(("order", #2), "order"))]"]; + N9["Items: [ItemId(1, Normal)]"]; + N10["Items: [ItemId(Export(("func", #2), "func"))]"]; + N1 --> N0; + N4 --> N1; + N5 --> N1; + N5 --> N4; + N2 --> N1; + N2 --> N0; + N6 --> N2; + N6 --> N0; + N6 --> N1; + N6 --> N4; + N6 --> N5; + N8 --> N6; + N8 --> N0; + N10 --> N9; + N3 --> N2; + N9 --> N6; + N9 --> N0; + N9 -.-> N8; + N7 --> N1; + N7 --> N4; + N7 --> N5; + N7 --> N6; +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 7, + Export( + "order", + ): 8, + Exports: 11, + Export( + "func", + ): 10, + Export( + "shared", + ): 3, +} +``` + + +# Modules (dev) +## Part 0 +```js +const order = []; +export { order } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("a"); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const shared = { + effect: order.push("b") +}; +export { shared } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { shared }; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const x1 = externalFunction(); +export { x1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const x2 = externalFunction(); +export { x2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("c"); + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +"module evaluation"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { order }; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function func() { + order.push("d"); +} +export { func } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +import { func } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 9 +}; +export { func }; + +``` +## Part 11 +```js +export { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export shared" +}; +export { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export order" +}; +export { func } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export func" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +"module evaluation"; + +``` +# Entrypoints + +``` +{ + ModuleEvaluation: 7, + Export( + "order", + ): 10, + Exports: 11, + Export( + "func", + ): 9, + Export( + "shared", + ): 3, +} +``` + + +# Modules (prod) +## Part 0 +```js +const order = []; +export { order } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 1 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("a"); + +``` +## Part 2 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +const shared = { + effect: order.push("b") +}; +export { shared } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 3 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +export { shared }; + +``` +## Part 4 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +const x1 = externalFunction(); +export { x1 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 5 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +const x2 = externalFunction(); +export { x2 } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 6 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 2 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +order.push("c"); + +``` +## Part 7 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +"module evaluation"; + +``` +## Part 8 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +function func() { + order.push("d"); +} +export { func } from "__TURBOPACK_VAR__" assert { + __turbopack_var__: true +}; + +``` +## Part 9 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +import { func } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 8 +}; +export { func }; + +``` +## Part 10 +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +import { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: 0 +}; +export { order }; + +``` +## Part 11 +```js +export { shared } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export shared" +}; +export { func } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export func" +}; +export { order } from "__TURBOPACK_PART__" assert { + __turbopack_part__: "export order" +}; + +``` +## Merged (module eval) +```js +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 6 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 1 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 4 +}; +import "__TURBOPACK_PART__" assert { + __turbopack_part__: 5 +}; +"module evaluation"; + +``` diff --git a/turbopack/crates/turbopack-env/Cargo.toml b/turbopack/crates/turbopack-env/Cargo.toml new file mode 100644 index 0000000000000..3287e316df473 --- /dev/null +++ b/turbopack/crates/turbopack-env/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "turbopack-env" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +indexmap = { workspace = true } +serde = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-env = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-env/build.rs b/turbopack/crates/turbopack-env/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-env/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-env/src/asset.rs b/turbopack/crates/turbopack-env/src/asset.rs new file mode 100644 index 0000000000000..95af2e2d6e9e0 --- /dev/null +++ b/turbopack/crates/turbopack-env/src/asset.rs @@ -0,0 +1,64 @@ +use std::io::Write; + +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::{rope::RopeBuilder, File, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + ident::AssetIdent, + source::Source, +}; +use turbopack_ecmascript::utils::StringifyJs; + +/// The `process.env` asset, responsible for initializing the env (shared by all +/// chunks) during app startup. +#[turbo_tasks::value] +pub struct ProcessEnvAsset { + /// The root path which we can construct our env asset path. + root: Vc, + + /// A HashMap filled with the env key/values. + env: Vc>, +} + +#[turbo_tasks::value_impl] +impl ProcessEnvAsset { + #[turbo_tasks::function] + pub fn new(root: Vc, env: Vc>) -> Vc { + ProcessEnvAsset { root, env }.cell() + } +} + +#[turbo_tasks::value_impl] +impl Source for ProcessEnvAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + AssetIdent::from_path(self.root.join(".env.js".into())) + } +} + +#[turbo_tasks::value_impl] +impl Asset for ProcessEnvAsset { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let env = self.env.read_all().await?; + + // TODO: In SSR, we use the native process.env, which can only contain string + // values. We need to inject literal values (to emulate webpack's + // DefinePlugin), so create a new regular object out of the old env. + let mut code = RopeBuilder::default(); + code += "const env = process.env = {...process.env};\n\n"; + + for (name, val) in &*env { + // It's assumed the env has passed through an EmbeddableProcessEnv, so the value + // is ready to be directly embedded. Values _after_ an embeddable + // env can be used to inject live code into the output. + // TODO this is not completely correct as env vars need to ignore casing + // So `process.env.path === process.env.PATH === process.env.PaTh` + writeln!(code, "env[{}] = {};", StringifyJs(name), val)?; + } + + Ok(AssetContent::file(File::from(code.build()).into())) + } +} diff --git a/turbopack/crates/turbopack-env/src/dotenv.rs b/turbopack/crates/turbopack-env/src/dotenv.rs new file mode 100644 index 0000000000000..b73c92258dac0 --- /dev/null +++ b/turbopack/crates/turbopack-env/src/dotenv.rs @@ -0,0 +1,44 @@ +use anyhow::Result; +use indexmap::indexmap; +use turbo_tasks::Vc; +use turbo_tasks_env::{CommandLineProcessEnv, CustomProcessEnv, ProcessEnv}; +use turbo_tasks_fs::FileSystemPath; + +use crate::TryDotenvProcessEnv; + +/// Loads a series of dotenv files according to the precedence rules set by +/// https://nextjs.org/docs/basic-features/environment-variables#environment-variable-load-order +#[turbo_tasks::function] +pub async fn load_env(project_path: Vc) -> Result>> { + let env: Vc> = Vc::upcast(CommandLineProcessEnv::new()); + + let node_env = env.read("NODE_ENV".into()).await?; + let node_env = node_env.as_deref().unwrap_or("development"); + + let env = Vc::upcast(CustomProcessEnv::new( + env, + Vc::cell(indexmap! { + "NODE_ENV".into() => node_env.into(), + }), + )); + + let files = [ + Some(format!(".env.{node_env}.local")), + if node_env == "test" { + None + } else { + Some(".env.local".into()) + }, + Some(format!(".env.{node_env}")), + Some(".env".into()), + ] + .into_iter() + .flatten(); + + let env = files.fold(env, |prior, f| { + let path = project_path.join(f.into()); + Vc::upcast(TryDotenvProcessEnv::new(prior, path)) + }); + + Ok(env) +} diff --git a/turbopack/crates/turbopack-env/src/embeddable.rs b/turbopack/crates/turbopack-env/src/embeddable.rs new file mode 100644 index 0000000000000..0f7cebce1e119 --- /dev/null +++ b/turbopack/crates/turbopack-env/src/embeddable.rs @@ -0,0 +1,44 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_env::{EnvMap, ProcessEnv}; +use turbopack_ecmascript::utils::StringifyJs; + +/// Encodes values as JS strings so that they can be safely injected into a JS +/// output. +#[turbo_tasks::value] +pub struct EmbeddableProcessEnv { + prior: Vc>, +} + +#[turbo_tasks::value_impl] +impl EmbeddableProcessEnv { + #[turbo_tasks::function] + pub fn new(prior: Vc>) -> Vc { + EmbeddableProcessEnv { prior }.cell() + } +} + +#[turbo_tasks::value_impl] +impl ProcessEnv for EmbeddableProcessEnv { + #[turbo_tasks::function] + async fn read_all(&self) -> Result> { + let prior = self.prior.read_all().await?; + + let encoded = prior + .iter() + .map(|(k, v)| (k.clone(), StringifyJs(v).to_string().into())) + .collect(); + + Ok(Vc::cell(encoded)) + } + + #[turbo_tasks::function] + async fn read(&self, name: RcStr) -> Result>> { + let prior = self.prior.read(name).await?; + let encoded = prior + .as_deref() + .map(|s| StringifyJs(s).to_string()) + .map(RcStr::from); + Ok(Vc::cell(encoded)) + } +} diff --git a/turbopack/crates/turbopack-env/src/issue.rs b/turbopack/crates/turbopack-env/src/issue.rs new file mode 100644 index 0000000000000..076e17ace38a4 --- /dev/null +++ b/turbopack/crates/turbopack-env/src/issue.rs @@ -0,0 +1,33 @@ +use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::issue::{Issue, IssueStage, OptionStyledString, StyledString}; + +/// An issue that occurred while resolving the parsing or evaluating the .env. +#[turbo_tasks::value(shared)] +pub struct ProcessEnvIssue { + pub path: Vc, + pub description: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for ProcessEnvIssue { + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Error loading dotenv file".into()).cell() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Load.into() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.path + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some(self.description)) + } +} diff --git a/turbopack/crates/turbopack-env/src/lib.rs b/turbopack/crates/turbopack-env/src/lib.rs new file mode 100644 index 0000000000000..fd5fc2e869a21 --- /dev/null +++ b/turbopack/crates/turbopack-env/src/lib.rs @@ -0,0 +1,34 @@ +//! Environment Variable support for turbopack. +//! +//! Environment variables can come from multiple sources, including the rust +//! process's env (immutable and by passing `FOO=BAR` keys when executing the +//! turbopack binary) or loaded via dotenv files. +//! +//! Dotenv file loading is a chain. Dotenv files that come first in the chain +//! have higher priority to define a environment variable (later dotenv files +//! cannot override it). Later dotenv files can reference variables prior +//! defined variables. + +#![feature(async_closure)] +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +mod asset; +pub mod dotenv; +mod embeddable; +mod issue; +mod try_env; + +pub use asset::ProcessEnvAsset; +pub use embeddable::EmbeddableProcessEnv; +pub use issue::ProcessEnvIssue; +pub use try_env::TryDotenvProcessEnv; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbo_tasks_env::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-env/src/try_env.rs b/turbopack/crates/turbopack-env/src/try_env.rs new file mode 100644 index 0000000000000..65d862d0c6dd5 --- /dev/null +++ b/turbopack/crates/turbopack-env/src/try_env.rs @@ -0,0 +1,61 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_env::{DotenvProcessEnv, EnvMap, ProcessEnv}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::issue::{IssueExt, StyledString}; + +use crate::ProcessEnvIssue; + +#[turbo_tasks::value] +pub struct TryDotenvProcessEnv { + dotenv: Vc, + prior: Vc>, + path: Vc, +} + +#[turbo_tasks::value_impl] +impl TryDotenvProcessEnv { + #[turbo_tasks::function] + pub fn new(prior: Vc>, path: Vc) -> Vc { + let dotenv = DotenvProcessEnv::new(Some(prior), path); + TryDotenvProcessEnv { + dotenv, + prior, + path, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl ProcessEnv for TryDotenvProcessEnv { + #[turbo_tasks::function] + async fn read_all(&self) -> Result> { + let dotenv = self.dotenv; + let prior = dotenv.read_prior(); + + // Ensure prior succeeds. If it doesn't, then we don't want to attempt to read + // the dotenv file (and potentially emit an Issue), just trust that the prior + // will have emitted its own. + prior.await?; + + let vars = dotenv.read_all_with_prior(prior); + match vars.await { + Ok(_) => Ok(vars), + Err(e) => { + // If parsing the dotenv file fails (but getting the prior value didn't), then + // we want to emit an Issue and fall back to the prior's read. + ProcessEnvIssue { + path: self.path, + // read_all_with_prior will wrap a current error with a context containing the + // failing file, which we don't really care about (we report the filepath as the + // Issue context, not the description). So extract the real error. + description: StyledString::Text(e.root_cause().to_string().into()).cell(), + } + .cell() + .emit(); + Ok(prior) + } + } + } +} diff --git a/turbopack/crates/turbopack-image/Cargo.toml b/turbopack/crates/turbopack-image/Cargo.toml new file mode 100644 index 0000000000000..98e775f7225c8 --- /dev/null +++ b/turbopack/crates/turbopack-image/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "turbopack-image" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[features] + +# [NOTE]: Before enable this, ensure this can build all of the target platforms we support. +avif = ["image/avif"] +webp = ["image/webp"] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +base64 = "0.21.0" +image = { workspace = true, default-features = false, features = [ + "gif", + "png", + "jpeg", + "ico", + "bmp", + "tga", +] } +mime = { workspace = true } +once_cell = { workspace = true } +regex = { workspace = true } +serde = { workspace = true } +serde_with = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-image/build.rs b/turbopack/crates/turbopack-image/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-image/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-image/src/lib.rs b/turbopack/crates/turbopack-image/src/lib.rs new file mode 100644 index 0000000000000..16da8fd635043 --- /dev/null +++ b/turbopack/crates/turbopack-image/src/lib.rs @@ -0,0 +1,10 @@ +#![feature(arbitrary_self_types)] + +pub mod process; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-image/src/process/SVG_LICENSE b/turbopack/crates/turbopack-image/src/process/SVG_LICENSE new file mode 100644 index 0000000000000..1341a90d565fa --- /dev/null +++ b/turbopack/crates/turbopack-image/src/process/SVG_LICENSE @@ -0,0 +1,9 @@ +The MIT License (MIT) + +Copyright © 2017 Aditya Yadav, http://netroy.in + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/turbopack/crates/turbopack-image/src/process/mod.rs b/turbopack/crates/turbopack-image/src/process/mod.rs new file mode 100644 index 0000000000000..2db40e084f459 --- /dev/null +++ b/turbopack/crates/turbopack-image/src/process/mod.rs @@ -0,0 +1,513 @@ +pub mod svg; + +use std::{io::Cursor, str::FromStr}; + +use anyhow::{bail, Context, Result}; +use base64::{display::Base64Display, engine::general_purpose::STANDARD}; +use image::{ + codecs::{ + bmp::BmpEncoder, + ico::IcoEncoder, + jpeg::JpegEncoder, + png::{CompressionType, PngEncoder}, + }, + imageops::FilterType, + DynamicImage, GenericImageView, ImageEncoder, ImageFormat, +}; +use mime::Mime; +use serde::{Deserialize, Serialize}; +use serde_with::{serde_as, DisplayFromStr}; +use turbo_tasks::{debug::ValueDebugFormat, trace::TraceRawVcs, Vc}; +use turbo_tasks_fs::{File, FileContent, FileSystemPath}; +use turbopack_core::{ + error::PrettyPrintError, + ident::AssetIdent, + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, +}; + +use self::svg::calculate; + +/// Small placeholder version of the image. +#[derive(PartialEq, Eq, Serialize, Deserialize, TraceRawVcs, ValueDebugFormat)] +pub struct BlurPlaceholder { + pub data_url: String, + pub width: u32, + pub height: u32, +} + +impl BlurPlaceholder { + pub fn fallback() -> Self { + BlurPlaceholder { + data_url: "data:image/gif;base64,R0lGODlhAQABAIAAAP///\ + wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" + .to_string(), + width: 1, + height: 1, + } + } +} + +/// Gathered meta information about an image. +#[allow(clippy::manual_non_exhaustive)] +#[serde_as] +#[turbo_tasks::value] +#[derive(Default)] +#[non_exhaustive] +pub struct ImageMetaData { + pub width: u32, + pub height: u32, + #[turbo_tasks(trace_ignore, debug_ignore)] + #[serde_as(as = "Option")] + pub mime_type: Option, + pub blur_placeholder: Option, +} + +impl ImageMetaData { + pub fn fallback_value(mime_type: Option) -> Self { + ImageMetaData { + width: 100, + height: 100, + mime_type, + blur_placeholder: Some(BlurPlaceholder::fallback()), + } + } +} + +/// Options for generating a blur placeholder. +#[turbo_tasks::value(shared)] +pub struct BlurPlaceholderOptions { + pub quality: u8, + pub size: u32, +} + +fn extension_to_image_format(extension: &str) -> Option { + Some(match extension { + "avif" => ImageFormat::Avif, + "jpg" | "jpeg" => ImageFormat::Jpeg, + "png" => ImageFormat::Png, + "gif" => ImageFormat::Gif, + "webp" => ImageFormat::WebP, + "tif" | "tiff" => ImageFormat::Tiff, + "tga" => ImageFormat::Tga, + "dds" => ImageFormat::Dds, + "bmp" => ImageFormat::Bmp, + "ico" => ImageFormat::Ico, + "hdr" => ImageFormat::Hdr, + "exr" => ImageFormat::OpenExr, + "pbm" | "pam" | "ppm" | "pgm" => ImageFormat::Pnm, + "ff" | "farbfeld" => ImageFormat::Farbfeld, + "qoi" => ImageFormat::Qoi, + _ => return None, + }) +} + +fn result_to_issue(ident: Vc, result: Result) -> Option { + match result { + Ok(r) => Some(r), + Err(err) => { + ImageProcessingIssue { + path: ident.path(), + message: StyledString::Text(format!("{}", PrettyPrintError(&err)).into()).cell(), + issue_severity: None, + title: None, + } + .cell() + .emit(); + None + } + } +} + +fn load_image( + ident: Vc, + bytes: &[u8], + extension: Option<&str>, +) -> Option<(ImageBuffer, Option)> { + result_to_issue(ident, load_image_internal(ident, bytes, extension)) +} + +/// Type of raw image buffer read by reader from `load_image`. +/// If the image could not be decoded, the raw bytes are returned. +enum ImageBuffer { + Raw(Vec), + Decoded(image::DynamicImage), +} + +fn load_image_internal( + ident: Vc, + bytes: &[u8], + extension: Option<&str>, +) -> Result<(ImageBuffer, Option)> { + let reader = image::io::Reader::new(Cursor::new(&bytes)); + let mut reader = reader + .with_guessed_format() + .context("unable to determine image format from file content")?; + let mut format = reader.format(); + if format.is_none() { + if let Some(extension) = extension { + if let Some(new_format) = extension_to_image_format(extension) { + format = Some(new_format); + reader.set_format(new_format); + } + } + } + + // [NOTE] + // Workaround for missing codec supports in Turbopack, + // Instead of erroring out the whole build, emitting raw image bytes as-is + // (Not applying resize, not applying optimization or anything else) + // and expect a browser decodes it. + // This is a stop gap until we have proper encoding/decoding in majority of the + // platforms + + #[cfg(not(feature = "avif"))] + if matches!(format, Some(ImageFormat::Avif)) { + ImageProcessingIssue { + path: ident.path(), + message: StyledString::Text( + "This version of Turbopack does not support AVIF images, will emit without \ + optimization or encoding" + .into(), + ) + .cell(), + title: Some(StyledString::Text("AVIF image not supported".into()).cell()), + issue_severity: Some(IssueSeverity::Warning.into()), + } + .cell() + .emit(); + return Ok((ImageBuffer::Raw(bytes.to_vec()), format)); + } + + #[cfg(not(feature = "webp"))] + if matches!(format, Some(ImageFormat::WebP)) { + ImageProcessingIssue { + path: ident.path(), + message: StyledString::Text( + "This version of Turbopack does not support WEBP images, will emit without \ + optimization or encoding" + .into(), + ) + .cell(), + title: Some(StyledString::Text("WEBP image not supported".into()).cell()), + issue_severity: Some(IssueSeverity::Warning.into()), + } + .cell() + .emit(); + return Ok((ImageBuffer::Raw(bytes.to_vec()), format)); + } + + let image = reader.decode().context("unable to decode image data")?; + Ok((ImageBuffer::Decoded(image), format)) +} + +fn compute_blur_data( + ident: Vc, + image: image::DynamicImage, + format: ImageFormat, + options: &BlurPlaceholderOptions, +) -> Option { + match compute_blur_data_internal(image, format, options) + .context("unable to compute blur placeholder") + { + Ok(r) => Some(r), + Err(err) => { + ImageProcessingIssue { + path: ident.path(), + message: StyledString::Text(format!("{}", PrettyPrintError(&err)).into()).cell(), + issue_severity: None, + title: None, + } + .cell() + .emit(); + Some(BlurPlaceholder::fallback()) + } + } +} + +fn encode_image(image: DynamicImage, format: ImageFormat, quality: u8) -> Result<(Vec, Mime)> { + let mut buf = Vec::new(); + let (width, height) = image.dimensions(); + + Ok(match format { + ImageFormat::Png => { + PngEncoder::new_with_quality( + &mut buf, + CompressionType::Best, + image::codecs::png::FilterType::NoFilter, + ) + .write_image(image.as_bytes(), width, height, image.color().into())?; + (buf, mime::IMAGE_PNG) + } + ImageFormat::Jpeg => { + JpegEncoder::new_with_quality(&mut buf, quality).write_image( + image.as_bytes(), + width, + height, + image.color().into(), + )?; + (buf, mime::IMAGE_JPEG) + } + ImageFormat::Ico => { + IcoEncoder::new(&mut buf).write_image( + image.as_bytes(), + width, + height, + image.color().into(), + )?; + // mime does not support typed IMAGE_X_ICO yet + (buf, Mime::from_str("image/x-icon")?) + } + ImageFormat::Bmp => { + BmpEncoder::new(&mut buf).write_image( + image.as_bytes(), + width, + height, + image.color().into(), + )?; + (buf, mime::IMAGE_BMP) + } + #[cfg(feature = "webp")] + ImageFormat::WebP => { + use image::codecs::webp::WebPEncoder; + let encoder = WebPEncoder::new_lossless(&mut buf); + encoder.encode(image.as_bytes(), width, height, image.color().into())?; + + (buf, Mime::from_str("image/webp")?) + } + #[cfg(feature = "avif")] + ImageFormat::Avif => { + use image::codecs::avif::AvifEncoder; + AvifEncoder::new_with_speed_quality(&mut buf, 6, quality).write_image( + image.as_bytes(), + width, + height, + image.color().into(), + )?; + (buf, Mime::from_str("image/avif")?) + } + _ => bail!( + "Encoding for image format {:?} has not been compiled into the current build", + format + ), + }) +} + +fn compute_blur_data_internal( + image: image::DynamicImage, + format: ImageFormat, + options: &BlurPlaceholderOptions, +) -> Result { + let small_image = image.resize(options.size, options.size, FilterType::Triangle); + let width = small_image.width(); + let height = small_image.height(); + let (data, mime) = encode_image(small_image, format, options.quality)?; + let data_url = format!( + "data:{mime};base64,{}", + Base64Display::new(&data, &STANDARD) + ); + + Ok(BlurPlaceholder { + data_url, + width, + height, + }) +} + +fn image_format_to_mime_type(format: ImageFormat) -> Result> { + Ok(match format { + ImageFormat::Png => Some(mime::IMAGE_PNG), + ImageFormat::Jpeg => Some(mime::IMAGE_JPEG), + ImageFormat::WebP => Some(Mime::from_str("image/webp")?), + ImageFormat::Avif => Some(Mime::from_str("image/avif")?), + ImageFormat::Bmp => Some(mime::IMAGE_BMP), + ImageFormat::Dds => Some(Mime::from_str("image/vnd-ms.dds")?), + ImageFormat::Farbfeld => Some(mime::APPLICATION_OCTET_STREAM), + ImageFormat::Gif => Some(mime::IMAGE_GIF), + ImageFormat::Hdr => Some(Mime::from_str("image/vnd.radiance")?), + ImageFormat::Ico => Some(Mime::from_str("image/x-icon")?), + ImageFormat::OpenExr => Some(Mime::from_str("image/x-exr")?), + ImageFormat::Pnm => Some(Mime::from_str("image/x-portable-anymap")?), + ImageFormat::Qoi => Some(mime::APPLICATION_OCTET_STREAM), + ImageFormat::Tga => Some(Mime::from_str("image/x-tga")?), + ImageFormat::Tiff => Some(Mime::from_str("image/tiff")?), + _ => None, + }) +} + +/// Analyze an image and return meta information about it. +/// Optionally computes a blur placeholder. +#[turbo_tasks::function] +pub async fn get_meta_data( + ident: Vc, + content: Vc, + blur_placeholder: Option>, +) -> Result> { + let FileContent::Content(content) = &*content.await? else { + bail!("Input image not found"); + }; + let bytes = content.content().to_bytes()?; + let path = ident.path().await?; + let extension = path.extension_ref(); + if extension == Some("svg") { + let content = result_to_issue( + ident, + std::str::from_utf8(&bytes).context("Input image is not valid utf-8"), + ); + let Some(content) = content else { + return Ok(ImageMetaData::fallback_value(Some(mime::IMAGE_SVG)).cell()); + }; + let info = result_to_issue( + ident, + calculate(content).context("Failed to parse svg source code for image dimensions"), + ); + let Some((width, height)) = info else { + return Ok(ImageMetaData::fallback_value(Some(mime::IMAGE_SVG)).cell()); + }; + return Ok(ImageMetaData { + width, + height, + mime_type: Some(mime::IMAGE_SVG), + blur_placeholder: None, + } + .cell()); + } + let Some((image, format)) = load_image(ident, &bytes, extension) else { + return Ok(ImageMetaData::fallback_value(None).cell()); + }; + + match image { + ImageBuffer::Raw(..) => Ok(ImageMetaData::fallback_value(None).cell()), + ImageBuffer::Decoded(image) => { + let (width, height) = image.dimensions(); + let blur_placeholder = if let Some(blur_placeholder) = blur_placeholder { + if matches!( + format, + // list should match next/client/image.tsx + Some(ImageFormat::Png) + | Some(ImageFormat::Jpeg) + | Some(ImageFormat::WebP) + | Some(ImageFormat::Avif) + ) { + compute_blur_data(ident, image, format.unwrap(), &*blur_placeholder.await?) + } else { + None + } + } else { + None + }; + + Ok(ImageMetaData { + width, + height, + mime_type: if let Some(format) = format { + image_format_to_mime_type(format)? + } else { + None + }, + blur_placeholder, + } + .cell()) + } + } +} + +#[turbo_tasks::function] +pub async fn optimize( + ident: Vc, + content: Vc, + max_width: u32, + max_height: u32, + quality: u8, +) -> Result> { + let FileContent::Content(content) = &*content.await? else { + return Ok(FileContent::NotFound.cell()); + }; + let bytes = content.content().to_bytes()?; + + let Some((image, format)) = load_image(ident, &bytes, ident.path().await?.extension_ref()) + else { + return Ok(FileContent::NotFound.cell()); + }; + match image { + ImageBuffer::Raw(buffer) => { + #[cfg(not(feature = "avif"))] + if matches!(format, Some(ImageFormat::Avif)) { + return Ok(FileContent::Content( + File::from(buffer).with_content_type(Mime::from_str("image/avif")?), + ) + .cell()); + } + + #[cfg(not(feature = "webp"))] + if matches!(format, Some(ImageFormat::WebP)) { + return Ok(FileContent::Content( + File::from(buffer).with_content_type(Mime::from_str("image/webp")?), + ) + .cell()); + } + + let mime_type = if let Some(format) = format { + image_format_to_mime_type(format)? + } else { + None + }; + + // Falls back to image/jpeg if the format is unknown, thouogh it is not + // technically correct + Ok(FileContent::Content( + File::from(buffer).with_content_type(mime_type.unwrap_or(mime::IMAGE_JPEG)), + ) + .cell()) + } + ImageBuffer::Decoded(image) => { + let (width, height) = image.dimensions(); + let image = if width > max_width || height > max_height { + image.resize(max_width, max_height, FilterType::Lanczos3) + } else { + image + }; + + let format = format.unwrap_or(ImageFormat::Jpeg); + let (data, mime_type) = encode_image(image, format, quality)?; + + Ok(FileContent::Content(File::from(data).with_content_type(mime_type)).cell()) + } + } +} + +#[turbo_tasks::value] +struct ImageProcessingIssue { + path: Vc, + message: Vc, + title: Option>, + issue_severity: Option>, +} + +#[turbo_tasks::value_impl] +impl Issue for ImageProcessingIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + self.issue_severity.unwrap_or(IssueSeverity::Error.into()) + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.path + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Transform.cell() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + self.title + .unwrap_or(StyledString::Text("Processing image failed".into()).cell()) + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some(self.message)) + } +} diff --git a/turbopack/crates/turbopack-image/src/process/svg.rs b/turbopack/crates/turbopack-image/src/process/svg.rs new file mode 100644 index 0000000000000..59956bbbc0715 --- /dev/null +++ b/turbopack/crates/turbopack-image/src/process/svg.rs @@ -0,0 +1,172 @@ +// Ported from https://github.com/image-size/image-size/blob/94e9c1ee913b71222d7583dc904ac0116ae00834/lib/types/svg.ts +// see SVG_LICENSE for license info + +use std::collections::HashMap; + +use anyhow::{anyhow, bail, Result}; +use once_cell::sync::Lazy; +use regex::Regex; + +const INCH_CM: f64 = 2.54; +static UNITS: Lazy> = Lazy::new(|| { + HashMap::from([ + ("in", 96.0), + ("cm", 96.0 / INCH_CM), + ("em", 16.0), + ("ex", 8.0), + ("m", 96.0 / INCH_CM * 100.0), + ("mm", 96.0 / INCH_CM / 10.0), + ("pc", 96.0 / 72.0 / 12.0), + ("pt", 96.0 / 72.0), + ("px", 1.0), + ("", 1.0), + ]) +}); + +static UNIT_REGEX: Lazy = + Lazy::new(|| Regex::new(r"^([0-9.]+(?:e-?\d+)?)((?:in|cm|em|ex|m|mm|pc|pt|px)?)$").unwrap()); + +static ROOT_REGEX: Lazy = + Lazy::new(|| Regex::new(r#""']|"[^"]*"|'[^']*')*>"#).unwrap()); +static WIDTH_REGEX: Lazy = Lazy::new(|| Regex::new(r#"\swidth=['"]([^%]+?)['"]"#).unwrap()); +static HEIGHT_REGEX: Lazy = + Lazy::new(|| Regex::new(r#"\sheight=['"]([^%]+?)['"]"#).unwrap()); +static VIEW_BOX_REGEX: Lazy = + Lazy::new(|| Regex::new(r#"\sviewBox=['"](.+?)['"]"#).unwrap()); +static VIEW_BOX_CONTENT_REGEX: Lazy = Lazy::new(|| { + Regex::new(r"^\s*((?:\w|\.|-)+)\s+((?:\w|\.|-)+)\s+((?:\w|\.|-)+)\s+((?:\w|\.|-)+)\s*$") + .unwrap() +}); + +fn parse_length(len: &str) -> Result { + let captures = UNIT_REGEX + .captures(len) + .ok_or_else(|| anyhow!("Unknown syntax for length, expected value with unit ({len})"))?; + let val = captures[1].parse::()?; + let unit = &captures[2]; + let unit_scale = UNITS + .get(unit) + .ok_or_else(|| anyhow!("Unknown unit {unit}"))?; + Ok(val * unit_scale) +} + +fn parse_viewbox(viewbox: &str) -> Result<(f64, f64)> { + let captures = VIEW_BOX_CONTENT_REGEX + .captures(viewbox) + .ok_or_else(|| anyhow!("Unknown syntax for viewBox ({viewbox})"))?; + let width = parse_length(&captures[3])?; + let height = parse_length(&captures[4])?; + Ok((width, height)) +} + +fn calculate_by_viewbox( + view_box: (f64, f64), + width: Option>, + height: Option>, +) -> Result<(u32, u32)> { + let ratio = view_box.0 / view_box.1; + if let Some(width) = width { + let width = width?.round() as u32; + let height = (width as f64 / ratio).round() as u32; + return Ok((width, height)); + } + if let Some(height) = height { + let height = height?.round() as u32; + let width = (height as f64 * ratio).round() as u32; + return Ok((width, height)); + } + Ok((view_box.0.round() as u32, view_box.1.round() as u32)) +} + +pub fn calculate(content: &str) -> Result<(u32, u32)> { + let Some(root) = ROOT_REGEX.find(content) else { + bail!("Source code does not contain a root element"); + }; + let root = root.as_str(); + let width = WIDTH_REGEX.captures(root).map(|c| parse_length(&c[1])); + let height = HEIGHT_REGEX.captures(root).map(|c| parse_length(&c[1])); + let viewbox = VIEW_BOX_REGEX.captures(root).map(|c| parse_viewbox(&c[1])); + if let Some(width) = width { + if let Some(height) = height { + Ok((width?.round() as u32, height?.round() as u32)) + } else { + bail!("SVG source code contains only a width attribute but not height attribute"); + } + } else if let Some(viewbox) = viewbox { + calculate_by_viewbox(viewbox?, width, height) + } else { + bail!("SVG source code does not contain width and height or viewBox attribute"); + } +} + +#[cfg(test)] +mod tests { + use anyhow::Result; + + use super::calculate; + + #[test] + fn test_calculate() { + let svg1 = r#""#; + assert_eq!(calculate(svg1).unwrap(), (100, 50)); + + let svg2 = r#""#; + assert_eq!(calculate(svg2).unwrap(), (100, 50)); + + let svg3 = r#""#; + assert_eq!(calculate(svg3).unwrap(), (200, 100)); + + let svg4 = r#""#; + assert_eq!(calculate(svg4).unwrap(), (100, 50)); + + let svg5 = r#""#; + assert_eq!(calculate(svg5).unwrap(), (100, 50)); + + let svg6 = r#""#; + assert!(calculate(svg6).is_err()); + + let svg7 = r#""#; + assert!(calculate(svg7).is_err()); + + let svg8 = r#""#; + assert!(calculate(svg8).is_err()); + + let svg9 = r#""#; + assert!(calculate(svg9).is_err()); + + let svg10 = r#""#; + assert!(calculate(svg10).is_err()); + } + + #[test] + fn test_calculate_with_units() -> Result<()> { + let svg = r#""#; + let result = calculate(svg)?; + assert_eq!(result, (76, 189)); + Ok(()) + } + + #[test] + fn test_calculate_with_em() -> Result<()> { + let svg = r#""#; + let result = calculate(svg)?; + assert_eq!(result, (320, 160)); + Ok(()) + } + + #[test] + fn test_calculate_with_ex() -> Result<()> { + let svg = r#""#; + let result = calculate(svg)?; + assert_eq!(result, (160, 80)); + Ok(()) + } + + #[test] + fn test_calculate_complex_viewbox() -> Result<()> { + let svg = r#""#; + let result = calculate(svg)?; + assert_eq!(result, (50, 50420)); + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-json/Cargo.toml b/turbopack/crates/turbopack-json/Cargo.toml new file mode 100644 index 0000000000000..69a788ae4fb52 --- /dev/null +++ b/turbopack/crates/turbopack-json/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "turbopack-json" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } + +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } + +serde = { workspace = true } +serde_json = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-json/build.rs b/turbopack/crates/turbopack-json/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-json/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-json/src/lib.rs b/turbopack/crates/turbopack-json/src/lib.rs new file mode 100644 index 0000000000000..0005a466f7914 --- /dev/null +++ b/turbopack/crates/turbopack-json/src/lib.rs @@ -0,0 +1,173 @@ +//! JSON asset support for turbopack. +//! +//! JSON assets are parsed to ensure they contain valid JSON. +//! +//! When imported from ES modules, they produce a module that exports the +//! JSON value as an object. + +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +use std::fmt::Write; + +use anyhow::{bail, Error, Result}; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks_fs::{FileContent, FileJsonContent}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext}, + ident::AssetIdent, + module::Module, + reference::ModuleReferences, + source::Source, +}; +use turbopack_ecmascript::chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, EcmascriptChunkType, + EcmascriptExports, +}; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("json".into()) +} + +#[turbo_tasks::value] +pub struct JsonModuleAsset { + source: Vc>, +} + +#[turbo_tasks::value_impl] +impl JsonModuleAsset { + #[turbo_tasks::function] + pub fn new(source: Vc>) -> Vc { + Self::cell(JsonModuleAsset { source }) + } +} + +#[turbo_tasks::value_impl] +impl Module for JsonModuleAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source.ident().with_modifier(modifier()) + } +} + +#[turbo_tasks::value_impl] +impl Asset for JsonModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for JsonModuleAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast(JsonChunkItem::cell(JsonChunkItem { + module: self, + chunking_context, + }))) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for JsonModuleAsset { + #[turbo_tasks::function] + fn get_exports(&self) -> Vc { + EcmascriptExports::Value.cell() + } +} + +#[turbo_tasks::value] +struct JsonChunkItem { + module: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for JsonChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for JsonChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn content(&self) -> Result> { + // We parse to JSON and then stringify again to ensure that the + // JSON is valid. + let content = self.module.content().file_content(); + let data = content.parse_json().await?; + match &*data { + FileJsonContent::Content(data) => { + let js_str_content = serde_json::to_string(&data.to_string())?; + let inner_code = + format!("__turbopack_export_value__(JSON.parse({js_str_content}));"); + + Ok(EcmascriptChunkItemContent { + inner_code: inner_code.into(), + ..Default::default() + } + .into()) + } + FileJsonContent::Unparseable(e) => { + let mut message = "Unable to make a module from invalid JSON: ".to_string(); + if let FileContent::Content(content) = &*content.await? { + let text = content.content().to_str()?; + e.write_with_content(&mut message, text.as_ref())?; + } else { + write!(message, "{}", e)?; + } + + Err(Error::msg(message)) + } + FileJsonContent::NotFound => { + bail!( + "JSON file not found: {}", + self.module.ident().to_string().await? + ); + } + } + } +} + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-mdx/Cargo.toml b/turbopack/crates/turbopack-mdx/Cargo.toml new file mode 100644 index 0000000000000..a3a0ad300823d --- /dev/null +++ b/turbopack/crates/turbopack-mdx/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "turbopack-mdx" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +serde = { workspace = true } + +mdxjs = { workspace = true } + +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-mdx/build.rs b/turbopack/crates/turbopack-mdx/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-mdx/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-mdx/src/lib.rs b/turbopack/crates/turbopack-mdx/src/lib.rs new file mode 100644 index 0000000000000..9468495d4a9bc --- /dev/null +++ b/turbopack/crates/turbopack-mdx/src/lib.rs @@ -0,0 +1,338 @@ +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +use anyhow::{anyhow, Context, Result}; +use mdxjs::{compile, MdxParseOptions, Options}; +use turbo_tasks::{RcStr, Value, ValueDefault, Vc}; +use turbo_tasks_fs::{rope::Rope, File, FileContent, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext}, + context::AssetContext, + ident::AssetIdent, + module::Module, + reference::ModuleReferences, + resolve::origin::ResolveOrigin, + source::Source, + virtual_source::VirtualSource, +}; +use turbopack_ecmascript::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkType, EcmascriptExports, + }, + references::AnalyzeEcmascriptModuleResultBuilder, + AnalyzeEcmascriptModuleResult, EcmascriptInputTransforms, EcmascriptModuleAsset, + EcmascriptModuleAssetType, EcmascriptOptions, +}; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("mdx".into()) +} + +#[turbo_tasks::value(shared)] +#[derive(Hash, Debug, Clone)] +#[serde(rename_all = "camelCase")] +pub enum MdxParseConstructs { + Commonmark, + Gfm, +} + +/// Subset of mdxjs::Options to allow to inherit turbopack's jsx-related configs +/// into mdxjs. This is thin, near straightforward subset of mdxjs::Options to +/// enable turbo tasks. +#[turbo_tasks::value(shared)] +#[derive(Hash, Debug, Clone)] +#[serde(rename_all = "camelCase", default)] +pub struct MdxTransformOptions { + pub development: Option, + pub jsx: Option, + pub jsx_runtime: Option, + pub jsx_import_source: Option, + /// The path to a module providing Components to mdx modules. + /// The provider must export a useMDXComponents, which is called to access + /// an object of components. + pub provider_import_source: Option, + /// Determines how to parse mdx contents. + pub mdx_type: Option, +} + +impl Default for MdxTransformOptions { + fn default() -> Self { + Self { + development: Some(true), + jsx: Some(false), + jsx_runtime: None, + jsx_import_source: None, + provider_import_source: None, + mdx_type: Some(MdxParseConstructs::Commonmark), + } + } +} + +#[turbo_tasks::value_impl] +impl MdxTransformOptions { + #[turbo_tasks::function] + fn default_private() -> Vc { + Self::cell(Default::default()) + } +} + +impl ValueDefault for MdxTransformOptions { + fn value_default() -> Vc { + Self::default_private() + } +} + +#[turbo_tasks::value] +#[derive(Clone, Copy)] +pub struct MdxModuleAsset { + source: Vc>, + asset_context: Vc>, + transforms: Vc, + options: Vc, + ecmascript_options: Vc, +} + +/// MDX components should be treated as normal j|tsx components to analyze +/// its imports or run ecma transforms, +/// only difference is it is not a valid ecmascript AST we +/// can't pass it forward directly. Internally creates an jsx from mdx +/// via mdxrs, then pass it through existing ecmascript analyzer. +/// +/// To make mdx as a variant of ecmascript and use its `source_transforms` +/// instead, there should be a way to get a valid SWC ast from mdx source input +/// - which we don't have yet. +async fn into_ecmascript_module_asset( + current_context: &Vc, +) -> Result> { + let content = current_context.content(); + let this = current_context.await?; + let transform_options = this.options.await?; + + let AssetContent::File(file) = &*content.await? else { + anyhow::bail!("Unexpected mdx asset content"); + }; + + let FileContent::Content(file) = &*file.await? else { + anyhow::bail!("Not able to read mdx file content"); + }; + + let jsx_runtime = if let Some(runtime) = &transform_options.jsx_runtime { + match runtime.as_str() { + "automatic" => Some(mdxjs::JsxRuntime::Automatic), + "classic" => Some(mdxjs::JsxRuntime::Classic), + _ => None, + } + } else { + None + }; + + let parse_options = match transform_options.mdx_type { + Some(MdxParseConstructs::Gfm) => MdxParseOptions::gfm(), + _ => MdxParseOptions::default(), + }; + + let options = Options { + parse: parse_options, + development: transform_options.development.unwrap_or(false), + provider_import_source: transform_options + .provider_import_source + .clone() + .map(RcStr::into_owned), + jsx: transform_options.jsx.unwrap_or(false), // true means 'preserve' jsx syntax. + jsx_runtime, + jsx_import_source: transform_options + .jsx_import_source + .clone() + .map(RcStr::into_owned), + filepath: Some(this.source.ident().path().await?.to_string()), + ..Default::default() + }; + // TODO: upstream mdx currently bubbles error as string + let mdx_jsx_component = + compile(&file.content().to_str()?, &options).map_err(|e| anyhow!("{}", e))?; + + let source = VirtualSource::new_with_ident( + this.source.ident(), + AssetContent::file(File::from(Rope::from(mdx_jsx_component)).into()), + ); + Ok(EcmascriptModuleAsset::new( + Vc::upcast(source), + this.asset_context, + Value::new(EcmascriptModuleAssetType::Typescript { + tsx: true, + analyze_types: false, + }), + this.transforms, + this.ecmascript_options, + this.asset_context.compile_time_info(), + )) +} + +#[turbo_tasks::value_impl] +impl MdxModuleAsset { + #[turbo_tasks::function] + pub fn new( + source: Vc>, + asset_context: Vc>, + transforms: Vc, + options: Vc, + ecmascript_options: Vc, + ) -> Vc { + Self::cell(MdxModuleAsset { + source, + asset_context, + transforms, + options, + ecmascript_options, + }) + } + + #[turbo_tasks::function] + async fn analyze(self: Vc) -> Result> { + let asset = into_ecmascript_module_asset(&self).await; + + if let Ok(asset) = asset { + Ok(asset.analyze()) + } else { + let mut result = AnalyzeEcmascriptModuleResultBuilder::new(); + result.set_successful(false); + result.build(false).await + } + } +} + +#[turbo_tasks::value_impl] +impl Module for MdxModuleAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source + .ident() + .with_modifier(modifier()) + .with_layer(self.asset_context.layer()) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let analyze = self.analyze().await?; + Ok(analyze.references) + } +} + +#[turbo_tasks::value_impl] +impl Asset for MdxModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for MdxModuleAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast(MdxChunkItem::cell(MdxChunkItem { + module: self, + chunking_context, + }))) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for MdxModuleAsset { + #[turbo_tasks::function] + fn get_exports(&self) -> Vc { + EcmascriptExports::Value.cell() + } +} + +#[turbo_tasks::value_impl] +impl ResolveOrigin for MdxModuleAsset { + #[turbo_tasks::function] + fn origin_path(&self) -> Vc { + self.source.ident().path() + } + + #[turbo_tasks::function] + fn asset_context(&self) -> Vc> { + self.asset_context + } +} + +#[turbo_tasks::value] +struct MdxChunkItem { + module: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for MdxChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for MdxChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("MdxChunkItem::content should never be called"); + } + + /// Once we have mdx contents, we should treat it as j|tsx components and + /// apply all of the ecma transforms + #[turbo_tasks::function] + async fn content_with_async_module_info( + &self, + async_module_info: Option>, + ) -> Result> { + let item = into_ecmascript_module_asset(&self.module) + .await? + .as_chunk_item(Vc::upcast(self.chunking_context)); + let ecmascript_item = Vc::try_resolve_downcast::>(item) + .await? + .context("MdxChunkItem must generate an EcmascriptChunkItem")?; + Ok(ecmascript_item.content_with_async_module_info(async_module_info)) + } +} + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-node/Cargo.toml b/turbopack/crates/turbopack-node/Cargo.toml new file mode 100644 index 0000000000000..220319306fe60 --- /dev/null +++ b/turbopack/crates/turbopack-node/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "turbopack-node" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[features] +# enable "HMR" for embedded assets +dynamic_embed_contents = ["turbo-tasks-fs/dynamic_embed_contents"] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +async-stream = "0.3.4" +async-trait = { workspace = true } +const_format = "0.2.30" +futures = { workspace = true } +futures-retry = { workspace = true } +indexmap = { workspace = true, features = ["serde"] } +indoc = { workspace = true } +mime = { workspace = true } +once_cell = { workspace = true } +owo-colors = { workspace = true } +parking_lot = { workspace = true } +regex = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +#serde_qs = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tracing = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-bytes = { workspace = true } +turbo-tasks-env = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-cli-utils = { workspace = true } +turbopack-core = { workspace = true } +turbopack-dev-server = { workspace = true } +turbopack-ecmascript = { workspace = true } +turbopack-resolve = { workspace = true } +#url = { workspace = true } +#urlencoding = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-node/build.rs b/turbopack/crates/turbopack-node/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-node/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-node/js/package.json b/turbopack/crates/turbopack-node/js/package.json new file mode 100644 index 0000000000000..a75527735f00e --- /dev/null +++ b/turbopack/crates/turbopack-node/js/package.json @@ -0,0 +1,20 @@ +{ + "name": "@vercel/turbopack-node", + "version": "0.0.0", + "description": "turbopack node runtime", + "license": "UNLICENSED", + "private": true, + "scripts": { + "check": "tsc --noEmit" + }, + "dependencies": { + "loader-runner": "^4.3.0" + }, + "devDependencies": { + "@types/loader-runner": "^2.2.4", + "@types/node": "^18.11.11" + }, + "exports": { + "./*": "./src/*.ts" + } +} diff --git a/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/LICENSE b/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/LICENSE new file mode 100644 index 0000000000000..89e0797d875e1 --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2014-2019 Georg Tavonius + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/index.d.ts b/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/index.d.ts new file mode 100644 index 0000000000000..59cb13c617d30 --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/index.d.ts @@ -0,0 +1,2 @@ +export type StackFrame = any; +export const parse: any; diff --git a/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/index.js b/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/index.js new file mode 100644 index 0000000000000..e6546a064f7a0 --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/index.js @@ -0,0 +1,110 @@ +if (typeof __nccwpck_require__ !== "undefined") + __nccwpck_require__.ab = __dirname + "/"; + +var n = ""; +export function parse(e) { + var r = e.split("\n"); + return r.reduce(function (e, r) { + var n = + parseChrome(r) || + parseWinjs(r) || + parseGecko(r) || + parseNode(r) || + parseJSC(r); + if (n) { + e.push(n); + } + return e; + }, []); +} +var a = + /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack||\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i; +var l = /\((\S*)(?::(\d+))(?::(\d+))\)/; +function parseChrome(e) { + var r = a.exec(e); + if (!r) { + return null; + } + var u = r[2] && r[2].indexOf("native") === 0; + var t = r[2] && r[2].indexOf("eval") === 0; + var i = l.exec(r[2]); + if (t && i != null) { + r[2] = i[1]; + r[3] = i[2]; + r[4] = i[3]; + } + return { + file: !u ? r[2] : null, + methodName: r[1] || n, + arguments: u ? [r[2]] : [], + lineNumber: r[3] ? +r[3] : null, + column: r[4] ? +r[4] : null, + }; +} +var u = + /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i; +function parseWinjs(e) { + var r = u.exec(e); + if (!r) { + return null; + } + return { + file: r[2], + methodName: r[1] || n, + arguments: [], + lineNumber: +r[3], + column: r[4] ? +r[4] : null, + }; +} +var t = + /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i; +var i = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i; +function parseGecko(e) { + var r = t.exec(e); + if (!r) { + return null; + } + var a = r[3] && r[3].indexOf(" > eval") > -1; + var l = i.exec(r[3]); + if (a && l != null) { + r[3] = l[1]; + r[4] = l[2]; + r[5] = null; + } + return { + file: r[3], + methodName: r[1] || n, + arguments: r[2] ? r[2].split(",") : [], + lineNumber: r[4] ? +r[4] : null, + column: r[5] ? +r[5] : null, + }; +} +var s = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i; +function parseJSC(e) { + var r = s.exec(e); + if (!r) { + return null; + } + return { + file: r[3], + methodName: r[1] || n, + arguments: [], + lineNumber: +r[4], + column: r[5] ? +r[5] : null, + }; +} +var o = + /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i; +function parseNode(e) { + var r = o.exec(e); + if (!r) { + return null; + } + return { + file: r[2], + methodName: r[1] || n, + arguments: [], + lineNumber: +r[3], + column: r[4] ? +r[4] : null, + }; +} diff --git a/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/package.json b/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/package.json new file mode 100644 index 0000000000000..fee051ebe4952 --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/compiled/stacktrace-parser/package.json @@ -0,0 +1 @@ +{"name":"stacktrace-parser","main":"index.js","author":"Georg Tavonius (http://jaz-lounge.com)","license":"MIT", "types": "index.d.ts"} diff --git a/turbopack/crates/turbopack-node/js/src/globals.ts b/turbopack/crates/turbopack-node/js/src/globals.ts new file mode 100644 index 0000000000000..257842725280c --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/globals.ts @@ -0,0 +1,2 @@ +// @ts-ignore +process.turbopack = {}; diff --git a/turbopack/crates/turbopack-node/js/src/ipc/error.ts b/turbopack/crates/turbopack-node/js/src/ipc/error.ts new file mode 100644 index 0000000000000..fbab205b99cdc --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/ipc/error.ts @@ -0,0 +1,52 @@ +// merged from next.js +// https://github.com/vercel/next.js/blob/e657741b9908cf0044aaef959c0c4defb19ed6d8/packages/next/src/lib/is-error.ts +// https://github.com/vercel/next.js/blob/e657741b9908cf0044aaef959c0c4defb19ed6d8/packages/next/src/shared/lib/is-plain-object.ts + +export default function isError(err: unknown): err is Error { + return ( + typeof err === "object" && err !== null && "name" in err && "message" in err + ); +} + +export function getProperError(err: unknown): Error { + if (isError(err)) { + return err; + } + + if (process.env.NODE_ENV === "development") { + // Provide a better error message for cases where `throw undefined` + // is called in development + if (typeof err === "undefined") { + return new Error("`undefined` was thrown instead of a real error"); + } + + if (err === null) { + return new Error("`null` was thrown instead of a real error"); + } + } + + return new Error(isPlainObject(err) ? JSON.stringify(err) : err + ""); +} + +function getObjectClassLabel(value: any): string { + return Object.prototype.toString.call(value); +} + +function isPlainObject(value: any): boolean { + if (getObjectClassLabel(value) !== "[object Object]") { + return false; + } + + const prototype = Object.getPrototypeOf(value); + + /** + * this used to be previously: + * + * `return prototype === null || prototype === Object.prototype` + * + * but Edge Runtime expose Object from vm, being that kind of type-checking wrongly fail. + * + * It was changed to the current implementation since it's resilient to serialization. + */ + return prototype === null || prototype.hasOwnProperty("isPrototypeOf"); +} diff --git a/turbopack/crates/turbopack-node/js/src/ipc/evaluate.ts b/turbopack/crates/turbopack-node/js/src/ipc/evaluate.ts new file mode 100644 index 0000000000000..beb0c03229c99 --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/ipc/evaluate.ts @@ -0,0 +1,139 @@ +import { IPC, StructuredError } from "./index"; +import type { Ipc as GenericIpc } from "./index"; + +type IpcIncomingMessage = + | { + type: "evaluate"; + args: string[]; + } + | { + type: "result"; + id: number; + error: string | null; + data: any | null; + }; + +type IpcOutgoingMessage = + | { + type: "end"; + data: string | undefined; + duration: number; + } + | { + type: "info"; + data: any; + } + | { + type: "request"; + id: number; + data: any; + }; + +export type Ipc = { + sendInfo(message: IM): Promise; + sendRequest(message: RM): Promise; + sendError(error: Error): Promise; +}; +const ipc = IPC as GenericIpc; + +const queue: string[][] = []; + +export const run = async ( + moduleFactory: () => Promise<{ + init?: () => Promise; + default: (ipc: Ipc, ...deserializedArgs: any[]) => any; + }> +) => { + let nextId = 1; + const requests = new Map(); + const internalIpc = { + sendInfo: (message: any) => + ipc.send({ + type: "info", + data: message, + }), + sendRequest: (message: any) => { + const id = nextId++; + let resolve, reject; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + requests.set(id, { resolve, reject }); + return ipc + .send({ type: "request", id, data: message }) + .then(() => promise); + }, + sendError: (error: Error) => { + return ipc.sendError(error); + }, + }; + + // Initialize module and send ready message + let getValue: (ipc: Ipc, ...deserializedArgs: any[]) => any; + try { + const module = await moduleFactory(); + if (typeof module.init === "function") { + await module.init(); + } + getValue = module.default; + await ipc.sendReady(); + } catch (err) { + await ipc.sendReady(); + await ipc.sendError(err as Error); + } + + // Queue handling + let isRunning = false; + const run = async () => { + while (queue.length > 0) { + const args = queue.shift()!; + try { + const value = await getValue(internalIpc, ...args); + await ipc.send({ + type: "end", + data: + value === undefined ? undefined : JSON.stringify(value, null, 2), + duration: 0, + }); + } catch (e) { + await ipc.sendError(e as Error); + } + } + isRunning = false; + }; + + // Communication handling + while (true) { + const msg = await ipc.recv(); + + switch (msg.type) { + case "evaluate": { + queue.push(msg.args); + if (!isRunning) { + isRunning = true; + run(); + } + break; + } + case "result": { + const request = requests.get(msg.id); + if (request) { + requests.delete(msg.id); + if (msg.error) { + request.reject(new Error(msg.error)); + } else { + request.resolve(msg.data); + } + } + break; + } + default: { + console.error("unexpected message type", (msg as any).type); + process.exit(1); + } + } + } +}; + +export type { IpcIncomingMessage, IpcOutgoingMessage }; diff --git a/turbopack/crates/turbopack-node/js/src/ipc/index.ts b/turbopack/crates/turbopack-node/js/src/ipc/index.ts new file mode 100644 index 0000000000000..fa8d37f0c8a74 --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/ipc/index.ts @@ -0,0 +1,209 @@ +import { createConnection } from "node:net"; +import type { StackFrame } from "../compiled/stacktrace-parser"; +import { parse as parseStackTrace } from "../compiled/stacktrace-parser"; +import { getProperError } from "./error"; + +export type StructuredError = { + name: string; + message: string; + stack: StackFrame[]; +}; + +export function structuredError(e: Error): StructuredError { + e = getProperError(e); + + return { + name: e.name, + message: e.message, + stack: typeof e.stack === "string" ? parseStackTrace(e.stack!) : [], + }; +} + +type State = + | { + type: "waiting"; + } + | { + type: "packet"; + length: number; + }; + +export type Ipc = { + recv(): Promise; + send(message: TOutgoing): Promise; + sendError(error: Error): Promise; + sendReady(): Promise; +}; + +function createIpc( + port: number +): Ipc { + const socket = createConnection(port, "127.0.0.1"); + const packetQueue: Buffer[] = []; + const recvPromiseResolveQueue: Array<(message: TIncoming) => void> = []; + + function pushPacket(packet: Buffer) { + const recvPromiseResolve = recvPromiseResolveQueue.shift(); + if (recvPromiseResolve != null) { + recvPromiseResolve(JSON.parse(packet.toString("utf8")) as TIncoming); + } else { + packetQueue.push(packet); + } + } + + let state: State = { type: "waiting" }; + let buffer: Buffer = Buffer.alloc(0); + socket.once("connect", () => { + socket.on("data", (chunk) => { + buffer = Buffer.concat([buffer, chunk]); + + loop: while (true) { + switch (state.type) { + case "waiting": { + if (buffer.length >= 4) { + const length = buffer.readUInt32BE(0); + buffer = buffer.subarray(4); + state = { type: "packet", length }; + } else { + break loop; + } + break; + } + case "packet": { + if (buffer.length >= state.length) { + const packet = buffer.subarray(0, state.length); + buffer = buffer.subarray(state.length); + state = { type: "waiting" }; + pushPacket(packet); + } else { + break loop; + } + break; + } + } + } + }); + }); + // When the socket is closed, this process is no longer needed. + // This might happen e. g. when parent process is killed or + // node.js pool is garbage collected. + socket.once("close", () => { + process.exit(0); + }); + + function send(message: any): Promise { + const packet = Buffer.from(JSON.stringify(message), "utf8"); + const length = Buffer.alloc(4); + length.writeUInt32BE(packet.length); + socket.write(length); + + return new Promise((resolve, reject) => { + socket.write(packet, (err) => { + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + + function sendReady(): Promise { + const length = Buffer.from([0, 0, 0, 0]); + return new Promise((resolve, reject) => { + socket.write(length, (err) => { + process.stderr.write(`TURBOPACK_OUTPUT_D\n`); + process.stdout.write(`TURBOPACK_OUTPUT_D\n`); + + if (err != null) { + reject(err); + } else { + resolve(); + } + }); + }); + } + + return { + async recv() { + const packet = packetQueue.shift(); + if (packet != null) { + return JSON.parse(packet.toString("utf8")) as TIncoming; + } + + const result = await new Promise((resolve) => { + recvPromiseResolveQueue.push((result) => { + resolve(result); + }); + }); + + return result; + }, + + send(message: TOutgoing) { + return send(message); + }, + + sendReady, + + async sendError(error: Error): Promise { + try { + await send({ + type: "error", + ...structuredError(error), + }); + } catch (err) { + console.error("failed to send error back to rust:", err); + // ignore and exit anyway + process.exit(1); + } + + process.exit(0); + }, + }; +} + +const PORT = process.argv[2]; + +export const IPC = createIpc(parseInt(PORT, 10)); + +process.on("uncaughtException", (err) => { + IPC.sendError(err); +}); + +const improveConsole = (name: string, stream: string, addStack: boolean) => { + // @ts-ignore + const original = console[name]; + // @ts-ignore + const stdio = process[stream]; + // @ts-ignore + console[name] = (...args: any[]) => { + stdio.write(`TURBOPACK_OUTPUT_B\n`); + original(...args); + if (addStack) { + const stack = new Error().stack?.replace(/^.+\n.+\n/, "") + "\n"; + stdio.write("TURBOPACK_OUTPUT_S\n"); + stdio.write(stack); + } + stdio.write("TURBOPACK_OUTPUT_E\n"); + }; +}; + +improveConsole("error", "stderr", true); +improveConsole("warn", "stderr", true); +improveConsole("count", "stdout", true); +improveConsole("trace", "stderr", false); +improveConsole("log", "stdout", true); +improveConsole("group", "stdout", true); +improveConsole("groupCollapsed", "stdout", true); +improveConsole("table", "stdout", true); +improveConsole("debug", "stdout", true); +improveConsole("info", "stdout", true); +improveConsole("dir", "stdout", true); +improveConsole("dirxml", "stdout", true); +improveConsole("timeEnd", "stdout", true); +improveConsole("timeLog", "stdout", true); +improveConsole("timeStamp", "stdout", true); +improveConsole("assert", "stderr", true); diff --git a/turbopack/crates/turbopack-node/js/src/transforms/postcss.ts b/turbopack/crates/turbopack-node/js/src/transforms/postcss.ts new file mode 100644 index 0000000000000..7d7a558a32bac --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/transforms/postcss.ts @@ -0,0 +1,134 @@ +declare const __turbopack_external_require__: (id: string) => any; + +// @ts-ignore +import postcss from "@vercel/turbopack/postcss"; +// @ts-ignore +import importedConfig from "CONFIG"; +import { relative, isAbsolute, sep } from "path"; +import type { Ipc } from "../ipc/evaluate"; +import type { IpcInfoMessage, IpcRequestMessage } from "./webpack-loaders"; + +const contextDir = process.cwd(); + +function toPath(file: string) { + const relPath = relative(contextDir, file); + if (isAbsolute(relPath)) { + throw new Error( + `Cannot depend on path (${file}) outside of root directory (${contextDir})` + ); + } + return sep !== "/" ? relPath.replaceAll(sep, "/") : relPath; +} + +let processor: any; + +export const init = async (ipc: Ipc) => { + let config = importedConfig; + if (typeof config === "function") { + config = await config({ env: "development" }); + } + if (typeof config === "undefined") { + throw new Error( + "PostCSS config is undefined (make sure to export an function or object from config file)" + ); + } + let plugins: any[]; + if (Array.isArray(config.plugins)) { + plugins = config.plugins.map((plugin: [string, any] | string | any) => { + if (Array.isArray(plugin)) { + return plugin; + } else if (typeof plugin === "string") { + return [plugin, {}]; + } else { + return plugin; + } + }); + } else if (typeof config.plugins === "object") { + plugins = Object.entries(config.plugins).filter(([, options]) => options); + } else { + plugins = []; + } + const loadedPlugins = plugins.map((plugin) => { + if (Array.isArray(plugin)) { + const [arg, options] = plugin; + let pluginFactory = arg; + + if (typeof pluginFactory === "string") { + pluginFactory = __turbopack_external_require__(pluginFactory); + } + + if (pluginFactory.default) { + pluginFactory = pluginFactory.default; + } + + return pluginFactory(options); + } + return plugin; + }); + + processor = postcss(loadedPlugins); +}; + +export default async function transform( + ipc: Ipc, + cssContent: string, + name: string +) { + const { css, map, messages } = await processor.process(cssContent, { + from: name, + to: name, + map: { + inline: false, + annotation: false, + }, + }); + + const assets = []; + for (const msg of messages) { + switch (msg.type) { + case "asset": + assets.push({ + file: msg.file, + content: msg.content, + sourceMap: + typeof msg.sourceMap === "string" + ? msg.sourceMap + : JSON.stringify(msg.sourceMap), + // There is also an info field, which we currently ignore + }); + break; + case "file-dependency": + case "missing-dependency": + ipc.sendInfo({ + type: "fileDependency", + path: toPath(msg.file), + }); + break; + case "build-dependency": + ipc.sendInfo({ + type: "buildDependency", + path: toPath(msg.file), + }); + break; + case "dir-dependency": + ipc.sendInfo({ + type: "dirDependency", + path: toPath(msg.dir), + glob: msg.glob, + }); + break; + case "context-dependency": + ipc.sendInfo({ + type: "dirDependency", + path: toPath(msg.file), + glob: "**", + }); + break; + } + } + return { + css, + map: JSON.stringify(map), + assets, + }; +} diff --git a/turbopack/crates/turbopack-node/js/src/transforms/webpack-loaders.ts b/turbopack/crates/turbopack-node/js/src/transforms/webpack-loaders.ts new file mode 100644 index 0000000000000..ff254a0bccd04 --- /dev/null +++ b/turbopack/crates/turbopack-node/js/src/transforms/webpack-loaders.ts @@ -0,0 +1,519 @@ +declare const __turbopack_external_require__: { + resolve: (name: string, opt: { paths: string[] }) => string; +} & ((id: string) => any); + +import type { Ipc } from "../ipc/evaluate"; +import { + relative, + isAbsolute, + join, + sep, + dirname, + resolve as pathResolve, +} from "path"; +import { + StackFrame, + parse as parseStackTrace, +} from "../compiled/stacktrace-parser"; +import { type StructuredError } from "src/ipc"; + +export type IpcInfoMessage = + | { + type: "fileDependency"; + path: string; + } + | { + type: "buildDependency"; + path: string; + } + | { + type: "dirDependency"; + path: string; + glob: string; + } + | { + type: "emittedError"; + severity: "warning" | "error"; + error: StructuredError; + } + | { + type: "log"; + time: number; + logType: string; + args: any[]; + trace?: StackFrame[]; + }; + +export type IpcRequestMessage = { + type: "resolve"; + options: any; + lookupPath: string; + request: string; +}; + +type LoaderConfig = + | string + | { + loader: string; + options: { [k: string]: unknown }; + }; + +let runLoaders: typeof import("loader-runner")["runLoaders"]; +try { + ({ runLoaders } = require("@vercel/turbopack/loader-runner")); +} catch { + ({ runLoaders } = __turbopack_external_require__("loader-runner")); +} + +const contextDir = process.cwd(); +const toPath = (file: string) => { + const relPath = relative(contextDir, file); + if (isAbsolute(relPath)) { + throw new Error( + `Cannot depend on path (${file}) outside of root directory (${contextDir})` + ); + } + return sep !== "/" ? relPath.replaceAll(sep, "/") : relPath; +}; +const fromPath = (path: string) => { + return join(contextDir, sep !== "/" ? path.replaceAll("/", sep) : path); +}; + +const LogType = Object.freeze({ + error: "error", + warn: "warn", + info: "info", + log: "log", + debug: "debug", + + trace: "trace", + + group: "group", + groupCollapsed: "groupCollapsed", + groupEnd: "groupEnd", + + profile: "profile", + profileEnd: "profileEnd", + + time: "time", + + clear: "clear", + status: "status", +}); + +const loaderFlag = "LOADER_EXECUTION"; + +const cutOffByFlag = (stack: string, flag: string): string => { + const errorStack = stack.split("\n"); + for (let i = 0; i < errorStack.length; i++) { + if (errorStack[i].includes(flag)) { + errorStack.length = i; + } + } + return errorStack.join("\n"); +}; + +/** + * @param stack stack trace + * @returns stack trace without the loader execution flag included + */ +const cutOffLoaderExecution = (stack: string): string => + cutOffByFlag(stack, loaderFlag); + +class DummySpan { + traceChild() { + return new DummySpan(); + } + + traceFn(fn: (span: DummySpan) => T): T { + return fn(this); + } + + async traceAsyncFn(fn: (span: DummySpan) => T | Promise): Promise { + return await fn(this); + } + + stop() { + return; + } +} + +type ResolveOptions = { + dependencyType?: string; + alias?: Record | unknown[]; + aliasFields?: string[]; + cacheWithContext?: boolean; + conditionNames?: string[]; + descriptionFiles?: string[]; + enforceExtension?: boolean; + extensionAlias: Record; + extensions?: string[]; + fallback?: Record; + mainFields?: string[]; + mainFiles?: string[]; + exportsFields?: string[]; + modules?: string[]; + plugins?: unknown[]; + symlinks?: boolean; + unsafeCache?: boolean; + useSyncFileSystemCalls?: boolean; + preferRelative?: boolean; + preferAbsolute?: boolean; + restrictions?: unknown[]; + roots?: string[]; + importFields?: string[]; +}; +const SUPPORTED_RESOLVE_OPTIONS = new Set([ + "alias", + "aliasFields", + "conditionNames", + "descriptionFiles", + "extensions", + "exportsFields", + "mainFields", + "mainFiles", + "modules", + "restrictions", + "preferRelative", + "dependencyType", +]); + +const transform = ( + ipc: Ipc, + content: string, + name: string, + loaders: LoaderConfig[] +) => { + return new Promise((resolve, reject) => { + const resource = pathResolve(contextDir, name); + const resourceDir = dirname(resource); + + const loadersWithOptions = loaders.map((loader) => + typeof loader === "string" ? { loader, options: {} } : loader + ); + + runLoaders( + { + resource, + context: { + _module: { + // For debugging purpose, if someone find context is not full compatible to + // webpack they can guess this comes from turbopack + __reserved: "TurbopackContext", + }, + currentTraceSpan: new DummySpan(), + rootContext: contextDir, + getOptions() { + const entry = this.loaders[this.loaderIndex]; + return entry.options && typeof entry.options === "object" + ? entry.options + : {}; + }, + getResolve: (options: ResolveOptions) => { + const rustOptions = { + aliasFields: undefined as undefined | string[], + conditionNames: undefined as undefined | string[], + noPackageJson: false, + extensions: undefined as undefined | string[], + mainFields: undefined as undefined | string[], + noExportsField: false, + mainFiles: undefined as undefined | string[], + noModules: false, + preferRelative: false, + }; + if (options.alias) { + if (!Array.isArray(options.alias) || options.alias.length > 0) { + throw new Error("alias resolve option is not supported"); + } + } + if (options.aliasFields) { + if (!Array.isArray(options.aliasFields)) { + throw new Error("aliasFields resolve option must be an array"); + } + rustOptions.aliasFields = options.aliasFields; + } + if (options.conditionNames) { + if (!Array.isArray(options.conditionNames)) { + throw new Error( + "conditionNames resolve option must be an array" + ); + } + rustOptions.conditionNames = options.conditionNames; + } + if (options.descriptionFiles) { + if ( + !Array.isArray(options.descriptionFiles) || + options.descriptionFiles.length > 0 + ) { + throw new Error( + "descriptionFiles resolve option is not supported" + ); + } + rustOptions.noPackageJson = true; + } + if (options.extensions) { + if (!Array.isArray(options.extensions)) { + throw new Error("extensions resolve option must be an array"); + } + rustOptions.extensions = options.extensions; + } + if (options.mainFields) { + if (!Array.isArray(options.mainFields)) { + throw new Error("mainFields resolve option must be an array"); + } + rustOptions.mainFields = options.mainFields; + } + if (options.exportsFields) { + if ( + !Array.isArray(options.exportsFields) || + options.exportsFields.length > 0 + ) { + throw new Error( + "exportsFields resolve option is not supported" + ); + } + rustOptions.noExportsField = true; + } + if (options.mainFiles) { + if (!Array.isArray(options.mainFiles)) { + throw new Error("mainFiles resolve option must be an array"); + } + rustOptions.mainFiles = options.mainFiles; + } + if (options.modules) { + if ( + !Array.isArray(options.modules) || + options.modules.length > 0 + ) { + throw new Error("modules resolve option is not supported"); + } + rustOptions.noModules = true; + } + if (options.restrictions) { + // TODO This is ignored for now + } + if (options.dependencyType) { + // TODO This is ignored for now + } + if (options.preferRelative) { + if (typeof options.preferRelative !== "boolean") { + throw new Error( + "preferRelative resolve option must be a boolean" + ); + } + rustOptions.preferRelative = options.preferRelative; + } + return ( + lookupPath: string, + request: string, + callback?: (err?: Error, result?: string) => void + ) => { + const promise = ipc + .sendRequest({ + type: "resolve", + options: rustOptions, + lookupPath: toPath(lookupPath), + request, + }) + .then((unknownResult) => { + let result = unknownResult as { path: string }; + if (result && typeof result.path === "string") { + return fromPath(result.path); + } else { + throw Error( + "Expected { path: string } from resolve request" + ); + } + }); + if (callback) { + promise + .then( + (result) => callback(undefined, result), + (err) => callback(err) + ) + .catch((err) => { + ipc.sendError(err); + }); + } else { + return promise; + } + }; + }, + emitWarning: makeErrorEmitter("warning", ipc), + emitError: makeErrorEmitter("error", ipc), + getLogger(name: unknown) { + const logFn = (logType: string, ...args: unknown[]) => { + let trace; + switch (logType) { + case LogType.warn: + case LogType.error: + case LogType.trace: + case LogType.debug: + trace = parseStackTrace( + cutOffLoaderExecution(new Error("Trace").stack!) + .split("\n") + .slice(3) + .join("\n") + ); + break; + } + + ipc.sendInfo({ + type: "log", + time: Date.now(), + logType, + args, + trace, + }); + }; + let timers: Map | undefined; + let timersAggregates: Map | undefined; + + // See https://github.com/webpack/webpack/blob/a48c34b34d2d6c44f9b2b221d7baf278d34ac0be/lib/logging/Logger.js#L8 + return { + error: logFn.bind(this, LogType.error), + warn: logFn.bind(this, LogType.warn), + info: logFn.bind(this, LogType.info), + log: logFn.bind(this, LogType.log), + debug: logFn.bind(this, LogType.debug), + assert: (assertion: boolean, ...args: any[]) => { + if (!assertion) { + logFn(LogType.error, ...args); + } + }, + trace: logFn.bind(this, LogType.trace), + clear: logFn.bind(this, LogType.clear), + status: logFn.bind(this, LogType.status), + group: logFn.bind(this, LogType.group), + groupCollapsed: logFn.bind(this, LogType.groupCollapsed), + groupEnd: logFn.bind(this, LogType.groupEnd), + profile: logFn.bind(this, LogType.profile), + profileEnd: logFn.bind(this, LogType.profileEnd), + time: (label: string) => { + timers = timers || new Map(); + timers.set(label, process.hrtime()); + }, + timeLog: (label: string) => { + const prev = timers && timers.get(label); + if (!prev) { + throw new Error( + `No such label '${label}' for WebpackLogger.timeLog()` + ); + } + const time = process.hrtime(prev); + logFn(LogType.time, [label, ...time]); + }, + timeEnd: (label: string) => { + const prev = timers && timers.get(label); + if (!prev) { + throw new Error( + `No such label '${label}' for WebpackLogger.timeEnd()` + ); + } + const time = process.hrtime(prev); + /** @type {Map} */ + timers!.delete(label); + logFn(LogType.time, [label, ...time]); + }, + timeAggregate: (label: string) => { + const prev = timers && timers.get(label); + if (!prev) { + throw new Error( + `No such label '${label}' for WebpackLogger.timeAggregate()` + ); + } + const time = process.hrtime(prev); + /** @type {Map} */ + timers!.delete(label); + /** @type {Map} */ + timersAggregates = timersAggregates || new Map(); + const current = timersAggregates.get(label); + if (current !== undefined) { + if (time[1] + current[1] > 1e9) { + time[0] += current[0] + 1; + time[1] = time[1] - 1e9 + current[1]; + } else { + time[0] += current[0]; + time[1] += current[1]; + } + } + timersAggregates.set(label, time); + }, + timeAggregateEnd: (label: string) => { + if (timersAggregates === undefined) return; + const time = timersAggregates.get(label); + if (time === undefined) return; + timersAggregates.delete(label); + logFn(LogType.time, [label, ...time]); + }, + }; + }, + }, + + loaders: loadersWithOptions.map((loader) => ({ + loader: __turbopack_external_require__.resolve(loader.loader, { + paths: [resourceDir], + }), + options: loader.options, + })), + readResource: (_filename, callback) => { + // TODO assuming the filename === resource, but loaders might change that + callback(null, Buffer.from(content, "utf-8")); + }, + }, + (err, result) => { + if (err) return reject(err); + for (const dep of result.contextDependencies) { + ipc.sendInfo({ + type: "dirDependency", + path: toPath(dep), + glob: "**", + }); + } + for (const dep of result.fileDependencies) { + ipc.sendInfo({ + type: "fileDependency", + path: toPath(dep), + }); + } + if (!result.result) return reject(new Error("No result from loaders")); + const [source, map] = result.result; + resolve({ + source, + map: + typeof map === "string" + ? map + : typeof map === "object" + ? JSON.stringify(map) + : undefined, + }); + } + ); + }); +}; + +export { transform as default }; + +function makeErrorEmitter( + severity: "warning" | "error", + ipc: Ipc +) { + return function (error: Error | string) { + ipc.sendInfo({ + type: "emittedError", + severity: severity, + error: + error instanceof Error + ? { + name: error.name, + message: error.message, + stack: parseStackTrace(error.stack), + } + : { + name: "Error", + message: error, + stack: [], + }, + }); + }; +} diff --git a/turbopack/crates/turbopack-node/js/tsconfig.json b/turbopack/crates/turbopack-node/js/tsconfig.json new file mode 100644 index 0000000000000..4c88e2f5ef179 --- /dev/null +++ b/turbopack/crates/turbopack-node/js/tsconfig.json @@ -0,0 +1,30 @@ +{ + "compilerOptions": { + // type checking + "strict": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + + // interop constraints + "allowSyntheticDefaultImports": true, + "esModuleInterop": true, + + // js support + "allowJs": true, + "checkJs": false, + + // environment + "lib": ["ESNext"], + "target": "esnext", + + // modules + "baseUrl": ".", + "module": "esnext", + "moduleResolution": "node", + + // emit + "noEmit": true, + "stripInternal": true + }, + "include": ["src"] +} diff --git a/turbopack/crates/turbopack-node/src/debug.rs b/turbopack/crates/turbopack-node/src/debug.rs new file mode 100644 index 0000000000000..0d95ffd4f0573 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/debug.rs @@ -0,0 +1,18 @@ +use std::env; + +const DEBUG_JS_VAR: &str = "TURBOPACK_DEBUG_JS"; + +/// Checks if the operation passed is included in the `TURBOPACK_DEBUG_JS` env +/// var to enable node.js debugging at runtime. +/// +/// This is preferable to manually passing a boolean because recompiling won't +/// be necessary. +pub fn should_debug(operation: &str) -> bool { + // TODO(sokra) It's not persistent caching safe to read an env var this way. + // This must use turbo_tasks_env instead. + let Ok(val) = env::var(DEBUG_JS_VAR) else { + return false; + }; + + val == "*" || val.split(',').any(|part| part == operation) +} diff --git a/turbopack/crates/turbopack-node/src/embed_js.rs b/turbopack/crates/turbopack-node/src/embed_js.rs new file mode 100644 index 0000000000000..93f31eb503dd1 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/embed_js.rs @@ -0,0 +1,17 @@ +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::{embed_directory, FileContent, FileSystem, FileSystemPath}; + +#[turbo_tasks::function] +pub fn embed_fs() -> Vc> { + embed_directory!("turbopack-node", "$CARGO_MANIFEST_DIR/js/src") +} + +#[turbo_tasks::function] +pub(crate) fn embed_file(path: RcStr) -> Vc { + embed_fs().root().join(path).read() +} + +#[turbo_tasks::function] +pub(crate) fn embed_file_path(path: RcStr) -> Vc { + embed_fs().root().join(path) +} diff --git a/turbopack/crates/turbopack-node/src/evaluate.rs b/turbopack/crates/turbopack-node/src/evaluate.rs new file mode 100644 index 0000000000000..505755b12c711 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/evaluate.rs @@ -0,0 +1,603 @@ +use std::{borrow::Cow, ops::ControlFlow, thread::available_parallelism, time::Duration}; + +use anyhow::{anyhow, bail, Result}; +use async_stream::try_stream as generator; +use async_trait::async_trait; +use futures::{ + channel::mpsc::{unbounded, UnboundedSender}, + pin_mut, SinkExt, StreamExt, +}; +use futures_retry::{FutureRetry, RetryPolicy}; +use indexmap::indexmap; +use parking_lot::Mutex; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use serde_json::Value as JsonValue; +use turbo_tasks::{ + duration_span, mark_finished, prevent_gc, util::SharedError, Completion, RawVc, TaskInput, + TryJoinIterExt, Value, Vc, +}; +use turbo_tasks_bytes::{Bytes, Stream}; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::{to_sys_path, File, FileSystemPath}; +use turbopack_core::{ + asset::AssetContent, + chunk::{ChunkingContext, ChunkingContextExt, EvaluatableAsset, EvaluatableAssets}, + context::AssetContext, + error::PrettyPrintError, + file_source::FileSource, + ident::AssetIdent, + issue::{Issue, IssueExt, IssueStage, OptionStyledString, StyledString}, + module::Module, + reference_type::{InnerAssets, ReferenceType}, + virtual_source::VirtualSource, +}; + +use crate::{ + embed_js::embed_file_path, + emit, emit_package_json, internal_assets_for_source_mapping, + pool::{FormattingMode, NodeJsOperation, NodeJsPool}, + source_map::StructuredError, + AssetsForSourceMapping, +}; + +#[derive(Serialize)] +#[serde(tag = "type", rename_all = "camelCase")] +enum EvalJavaScriptOutgoingMessage<'a> { + #[serde(rename_all = "camelCase")] + Evaluate { args: Vec<&'a JsonValue> }, + Result { + id: u64, + data: Option, + error: Option, + }, +} + +#[derive(Deserialize, Debug)] +#[serde(tag = "type", rename_all = "camelCase")] +enum EvalJavaScriptIncomingMessage { + Info { data: JsonValue }, + Request { id: u64, data: JsonValue }, + End { data: Option }, + Error(StructuredError), +} + +type LoopResult = ControlFlow, StructuredError>, String>; + +type EvaluationItem = Result; +type JavaScriptStream = Stream; + +#[turbo_tasks::value(eq = "manual", cell = "new", serialization = "none")] +pub struct JavaScriptStreamSender { + #[turbo_tasks(trace_ignore, debug_ignore)] + get: Box UnboundedSender> + Send + Sync>, +} + +#[turbo_tasks::value(transparent)] +#[derive(Clone, Debug)] +pub struct JavaScriptEvaluation(#[turbo_tasks(trace_ignore)] JavaScriptStream); + +#[turbo_tasks::function] +/// Pass the file you cared as `runtime_entries` to invalidate and reload the +/// evaluated result automatically. +pub async fn get_evaluate_pool( + module_asset: Vc>, + cwd: Vc, + env: Vc>, + asset_context: Vc>, + chunking_context: Vc>, + runtime_entries: Option>, + additional_invalidation: Vc, + debug: bool, +) -> Result> { + let runtime_asset = asset_context + .process( + Vc::upcast(FileSource::new(embed_file_path("ipc/evaluate.ts".into()))), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) + .module(); + + let module_path = module_asset.ident().path().await?; + let file_name = module_path.file_name(); + let file_name = if file_name.ends_with(".js") { + Cow::Borrowed(file_name) + } else if let Some(file_name) = file_name.strip_suffix(".ts") { + Cow::Owned(format!("{file_name}.js")) + } else { + Cow::Owned(format!("{file_name}.js")) + }; + let path = chunking_context.output_root().join(file_name.into()); + let entry_module = asset_context + .process( + Vc::upcast(VirtualSource::new( + runtime_asset.ident().path().join("evaluate.js".into()), + AssetContent::file( + File::from("import { run } from 'RUNTIME'; run(() => import('INNER'))").into(), + ), + )), + Value::new(ReferenceType::Internal(Vc::cell(indexmap! { + "INNER".into() => module_asset, + "RUNTIME".into() => runtime_asset + }))), + ) + .module(); + + let (Some(cwd), Some(entrypoint)) = (to_sys_path(cwd).await?, to_sys_path(path).await?) else { + panic!("can only evaluate from a disk filesystem"); + }; + + let runtime_entries = { + let globals_module = asset_context + .process( + Vc::upcast(FileSource::new(embed_file_path("globals.ts".into()))), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) + .module(); + + let Some(globals_module) = + Vc::try_resolve_sidecast::>(globals_module).await? + else { + bail!("Internal module is not evaluatable"); + }; + + let mut entries = vec![globals_module]; + if let Some(runtime_entries) = runtime_entries { + for &entry in &*runtime_entries.await? { + entries.push(entry) + } + } + + Vc::::cell(entries) + }; + + let bootstrap = + chunking_context.root_entry_chunk_group_asset(path, entry_module, runtime_entries); + + let output_root: Vc = chunking_context.output_root(); + let emit_package = emit_package_json(output_root); + let emit = emit(bootstrap, output_root); + let assets_for_source_mapping = internal_assets_for_source_mapping(bootstrap, output_root); + emit_package.await?; + emit.await?; + let pool = NodeJsPool::new( + cwd, + entrypoint, + env.read_all() + .await? + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), + assets_for_source_mapping, + output_root, + chunking_context.context_path().root(), + available_parallelism().map_or(1, |v| v.get()), + debug, + ); + additional_invalidation.await?; + Ok(pool.cell()) +} + +struct PoolErrorHandler; + +/// Number of attempts before we start slowing down the retry. +const MAX_FAST_ATTEMPTS: usize = 5; +/// Total number of attempts. +const MAX_ATTEMPTS: usize = MAX_FAST_ATTEMPTS * 2; + +impl futures_retry::ErrorHandler for PoolErrorHandler { + type OutError = anyhow::Error; + + fn handle(&mut self, attempt: usize, err: anyhow::Error) -> RetryPolicy { + if attempt >= MAX_ATTEMPTS { + RetryPolicy::ForwardError(err) + } else if attempt >= MAX_FAST_ATTEMPTS { + RetryPolicy::WaitRetry(Duration::from_secs(1)) + } else { + RetryPolicy::Repeat + } + } +} + +#[async_trait] +pub trait EvaluateContext { + type InfoMessage: DeserializeOwned; + type RequestMessage: DeserializeOwned; + type ResponseMessage: Serialize; + type State: Default; + + fn compute(self, sender: Vc); + fn pool(&self) -> Vc; + fn keep_alive(&self) -> bool { + false + } + fn args(&self) -> &[Vc]; + fn cwd(&self) -> Vc; + async fn emit_error(&self, error: StructuredError, pool: &NodeJsPool) -> Result<()>; + async fn info( + &self, + state: &mut Self::State, + data: Self::InfoMessage, + pool: &NodeJsPool, + ) -> Result<()>; + async fn request( + &self, + state: &mut Self::State, + data: Self::RequestMessage, + pool: &NodeJsPool, + ) -> Result; + async fn finish(&self, _state: Self::State, _pool: &NodeJsPool) -> Result<()>; +} + +pub fn custom_evaluate(evaluate_context: impl EvaluateContext) -> Vc { + // TODO: The way we invoke compute_evaluate_stream as side effect is not + // GC-safe, so we disable GC for this task. + prevent_gc(); + + // Note the following code uses some hacks to create a child task that produces + // a stream that is returned by this task. + + // We create a new cell in this task, which will be updated from the + // [compute_evaluate_stream] task. + let cell = turbo_tasks::macro_helpers::find_cell_by_type(*JAVASCRIPTEVALUATION_VALUE_TYPE_ID); + + // We initialize the cell with a stream that is open, but has no values. + // The first [compute_evaluate_stream] pipe call will pick up that stream. + let (sender, receiver) = unbounded(); + cell.update_shared(JavaScriptEvaluation(JavaScriptStream::new_open( + vec![], + Box::new(receiver), + ))); + let initial = Mutex::new(Some(sender)); + + // run the evaluation as side effect + evaluate_context.compute( + JavaScriptStreamSender { + get: Box::new(move || { + if let Some(sender) = initial.lock().take() { + sender + } else { + // In cases when only [compute_evaluate_stream] is (re)executed, we need to + // update the old stream with a new value. + let (sender, receiver) = unbounded(); + cell.update_shared(JavaScriptEvaluation(JavaScriptStream::new_open( + vec![], + Box::new(receiver), + ))); + sender + } + }), + } + .cell(), + ); + + let raw: RawVc = cell.into(); + raw.into() +} + +/// Pass the file you cared as `runtime_entries` to invalidate and reload the +/// evaluated result automatically. +#[turbo_tasks::function] +pub fn evaluate( + module_asset: Vc>, + cwd: Vc, + env: Vc>, + context_ident_for_issue: Vc, + asset_context: Vc>, + chunking_context: Vc>, + runtime_entries: Option>, + args: Vec>, + additional_invalidation: Vc, + debug: bool, +) -> Vc { + custom_evaluate(BasicEvaluateContext { + module_asset, + cwd, + env, + context_ident_for_issue, + asset_context, + chunking_context, + runtime_entries, + args, + additional_invalidation, + debug, + }) +} + +pub async fn compute( + evaluate_context: impl EvaluateContext, + sender: Vc, +) -> Result> { + mark_finished(); + let Ok(sender) = sender.await else { + // Impossible to handle the error in a good way. + return Ok(Default::default()); + }; + + let stream = generator! { + let pool = evaluate_context.pool(); + let mut state = Default::default(); + + // Read this strongly consistent, since we don't want to run inconsistent + // node.js code. + let pool = pool.strongly_consistent().await?; + + let args = evaluate_context.args().iter().try_join().await?; + // Assume this is a one-off operation, so we can kill the process + // TODO use a better way to decide that. + let kill = !evaluate_context.keep_alive(); + + // Workers in the pool could be in a bad state that we didn't detect yet. + // The bad state might even be unnoticeable until we actually send the job to the + // worker. So we retry picking workers from the pools until we succeed + // sending the job. + + let (mut operation, _) = FutureRetry::new( + || async { + let mut operation = pool.operation().await?; + operation + .send(EvalJavaScriptOutgoingMessage::Evaluate { + args: args.iter().map(|v| &**v).collect(), + }) + .await?; + Ok(operation) + }, + PoolErrorHandler, + ) + .await + .map_err(|(e, _)| e)?; + + // The evaluation sent an initial intermediate value without completing. We'll + // need to spawn a new thread to continually pull data out of the process, + // and ferry that along. + loop { + let output = pull_operation(&mut operation, &pool, &evaluate_context, &mut state).await?; + + match output { + LoopResult::Continue(data) => { + yield data.into(); + } + LoopResult::Break(Ok(Some(data))) => { + yield data.into(); + break; + } + LoopResult::Break(Err(e)) => { + let error = print_error(e, &pool, &evaluate_context).await?; + Err(anyhow!("Node.js evaluation failed: {}", error))?; + break; + } + LoopResult::Break(Ok(None)) => { + break; + } + } + } + + evaluate_context.finish(state, &pool).await?; + + if kill { + operation.wait_or_kill().await?; + } + }; + + let mut sender = (sender.get)(); + pin_mut!(stream); + while let Some(value) = stream.next().await { + if sender.send(value).await.is_err() { + return Ok(Default::default()); + } + if sender.flush().await.is_err() { + return Ok(Default::default()); + } + } + + Ok(Default::default()) +} + +/// Repeatedly pulls from the NodeJsOperation until we receive a +/// value/error/end. +async fn pull_operation( + operation: &mut NodeJsOperation, + pool: &NodeJsPool, + evaluate_context: &T, + state: &mut T::State, +) -> Result { + let guard = duration_span!("Node.js evaluation"); + + let output = loop { + match operation.recv().await? { + EvalJavaScriptIncomingMessage::Error(error) => { + evaluate_context.emit_error(error, pool).await?; + // Do not reuse the process in case of error + operation.disallow_reuse(); + // Issue emitted, we want to break but don't want to return an error + break ControlFlow::Break(Ok(None)); + } + EvalJavaScriptIncomingMessage::End { data } => break ControlFlow::Break(Ok(data)), + EvalJavaScriptIncomingMessage::Info { data } => { + evaluate_context + .info(state, serde_json::from_value(data)?, pool) + .await?; + } + EvalJavaScriptIncomingMessage::Request { id, data } => { + match evaluate_context + .request(state, serde_json::from_value(data)?, pool) + .await + { + Ok(response) => { + operation + .send(EvalJavaScriptOutgoingMessage::Result { + id, + error: None, + data: Some(serde_json::to_value(response)?), + }) + .await?; + } + Err(e) => { + operation + .send(EvalJavaScriptOutgoingMessage::Result { + id, + error: Some(PrettyPrintError(&e).to_string()), + data: None, + }) + .await?; + } + } + } + } + }; + drop(guard); + + Ok(output) +} + +#[turbo_tasks::function] +async fn basic_compute( + evaluate_context: BasicEvaluateContext, + sender: Vc, +) -> Result> { + compute(evaluate_context, sender).await +} + +#[derive(Clone, PartialEq, Eq, Hash, TaskInput, Debug, Serialize, Deserialize)] +struct BasicEvaluateContext { + module_asset: Vc>, + cwd: Vc, + env: Vc>, + context_ident_for_issue: Vc, + asset_context: Vc>, + chunking_context: Vc>, + runtime_entries: Option>, + args: Vec>, + additional_invalidation: Vc, + debug: bool, +} + +#[async_trait] +impl EvaluateContext for BasicEvaluateContext { + type InfoMessage = (); + type RequestMessage = (); + type ResponseMessage = (); + type State = (); + + fn compute(self, sender: Vc) { + let _ = basic_compute(self, sender); + } + + fn pool(&self) -> Vc { + get_evaluate_pool( + self.module_asset, + self.cwd, + self.env, + self.asset_context, + self.chunking_context, + self.runtime_entries, + self.additional_invalidation, + self.debug, + ) + } + + fn args(&self) -> &[Vc] { + &self.args + } + + fn cwd(&self) -> Vc { + self.cwd + } + + fn keep_alive(&self) -> bool { + !self.args.is_empty() + } + + async fn emit_error(&self, error: StructuredError, pool: &NodeJsPool) -> Result<()> { + EvaluationIssue { + error, + context_ident: self.context_ident_for_issue, + assets_for_source_mapping: pool.assets_for_source_mapping, + assets_root: pool.assets_root, + project_dir: self.chunking_context.context_path().root(), + } + .cell() + .emit(); + Ok(()) + } + + async fn info( + &self, + _state: &mut Self::State, + _data: Self::InfoMessage, + _pool: &NodeJsPool, + ) -> Result<()> { + bail!("BasicEvaluateContext does not support info messages") + } + + async fn request( + &self, + _state: &mut Self::State, + _data: Self::RequestMessage, + _pool: &NodeJsPool, + ) -> Result { + bail!("BasicEvaluateContext does not support request messages") + } + + async fn finish(&self, _state: Self::State, _pool: &NodeJsPool) -> Result<()> { + Ok(()) + } +} + +async fn print_error( + error: StructuredError, + pool: &NodeJsPool, + evaluate_context: &impl EvaluateContext, +) -> Result { + error + .print( + pool.assets_for_source_mapping, + pool.assets_root, + evaluate_context.cwd(), + FormattingMode::Plain, + ) + .await +} +/// An issue that occurred while evaluating node code. +#[turbo_tasks::value(shared)] +pub struct EvaluationIssue { + pub context_ident: Vc, + pub error: StructuredError, + pub assets_for_source_mapping: Vc, + pub assets_root: Vc, + pub project_dir: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for EvaluationIssue { + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Error evaluating Node.js code".into()).cell() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Transform.into() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.context_ident.path() + } + + #[turbo_tasks::function] + async fn description(&self) -> Result> { + Ok(Vc::cell(Some( + StyledString::Text( + self.error + .print( + self.assets_for_source_mapping, + self.assets_root, + self.project_dir, + FormattingMode::Plain, + ) + .await? + .into(), + ) + .cell(), + ))) + } +} diff --git a/turbopack/crates/turbopack-node/src/execution_context.rs b/turbopack/crates/turbopack-node/src/execution_context.rs new file mode 100644 index 0000000000000..a6846c75e082e --- /dev/null +++ b/turbopack/crates/turbopack-node/src/execution_context.rs @@ -0,0 +1,44 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::chunk::ChunkingContext; + +#[turbo_tasks::value] +pub struct ExecutionContext { + pub project_path: Vc, + pub chunking_context: Vc>, + pub env: Vc>, +} + +#[turbo_tasks::value_impl] +impl ExecutionContext { + #[turbo_tasks::function] + pub fn new( + project_path: Vc, + chunking_context: Vc>, + env: Vc>, + ) -> Vc { + ExecutionContext { + project_path, + chunking_context, + env, + } + .cell() + } + + #[turbo_tasks::function] + pub async fn project_path(self: Vc) -> Result> { + Ok(self.await?.project_path) + } + + #[turbo_tasks::function] + pub async fn chunking_context(self: Vc) -> Result>> { + Ok(self.await?.chunking_context) + } + + #[turbo_tasks::function] + pub async fn env(self: Vc) -> Result>> { + Ok(self.await?.env) + } +} diff --git a/turbopack/crates/turbopack-node/src/lib.rs b/turbopack/crates/turbopack-node/src/lib.rs new file mode 100644 index 0000000000000..73c39aff9c819 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/lib.rs @@ -0,0 +1,287 @@ +#![feature(async_closure)] +#![feature(min_specialization)] +#![feature(lint_reasons)] +#![feature(arbitrary_self_types)] +#![feature(extract_if)] + +use std::{collections::HashMap, iter::once, thread::available_parallelism}; + +use anyhow::{bail, Result}; +use indexmap::IndexSet; +pub use node_entry::{NodeEntry, NodeRenderingEntries, NodeRenderingEntry}; +use turbo_tasks::{ + graph::{AdjacencyMap, GraphTraversal}, + Completion, Completions, RcStr, TryJoinIterExt, ValueToString, Vc, +}; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::{to_sys_path, File, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkingContext, ChunkingContextExt, EvaluatableAssets}, + module::Module, + output::{OutputAsset, OutputAssetsSet}, + source_map::GenerateSourceMap, + virtual_output::VirtualOutputAsset, +}; + +use self::{pool::NodeJsPool, source_map::StructuredError}; + +pub mod debug; +pub mod embed_js; +pub mod evaluate; +pub mod execution_context; +mod node_entry; +mod pool; +pub mod render; +pub mod route_matcher; +pub mod source_map; +pub mod transforms; + +#[turbo_tasks::function] +async fn emit( + intermediate_asset: Vc>, + intermediate_output_path: Vc, +) -> Result> { + Ok(Vc::::cell( + internal_assets(intermediate_asset, intermediate_output_path) + .strongly_consistent() + .await? + .iter() + .map(|a| a.content().write(a.ident().path())) + .collect(), + ) + .completed()) +} + +/// List of the all assets of the "internal" subgraph and a list of boundary +/// assets that are not considered "internal" ("external") +#[derive(Debug)] +#[turbo_tasks::value] +struct SeparatedAssets { + internal_assets: Vc, + external_asset_entrypoints: Vc, +} + +/// Extracts the subgraph of "internal" assets (assets within the passes +/// directory). Also lists all boundary assets that are not part of the +/// "internal" subgraph. +#[turbo_tasks::function] +async fn internal_assets( + intermediate_asset: Vc>, + intermediate_output_path: Vc, +) -> Result> { + Ok( + separate_assets(intermediate_asset, intermediate_output_path) + .strongly_consistent() + .await? + .internal_assets, + ) +} + +#[turbo_tasks::value(transparent)] +pub struct AssetsForSourceMapping(HashMap>>); + +/// Extracts a map of "internal" assets ([`internal_assets`]) which implement +/// the [GenerateSourceMap] trait. +#[turbo_tasks::function] +async fn internal_assets_for_source_mapping( + intermediate_asset: Vc>, + intermediate_output_path: Vc, +) -> Result> { + let internal_assets = internal_assets(intermediate_asset, intermediate_output_path).await?; + let intermediate_output_path = &*intermediate_output_path.await?; + let mut internal_assets_for_source_mapping = HashMap::new(); + for asset in internal_assets.iter() { + if let Some(generate_source_map) = + Vc::try_resolve_sidecast::>(*asset).await? + { + if let Some(path) = intermediate_output_path.get_path_to(&*asset.ident().path().await?) + { + internal_assets_for_source_mapping.insert(path.to_string(), generate_source_map); + } + } + } + Ok(Vc::cell(internal_assets_for_source_mapping)) +} + +/// Returns a set of "external" assets on the boundary of the "internal" +/// subgraph +#[turbo_tasks::function] +pub async fn external_asset_entrypoints( + module: Vc>, + runtime_entries: Vc, + chunking_context: Vc>, + intermediate_output_path: Vc, +) -> Result> { + Ok(separate_assets( + get_intermediate_asset(chunking_context, module, runtime_entries) + .resolve() + .await?, + intermediate_output_path, + ) + .strongly_consistent() + .await? + .external_asset_entrypoints) +} + +/// Splits the asset graph into "internal" assets and boundaries to "external" +/// assets. +#[turbo_tasks::function] +async fn separate_assets( + intermediate_asset: Vc>, + intermediate_output_path: Vc, +) -> Result> { + let intermediate_output_path = &*intermediate_output_path.await?; + #[derive(PartialEq, Eq, Hash, Clone, Copy)] + enum Type { + Internal(Vc>), + External(Vc>), + } + let get_asset_children = |asset| async move { + let Type::Internal(asset) = asset else { + return Ok(Vec::new()); + }; + asset + .references() + .await? + .iter() + .map(|asset| async { + // Assets within the output directory are considered as "internal" and all + // others as "external". We follow references on "internal" assets, but do not + // look into references of "external" assets, since there are no "internal" + // assets behind "externals" + if asset + .ident() + .path() + .await? + .is_inside_ref(intermediate_output_path) + { + Ok(Type::Internal(*asset)) + } else { + Ok(Type::External(*asset)) + } + }) + .try_join() + .await + }; + + let graph = AdjacencyMap::new() + .skip_duplicates() + .visit(once(Type::Internal(intermediate_asset)), get_asset_children) + .await + .completed()? + .into_inner(); + + let mut internal_assets = IndexSet::new(); + let mut external_asset_entrypoints = IndexSet::new(); + + for item in graph.into_reverse_topological() { + match item { + Type::Internal(asset) => { + internal_assets.insert(asset); + } + Type::External(asset) => { + external_asset_entrypoints.insert(asset); + } + } + } + + Ok(SeparatedAssets { + internal_assets: Vc::cell(internal_assets), + external_asset_entrypoints: Vc::cell(external_asset_entrypoints), + } + .cell()) +} + +/// Emit a basic package.json that sets the type of the package to commonjs. +/// Currently code generated for Node is CommonJS, while authored code may be +/// ESM, for example. +fn emit_package_json(dir: Vc) -> Vc { + emit( + Vc::upcast(VirtualOutputAsset::new( + dir.join("package.json".into()), + AssetContent::file(File::from("{\"type\": \"commonjs\"}").into()), + )), + dir, + ) +} + +/// Creates a node.js renderer pool for an entrypoint. +#[turbo_tasks::function] +pub async fn get_renderer_pool( + cwd: Vc, + env: Vc>, + intermediate_asset: Vc>, + intermediate_output_path: Vc, + output_root: Vc, + project_dir: Vc, + debug: bool, +) -> Result> { + emit_package_json(intermediate_output_path).await?; + + let emit = emit(intermediate_asset, output_root); + let assets_for_source_mapping = + internal_assets_for_source_mapping(intermediate_asset, output_root); + + let entrypoint = intermediate_asset.ident().path(); + + let Some(cwd) = to_sys_path(cwd).await? else { + bail!( + "can only render from a disk filesystem, but `cwd = {}`", + cwd.to_string().await? + ); + }; + let Some(entrypoint) = to_sys_path(entrypoint).await? else { + bail!( + "can only render from a disk filesystem, but `entrypoint = {}`", + entrypoint.to_string().await? + ); + }; + + emit.await?; + Ok(NodeJsPool::new( + cwd, + entrypoint, + env.read_all() + .await? + .iter() + .map(|(k, v)| (k.clone(), v.clone())) + .collect(), + assets_for_source_mapping, + output_root, + project_dir, + available_parallelism().map_or(1, |v| v.get()), + debug, + ) + .cell()) +} + +/// Converts a module graph into node.js executable assets +#[turbo_tasks::function] +pub async fn get_intermediate_asset( + chunking_context: Vc>, + main_entry: Vc>, + other_entries: Vc, +) -> Result>> { + Ok(Vc::upcast(chunking_context.root_entry_chunk_group_asset( + chunking_context.chunk_path(main_entry.ident(), ".js".into()), + main_entry, + other_entries, + ))) +} + +#[derive(Clone, Debug)] +#[turbo_tasks::value(shared)] +pub struct ResponseHeaders { + pub status: u16, + pub headers: Vec<(RcStr, RcStr)>, +} + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_bytes::register(); + turbo_tasks_fs::register(); + turbopack_dev_server::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-node/src/node_entry.rs b/turbopack/crates/turbopack-node/src/node_entry.rs new file mode 100644 index 0000000000000..ee74db8bb921b --- /dev/null +++ b/turbopack/crates/turbopack-node/src/node_entry.rs @@ -0,0 +1,29 @@ +use turbo_tasks::{Value, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + chunk::{ChunkingContext, EvaluatableAssets}, + module::Module, +}; +use turbopack_dev_server::source::ContentSourceData; + +#[turbo_tasks::value(shared)] +pub struct NodeRenderingEntry { + pub runtime_entries: Vc, + pub module: Vc>, + pub chunking_context: Vc>, + pub intermediate_output_path: Vc, + pub output_root: Vc, + pub project_dir: Vc, +} + +#[turbo_tasks::value(transparent)] +pub struct NodeRenderingEntries(Vec>); + +/// Trait that allows to get the entry module for rendering something in Node.js +#[turbo_tasks::value_trait] +pub trait NodeEntry { + fn entry(self: Vc, data: Value) -> Vc; + fn entries(self: Vc) -> Vc { + Vc::cell(vec![self.entry(Value::new(Default::default()))]) + } +} diff --git a/turbopack/crates/turbopack-node/src/pool.rs b/turbopack/crates/turbopack-node/src/pool.rs new file mode 100644 index 0000000000000..e1ef873927ec3 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/pool.rs @@ -0,0 +1,948 @@ +use std::{ + borrow::Cow, + cmp::max, + collections::HashMap, + fmt::{Debug, Display}, + future::Future, + mem::take, + path::{Path, PathBuf}, + process::{ExitStatus, Stdio}, + sync::Arc, + time::{Duration, Instant}, +}; + +use anyhow::{bail, Context, Result}; +use futures::join; +use indexmap::IndexSet; +use owo_colors::{OwoColorize, Style}; +use parking_lot::Mutex; +use serde::{de::DeserializeOwned, Serialize}; +use tokio::{ + io::{ + stderr, stdout, AsyncBufReadExt, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, + BufReader, Stderr, Stdout, + }, + net::{TcpListener, TcpStream}, + process::{Child, ChildStderr, ChildStdout, Command}, + select, + sync::{OwnedSemaphorePermit, Semaphore}, + time::{sleep, timeout}, +}; +use turbo_tasks::{duration_span, RcStr, Vc}; +use turbo_tasks_fs::{json::parse_json_with_source_context, FileSystemPath}; +use turbopack_ecmascript::magic_identifier::unmangle_identifiers; + +use crate::{source_map::apply_source_mapping, AssetsForSourceMapping}; + +#[derive(Clone, Copy)] +pub enum FormattingMode { + /// No formatting, just print the output + Plain, + /// Use ansi colors to format the output + AnsiColors, +} + +impl FormattingMode { + pub fn magic_identifier<'a>(&self, content: impl Display + 'a) -> impl Display + 'a { + match self { + FormattingMode::Plain => format!("{{{}}}", content), + FormattingMode::AnsiColors => format!("{{{}}}", content).italic().to_string(), + } + } + + pub fn lowlight<'a>(&self, content: impl Display + 'a) -> impl Display + 'a { + match self { + FormattingMode::Plain => Style::new(), + FormattingMode::AnsiColors => Style::new().dimmed(), + } + .style(content) + } + + pub fn highlight<'a>(&self, content: impl Display + 'a) -> impl Display + 'a { + match self { + FormattingMode::Plain => Style::new(), + FormattingMode::AnsiColors => Style::new().bold().underline(), + } + .style(content) + } +} + +struct NodeJsPoolProcess { + child: Option, + connection: TcpStream, + assets_for_source_mapping: Vc, + assets_root: Vc, + project_dir: Vc, + stdout_handler: OutputStreamHandler, + stderr_handler: OutputStreamHandler, + debug: bool, +} + +impl NodeJsPoolProcess { + pub async fn apply_source_mapping<'a>( + &self, + text: &'a str, + formatting_mode: FormattingMode, + ) -> Result> { + let text = unmangle_identifiers(text, |content| formatting_mode.magic_identifier(content)); + match text { + Cow::Borrowed(text) => { + apply_source_mapping( + text, + self.assets_for_source_mapping, + self.assets_root, + self.project_dir, + formatting_mode, + ) + .await + } + Cow::Owned(ref text) => { + let cow = apply_source_mapping( + text, + self.assets_for_source_mapping, + self.assets_root, + self.project_dir, + formatting_mode, + ) + .await?; + Ok(Cow::Owned(cow.into_owned())) + } + } + } +} + +const CONNECT_TIMEOUT: Duration = Duration::from_secs(30); + +#[derive(Clone, PartialEq, Eq, Hash)] +struct OutputEntry { + data: Arc<[u8]>, + stack_trace: Option>, +} + +type SharedOutputSet = Arc>>; + +static GLOBAL_OUTPUT_LOCK: tokio::sync::Mutex<()> = tokio::sync::Mutex::const_new(()); +static MARKER: &[u8] = b"TURBOPACK_OUTPUT_"; +static MARKER_STR: &str = "TURBOPACK_OUTPUT_"; + +struct OutputStreamHandler { + stream: BufReader, + shared: SharedOutputSet, + assets_for_source_mapping: Vc, + root: Vc, + project_dir: Vc, + final_stream: W, +} + +impl OutputStreamHandler { + /// Pipes the `stream` from `final_stream`, but uses `shared` to deduplicate + /// lines that has beem emitted by other [OutputStreamHandler] instances + /// with the same `shared` before. + /// Returns when one operation is done. + pub async fn handle_operation(&mut self) -> Result<()> { + let Self { + stream, + shared, + assets_for_source_mapping, + root, + project_dir, + final_stream, + } = self; + + async fn write_final( + mut bytes: &[u8], + final_stream: &mut W, + ) -> Result<()> { + let _lock = GLOBAL_OUTPUT_LOCK.lock().await; + while !bytes.is_empty() { + let count = final_stream.write(bytes).await?; + if count == 0 { + bail!("Failed to write to final stream as it was closed"); + } + bytes = &bytes[count..]; + } + Ok(()) + } + + async fn write_source_mapped_final( + bytes: &[u8], + assets_for_source_mapping: Vc, + root: Vc, + project_dir: Vc, + final_stream: &mut W, + ) -> Result<()> { + if let Ok(text) = std::str::from_utf8(bytes) { + let text = unmangle_identifiers(text, |content| { + format!("{{{}}}", content).italic().to_string() + }); + match apply_source_mapping( + text.as_ref(), + assets_for_source_mapping, + root, + project_dir, + FormattingMode::AnsiColors, + ) + .await + { + Err(e) => { + write_final( + format!("Error applying source mapping: {e}\n").as_bytes(), + final_stream, + ) + .await?; + write_final(text.as_bytes(), final_stream).await?; + } + Ok(text) => { + write_final(text.as_bytes(), final_stream).await?; + } + } + } else { + write_final(bytes, final_stream).await?; + } + Ok(()) + } + + let mut buffer = Vec::new(); + let mut own_output = HashMap::new(); + let mut nesting: u32 = 0; + let mut in_stack = None; + let mut stack_trace_buffer = Vec::new(); + loop { + let start = buffer.len(); + if stream + .read_until(b'\n', &mut buffer) + .await + .context("error reading from stream")? + == 0 + { + bail!("stream closed unexpectedly") + } + if buffer.len() - start == MARKER.len() + 2 + && &buffer[start..buffer.len() - 2] == MARKER + { + // This is new line + buffer.pop(); + // This is the type + match buffer.pop() { + Some(b'B') => { + stack_trace_buffer.clear(); + buffer.truncate(start); + nesting += 1; + in_stack = None; + continue; + } + Some(b'E') => { + buffer.truncate(start); + if let Some(in_stack) = in_stack { + if nesting != 0 { + stack_trace_buffer = buffer[in_stack..].to_vec(); + } + buffer.truncate(in_stack); + } + nesting = nesting.saturating_sub(1); + in_stack = None; + if nesting == 0 { + let line = Arc::from(take(&mut buffer).into_boxed_slice()); + let stack_trace = if stack_trace_buffer.is_empty() { + None + } else { + Some(Arc::from(take(&mut stack_trace_buffer).into_boxed_slice())) + }; + let entry = OutputEntry { + data: line, + stack_trace, + }; + let occurrence_number = *own_output + .entry(entry.clone()) + .and_modify(|c| *c += 1) + .or_insert(0); + let new_entry = { + let mut shared = shared.lock(); + shared.insert((entry.clone(), occurrence_number)) + }; + if !new_entry { + // This line has been printed by another process, so we don't need + // to print it again. + continue; + } + write_source_mapped_final( + &entry.data, + *assets_for_source_mapping, + *root, + *project_dir, + final_stream, + ) + .await?; + } + } + Some(b'S') => { + buffer.truncate(start); + in_stack = Some(start); + continue; + } + Some(b'D') => { + // operation done + break; + } + _ => {} + } + } + if nesting != 0 { + // When inside of a marked output we want to aggregate until the end marker + continue; + } + + write_source_mapped_final( + &buffer, + *assets_for_source_mapping, + *root, + *project_dir, + final_stream, + ) + .await?; + buffer.clear(); + } + Ok(()) + } +} + +impl NodeJsPoolProcess { + async fn new( + cwd: &Path, + env: &HashMap, + entrypoint: &Path, + assets_for_source_mapping: Vc, + assets_root: Vc, + project_dir: Vc, + shared_stdout: SharedOutputSet, + shared_stderr: SharedOutputSet, + debug: bool, + ) -> Result { + let guard = Box::new(duration_span!("Node.js process startup")); + let listener = TcpListener::bind("127.0.0.1:0") + .await + .context("binding to a port")?; + let port = listener.local_addr().context("getting port")?.port(); + let mut cmd = Command::new("node"); + cmd.current_dir(cwd); + if debug { + cmd.arg("--inspect-brk"); + } + cmd.arg(entrypoint); + cmd.arg(port.to_string()); + cmd.env_clear(); + cmd.env( + "PATH", + std::env::var("PATH").expect("the PATH environment variable should always be set"), + ); + #[cfg(target_family = "windows")] + cmd.env( + "SystemRoot", + std::env::var("SystemRoot") + .expect("the SystemRoot environment variable should always be set"), + ); + cmd.envs(env); + cmd.stderr(Stdio::piped()); + cmd.stdout(Stdio::piped()); + cmd.kill_on_drop(true); + + let mut child = cmd.spawn().context("spawning node pooled process")?; + + let timeout = if debug { + Duration::MAX + } else { + CONNECT_TIMEOUT + }; + + async fn get_output(child: &mut Child) -> Result<(String, String)> { + let mut stdout = Vec::new(); + let mut stderr = Vec::new(); + child + .stdout + .take() + .unwrap() + .read_to_end(&mut stdout) + .await?; + child + .stderr + .take() + .unwrap() + .read_to_end(&mut stderr) + .await?; + fn clean(buffer: Vec) -> Result { + Ok(String::from_utf8(buffer)? + .lines() + .filter(|line| { + line.len() != MARKER_STR.len() + 1 && !line.starts_with(MARKER_STR) + }) + .collect::>() + .join("\n")) + } + Ok((clean(stdout)?, clean(stderr)?)) + } + + let (connection, _) = select! { + connection = listener.accept() => connection.context("accepting connection")?, + status = child.wait() => { + match status { + Ok(status) => { + let (stdout, stderr) = get_output(&mut child).await?; + bail!("node process exited before we could connect to it with {status}\nProcess output:\n{stdout}\nProcess error output:\n{stderr}"); + } + Err(err) => { + let _ = child.start_kill(); + let (stdout, stderr) = get_output(&mut child).await?; + bail!("node process exited before we could connect to it: {err:?}\nProcess output:\n{stdout}\nProcess error output:\n{stderr}"); + }, + } + }, + _ = sleep(timeout) => { + let _ = child.start_kill(); + let (stdout, stderr) = get_output(&mut child).await?; + bail!("timed out waiting for the Node.js process to connect ({timeout:?} timeout)\nProcess output:\n{stdout}\nProcess error output:\n{stderr}"); + }, + }; + + let child_stdout = BufReader::new(child.stdout.take().unwrap()); + let child_stderr = BufReader::new(child.stderr.take().unwrap()); + + let stdout_handler = OutputStreamHandler { + stream: child_stdout, + shared: shared_stdout, + assets_for_source_mapping, + root: assets_root, + project_dir, + final_stream: stdout(), + }; + let stderr_handler = OutputStreamHandler { + stream: child_stderr, + shared: shared_stderr, + assets_for_source_mapping, + root: assets_root, + project_dir, + final_stream: stderr(), + }; + + let mut process = Self { + child: Some(child), + connection, + assets_for_source_mapping, + assets_root, + project_dir, + stdout_handler, + stderr_handler, + debug, + }; + + drop(guard); + + let guard = duration_span!("Node.js initialization"); + let ready_signal = process.recv().await?; + + if !ready_signal.is_empty() { + bail!( + "Node.js process didn't send the expected ready signal\nOutput:\n{}", + String::from_utf8_lossy(&ready_signal) + ); + } + + drop(guard); + + Ok(process) + } + + async fn recv(&mut self) -> Result> { + let connection = &mut self.connection; + async fn with_timeout>( + debug: bool, + fast: bool, + future: impl Future> + Send, + ) -> Result { + if debug { + future.await.map_err(Into::into) + } else { + let time = if fast { + Duration::from_secs(20) + } else { + Duration::from_secs(5 * 60) + }; + timeout(time, future) + .await + .context("timeout while receiving message from process")? + .map_err(Into::into) + } + } + let debug = self.debug; + let recv_future = async move { + let packet_len = with_timeout(debug, false, connection.read_u32()) + .await + .context("reading packet length")? + .try_into() + .context("storing packet length")?; + let mut packet_data = vec![0; packet_len]; + with_timeout(debug, true, connection.read_exact(&mut packet_data)) + .await + .context("reading packet data")?; + Ok::<_, anyhow::Error>(packet_data) + }; + let (result, stdout, stderr) = join!( + recv_future, + self.stdout_handler.handle_operation(), + self.stderr_handler.handle_operation(), + ); + let result = result?; + stdout.context("unable to handle stdout from the Node.js process in a structured way")?; + stderr.context("unable to handle stderr from the Node.js process in a structured way")?; + Ok(result) + } + + async fn send(&mut self, packet_data: Vec) -> Result<()> { + self.connection + .write_u32( + packet_data + .len() + .try_into() + .context("packet length does not fit into u32")?, + ) + .await + .context("writing packet length")?; + self.connection + .write_all(&packet_data) + .await + .context("writing packet data")?; + Ok(()) + } +} + +#[derive(Default)] +struct NodeJsPoolStats { + pub total_bootup_time: Duration, + pub bootup_count: u32, + pub total_cold_process_time: Duration, + pub cold_process_count: u32, + pub total_warm_process_time: Duration, + pub warm_process_count: u32, + pub workers: u32, + pub booting_workers: u32, + pub queued_tasks: u32, +} + +impl NodeJsPoolStats { + fn add_bootup_time(&mut self, time: Duration) { + self.total_bootup_time += time; + self.bootup_count += 1; + } + + fn add_booting_worker(&mut self) { + self.booting_workers += 1; + self.workers += 1; + } + + fn finished_booting_worker(&mut self) { + self.booting_workers -= 1; + } + + fn remove_worker(&mut self) { + self.workers -= 1; + } + + fn add_queued_task(&mut self) { + self.queued_tasks += 1; + } + + fn add_cold_process_time(&mut self, time: Duration) { + self.total_cold_process_time += time; + self.cold_process_count += 1; + self.queued_tasks -= 1; + } + + fn add_warm_process_time(&mut self, time: Duration) { + self.total_warm_process_time += time; + self.warm_process_count += 1; + self.queued_tasks -= 1; + } + + fn estimated_bootup_time(&self) -> Duration { + if self.bootup_count == 0 { + Duration::from_millis(200) + } else { + self.total_bootup_time / self.bootup_count + } + } + + fn estimated_warm_process_time(&self) -> Duration { + if self.warm_process_count == 0 { + self.estimated_cold_process_time() + } else { + self.total_warm_process_time / self.warm_process_count + } + } + + fn estimated_cold_process_time(&self) -> Duration { + if self.cold_process_count == 0 { + // We assume cold processing is half of bootup time + self.estimated_bootup_time() / 2 + } else { + self.total_cold_process_time / self.cold_process_count + } + } + fn wait_time_before_bootup(&self) -> Duration { + if self.workers == 0 { + return Duration::ZERO; + } + let booting_workers = self.booting_workers; + let workers = self.workers; + let warm_process_time = self.estimated_warm_process_time(); + let expected_completion = self.expected_completion(workers, booting_workers); + + let new_process_duration = + self.estimated_bootup_time() + self.estimated_cold_process_time(); + if expected_completion + warm_process_time < new_process_duration { + // Running the task with the existing warm pool is faster + return (expected_completion + warm_process_time + new_process_duration) / 2; + } + + let expected_completion_with_additional_worker = max( + new_process_duration, + self.expected_completion(workers + 1, booting_workers + 1), + ); + if expected_completion > expected_completion_with_additional_worker { + // Scaling up the pool would help to complete work faster + return Duration::ZERO; + } + + // It's expected to be faster if we queue the task + (expected_completion + expected_completion_with_additional_worker) / 2 + } + + fn expected_completion(&self, workers: u32, booting_workers: u32) -> Duration { + if workers == 0 { + return Duration::MAX; + } + let bootup_time = self.estimated_bootup_time(); + let cold_process_time = self.estimated_cold_process_time(); + let warm_process_time = self.estimated_warm_process_time(); + let expected_full_workers_in = booting_workers * (bootup_time / 2 + cold_process_time); + let expected_completed_task_until_full_workers = { + let millis = max(1, warm_process_time.as_millis()); + let ready_workers = workers - booting_workers; + (expected_full_workers_in.as_millis() / millis) as u32 * ready_workers + }; + let remaining_tasks = self + .queued_tasks + .saturating_sub(expected_completed_task_until_full_workers); + if remaining_tasks > 0 { + expected_full_workers_in + warm_process_time * remaining_tasks / workers + } else { + warm_process_time * self.queued_tasks / workers + } + } +} + +impl Debug for NodeJsPoolStats { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("NodeJsPoolStats") + .field("queued_tasks", &self.queued_tasks) + .field("workers", &self.workers) + .field("booting_workers", &self.booting_workers) + .field( + "expected_completion", + &self.expected_completion(self.workers, self.booting_workers), + ) + .field("bootup_time", &self.estimated_bootup_time()) + .field("cold_process_time", &self.estimated_cold_process_time()) + .field("warm_process_time", &self.estimated_warm_process_time()) + .field("bootup_count", &self.bootup_count) + .field("cold_process_count", &self.cold_process_count) + .field("warm_process_count", &self.warm_process_count) + .finish() + } +} + +enum AcquiredPermits { + Idle { + // This is used for drop + #[allow(dead_code)] + concurrency_permit: OwnedSemaphorePermit, + }, + Fresh { + // This is used for drop + #[allow(dead_code)] + concurrency_permit: OwnedSemaphorePermit, + // This is used for drop + #[allow(dead_code)] + bootup_permit: OwnedSemaphorePermit, + }, +} + +/// A pool of Node.js workers operating on [entrypoint] with specific [cwd] and +/// [env]. +/// +/// The pool will spawn processes when needed and reuses old ones. It will never +/// spawn more then a certain number of concurrent processes. This is specified +/// with the `concurrency` argument in the constructor. +/// +/// The worker will *not* use the env of the parent process by default. All env +/// vars need to be provided to make the execution as pure as possible. +#[turbo_tasks::value(into = "new", cell = "new", serialization = "none", eq = "manual")] +pub struct NodeJsPool { + cwd: PathBuf, + entrypoint: PathBuf, + env: HashMap, + pub assets_for_source_mapping: Vc, + pub assets_root: Vc, + pub project_dir: Vc, + #[turbo_tasks(trace_ignore, debug_ignore)] + processes: Arc>>, + /// Semaphore to limit the number of concurrent operations in general + #[turbo_tasks(trace_ignore, debug_ignore)] + concurrency_semaphore: Arc, + /// Semaphore to limit the number of concurrently booting up processes + /// (excludes one-off processes) + #[turbo_tasks(trace_ignore, debug_ignore)] + bootup_semaphore: Arc, + /// Semaphore to wait for an idle process to become available + #[turbo_tasks(trace_ignore, debug_ignore)] + idle_process_semaphore: Arc, + #[turbo_tasks(trace_ignore, debug_ignore)] + shared_stdout: SharedOutputSet, + #[turbo_tasks(trace_ignore, debug_ignore)] + shared_stderr: SharedOutputSet, + debug: bool, + #[turbo_tasks(trace_ignore, debug_ignore)] + stats: Arc>, +} + +impl NodeJsPool { + /// * debug: Whether to automatically enable Node's `--inspect-brk` when + /// spawning it. Note: automatically overrides concurrency to 1. + pub(super) fn new( + cwd: PathBuf, + entrypoint: PathBuf, + env: HashMap, + assets_for_source_mapping: Vc, + assets_root: Vc, + project_dir: Vc, + concurrency: usize, + debug: bool, + ) -> Self { + Self { + cwd, + entrypoint, + env, + assets_for_source_mapping, + assets_root, + project_dir, + processes: Arc::new(Mutex::new(Vec::new())), + concurrency_semaphore: Arc::new(Semaphore::new(if debug { 1 } else { concurrency })), + bootup_semaphore: Arc::new(Semaphore::new(1)), + idle_process_semaphore: Arc::new(Semaphore::new(0)), + shared_stdout: Arc::new(Mutex::new(IndexSet::new())), + shared_stderr: Arc::new(Mutex::new(IndexSet::new())), + debug, + stats: Default::default(), + } + } + + async fn acquire_process(&self) -> Result<(NodeJsPoolProcess, AcquiredPermits)> { + { + self.stats.lock().add_queued_task(); + } + + let concurrency_permit = self.concurrency_semaphore.clone().acquire_owned().await?; + + let bootup = async { + let permit = self.bootup_semaphore.clone().acquire_owned().await; + let wait_time = self.stats.lock().wait_time_before_bootup(); + tokio::time::sleep(wait_time).await; + permit + }; + + select! { + idle_process_permit = self.idle_process_semaphore.clone().acquire_owned() => { + let idle_process_permit = idle_process_permit.context("acquiring idle process permit")?; + let process = { + let mut processes = self.processes.lock(); + processes.pop().unwrap() + }; + idle_process_permit.forget(); + Ok((process, AcquiredPermits::Idle { concurrency_permit })) + }, + bootup_permit = bootup => { + let bootup_permit = bootup_permit.context("acquiring bootup permit")?; + { + self.stats.lock().add_booting_worker(); + } + let (process, bootup_time) = self.create_process().await?; + // Update the worker count + { + let mut stats = self.stats.lock(); + stats.add_bootup_time(bootup_time); + stats.finished_booting_worker(); + } + // Increase the allowed booting up processes + self.bootup_semaphore.add_permits(1); + Ok((process, AcquiredPermits::Fresh { concurrency_permit, bootup_permit })) + } + } + } + + async fn create_process(&self) -> Result<(NodeJsPoolProcess, Duration), anyhow::Error> { + let start = Instant::now(); + let process = NodeJsPoolProcess::new( + self.cwd.as_path(), + &self.env, + self.entrypoint.as_path(), + self.assets_for_source_mapping, + self.assets_root, + self.project_dir, + self.shared_stdout.clone(), + self.shared_stderr.clone(), + self.debug, + ) + .await + .context("creating new process")?; + Ok((process, start.elapsed())) + } + + pub async fn operation(&self) -> Result { + // Acquire a running process (handles concurrency limits, boots up the process) + let (process, permits) = self.acquire_process().await?; + + Ok(NodeJsOperation { + process: Some(process), + permits, + processes: self.processes.clone(), + idle_process_semaphore: self.idle_process_semaphore.clone(), + start: Instant::now(), + stats: self.stats.clone(), + allow_process_reuse: true, + }) + } +} + +pub struct NodeJsOperation { + process: Option, + // This is used for drop + #[allow(dead_code)] + permits: AcquiredPermits, + processes: Arc>>, + idle_process_semaphore: Arc, + start: Instant, + stats: Arc>, + allow_process_reuse: bool, +} + +impl NodeJsOperation { + async fn with_process<'a, F: Future> + Send + 'a, T>( + &'a mut self, + f: impl FnOnce(&'a mut NodeJsPoolProcess) -> F, + ) -> Result { + let process = self + .process + .as_mut() + .context("Node.js operation already finished")?; + + if !self.allow_process_reuse { + bail!("Node.js process is no longer usable"); + } + + let result = f(process).await; + if result.is_err() && self.allow_process_reuse { + self.stats.lock().remove_worker(); + self.allow_process_reuse = false; + } + result + } + + pub async fn recv(&mut self) -> Result + where + M: DeserializeOwned, + { + let message = self + .with_process(|process| async move { + process.recv().await.context("failed to receive message") + }) + .await?; + let message = std::str::from_utf8(&message).context("message is not valid UTF-8")?; + parse_json_with_source_context(message).context("failed to deserialize message") + } + + pub async fn send(&mut self, message: M) -> Result<()> + where + M: Serialize, + { + let message = serde_json::to_vec(&message).context("failed to serialize message")?; + self.with_process(|process| async move { + timeout(Duration::from_secs(30), process.send(message)) + .await + .context("timeout while sending message")? + .context("failed to send message")?; + Ok(()) + }) + .await + } + + pub async fn wait_or_kill(mut self) -> Result { + let mut process = self + .process + .take() + .context("Node.js operation already finished")?; + + if self.allow_process_reuse { + self.stats.lock().remove_worker(); + } + + let mut child = process + .child + .take() + .context("Node.js operation already finished")?; + + // Ignore error since we are not sure if the process is still alive + let _ = child.start_kill(); + let status = timeout(Duration::from_secs(30), child.wait()) + .await + .context("timeout while waiting for process end")? + .context("waiting for process end")?; + + Ok(status) + } + + pub fn disallow_reuse(&mut self) { + if self.allow_process_reuse { + self.stats.lock().remove_worker(); + self.allow_process_reuse = false; + } + } + + pub async fn apply_source_mapping<'a>( + &self, + text: &'a str, + formatting_mode: FormattingMode, + ) -> Result> { + if let Some(process) = self.process.as_ref() { + process.apply_source_mapping(text, formatting_mode).await + } else { + Ok(Cow::Borrowed(text)) + } + } +} + +impl Drop for NodeJsOperation { + fn drop(&mut self) { + if let Some(process) = self.process.take() { + let elapsed = self.start.elapsed(); + { + let stats = &mut self.stats.lock(); + match self.permits { + AcquiredPermits::Idle { .. } => stats.add_warm_process_time(elapsed), + AcquiredPermits::Fresh { .. } => stats.add_cold_process_time(elapsed), + } + } + if self.allow_process_reuse { + self.processes.lock().push(process); + self.idle_process_semaphore.add_permits(1); + } + } + } +} diff --git a/turbopack/crates/turbopack-node/src/render/error.html b/turbopack/crates/turbopack-node/src/render/error.html new file mode 100644 index 0000000000000..c526518f929ce --- /dev/null +++ b/turbopack/crates/turbopack-node/src/render/error.html @@ -0,0 +1,118 @@ + + + + + ${TITLE} + + +

    + + + +
    +
    +

    ${STATUS_CODE}

    +
    +

    ${TITLE}.

    +
    +
    +
    +

    Details

    +
    ${DETAILS}
    +
    +
    +
    + + diff --git a/turbopack/crates/turbopack-node/src/render/error_page.rs b/turbopack/crates/turbopack-node/src/render/error_page.rs new file mode 100644 index 0000000000000..cb8737e28239a --- /dev/null +++ b/turbopack/crates/turbopack-node/src/render/error_page.rs @@ -0,0 +1,46 @@ +use anyhow::{Context, Result}; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::embed_file; + +#[turbo_tasks::function] +pub(super) async fn error_html( + status_code: u16, + title: RcStr, + details: RcStr, +) -> Result> { + let html = create_html(status_code, title, details).await?; + + Ok(Vc::cell(html.into())) +} + +#[turbo_tasks::function] +pub(super) async fn error_html_body( + status_code: u16, + title: RcStr, + details: RcStr, +) -> Result> { + let html = create_html(status_code, title, details).await?; + + let (_, body) = html.split_once("").context("no body in html")?; + let (body, _) = body.split_once("").context("no body in html")?; + + Ok(Vc::cell(body.into())) +} + +async fn create_html(status_code: u16, title: RcStr, details: RcStr) -> Result { + let file_content = embed_file!("src/render/error.html").await?; + let file = file_content + .as_content() + .context("embedded file not found (this should not happen)")?; + + let html = file + .content() + .to_str() + .context("couldn't convert embedded html to string")?; + + let html = html.replace("${TITLE}", &title); + let html = html.replace("${STATUS_CODE}", &status_code.to_string()); + let html = html.replace("${DETAILS}", &details); + + Ok(html) +} diff --git a/turbopack/crates/turbopack-node/src/render/issue.rs b/turbopack/crates/turbopack-node/src/render/issue.rs new file mode 100644 index 0000000000000..96dfeeb7a5483 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/render/issue.rs @@ -0,0 +1,52 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::issue::{Issue, IssueStage, OptionStyledString, StyledString}; + +#[turbo_tasks::value(shared)] +#[derive(Copy, Clone)] +pub struct RenderingIssue { + pub file_path: Vc, + pub message: Vc, + pub status: Option, +} + +#[turbo_tasks::value_impl] +impl Issue for RenderingIssue { + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Error during SSR Rendering".into()).cell() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::CodeGen.cell() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.file_path + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some(self.message)) + } + + #[turbo_tasks::function] + async fn detail(&self) -> Result> { + let mut details = vec![]; + + if let Some(status) = self.status { + if status != 0 { + details.push(StyledString::Text( + format!("Node.js exit code: {status}").into(), + )); + } + } + + Ok(Vc::cell(Some(StyledString::Stack(details).cell()))) + } + + // TODO parse stack trace into source location +} diff --git a/turbopack/crates/turbopack-node/src/render/mod.rs b/turbopack/crates/turbopack-node/src/render/mod.rs new file mode 100644 index 0000000000000..a78026c2a4b2b --- /dev/null +++ b/turbopack/crates/turbopack-node/src/render/mod.rs @@ -0,0 +1,71 @@ +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; +use turbo_tasks::{RcStr, ReadRef}; + +use crate::{route_matcher::Param, ResponseHeaders, StructuredError}; + +pub(crate) mod error_page; +pub mod issue; +pub mod node_api_source; +pub mod render_proxy; +pub mod render_static; +pub mod rendered_source; + +#[turbo_tasks::value(shared)] +#[serde(rename_all = "camelCase")] +pub struct RenderData { + params: IndexMap, + method: RcStr, + url: RcStr, + original_url: RcStr, + raw_query: RcStr, + raw_headers: Vec<(RcStr, RcStr)>, + path: RcStr, + data: Option>, +} + +#[derive(Serialize)] +#[serde(tag = "type", rename_all = "camelCase")] +enum RenderStaticOutgoingMessage<'a> { + Headers { data: &'a RenderData }, +} + +#[derive(Serialize)] +#[serde(tag = "type", rename_all = "camelCase")] +enum RenderProxyOutgoingMessage<'a> { + Headers { data: &'a RenderData }, + BodyChunk { data: &'a [u8] }, + BodyEnd, +} + +#[derive(Deserialize, Debug)] +#[serde(tag = "type", rename_all = "camelCase")] +enum RenderProxyIncomingMessage { + Headers { data: ResponseHeaders }, + BodyChunk { data: Vec }, + BodyEnd, + Error(StructuredError), +} + +#[derive(Deserialize, Debug)] +#[serde(tag = "type", rename_all = "camelCase")] +enum RenderStaticIncomingMessage { + #[serde(rename_all = "camelCase")] + Response { + status_code: u16, + headers: Vec<(RcStr, RcStr)>, + body: RcStr, + }, + Headers { + data: ResponseHeaders, + }, + BodyChunk { + data: Vec, + }, + BodyEnd, + Rewrite { + path: RcStr, + }, + Error(StructuredError), +} diff --git a/turbopack/crates/turbopack-node/src/render/node_api_source.rs b/turbopack/crates/turbopack-node/src/render/node_api_source.rs new file mode 100644 index 0000000000000..d81e0819c6a9f --- /dev/null +++ b/turbopack/crates/turbopack-node/src/render/node_api_source.rs @@ -0,0 +1,207 @@ +use anyhow::{anyhow, Result}; +use indexmap::IndexSet; +use serde_json::Value as JsonValue; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::introspect::{ + module::IntrospectableModule, output_asset::IntrospectableOutputAsset, Introspectable, + IntrospectableChildren, +}; +use turbopack_dev_server::source::{ + route_tree::{BaseSegment, RouteTree, RouteType}, + ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataVary, + GetContentSourceContent, +}; + +use super::{render_proxy::render_proxy, RenderData}; +use crate::{get_intermediate_asset, node_entry::NodeEntry, route_matcher::RouteMatcher}; + +/// Creates a [NodeApiContentSource]. +#[turbo_tasks::function] +pub fn create_node_api_source( + cwd: Vc, + env: Vc>, + base_segments: Vec, + route_type: RouteType, + server_root: Vc, + route_match: Vc>, + pathname: Vc, + entry: Vc>, + render_data: Vc, + debug: bool, +) -> Vc> { + Vc::upcast( + NodeApiContentSource { + cwd, + env, + base_segments, + route_type, + server_root, + pathname, + route_match, + entry, + render_data, + debug, + } + .cell(), + ) +} + +/// A content source that proxies API requests to one-off Node.js +/// servers running the passed `entry` when it matches a `path_regex`. +/// +/// It needs a temporary directory (`intermediate_output_path`) to place file +/// for Node.js execution during rendering. The `chunking_context` should emit +/// to this directory. +#[turbo_tasks::value] +pub struct NodeApiContentSource { + cwd: Vc, + env: Vc>, + base_segments: Vec, + route_type: RouteType, + server_root: Vc, + pathname: Vc, + route_match: Vc>, + entry: Vc>, + render_data: Vc, + debug: bool, +} + +#[turbo_tasks::value_impl] +impl NodeApiContentSource { + #[turbo_tasks::function] + pub async fn get_pathname(self: Vc) -> Result> { + Ok(self.await?.pathname) + } +} + +#[turbo_tasks::value_impl] +impl ContentSource for NodeApiContentSource { + #[turbo_tasks::function] + async fn get_routes(self: Vc) -> Result> { + let this = self.await?; + Ok(RouteTree::new_route( + this.base_segments.clone(), + this.route_type.clone(), + Vc::upcast(self), + )) + } +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for NodeApiContentSource { + #[turbo_tasks::function] + fn vary(&self) -> Vc { + ContentSourceDataVary { + method: true, + url: true, + original_url: true, + raw_headers: true, + raw_query: true, + body: true, + cache_buster: true, + ..Default::default() + } + .cell() + } + + #[turbo_tasks::function] + async fn get( + &self, + path: RcStr, + data: Value, + ) -> Result> { + let Some(params) = &*self.route_match.params(path.clone()).await? else { + return Err(anyhow!("Non matching path provided")); + }; + let ContentSourceData { + method: Some(method), + url: Some(url), + original_url: Some(original_url), + raw_headers: Some(raw_headers), + raw_query: Some(raw_query), + body: Some(body), + .. + } = &*data + else { + return Err(anyhow!("Missing request data")); + }; + let entry = self.entry.entry(data.clone()).await?; + Ok(ContentSourceContent::HttpProxy(render_proxy( + self.cwd, + self.env, + self.server_root.join(path.clone()), + entry.module, + entry.runtime_entries, + entry.chunking_context, + entry.intermediate_output_path, + entry.output_root, + entry.project_dir, + RenderData { + params: params.clone(), + method: method.clone(), + url: url.clone(), + original_url: original_url.clone(), + raw_query: raw_query.clone(), + raw_headers: raw_headers.clone(), + path: format!("/{}", path).into(), + data: Some(self.render_data.await?), + } + .cell(), + *body, + self.debug, + )) + .cell()) + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("node api content source".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for NodeApiContentSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + self.pathname + } + + #[turbo_tasks::function] + async fn details(&self) -> Result> { + Ok(Vc::cell( + format!( + "base: {:?}\ntype: {:?}", + self.base_segments, self.route_type + ) + .into(), + )) + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + let mut set = IndexSet::new(); + for &entry in self.entry.entries().await?.iter() { + let entry = entry.await?; + set.insert(( + Vc::cell("module".into()), + IntrospectableModule::new(Vc::upcast(entry.module)), + )); + set.insert(( + Vc::cell("intermediate asset".into()), + IntrospectableOutputAsset::new(get_intermediate_asset( + entry.chunking_context, + Vc::upcast(entry.module), + entry.runtime_entries, + )), + )); + } + Ok(Vc::cell(set)) + } +} diff --git a/turbopack/crates/turbopack-node/src/render/render_proxy.rs b/turbopack/crates/turbopack-node/src/render/render_proxy.rs new file mode 100644 index 0000000000000..7e69575aff122 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/render/render_proxy.rs @@ -0,0 +1,342 @@ +use anyhow::{anyhow, bail, Result}; +use async_stream::try_stream as generator; +use futures::{ + channel::mpsc::{unbounded, UnboundedSender}, + pin_mut, SinkExt, StreamExt, TryStreamExt, +}; +use parking_lot::Mutex; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{ + duration_span, mark_finished, prevent_gc, util::SharedError, RawVc, RcStr, TaskInput, + ValueToString, Vc, +}; +use turbo_tasks_bytes::{Bytes, Stream}; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + chunk::{ChunkingContext, EvaluatableAssets}, + error::PrettyPrintError, + issue::{IssueExt, StyledString}, + module::Module, +}; +use turbopack_dev_server::source::{Body, ProxyResult}; + +use super::{ + issue::RenderingIssue, RenderData, RenderProxyIncomingMessage, RenderProxyOutgoingMessage, + ResponseHeaders, +}; +use crate::{ + get_intermediate_asset, get_renderer_pool, pool::NodeJsOperation, + render::error_page::error_html, source_map::trace_stack, +}; + +/// Renders a module as static HTML in a node.js process. +#[turbo_tasks::function] +pub async fn render_proxy( + cwd: Vc, + env: Vc>, + path: Vc, + module: Vc>, + runtime_entries: Vc, + chunking_context: Vc>, + intermediate_output_path: Vc, + output_root: Vc, + project_dir: Vc, + data: Vc, + body: Vc, + debug: bool, +) -> Result> { + let render = render_stream(RenderStreamOptions { + cwd, + env, + path, + module, + runtime_entries, + chunking_context, + intermediate_output_path, + output_root, + project_dir, + data, + body, + debug, + }) + .await?; + + let mut stream = render.read(); + let first = match stream.try_next().await? { + Some(f) => f, + None => { + // If an Error was received first, then it would have been + // transformed into a proxy err error response. + bail!("did not receive response from render"); + } + }; + + let RenderItem::Headers(data) = first else { + bail!("did not receive headers from render"); + }; + + let body = Body::from_stream(stream.map(|item| match item { + Ok(RenderItem::BodyChunk(b)) => Ok(b), + Ok(v) => Err(SharedError::new(anyhow!( + "unexpected render item: {:#?}", + v + ))), + Err(e) => Err(e), + })); + let result = ProxyResult { + status: data.status, + headers: data.headers, + body, + }; + + Ok(result.cell()) +} + +async fn proxy_error( + path: Vc, + error: anyhow::Error, + operation: Option, +) -> Result<(u16, RcStr)> { + let message = format!("{}", PrettyPrintError(&error)); + + let status = match operation { + Some(operation) => Some(operation.wait_or_kill().await?), + None => None, + }; + + let mut details = vec![]; + if let Some(status) = status { + details.push(format!("status: {status}")); + } + + let status_code = 500; + let body = error_html( + status_code, + "An error occurred while proxying the request to Node.js".into(), + format!("{message}\n\n{}", details.join("\n")).into(), + ) + .await? + .clone_value(); + + RenderingIssue { + file_path: path, + message: StyledString::Text(message.into()).cell(), + status: status.and_then(|status| status.code()), + } + .cell() + .emit(); + + Ok((status_code, body)) +} + +#[derive(Clone, Debug)] +#[turbo_tasks::value] +enum RenderItem { + Headers(ResponseHeaders), + BodyChunk(Bytes), +} + +type RenderItemResult = Result; + +#[turbo_tasks::value(eq = "manual", cell = "new", serialization = "none")] +struct RenderStreamSender { + #[turbo_tasks(trace_ignore, debug_ignore)] + get: Box UnboundedSender + Send + Sync>, +} + +#[turbo_tasks::value(transparent)] +struct RenderStream(#[turbo_tasks(trace_ignore)] Stream); + +#[derive(Clone, Debug, TaskInput, PartialEq, Eq, Hash, Serialize, Deserialize)] +struct RenderStreamOptions { + cwd: Vc, + env: Vc>, + path: Vc, + module: Vc>, + runtime_entries: Vc, + chunking_context: Vc>, + intermediate_output_path: Vc, + output_root: Vc, + project_dir: Vc, + data: Vc, + body: Vc, + debug: bool, +} + +#[turbo_tasks::function] +fn render_stream(options: RenderStreamOptions) -> Vc { + // TODO: The way we invoke render_stream_internal as side effect is not + // GC-safe, so we disable GC for this task. + prevent_gc(); + + // Note the following code uses some hacks to create a child task that produces + // a stream that is returned by this task. + + // We create a new cell in this task, which will be updated from the + // [render_stream_internal] task. + let cell = turbo_tasks::macro_helpers::find_cell_by_type(*RENDERSTREAM_VALUE_TYPE_ID); + + // We initialize the cell with a stream that is open, but has no values. + // The first [render_stream_internal] pipe call will pick up that stream. + let (sender, receiver) = unbounded(); + cell.update_shared(RenderStream(Stream::new_open(vec![], Box::new(receiver)))); + let initial = Mutex::new(Some(sender)); + + // run the evaluation as side effect + let _ = render_stream_internal( + options, + RenderStreamSender { + get: Box::new(move || { + if let Some(sender) = initial.lock().take() { + sender + } else { + // In cases when only [render_stream_internal] is (re)executed, we need to + // update the old stream with a new value. + let (sender, receiver) = unbounded(); + cell.update_shared(RenderStream(Stream::new_open(vec![], Box::new(receiver)))); + sender + } + }), + } + .cell(), + ); + + let raw: RawVc = cell.into(); + raw.into() +} + +#[turbo_tasks::function] +async fn render_stream_internal( + options: RenderStreamOptions, + sender: Vc, +) -> Result> { + let RenderStreamOptions { + cwd, + env, + path, + module, + runtime_entries, + chunking_context, + intermediate_output_path, + output_root, + project_dir, + data, + body, + debug, + } = options; + + mark_finished(); + let Ok(sender) = sender.await else { + // Impossible to handle the error in a good way. + return Ok(Default::default()); + }; + + let stream = generator! { + let intermediate_asset = get_intermediate_asset( + chunking_context, + module, + runtime_entries, + ); + let pool = get_renderer_pool( + cwd, + env, + intermediate_asset, + intermediate_output_path, + output_root, + project_dir, + debug, + ); + + // Read this strongly consistent, since we don't want to run inconsistent + // node.js code. + let pool = pool.strongly_consistent().await?; + let data = data.await?; + let mut operation = pool.operation().await?; + + // First, send the render data. + operation + .send(RenderProxyOutgoingMessage::Headers { data: &data }) + .await?; + // Then, send the binary body in chunks. + let mut body = body.await?.read(); + while let Some(data) = body.next().await { + operation + .send(RenderProxyOutgoingMessage::BodyChunk { data: &data.unwrap() }) + .await?; + } + operation.send(RenderProxyOutgoingMessage::BodyEnd).await?; + + let entry = module.ident().to_string().await?; + let guard = duration_span!("Node.js api execution", entry = display(entry)); + + match operation.recv().await? { + RenderProxyIncomingMessage::Headers { data } => yield RenderItem::Headers(data), + RenderProxyIncomingMessage::Error(error) => { + drop(guard); + // If we don't get headers, then something is very wrong. Instead, we send down a + // 500 proxy error as if it were the proper result. + let trace = trace_stack( + error, + intermediate_asset, + intermediate_output_path, + project_dir + ) + .await?; + let (status, body) = proxy_error(path, anyhow!("error rendering: {}", trace), Some(operation)).await?; + yield RenderItem::Headers(ResponseHeaders { + status, + headers: vec![( + "content-type".into(), + "text/html; charset=utf-8".into(), + )], + }); + yield RenderItem::BodyChunk(body.into_owned().into_bytes().into()); + return; + } + v => { + drop(guard); + Err(anyhow!("unexpected message during rendering: {:#?}", v))?; + return; + }, + }; + + loop { + match operation.recv().await? { + RenderProxyIncomingMessage::BodyChunk { data } => { + yield RenderItem::BodyChunk(data.into()); + } + RenderProxyIncomingMessage::BodyEnd => break, + RenderProxyIncomingMessage::Error(error) => { + drop(guard); + // We have already started to send a result, so we can't change the + // headers/body to a proxy error. + operation.disallow_reuse(); + let trace = + trace_stack(error, intermediate_asset, intermediate_output_path, project_dir).await?; + Err(anyhow!("error during streaming render: {}", trace))?; + return; + } + v => { + drop(guard); + Err(anyhow!("unexpected message during rendering: {:#?}", v))?; + return; + }, + } + } + drop(guard); + }; + + let mut sender = (sender.get)(); + pin_mut!(stream); + while let Some(value) = stream.next().await { + if sender.send(value).await.is_err() { + return Ok(Default::default()); + } + if sender.flush().await.is_err() { + return Ok(Default::default()); + } + } + + Ok(Default::default()) +} diff --git a/turbopack/crates/turbopack-node/src/render/render_static.rs b/turbopack/crates/turbopack-node/src/render/render_static.rs new file mode 100644 index 0000000000000..05e3a161f6379 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/render/render_static.rs @@ -0,0 +1,403 @@ +use anyhow::{anyhow, bail, Context, Result}; +use async_stream::try_stream as generator; +use futures::{ + channel::mpsc::{unbounded, UnboundedSender}, + pin_mut, SinkExt, StreamExt, TryStreamExt, +}; +use parking_lot::Mutex; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{ + duration_span, mark_finished, prevent_gc, util::SharedError, RawVc, TaskInput, ValueToString, + Vc, +}; +use turbo_tasks_bytes::{Bytes, Stream}; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::{File, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkingContext, EvaluatableAssets}, + error::PrettyPrintError, + issue::{IssueExt, StyledString}, + module::Module, +}; +use turbopack_dev_server::{ + html::DevHtmlAsset, + source::{Body, HeaderList, Rewrite, RewriteBuilder}, +}; + +use super::{ + issue::RenderingIssue, RenderData, RenderStaticIncomingMessage, RenderStaticOutgoingMessage, +}; +use crate::{ + get_intermediate_asset, get_renderer_pool, pool::NodeJsOperation, + render::error_page::error_html_body, source_map::trace_stack, ResponseHeaders, +}; + +#[derive(Clone, Debug)] +#[turbo_tasks::value] +pub enum StaticResult { + Content { + content: Vc, + status_code: u16, + headers: Vc, + }, + StreamedContent { + status: u16, + headers: Vc, + body: Body, + }, + Rewrite(Vc), +} + +#[turbo_tasks::value_impl] +impl StaticResult { + #[turbo_tasks::function] + pub fn content( + content: Vc, + status_code: u16, + headers: Vc, + ) -> Vc { + StaticResult::Content { + content, + status_code, + headers, + } + .cell() + } + + #[turbo_tasks::function] + pub fn rewrite(rewrite: Vc) -> Vc { + StaticResult::Rewrite(rewrite).cell() + } +} + +/// Renders a module as static HTML in a node.js process. +#[turbo_tasks::function] +pub async fn render_static( + cwd: Vc, + env: Vc>, + path: Vc, + module: Vc>, + runtime_entries: Vc, + fallback_page: Vc, + chunking_context: Vc>, + intermediate_output_path: Vc, + output_root: Vc, + project_dir: Vc, + data: Vc, + debug: bool, +) -> Result> { + let render = render_stream(RenderStreamOptions { + cwd, + env, + path, + module, + runtime_entries, + fallback_page, + chunking_context, + intermediate_output_path, + output_root, + project_dir, + data, + debug, + }) + .await?; + + let mut stream = render.read(); + let first = match stream.try_next().await? { + Some(f) => f, + None => { + // If an Error was received first, then it would have been + // transformed into a proxy err error response. + bail!("did not receive response from render"); + } + }; + + Ok(match first { + RenderItem::Response(response) => response, + RenderItem::Headers(data) => { + let body = stream.map(|item| match item { + Ok(RenderItem::BodyChunk(b)) => Ok(b), + Ok(v) => Err(SharedError::new(anyhow!( + "unexpected render item: {:#?}", + v + ))), + Err(e) => Err(e), + }); + StaticResult::StreamedContent { + status: data.status, + headers: Vc::cell(data.headers), + body: Body::from_stream(body), + } + .cell() + } + v => bail!("unexpected render item: {:#?}", v), + }) +} + +async fn static_error( + path: Vc, + error: anyhow::Error, + operation: Option, + fallback_page: Vc, +) -> Result> { + let status = match operation { + Some(operation) => Some(operation.wait_or_kill().await?), + None => None, + }; + + let error = format!("{}", PrettyPrintError(&error)); + let mut message = error + // TODO this is pretty inefficient + .replace('&', "&") + .replace('>', ">") + .replace('<', "<"); + + if let Some(status) = status { + message.push_str(&format!("\n\nStatus: {}", status)); + } + + let mut body = "" + .to_string(); + + body.push_str( + error_html_body(500, "Error rendering page".into(), message.into()) + .await? + .as_str(), + ); + + let issue = RenderingIssue { + file_path: path, + message: StyledString::Text(error.into()).cell(), + status: status.and_then(|status| status.code()), + }; + + issue.cell().emit(); + + let html = fallback_page.with_body(body.into()); + + Ok(html.content()) +} + +#[derive(Clone, Debug)] +#[turbo_tasks::value] +enum RenderItem { + Response(Vc), + Headers(ResponseHeaders), + BodyChunk(Bytes), +} + +type RenderItemResult = Result; + +#[turbo_tasks::value(eq = "manual", cell = "new", serialization = "none")] +struct RenderStreamSender { + #[turbo_tasks(trace_ignore, debug_ignore)] + get: Box UnboundedSender + Send + Sync>, +} + +#[turbo_tasks::value(transparent)] +struct RenderStream(#[turbo_tasks(trace_ignore)] Stream); + +#[derive(Clone, Debug, TaskInput, PartialEq, Eq, Hash, Deserialize, Serialize)] +struct RenderStreamOptions { + cwd: Vc, + env: Vc>, + path: Vc, + module: Vc>, + runtime_entries: Vc, + fallback_page: Vc, + chunking_context: Vc>, + intermediate_output_path: Vc, + output_root: Vc, + project_dir: Vc, + data: Vc, + debug: bool, +} + +#[turbo_tasks::function] +fn render_stream(options: RenderStreamOptions) -> Vc { + // TODO: The way we invoke render_stream_internal as side effect is not + // GC-safe, so we disable GC for this task. + prevent_gc(); + + // Note the following code uses some hacks to create a child task that produces + // a stream that is returned by this task. + + // We create a new cell in this task, which will be updated from the + // [render_stream_internal] task. + let cell = turbo_tasks::macro_helpers::find_cell_by_type(*RENDERSTREAM_VALUE_TYPE_ID); + + // We initialize the cell with a stream that is open, but has no values. + // The first [render_stream_internal] pipe call will pick up that stream. + let (sender, receiver) = unbounded(); + cell.update_shared(RenderStream(Stream::new_open(vec![], Box::new(receiver)))); + let initial = Mutex::new(Some(sender)); + + // run the evaluation as side effect + let _ = render_stream_internal( + options, + RenderStreamSender { + get: Box::new(move || { + if let Some(sender) = initial.lock().take() { + sender + } else { + // In cases when only [render_stream_internal] is (re)executed, we need to + // update the old stream with a new value. + let (sender, receiver) = unbounded(); + cell.update_shared(RenderStream(Stream::new_open(vec![], Box::new(receiver)))); + sender + } + }), + } + .cell(), + ); + + let raw: RawVc = cell.into(); + raw.into() +} + +#[turbo_tasks::function] +async fn render_stream_internal( + options: RenderStreamOptions, + sender: Vc, +) -> Result> { + let RenderStreamOptions { + cwd, + env, + path, + module, + runtime_entries, + fallback_page, + chunking_context, + intermediate_output_path, + output_root, + project_dir, + data, + debug, + } = options; + + mark_finished(); + let Ok(sender) = sender.await else { + // Impossible to handle the error in a good way. + return Ok(Default::default()); + }; + + let stream = generator! { + let intermediate_asset = get_intermediate_asset( + chunking_context, + module, + runtime_entries, + ); + let renderer_pool = get_renderer_pool( + cwd, + env, + intermediate_asset, + intermediate_output_path, + output_root, + project_dir, + debug, + ); + + // Read this strongly consistent, since we don't want to run inconsistent + // node.js code. + let pool = renderer_pool.strongly_consistent().await?; + let data = data.await?; + let mut operation = pool.operation().await?; + + operation + .send(RenderStaticOutgoingMessage::Headers { data: &data }) + .await + .context("sending headers to node.js process")?; + + let entry = module.ident().to_string().await?; + let guard = duration_span!("Node.js rendering", entry = display(entry)); + + match operation.recv().await? { + RenderStaticIncomingMessage::Headers { data } => yield RenderItem::Headers(data), + RenderStaticIncomingMessage::Rewrite { path } => { + drop(guard); + yield RenderItem::Response(StaticResult::rewrite(RewriteBuilder::new(path).build())); + return; + } + RenderStaticIncomingMessage::Response { + status_code, + headers, + body, + } => { + drop(guard); + yield RenderItem::Response(StaticResult::content( + AssetContent::file(File::from(body).into()), + status_code, + Vc::cell(headers), + )); + return; + } + RenderStaticIncomingMessage::Error(error) => { + drop(guard); + // If we don't get headers, then something is very wrong. Instead, we send down a + // 500 proxy error as if it were the proper result. + let trace = trace_stack( + error, + intermediate_asset, + intermediate_output_path, + project_dir, + ) + .await?; + yield RenderItem::Response( + StaticResult::content( + static_error(path, anyhow!(trace), Some(operation), fallback_page).await?, + 500, + HeaderList::empty(), + ) + ); + return; + } + v => { + drop(guard); + Err(anyhow!("unexpected message during rendering: {:#?}", v))?; + return; + }, + }; + + // If we get here, then the first message was a Headers. Now we need to stream out the body + // chunks. + loop { + match operation.recv().await? { + RenderStaticIncomingMessage::BodyChunk { data } => { + yield RenderItem::BodyChunk(data.into()); + } + RenderStaticIncomingMessage::BodyEnd => break, + RenderStaticIncomingMessage::Error(error) => { + // We have already started to send a result, so we can't change the + // headers/body to a proxy error. + operation.disallow_reuse(); + let trace = + trace_stack(error, intermediate_asset, intermediate_output_path, project_dir).await?; + drop(guard); + Err(anyhow!("error during streaming render: {}", trace))?; + return; + } + v => { + drop(guard); + Err(anyhow!("unexpected message during rendering: {:#?}", v))?; + return; + }, + } + } + drop(guard); + }; + + let mut sender = (sender.get)(); + pin_mut!(stream); + while let Some(value) = stream.next().await { + if sender.send(value).await.is_err() { + return Ok(Default::default()); + } + if sender.flush().await.is_err() { + return Ok(Default::default()); + } + } + + Ok(Default::default()) +} diff --git a/turbopack/crates/turbopack-node/src/render/rendered_source.rs b/turbopack/crates/turbopack-node/src/render/rendered_source.rs new file mode 100644 index 0000000000000..7dc57cfa900a0 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/render/rendered_source.rs @@ -0,0 +1,296 @@ +use anyhow::{anyhow, Result}; +use indexmap::IndexSet; +use serde_json::Value as JsonValue; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + introspect::{ + module::IntrospectableModule, output_asset::IntrospectableOutputAsset, Introspectable, + IntrospectableChildren, + }, + issue::IssueDescriptionExt, + module::Module, + output::OutputAsset, + version::VersionedContentExt, +}; +use turbopack_dev_server::{ + html::DevHtmlAsset, + source::{ + asset_graph::AssetGraphContentSource, + conditional::ConditionalContentSource, + lazy_instantiated::{GetContentSource, LazyInstantiatedContentSource}, + route_tree::{BaseSegment, RouteTree, RouteType}, + ContentSource, ContentSourceContent, ContentSourceData, ContentSourceDataVary, + GetContentSourceContent, ProxyResult, + }, +}; + +use super::{ + render_static::{render_static, StaticResult}, + RenderData, +}; +use crate::{ + external_asset_entrypoints, get_intermediate_asset, node_entry::NodeEntry, + route_matcher::RouteMatcher, +}; + +/// Creates a content source that renders something in Node.js with the passed +/// `entry` when it matches a `path_regex`. Once rendered it serves +/// all assets referenced by the `entry` that are within the `server_root`. +/// It needs a temporary directory (`intermediate_output_path`) to place file +/// for Node.js execution during rendering. The `chunking_context` should emit +/// to this directory. +#[turbo_tasks::function] +pub fn create_node_rendered_source( + cwd: Vc, + env: Vc>, + base_segments: Vec, + route_type: RouteType, + server_root: Vc, + route_match: Vc>, + pathname: Vc, + entry: Vc>, + fallback_page: Vc, + render_data: Vc, + debug: bool, +) -> Vc> { + let source = NodeRenderContentSource { + cwd, + env, + base_segments, + route_type, + server_root, + route_match, + pathname, + entry, + fallback_page, + render_data, + debug, + } + .cell(); + Vc::upcast(ConditionalContentSource::new( + Vc::upcast(source), + Vc::upcast( + LazyInstantiatedContentSource { + get_source: Vc::upcast(source), + } + .cell(), + ), + )) +} + +/// see [create_node_rendered_source] +#[turbo_tasks::value] +pub struct NodeRenderContentSource { + cwd: Vc, + env: Vc>, + base_segments: Vec, + route_type: RouteType, + server_root: Vc, + route_match: Vc>, + pathname: Vc, + entry: Vc>, + fallback_page: Vc, + render_data: Vc, + debug: bool, +} + +#[turbo_tasks::value_impl] +impl NodeRenderContentSource { + #[turbo_tasks::function] + pub async fn get_pathname(self: Vc) -> Result> { + Ok(self.await?.pathname) + } +} + +#[turbo_tasks::value_impl] +impl GetContentSource for NodeRenderContentSource { + /// Returns the [ContentSource] that serves all referenced external + /// assets. This is wrapped into [LazyInstantiatedContentSource]. + #[turbo_tasks::function] + async fn content_source(&self) -> Result>> { + let entries = self.entry.entries(); + let mut set = IndexSet::new(); + for &reference in self.fallback_page.references().await?.iter() { + set.insert(reference); + } + for &entry in entries.await?.iter() { + let entry = entry.await?; + set.extend( + external_asset_entrypoints( + entry.module, + entry.runtime_entries, + entry.chunking_context, + entry.intermediate_output_path, + ) + .await? + .iter() + .copied(), + ) + } + Ok(Vc::upcast(AssetGraphContentSource::new_lazy_multiple( + self.server_root, + Vc::cell(set), + ))) + } +} + +#[turbo_tasks::value_impl] +impl ContentSource for NodeRenderContentSource { + #[turbo_tasks::function] + async fn get_routes(self: Vc) -> Result> { + let this = self.await?; + Ok(RouteTree::new_route( + this.base_segments.clone(), + this.route_type.clone(), + Vc::upcast(self), + )) + } +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for NodeRenderContentSource { + #[turbo_tasks::function] + fn vary(&self) -> Vc { + ContentSourceDataVary { + method: true, + url: true, + original_url: true, + raw_headers: true, + raw_query: true, + ..Default::default() + } + .cell() + } + + #[turbo_tasks::function] + async fn get( + &self, + path: RcStr, + data: Value, + ) -> Result> { + let pathname = self.pathname.await?; + let Some(params) = &*self.route_match.params(path.clone()).await? else { + return Err(anyhow!( + "Non matching path ({}) provided for {}", + path, + pathname + )); + }; + let ContentSourceData { + method: Some(method), + url: Some(url), + original_url: Some(original_url), + raw_headers: Some(raw_headers), + raw_query: Some(raw_query), + .. + } = &*data + else { + return Err(anyhow!("Missing request data")); + }; + let entry = self.entry.entry(data.clone()).await?; + let result = render_static( + self.cwd, + self.env, + self.server_root.join(path.clone()), + entry.module, + entry.runtime_entries, + self.fallback_page, + entry.chunking_context, + entry.intermediate_output_path, + entry.output_root, + entry.project_dir, + RenderData { + params: params.clone(), + method: method.clone(), + url: url.clone(), + original_url: original_url.clone(), + raw_query: raw_query.clone(), + raw_headers: raw_headers.clone(), + path: pathname.as_str().into(), + data: Some(self.render_data.await?), + } + .cell(), + self.debug, + ) + .issue_file_path( + entry.module.ident().path(), + format!("server-side rendering {}", pathname), + ) + .await?; + Ok(match *result.await? { + StaticResult::Content { + content, + status_code, + headers, + } => { + ContentSourceContent::static_with_headers(content.versioned(), status_code, headers) + } + StaticResult::StreamedContent { + status, + headers, + ref body, + } => ContentSourceContent::HttpProxy( + ProxyResult { + status, + headers: headers.await?.clone_value(), + body: body.clone(), + } + .cell(), + ) + .cell(), + StaticResult::Rewrite(rewrite) => ContentSourceContent::Rewrite(rewrite).cell(), + }) + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("node render content source".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for NodeRenderContentSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + self.pathname + } + + #[turbo_tasks::function] + async fn details(&self) -> Result> { + Ok(Vc::cell( + format!( + "base: {:?}\ntype: {:?}", + self.base_segments, self.route_type + ) + .into(), + )) + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + let mut set = IndexSet::new(); + for &entry in self.entry.entries().await?.iter() { + let entry = entry.await?; + set.insert(( + Vc::cell("module".into()), + IntrospectableModule::new(Vc::upcast(entry.module)), + )); + set.insert(( + Vc::cell("intermediate asset".into()), + IntrospectableOutputAsset::new(get_intermediate_asset( + entry.chunking_context, + entry.module, + entry.runtime_entries, + )), + )); + } + Ok(Vc::cell(set)) + } +} diff --git a/turbopack/crates/turbopack-node/src/route_matcher.rs b/turbopack/crates/turbopack-node/src/route_matcher.rs new file mode 100644 index 0000000000000..9148b4ab09da1 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/route_matcher.rs @@ -0,0 +1,33 @@ +use indexmap::IndexMap; +use turbo_tasks::{RcStr, Vc}; + +#[turbo_tasks::value] +#[derive(Debug, Clone)] +#[serde(untagged)] +pub enum Param { + Single(RcStr), + Multi(Vec), +} + +#[turbo_tasks::value(transparent)] +#[derive(Debug, Clone)] +pub struct Params(pub Option>); + +/// Extracts parameters from a URL path. +pub trait RouteMatcherRef { + /// Returns whether the given path is a match for the route. + fn matches(&self, path: &str) -> bool; + + /// Returns the parameters extracted from the given path. + fn params(&self, path: &str) -> Params; +} + +/// Extracts parameters from a URL path (Vc version) +#[turbo_tasks::value_trait] +pub trait RouteMatcher { + /// Returns whether the given path is a match for the route. + fn matches(self: Vc, path: RcStr) -> Vc; + + /// Returns the parameters extracted from the given path. + fn params(self: Vc, path: RcStr) -> Vc; +} diff --git a/turbopack/crates/turbopack-node/src/source_map/mod.rs b/turbopack/crates/turbopack-node/src/source_map/mod.rs new file mode 100644 index 0000000000000..122ca62951b86 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/source_map/mod.rs @@ -0,0 +1,344 @@ +use std::{ + borrow::Cow, + fmt::Write, + path::{Path, MAIN_SEPARATOR}, +}; + +use anyhow::Result; +use const_format::concatcp; +use once_cell::sync::Lazy; +use regex::Regex; +pub use trace::{SourceMapTrace, StackFrame, TraceResult}; +use tracing::{instrument, Level}; +use turbo_tasks::{ReadRef, Vc}; +use turbo_tasks_fs::{ + source_context::get_source_context, to_sys_path, FileLinesContent, FileSystemPath, +}; +use turbopack_cli_utils::source_context::format_source_context_lines; +use turbopack_core::{ + output::OutputAsset, source_map::GenerateSourceMap, PROJECT_FILESYSTEM_NAME, SOURCE_MAP_PREFIX, +}; +use turbopack_ecmascript::magic_identifier::unmangle_identifiers; + +use crate::{internal_assets_for_source_mapping, pool::FormattingMode, AssetsForSourceMapping}; + +pub mod trace; + +const MAX_CODE_FRAMES: usize = 3; + +pub async fn apply_source_mapping( + text: &'_ str, + assets_for_source_mapping: Vc, + root: Vc, + project_dir: Vc, + formatting_mode: FormattingMode, +) -> Result> { + static STACK_TRACE_LINE: Lazy = + Lazy::new(|| Regex::new("\n at (?:(.+) \\()?(.+):(\\d+):(\\d+)\\)?").unwrap()); + + let mut it = STACK_TRACE_LINE.captures_iter(text).peekable(); + if it.peek().is_none() { + return Ok(Cow::Borrowed(text)); + } + let mut first_error = true; + let mut visible_code_frames = 0; + let mut new = String::with_capacity(text.len() * 2); + let mut last_match = 0; + for cap in it { + // unwrap on 0 is OK because captures only reports matches + let m = cap.get(0).unwrap(); + new.push_str(&text[last_match..m.start()]); + let name = cap.get(1).map(|s| s.as_str()); + let file = cap.get(2).unwrap().as_str(); + let line = cap.get(3).unwrap().as_str(); + let column = cap.get(4).unwrap().as_str(); + let line = line.parse::()?; + let column = column.parse::()?; + let frame = StackFrame { + name: name.map(|s| s.into()), + file: file.into(), + line: Some(line), + column: Some(column), + }; + let resolved = + resolve_source_mapping(assets_for_source_mapping, root, project_dir.root(), &frame) + .await; + write_resolved( + &mut new, + resolved, + &frame, + &mut first_error, + &mut visible_code_frames, + formatting_mode, + )?; + last_match = m.end(); + } + new.push_str(&text[last_match..]); + Ok(Cow::Owned(new)) +} + +fn write_resolved( + writable: &mut impl Write, + resolved: Result, + original_frame: &StackFrame<'_>, + first_error: &mut bool, + visible_code_frames: &mut usize, + formatting_mode: FormattingMode, +) -> Result<()> { + const PADDING: &str = "\n "; + match resolved { + Err(err) => { + // There was an error resolving the source map + write!(writable, "{PADDING}at {}", original_frame)?; + if *first_error { + write!(writable, "{PADDING}(error resolving source map: {})", err)?; + *first_error = false; + } else { + write!(writable, "{PADDING}(error resolving source map)")?; + } + } + Ok(ResolvedSourceMapping::NoSourceMap) | Ok(ResolvedSourceMapping::Unmapped) => { + // There is no source map for this file or no mapping for the line + write!( + writable, + "{PADDING}{}", + formatting_mode.lowlight(&format_args!("[at {}]", original_frame)) + )?; + } + Ok(ResolvedSourceMapping::Mapped { frame }) => { + // There is a mapping to something outside of the project (e. g. plugins, + // internal code) + write!( + writable, + "{PADDING}{}", + formatting_mode.lowlight(&format_args!( + "at {} [{}]", + frame, + original_frame.with_name(None) + )) + )?; + } + Ok(ResolvedSourceMapping::MappedLibrary { + frame, + project_path, + }) => { + // There is a mapping to a file in the project directory, but to library code + write!( + writable, + "{PADDING}{}", + formatting_mode.lowlight(&format_args!( + "at {} [{}]", + frame.with_path(&project_path.path), + original_frame.with_name(None) + )) + )?; + } + Ok(ResolvedSourceMapping::MappedProject { + frame, + project_path, + lines, + }) => { + // There is a mapping to a file in the project directory + if let Some(name) = frame.name.as_ref() { + write!( + writable, + "{PADDING}at {name} ({}) {}", + formatting_mode.highlight(&frame.with_name(None).with_path(&project_path.path)), + formatting_mode.lowlight(&format_args!("[{}]", original_frame.with_name(None))) + )?; + } else { + write!( + writable, + "{PADDING}at {} {}", + formatting_mode.highlight(&frame.with_path(&project_path.path)), + formatting_mode.lowlight(&format_args!("[{}]", original_frame.with_name(None))) + )?; + } + let (line, column) = frame.get_pos().unwrap_or((0, 0)); + let line = line.saturating_sub(1); + let column = column.saturating_sub(1); + if let FileLinesContent::Lines(lines) = &*lines { + if *visible_code_frames < MAX_CODE_FRAMES { + let lines = lines.iter().map(|l| l.content.as_str()); + let ctx = get_source_context(lines, line, column, line, column); + match formatting_mode { + FormattingMode::Plain => { + write!(writable, "\n{}", ctx)?; + } + FormattingMode::AnsiColors => { + writable.write_char('\n')?; + format_source_context_lines(&ctx, writable); + } + } + *visible_code_frames += 1; + } + } + } + } + Ok(()) +} + +enum ResolvedSourceMapping { + NoSourceMap, + Unmapped, + Mapped { + frame: StackFrame<'static>, + }, + MappedProject { + frame: StackFrame<'static>, + project_path: ReadRef, + lines: ReadRef, + }, + MappedLibrary { + frame: StackFrame<'static>, + project_path: ReadRef, + }, +} + +async fn resolve_source_mapping( + assets_for_source_mapping: Vc, + root: Vc, + project_dir: Vc, + frame: &StackFrame<'_>, +) -> Result { + let Some((line, column)) = frame.get_pos() else { + return Ok(ResolvedSourceMapping::NoSourceMap); + }; + let name = frame.name.as_ref(); + let file = &frame.file; + let Some(root) = to_sys_path(root).await? else { + return Ok(ResolvedSourceMapping::NoSourceMap); + }; + let Ok(file) = Path::new(file.as_ref()).strip_prefix(root) else { + return Ok(ResolvedSourceMapping::NoSourceMap); + }; + let file = file.to_string_lossy(); + let file = if MAIN_SEPARATOR != '/' { + Cow::Owned(file.replace(MAIN_SEPARATOR, "/")) + } else { + file + }; + let map = assets_for_source_mapping.await?; + let Some(generate_source_map) = map.get(file.as_ref()) else { + return Ok(ResolvedSourceMapping::NoSourceMap); + }; + let Some(sm) = *generate_source_map.generate_source_map().await? else { + return Ok(ResolvedSourceMapping::NoSourceMap); + }; + let trace = SourceMapTrace::new(sm, line, column, name.map(|s| s.clone().into())) + .trace() + .await?; + match &*trace { + TraceResult::Found(frame) => { + let lib_code = frame.file.contains("/node_modules/"); + if let Some(project_path) = frame.file.strip_prefix(concatcp!( + SOURCE_MAP_PREFIX, + "[", + PROJECT_FILESYSTEM_NAME, + "]/" + )) { + let fs_path = project_dir.join(project_path.into()); + if lib_code { + return Ok(ResolvedSourceMapping::MappedLibrary { + frame: frame.clone(), + project_path: fs_path.await?, + }); + } else { + let lines = fs_path.read().lines().await?; + return Ok(ResolvedSourceMapping::MappedProject { + frame: frame.clone(), + project_path: fs_path.await?, + lines, + }); + } + } + Ok(ResolvedSourceMapping::Mapped { + frame: frame.clone(), + }) + } + TraceResult::NotFound => Ok(ResolvedSourceMapping::Unmapped), + } +} + +#[turbo_tasks::value(shared)] +#[derive(Clone, Debug)] +pub struct StructuredError { + pub name: String, + pub message: String, + #[turbo_tasks(trace_ignore)] + stack: Vec>, +} + +impl StructuredError { + pub async fn print( + &self, + assets_for_source_mapping: Vc, + root: Vc, + project_dir: Vc, + formatting_mode: FormattingMode, + ) -> Result { + let mut message = String::new(); + + let magic = |content| formatting_mode.magic_identifier(content); + + write!( + message, + "{}: {}", + self.name, + unmangle_identifiers(&self.message, magic) + )?; + + let mut first_error = true; + let mut visible_code_frames = 0; + + for frame in &self.stack { + let frame = frame.unmangle_identifiers(magic); + let resolved = + resolve_source_mapping(assets_for_source_mapping, root, project_dir.root(), &frame) + .await; + write_resolved( + &mut message, + resolved, + &frame, + &mut first_error, + &mut visible_code_frames, + formatting_mode, + )?; + } + Ok(message) + } +} + +pub async fn trace_stack( + error: StructuredError, + root_asset: Vc>, + output_path: Vc, + project_dir: Vc, +) -> Result { + let assets_for_source_mapping = internal_assets_for_source_mapping(root_asset, output_path); + + trace_stack_with_source_mapping_assets( + error, + assets_for_source_mapping, + output_path, + project_dir, + ) + .await +} + +#[instrument(level = Level::TRACE, skip_all)] +pub async fn trace_stack_with_source_mapping_assets( + error: StructuredError, + assets_for_source_mapping: Vc, + output_path: Vc, + project_dir: Vc, +) -> Result { + error + .print( + assets_for_source_mapping, + output_path, + project_dir, + FormattingMode::Plain, + ) + .await +} diff --git a/turbopack/crates/turbopack-node/src/source_map/trace.rs b/turbopack/crates/turbopack-node/src/source_map/trace.rs new file mode 100644 index 0000000000000..433ed0d523d76 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/source_map/trace.rs @@ -0,0 +1,174 @@ +use std::{borrow::Cow, fmt::Display}; + +use anyhow::Result; +use mime::APPLICATION_JSON; +use serde::{Deserialize, Serialize}; +use serde_json::json; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::File; +use turbopack_core::{ + asset::AssetContent, + source_map::{SourceMap, Token}, +}; +use turbopack_ecmascript::magic_identifier::unmangle_identifiers; + +/// An individual stack frame, as parsed by the stacktrace-parser npm module. +/// +/// Line and column can be None if the frame is anonymous. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] +pub struct StackFrame<'a> { + pub file: Cow<'a, str>, + #[serde(rename = "lineNumber")] + pub line: Option, + pub column: Option, + #[serde(rename = "methodName")] + pub name: Option>, +} + +impl<'a> StackFrame<'a> { + pub fn unmangle_identifiers(&self, magic: impl Fn(String) -> T) -> StackFrame<'_> { + StackFrame { + file: Cow::Borrowed(self.file.as_ref()), + line: self.line, + column: self.column, + name: self + .name + .as_ref() + .map(|n| unmangle_identifiers(n.as_ref(), magic)), + } + } + + pub fn with_path<'b>(&'a self, path: &'b str) -> StackFrame<'b> + where + 'a: 'b, + { + StackFrame { + file: Cow::Borrowed(path), + line: self.line, + column: self.column, + name: self.name.as_ref().map(|n| Cow::Borrowed(n.as_ref())), + } + } + + pub fn with_name<'b>(&'a self, name: Option<&'b str>) -> StackFrame<'b> + where + 'a: 'b, + { + StackFrame { + file: Cow::Borrowed(self.file.as_ref()), + line: self.line, + column: self.column, + name: name.map(Cow::Borrowed), + } + } + + pub fn get_pos(&self) -> Option<(usize, usize)> { + self.line.zip(self.column) + } +} + +impl<'a> Display for StackFrame<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.get_pos() { + Some((l, c)) => match &self.name.as_deref() { + None | Some("") | Some("(anonymous)") => { + write!(f, "{}:{}:{}", self.file, l, c) + } + Some(n) => write!(f, "{} ({}:{}:{})", n, self.file, l, c), + }, + None => write!(f, "{}", self.file), + } + } +} +/// Source Map Trace is a convenient wrapper to perform and consume a source map +/// trace's token. +#[turbo_tasks::value(shared)] +#[derive(Debug)] +pub struct SourceMapTrace { + map: Vc, + line: usize, + column: usize, + name: Option, +} + +/// The result of performing a source map trace. +#[turbo_tasks::value(shared)] +#[derive(Debug)] +pub enum TraceResult { + NotFound, + Found(#[turbo_tasks(trace_ignore)] StackFrame<'static>), +} + +#[turbo_tasks::value_impl] +impl SourceMapTrace { + #[turbo_tasks::function] + pub async fn new( + map: Vc, + line: usize, + column: usize, + name: Option, + ) -> Vc { + SourceMapTrace { + map, + line, + column, + name, + } + .cell() + } + + /// Traces the line/column through the source map into its original + /// position. + /// + /// This method is god-awful slow. We're getting the content + /// of a .map file, which means we're serializing all of the individual + /// sections into a string and concatenating, taking that and + /// deserializing into a DecodedMap, and then querying it. Besides being a + /// memory hog, it'd be so much faster if we could just directly access + /// the individual sections of the JS file's map without the + /// serialization. + #[turbo_tasks::function] + pub async fn trace(self: Vc) -> Result> { + let this = self.await?; + + let token = this + .map + .lookup_token(this.line.saturating_sub(1), this.column.saturating_sub(1)) + .await?; + let result = match &*token { + Token::Original(t) => TraceResult::Found(StackFrame { + file: t.original_file.clone().into(), + line: Some(t.original_line.saturating_add(1)), + column: Some(t.original_column.saturating_add(1)), + name: t + .name + .clone() + .or_else(|| this.name.clone()) + .map(|v| v.into_owned()) + .map(Cow::Owned), + }), + _ => TraceResult::NotFound, + }; + + Ok(result.cell()) + } + + /// Takes the trace and generates a (possibly valid) JSON asset content. + #[turbo_tasks::function] + pub async fn content(self: Vc) -> Result> { + let trace = self.trace().await?; + let result = match &*trace { + // purposefully invalid JSON (it can't be empty), so that the catch handler will default + // to the generated stack frame. + TraceResult::NotFound => "".to_string(), + TraceResult::Found(frame) => json!({ + "originalStackFrame": frame, + // TODO + "originalCodeFrame": null, + }) + .to_string(), + }; + let file = File::from(result).with_content_type(APPLICATION_JSON); + Ok(AssetContent::file(file.into())) + } +} diff --git a/turbopack/crates/turbopack-node/src/transforms/mod.rs b/turbopack/crates/turbopack-node/src/transforms/mod.rs new file mode 100644 index 0000000000000..996a8a5fc86dc --- /dev/null +++ b/turbopack/crates/turbopack-node/src/transforms/mod.rs @@ -0,0 +1,3 @@ +pub mod postcss; +mod util; +pub mod webpack; diff --git a/turbopack/crates/turbopack-node/src/transforms/postcss.rs b/turbopack/crates/turbopack-node/src/transforms/postcss.rs new file mode 100644 index 0000000000000..76497668ffdcc --- /dev/null +++ b/turbopack/crates/turbopack-node/src/transforms/postcss.rs @@ -0,0 +1,449 @@ +use anyhow::{bail, Context, Result}; +use indexmap::indexmap; +use indoc::formatdoc; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{ + trace::TraceRawVcs, Completion, Completions, RcStr, TaskInput, TryFlatJoinIterExt, Value, Vc, +}; +use turbo_tasks_bytes::stream::SingleValue; +use turbo_tasks_fs::{ + json::parse_json_with_source_context, File, FileContent, FileSystemEntryType, FileSystemPath, +}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + changed::any_content_changed_of_module, + context::{AssetContext, ProcessResult}, + file_source::FileSource, + ident::AssetIdent, + issue::{ + Issue, IssueDescriptionExt, IssueSeverity, IssueStage, OptionStyledString, StyledString, + }, + reference_type::{EntryReferenceSubType, InnerAssets, ReferenceType}, + resolve::{find_context_file, options::ImportMapping, FindContextFileResult}, + source::Source, + source_transform::SourceTransform, + virtual_source::VirtualSource, +}; + +use super::{ + util::{emitted_assets_to_virtual_sources, EmittedAsset}, + webpack::WebpackLoaderContext, +}; +use crate::{ + embed_js::embed_file, execution_context::ExecutionContext, + transforms::webpack::evaluate_webpack_loader, +}; + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +#[turbo_tasks::value(serialization = "custom")] +struct PostCssProcessingResult { + css: String, + map: Option, + #[turbo_tasks(trace_ignore)] + assets: Option>, +} + +#[derive( + Default, Copy, Clone, PartialEq, Eq, Hash, Debug, TraceRawVcs, Serialize, Deserialize, TaskInput, +)] +pub enum PostCssConfigLocation { + #[default] + ProjectPath, + ProjectPathOrLocalPath, +} + +#[turbo_tasks::value(shared)] +#[derive(Clone, Default)] +pub struct PostCssTransformOptions { + pub postcss_package: Option>, + pub config_location: PostCssConfigLocation, + pub placeholder_for_future_extensions: u8, +} + +#[turbo_tasks::function] +fn postcss_configs() -> Vc> { + Vc::cell( + [ + ".postcssrc", + ".postcssrc.json", + ".postcssrc.yaml", + ".postcssrc.yml", + ".postcssrc.js", + ".postcssrc.mjs", + ".postcssrc.cjs", + ".config/postcssrc", + ".config/postcssrc.json", + ".config/postcssrc.yaml", + ".config/postcssrc.yml", + ".config/postcssrc.js", + ".config/postcssrc.mjs", + ".config/postcssrc.cjs", + "postcss.config.js", + "postcss.config.mjs", + "postcss.config.cjs", + "postcss.config.json", + ] + .into_iter() + .map(RcStr::from) + .collect(), + ) +} + +#[turbo_tasks::value] +pub struct PostCssTransform { + evaluate_context: Vc>, + execution_context: Vc, + config_location: PostCssConfigLocation, +} + +#[turbo_tasks::value_impl] +impl PostCssTransform { + #[turbo_tasks::function] + pub fn new( + evaluate_context: Vc>, + execution_context: Vc, + config_location: PostCssConfigLocation, + ) -> Vc { + PostCssTransform { + evaluate_context, + execution_context, + config_location, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl SourceTransform for PostCssTransform { + #[turbo_tasks::function] + fn transform(&self, source: Vc>) -> Vc> { + Vc::upcast( + PostCssTransformedAsset { + evaluate_context: self.evaluate_context, + execution_context: self.execution_context, + config_location: self.config_location, + source, + } + .cell(), + ) + } +} + +#[turbo_tasks::value] +struct PostCssTransformedAsset { + evaluate_context: Vc>, + execution_context: Vc, + config_location: PostCssConfigLocation, + source: Vc>, +} + +#[turbo_tasks::value_impl] +impl Source for PostCssTransformedAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source.ident() + } +} + +#[turbo_tasks::value_impl] +impl Asset for PostCssTransformedAsset { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let this = self.await?; + Ok(self + .process() + .issue_file_path(this.source.ident().path(), "PostCSS processing") + .await? + .await? + .content) + } +} + +#[turbo_tasks::value] +struct ProcessPostCssResult { + content: Vc, + assets: Vec>, +} + +#[turbo_tasks::function] +async fn config_changed( + asset_context: Vc>, + postcss_config_path: Vc, +) -> Result> { + let config_asset = asset_context + .process( + Vc::upcast(FileSource::new(postcss_config_path)), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) + .module(); + + Ok(Vc::::cell(vec![ + any_content_changed_of_module(config_asset), + extra_configs_changed(asset_context, postcss_config_path), + ]) + .completed()) +} + +#[turbo_tasks::function] +async fn extra_configs_changed( + asset_context: Vc>, + postcss_config_path: Vc, +) -> Result> { + let parent_path = postcss_config_path.parent(); + + let config_paths = [ + parent_path.join("tailwind.config.js".into()), + parent_path.join("tailwind.config.ts".into()), + ]; + + let configs = config_paths + .into_iter() + .map(|path| async move { + Ok( + if matches!(&*path.get_type().await?, FileSystemEntryType::File) { + match *asset_context + .process( + Vc::upcast(FileSource::new(path)), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) + .await? + { + ProcessResult::Module(module) => { + Some(any_content_changed_of_module(module)) + } + ProcessResult::Ignore => None, + } + } else { + None + }, + ) + }) + .try_flat_join() + .await?; + + Ok(Vc::::cell(configs).completed()) +} + +#[turbo_tasks::function] +pub(crate) async fn config_loader_source( + project_path: Vc, + postcss_config_path: Vc, +) -> Result>> { + let postcss_config_path_value = &*postcss_config_path.await?; + + // We can only load js files with `import()`. + if !postcss_config_path_value.path.ends_with(".js") { + return Ok(Vc::upcast(FileSource::new(postcss_config_path))); + } + + let Some(config_path) = project_path + .await? + .get_relative_path_to(postcss_config_path_value) + else { + bail!("Unable to get relative path to postcss config"); + }; + + // We don't want to bundle the config file, so we load it with `import()`. + // Bundling would break the ability to use `require.resolve` in the config file. + let code = formatdoc! { + r#" + import {{ pathToFileURL }} from 'node:url'; + import path from 'node:path'; + + const configPath = path.join(process.cwd(), {config_path}); + // Absolute paths don't work with ESM imports on Windows: + // https://github.com/nodejs/node/issues/31710 + // convert it to a file:// URL, which works on all platforms + const configUrl = pathToFileURL(configPath).toString(); + const mod = await __turbopack_external_import__(configUrl); + + export default mod.default ?? mod; + "#, + config_path = serde_json::to_string(&config_path).expect("a string should be serializable"), + }; + + Ok(Vc::upcast(VirtualSource::new( + postcss_config_path.append("_.loader.mjs".into()), + AssetContent::file(File::from(code).into()), + ))) +} + +#[turbo_tasks::function] +async fn postcss_executor( + asset_context: Vc>, + project_path: Vc, + postcss_config_path: Vc, +) -> Result> { + let config_asset = asset_context + .process( + config_loader_source(project_path, postcss_config_path), + Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)), + ) + .module(); + + Ok(asset_context.process( + Vc::upcast(VirtualSource::new( + postcss_config_path.join("transform.ts".into()), + AssetContent::File(embed_file("transforms/postcss.ts".into())).cell(), + )), + Value::new(ReferenceType::Internal(Vc::cell(indexmap! { + "CONFIG".into() => config_asset + }))), + )) +} + +async fn find_config_in_location( + project_path: Vc, + location: PostCssConfigLocation, + source: Vc>, +) -> Result>> { + if let FindContextFileResult::Found(config_path, _) = + *find_context_file(project_path, postcss_configs()).await? + { + return Ok(Some(config_path)); + } + + if matches!(location, PostCssConfigLocation::ProjectPathOrLocalPath) { + if let FindContextFileResult::Found(config_path, _) = + *find_context_file(source.ident().path().parent(), postcss_configs()).await? + { + return Ok(Some(config_path)); + } + } + + Ok(None) +} + +#[turbo_tasks::value_impl] +impl PostCssTransformedAsset { + #[turbo_tasks::function] + async fn process(self: Vc) -> Result> { + let this = self.await?; + let ExecutionContext { + project_path, + chunking_context, + env, + } = *this.execution_context.await?; + + // For this postcss transform, there is no gaurantee that looking up for the + // source path will arrives specific project config for the postcss. + // i.e, this is possible + // - root + // - node_modules + // - somepkg/(some.module.css, postcss.config.js) // this could be symlinked + // local, or actual remote pkg or anything + // - packages // root of workspace pkgs + // - pkg1/(postcss.config.js) // The actual config we're looking for + // + // We look for the config in the project path first, then the source path + let Some(config_path) = + find_config_in_location(project_path, this.config_location, this.source).await? + else { + return Ok(ProcessPostCssResult { + content: this.source.content(), + assets: Vec::new(), + } + .cell()); + }; + + let source_content = this.source.content(); + let AssetContent::File(file) = *source_content.await? else { + bail!("PostCSS transform only support transforming files"); + }; + let FileContent::Content(content) = &*file.await? else { + return Ok(ProcessPostCssResult { + content: AssetContent::File(FileContent::NotFound.cell()).cell(), + assets: Vec::new(), + } + .cell()); + }; + let content = content.content().to_str()?; + let evaluate_context = this.evaluate_context; + + // This invalidates the transform when the config changes. + let config_changed = config_changed(evaluate_context, config_path); + + let postcss_executor = + postcss_executor(evaluate_context, project_path, config_path).module(); + let css_fs_path = this.source.ident().path(); + + // We need to get a path relative to the project because the postcss loader + // runs with the project as the current working directory. + let css_path = if let Some(css_path) = project_path + .await? + .get_relative_path_to(&*css_fs_path.await?) + { + css_path.into_owned() + } else { + // This shouldn't be an error since it can happen on virtual assets + "".into() + }; + + let config_value = evaluate_webpack_loader(WebpackLoaderContext { + module_asset: postcss_executor, + cwd: project_path, + env, + context_ident_for_issue: this.source.ident(), + asset_context: evaluate_context, + chunking_context, + resolve_options_context: None, + args: vec![Vc::cell(content.into()), Vc::cell(css_path.into())], + additional_invalidation: config_changed, + }) + .await?; + + let SingleValue::Single(val) = config_value.try_into_single().await? else { + // An error happened, which has already been converted into an issue. + return Ok(ProcessPostCssResult { + content: AssetContent::File(FileContent::NotFound.cell()).cell(), + assets: Vec::new(), + } + .cell()); + }; + let processed_css: PostCssProcessingResult = parse_json_with_source_context(val.to_str()?) + .context("Unable to deserializate response from PostCSS transform operation")?; + + // TODO handle SourceMap + let file = File::from(processed_css.css); + let assets = emitted_assets_to_virtual_sources(processed_css.assets); + let content = AssetContent::File(FileContent::Content(file).cell()).cell(); + Ok(ProcessPostCssResult { content, assets }.cell()) + } +} + +#[turbo_tasks::value] +struct PostCssTransformIssue { + source: Vc, + description: RcStr, + severity: Vc, + title: RcStr, +} + +#[turbo_tasks::value_impl] +impl Issue for PostCssTransformIssue { + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.source + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text(self.title.clone()).cell() + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some(StyledString::Text(self.description.clone()).cell())) + } + + #[turbo_tasks::function] + fn severity(&self) -> Vc { + self.severity + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Transform.cell() + } +} diff --git a/turbopack/crates/turbopack-node/src/transforms/util.rs b/turbopack/crates/turbopack-node/src/transforms/util.rs new file mode 100644 index 0000000000000..bb1fb69eff09b --- /dev/null +++ b/turbopack/crates/turbopack-node/src/transforms/util.rs @@ -0,0 +1,43 @@ +use std::collections::BTreeMap; + +use serde::{Deserialize, Serialize}; +use serde_json::Value as JsonValue; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::{File, FileContent, FileSystem}; +use turbopack_core::{ + asset::AssetContent, server_fs::ServerFileSystem, virtual_source::VirtualSource, +}; + +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +pub struct EmittedAsset { + file: RcStr, + content: RcStr, + source_map: Option, +} + +pub fn emitted_assets_to_virtual_sources( + assets: Option>, +) -> Vec> { + assets + .into_iter() + .flatten() + .map( + |EmittedAsset { + file, + content, + source_map, + }| (file, (content, source_map)), + ) + // Sort it to make it determinstic + .collect::>() + .into_iter() + .map(|(file, (content, _source_map))| { + // TODO handle SourceMap + VirtualSource::new( + ServerFileSystem::new().root().join(file), + AssetContent::File(FileContent::Content(File::from(content)).cell()).cell(), + ) + }) + .collect() +} diff --git a/turbopack/crates/turbopack-node/src/transforms/webpack.rs b/turbopack/crates/turbopack-node/src/transforms/webpack.rs new file mode 100644 index 0000000000000..a218d3f21a699 --- /dev/null +++ b/turbopack/crates/turbopack-node/src/transforms/webpack.rs @@ -0,0 +1,843 @@ +use std::mem::take; + +use anyhow::{bail, Context, Result}; +use async_trait::async_trait; +use serde::{Deserialize, Serialize}; +use serde_json::{json, Value as JsonValue}; +use turbo_tasks::{ + trace::TraceRawVcs, Completion, RcStr, TaskInput, TryJoinIterExt, Value, ValueToString, Vc, +}; +use turbo_tasks_bytes::stream::SingleValue; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::{ + glob::Glob, json::parse_json_with_source_context, DirectoryEntry, File, FileContent, + FileSystemPath, ReadGlobResult, +}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::ChunkingContext, + context::{AssetContext, ProcessResult}, + file_source::FileSource, + ident::AssetIdent, + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, + module::Module, + reference_type::{InnerAssets, ReferenceType}, + resolve::{ + options::{ConditionValue, ResolveInPackage, ResolveIntoPackage, ResolveOptions}, + parse::Request, + pattern::Pattern, + resolve, + }, + source::Source, + source_map::{GenerateSourceMap, OptionSourceMap, SourceMap}, + source_transform::SourceTransform, + virtual_source::VirtualSource, +}; +use turbopack_resolve::{ + ecmascript::get_condition_maps, resolve::resolve_options, + resolve_options_context::ResolveOptionsContext, +}; + +use super::util::{emitted_assets_to_virtual_sources, EmittedAsset}; +use crate::{ + debug::should_debug, + embed_js::embed_file_path, + evaluate::{ + compute, custom_evaluate, get_evaluate_pool, EvaluateContext, EvaluationIssue, + JavaScriptEvaluation, JavaScriptStreamSender, + }, + execution_context::ExecutionContext, + pool::{FormattingMode, NodeJsPool}, + source_map::{StackFrame, StructuredError}, + AssetsForSourceMapping, +}; + +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(rename_all = "camelCase")] +#[turbo_tasks::value(serialization = "custom")] +struct WebpackLoadersProcessingResult { + source: RcStr, + map: Option, + #[turbo_tasks(trace_ignore)] + assets: Option>, +} + +#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] +pub struct WebpackLoaderItem { + pub loader: RcStr, + #[turbo_tasks(trace_ignore)] + pub options: serde_json::Map, +} + +#[derive(Debug, Clone)] +#[turbo_tasks::value(shared, transparent)] +pub struct WebpackLoaderItems(pub Vec); + +#[turbo_tasks::value] +pub struct WebpackLoaders { + evaluate_context: Vc>, + execution_context: Vc, + loaders: Vc, + rename_as: Option, + resolve_options_context: Vc, +} + +#[turbo_tasks::value_impl] +impl WebpackLoaders { + #[turbo_tasks::function] + pub fn new( + evaluate_context: Vc>, + execution_context: Vc, + loaders: Vc, + rename_as: Option, + resolve_options_context: Vc, + ) -> Vc { + WebpackLoaders { + evaluate_context, + execution_context, + loaders, + rename_as, + resolve_options_context, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl SourceTransform for WebpackLoaders { + #[turbo_tasks::function] + fn transform(self: Vc, source: Vc>) -> Vc> { + Vc::upcast( + WebpackLoadersProcessedAsset { + transform: self, + source, + } + .cell(), + ) + } +} + +#[turbo_tasks::value] +struct WebpackLoadersProcessedAsset { + transform: Vc, + source: Vc>, +} + +#[turbo_tasks::value_impl] +impl Source for WebpackLoadersProcessedAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + Ok( + if let Some(rename_as) = self.transform.await?.rename_as.as_deref() { + self.source.ident().rename_as(rename_as.into()) + } else { + self.source.ident() + }, + ) + } +} + +#[turbo_tasks::value_impl] +impl Asset for WebpackLoadersProcessedAsset { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + Ok(self.process().await?.content) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for WebpackLoadersProcessedAsset { + #[turbo_tasks::function] + async fn generate_source_map(self: Vc) -> Result> { + Ok(Vc::cell(self.process().await?.source_map)) + } +} + +#[turbo_tasks::value] +struct ProcessWebpackLoadersResult { + content: Vc, + source_map: Option>, + assets: Vec>, +} + +#[turbo_tasks::function] +fn webpack_loaders_executor(evaluate_context: Vc>) -> Vc { + evaluate_context.process( + Vc::upcast(FileSource::new(embed_file_path( + "transforms/webpack-loaders.ts".into(), + ))), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) +} + +#[turbo_tasks::value_impl] +impl WebpackLoadersProcessedAsset { + #[turbo_tasks::function] + async fn process(self: Vc) -> Result> { + let this = self.await?; + let transform = this.transform.await?; + + let ExecutionContext { + project_path, + chunking_context, + env, + } = *transform.execution_context.await?; + let source_content = this.source.content(); + let AssetContent::File(file) = *source_content.await? else { + bail!("Webpack Loaders transform only support transforming files"); + }; + let FileContent::Content(content) = &*file.await? else { + return Ok(ProcessWebpackLoadersResult { + content: AssetContent::File(FileContent::NotFound.cell()).cell(), + assets: Vec::new(), + source_map: None, + } + .cell()); + }; + let content = content.content().to_str()?; + let evaluate_context = transform.evaluate_context; + + let webpack_loaders_executor = webpack_loaders_executor(evaluate_context).module(); + let resource_fs_path = this.source.ident().path(); + let resource_fs_path_ref = resource_fs_path.await?; + let Some(resource_path) = project_path + .await? + .get_relative_path_to(&resource_fs_path_ref) + else { + bail!(format!( + "Resource path \"{}\" need to be on project filesystem \"{}\"", + resource_fs_path_ref, + project_path.await? + )); + }; + let loaders = transform.loaders.await?; + let config_value = evaluate_webpack_loader(WebpackLoaderContext { + module_asset: webpack_loaders_executor, + cwd: project_path, + env, + context_ident_for_issue: this.source.ident(), + asset_context: evaluate_context, + chunking_context, + resolve_options_context: Some(transform.resolve_options_context), + args: vec![ + Vc::cell(content.into()), + Vc::cell(resource_path.to_string().into()), + Vc::cell(json!(*loaders)), + ], + additional_invalidation: Completion::immutable(), + }) + .await?; + + let SingleValue::Single(val) = config_value.try_into_single().await? else { + // An error happened, which has already been converted into an issue. + return Ok(ProcessWebpackLoadersResult { + content: AssetContent::File(FileContent::NotFound.cell()).cell(), + assets: Vec::new(), + source_map: None, + } + .cell()); + }; + let processed: WebpackLoadersProcessingResult = parse_json_with_source_context( + val.to_str()?, + ) + .context("Unable to deserializate response from webpack loaders transform operation")?; + + // handle SourceMap + let source_map = if let Some(source_map) = processed.map { + SourceMap::new_from_file_content(FileContent::Content(File::from(source_map)).cell()) + .await? + .map(|source_map| source_map.cell()) + } else { + None + }; + let file = File::from(processed.source); + let assets = emitted_assets_to_virtual_sources(processed.assets); + let content = AssetContent::File(FileContent::Content(file).cell()).cell(); + Ok(ProcessWebpackLoadersResult { + content, + assets, + source_map, + } + .cell()) + } +} + +#[turbo_tasks::function] +pub(crate) fn evaluate_webpack_loader( + webpack_loader_context: WebpackLoaderContext, +) -> Vc { + custom_evaluate(webpack_loader_context) +} + +#[turbo_tasks::function] +async fn compute_webpack_loader_evaluation( + webpack_loader_context: WebpackLoaderContext, + sender: Vc, +) -> Result> { + compute(webpack_loader_context, sender).await +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +enum LogType { + Error, + Warn, + Info, + Log, + Debug, + Trace, + Group, + GroupCollapsed, + GroupEnd, + Profile, + ProfileEnd, + Time, + Clear, + Status, +} + +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] +#[serde(rename_all = "camelCase")] +pub struct LogInfo { + time: u64, + log_type: LogType, + args: Vec, + trace: Option>>, +} + +#[derive(Deserialize, Debug)] +#[serde(tag = "type", rename_all = "camelCase")] +pub enum InfoMessage { + FileDependency { + path: RcStr, + }, + BuildDependency { + path: RcStr, + }, + DirDependency { + path: RcStr, + glob: RcStr, + }, + EmittedError { + severity: IssueSeverity, + error: StructuredError, + }, + Log(LogInfo), +} + +#[derive(Debug, Clone, TaskInput, Hash, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] + +pub struct WebpackResolveOptions { + alias_fields: Option>, + condition_names: Option>, + no_package_json: bool, + extensions: Option>, + main_fields: Option>, + no_exports_field: bool, + main_files: Option>, + no_modules: bool, + prefer_relative: bool, +} + +#[derive(Deserialize, Debug)] +#[serde(tag = "type", rename_all = "camelCase")] +pub enum RequestMessage { + #[serde(rename_all = "camelCase")] + Resolve { + options: WebpackResolveOptions, + lookup_path: RcStr, + request: RcStr, + }, +} + +#[derive(Serialize, Debug)] +#[serde(untagged)] +pub enum ResponseMessage { + Resolve { path: RcStr }, +} + +#[derive(Clone, PartialEq, Eq, Hash, TaskInput, Serialize, Deserialize, Debug)] +pub struct WebpackLoaderContext { + pub module_asset: Vc>, + pub cwd: Vc, + pub env: Vc>, + pub context_ident_for_issue: Vc, + pub asset_context: Vc>, + pub chunking_context: Vc>, + pub resolve_options_context: Option>, + pub args: Vec>, + pub additional_invalidation: Vc, +} + +#[async_trait] +impl EvaluateContext for WebpackLoaderContext { + type InfoMessage = InfoMessage; + type RequestMessage = RequestMessage; + type ResponseMessage = ResponseMessage; + type State = Vec; + + fn compute(self, sender: Vc) { + let _ = compute_webpack_loader_evaluation(self, sender); + } + + fn pool(&self) -> Vc { + get_evaluate_pool( + self.module_asset, + self.cwd, + self.env, + self.asset_context, + self.chunking_context, + None, + self.additional_invalidation, + should_debug("webpack_loader"), + ) + } + + fn args(&self) -> &[Vc] { + &self.args + } + + fn cwd(&self) -> Vc { + self.cwd + } + + fn keep_alive(&self) -> bool { + true + } + + async fn emit_error(&self, error: StructuredError, pool: &NodeJsPool) -> Result<()> { + EvaluationIssue { + error, + context_ident: self.context_ident_for_issue, + assets_for_source_mapping: pool.assets_for_source_mapping, + assets_root: pool.assets_root, + project_dir: self.chunking_context.context_path().root(), + } + .cell() + .emit(); + Ok(()) + } + + async fn info( + &self, + state: &mut Self::State, + data: Self::InfoMessage, + pool: &NodeJsPool, + ) -> Result<()> { + match data { + InfoMessage::FileDependency { path } => { + // TODO We might miss some changes that happened during execution + // Read dependencies to make them a dependencies of this task. This task will + // execute again when they change. + self.cwd.join(path).read().await?; + } + InfoMessage::BuildDependency { path } => { + // TODO We might miss some changes that happened during execution + BuildDependencyIssue { + context_ident: self.context_ident_for_issue, + path: self.cwd.join(path), + } + .cell() + .emit(); + } + InfoMessage::DirDependency { path, glob } => { + // TODO We might miss some changes that happened during execution + // Read dependencies to make them a dependencies of this task. This task will + // execute again when they change. + dir_dependency(self.cwd.join(path).read_glob(Glob::new(glob), false)).await?; + } + InfoMessage::EmittedError { error, severity } => { + EvaluateEmittedErrorIssue { + file_path: self.context_ident_for_issue.path(), + error, + severity: severity.cell(), + assets_for_source_mapping: pool.assets_for_source_mapping, + assets_root: pool.assets_root, + project_dir: self.chunking_context.context_path().root(), + } + .cell() + .emit(); + } + InfoMessage::Log(log) => { + state.push(log); + } + } + Ok(()) + } + + async fn request( + &self, + _state: &mut Self::State, + data: Self::RequestMessage, + _pool: &NodeJsPool, + ) -> Result { + match data { + RequestMessage::Resolve { + options: webpack_options, + lookup_path, + request, + } => { + let Some(resolve_options_context) = self.resolve_options_context else { + bail!("Resolve options are not available in this context"); + }; + let lookup_path = self.cwd.join(lookup_path); + let request = Request::parse(Value::new(Pattern::Constant(request))); + let options = resolve_options(lookup_path, resolve_options_context); + + let options = apply_webpack_resolve_options(options, webpack_options); + + let resolved = resolve( + lookup_path, + Value::new(ReferenceType::Undefined), + request, + options, + ); + + let request_str = request.to_string().await?; + let lookup_path_str = lookup_path.to_string().await?; + if let Some(source) = *resolved.first_source().await? { + if let Some(path) = self + .cwd + .await? + .get_relative_path_to(&*source.ident().path().await?) + { + Ok(ResponseMessage::Resolve { path }) + } else { + bail!( + "Resolving {} in {} ends up on a different filesystem", + request_str, + lookup_path_str + ); + } + } else { + bail!("Unable to resolve {} in {}", request_str, lookup_path_str); + } + } + } + } + + async fn finish(&self, state: Self::State, pool: &NodeJsPool) -> Result<()> { + let has_errors = state.iter().any(|log| log.log_type == LogType::Error); + let has_warnings = state.iter().any(|log| log.log_type == LogType::Warn); + if has_errors || has_warnings { + let logs = state + .into_iter() + .filter(|log| { + matches!( + log.log_type, + LogType::Error + | LogType::Warn + | LogType::Info + | LogType::Log + | LogType::Clear, + ) + }) + .collect(); + + EvaluateErrorLoggingIssue { + file_path: self.context_ident_for_issue.path(), + logging: logs, + severity: if has_errors { + IssueSeverity::Error.cell() + } else { + IssueSeverity::Warning.cell() + }, + assets_for_source_mapping: pool.assets_for_source_mapping, + assets_root: pool.assets_root, + project_dir: self.chunking_context.context_path().root(), + } + .cell() + .emit(); + } + Ok(()) + } +} + +#[turbo_tasks::function] +async fn apply_webpack_resolve_options( + resolve_options: Vc, + webpack_resolve_options: WebpackResolveOptions, +) -> Result> { + let mut resolve_options = resolve_options.await?.clone_value(); + if let Some(alias_fields) = webpack_resolve_options.alias_fields { + let mut old = resolve_options + .in_package + .extract_if(|field| matches!(field, ResolveInPackage::AliasField(..))) + .collect::>(); + for field in alias_fields { + if &*field == "..." { + resolve_options.in_package.extend(take(&mut old)); + } else { + resolve_options + .in_package + .push(ResolveInPackage::AliasField(field)); + } + } + } + if let Some(condition_names) = webpack_resolve_options.condition_names { + for conditions in get_condition_maps(&mut resolve_options) { + let mut old = take(conditions); + for name in &condition_names { + if name == "..." { + conditions.extend(take(&mut old)); + } else { + conditions.insert(name.clone(), ConditionValue::Set); + } + } + } + } + if webpack_resolve_options.no_package_json { + resolve_options.into_package.retain(|item| { + !matches!( + item, + ResolveIntoPackage::ExportsField { .. } | ResolveIntoPackage::MainField { .. } + ) + }); + } + if let Some(mut extensions) = webpack_resolve_options.extensions { + if let Some(pos) = extensions.iter().position(|ext| ext == "...") { + extensions.splice(pos..=pos, take(&mut resolve_options.extensions)); + } + resolve_options.extensions = extensions; + } + if let Some(main_fields) = webpack_resolve_options.main_fields { + let mut old = resolve_options + .into_package + .extract_if(|field| matches!(field, ResolveIntoPackage::MainField { .. })) + .collect::>(); + for field in main_fields { + if &*field == "..." { + resolve_options.into_package.extend(take(&mut old)); + } else { + resolve_options + .into_package + .push(ResolveIntoPackage::MainField { field }); + } + } + } + if webpack_resolve_options.no_exports_field { + resolve_options + .into_package + .retain(|field| !matches!(field, ResolveIntoPackage::ExportsField { .. })); + } + if let Some(main_files) = webpack_resolve_options.main_files { + resolve_options.default_files = main_files; + } + if webpack_resolve_options.no_modules { + resolve_options.modules.clear(); + } + if webpack_resolve_options.prefer_relative { + resolve_options.prefer_relative = true; + } + Ok(resolve_options.cell()) +} + +/// An issue that occurred while evaluating node code. +#[turbo_tasks::value(shared)] +pub struct BuildDependencyIssue { + pub context_ident: Vc, + pub path: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for BuildDependencyIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Warning.into() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Build dependencies are not yet supported".into()).cell() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Unsupported.cell() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.context_ident.path() + } + + #[turbo_tasks::function] + async fn description(&self) -> Result> { + Ok(Vc::cell(Some( + StyledString::Line(vec![ + StyledString::Text("The file at ".into()), + StyledString::Code(self.path.await?.to_string().into()), + StyledString::Text( + " is a build dependency, which is not yet implemented. + Changing this file or any dependency will not be recognized and might require restarting the \ + server" + .into(), + ), + ]) + .cell(), + ))) + } +} + +/// A hack to invalidate when any file in a directory changes. Need to be +/// awaited before files are accessed. +#[turbo_tasks::function] +async fn dir_dependency(glob: Vc) -> Result> { + let shallow = dir_dependency_shallow(glob); + let glob = glob.await?; + glob.inner + .values() + .map(|&inner| dir_dependency(inner)) + .try_join() + .await?; + shallow.await?; + Ok(Completion::new()) +} + +#[turbo_tasks::function] +async fn dir_dependency_shallow(glob: Vc) -> Result> { + let glob = glob.await?; + for item in glob.results.values() { + // Reading all files to add itself as dependency + match *item { + DirectoryEntry::File(file) => { + file.track().await?; + } + DirectoryEntry::Directory(dir) => { + dir_dependency(dir.read_glob(Glob::new("**".into()), false)).await?; + } + DirectoryEntry::Symlink(symlink) => { + symlink.read_link().await?; + } + DirectoryEntry::Other(other) => { + other.get_type().await?; + } + DirectoryEntry::Error => {} + } + } + Ok(Completion::new()) +} + +#[turbo_tasks::value(shared)] +pub struct EvaluateEmittedErrorIssue { + pub file_path: Vc, + pub severity: Vc, + pub error: StructuredError, + pub assets_for_source_mapping: Vc, + pub assets_root: Vc, + pub project_dir: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for EvaluateEmittedErrorIssue { + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.file_path + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Transform.cell() + } + + #[turbo_tasks::function] + fn severity(&self) -> Vc { + self.severity + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Issue while running loader".into()).cell() + } + + #[turbo_tasks::function] + async fn description(&self) -> Result> { + Ok(Vc::cell(Some( + StyledString::Text( + self.error + .print( + self.assets_for_source_mapping, + self.assets_root, + self.project_dir, + FormattingMode::Plain, + ) + .await? + .into(), + ) + .cell(), + ))) + } +} + +#[turbo_tasks::value(shared)] +pub struct EvaluateErrorLoggingIssue { + pub file_path: Vc, + pub severity: Vc, + #[turbo_tasks(trace_ignore)] + pub logging: Vec, + pub assets_for_source_mapping: Vc, + pub assets_root: Vc, + pub project_dir: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for EvaluateErrorLoggingIssue { + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.file_path + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Transform.cell() + } + + #[turbo_tasks::function] + fn severity(&self) -> Vc { + self.severity + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Error logging while running loader".into()).cell() + } + + #[turbo_tasks::function] + async fn description(&self) -> Result> { + fn fmt_args(prefix: String, args: &[JsonValue]) -> String { + let mut iter = args.iter(); + let Some(first) = iter.next() else { + return "".to_string(); + }; + let mut result = prefix; + if let JsonValue::String(s) = first { + result.push_str(s); + } else { + result.push_str(&first.to_string()); + } + for arg in iter { + result.push(' '); + result.push_str(&arg.to_string()); + } + result + } + let lines = self + .logging + .iter() + .map(|log| match log.log_type { + LogType::Error => { + StyledString::Strong(fmt_args(" ".to_string(), &log.args).into()) + } + LogType::Warn => StyledString::Text(fmt_args(" ".to_string(), &log.args).into()), + LogType::Info => StyledString::Text(fmt_args(" ".to_string(), &log.args).into()), + LogType::Log => StyledString::Text(fmt_args(" ".to_string(), &log.args).into()), + LogType::Clear => StyledString::Strong("---".into()), + _ => { + unimplemented!("{:?} is not implemented", log.log_type) + } + }) + .collect::>(); + Ok(Vc::cell(Some(StyledString::Stack(lines).cell()))) + } +} diff --git a/turbopack/crates/turbopack-nodejs/Cargo.toml b/turbopack/crates/turbopack-nodejs/Cargo.toml new file mode 100644 index 0000000000000..d49dec0df3605 --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "turbopack-nodejs" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[features] +# enable "HMR" for embedded assets +dynamic_embed_contents = ["turbo-tasks-fs/dynamic_embed_contents"] +# enable test utilities such as `RuntimeType::Dummy` +test = ["turbopack-ecmascript-runtime/test"] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +indexmap = { workspace = true } +indoc = { workspace = true } +serde = { workspace = true } +tracing = { workspace = true } +urlencoding = { workspace = true } + +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-hash = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } +turbopack-ecmascript-runtime = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-nodejs/build.rs b/turbopack/crates/turbopack-nodejs/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-nodejs/src/chunking_context.rs b/turbopack/crates/turbopack-nodejs/src/chunking_context.rs new file mode 100644 index 0000000000000..169623d9955ec --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/chunking_context.rs @@ -0,0 +1,383 @@ +use std::iter::once; + +use anyhow::{bail, Context, Result}; +use tracing::Instrument; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + chunk::{ + availability_info::AvailabilityInfo, + chunk_group::{make_chunk_group, MakeChunkGroupResult}, + Chunk, ChunkGroupResult, ChunkItem, ChunkableModule, ChunkingContext, + EntryChunkGroupResult, EvaluatableAssets, MinifyType, ModuleId, + }, + environment::Environment, + ident::AssetIdent, + module::Module, + output::OutputAsset, +}; +use turbopack_ecmascript::{ + async_chunk::module::AsyncLoaderModule, + chunk::EcmascriptChunk, + manifest::{chunk_asset::ManifestAsyncModule, loader_item::ManifestLoaderChunkItem}, +}; +use turbopack_ecmascript_runtime::RuntimeType; + +use crate::ecmascript::node::{ + chunk::EcmascriptBuildNodeChunk, entry::chunk::EcmascriptBuildNodeEntryChunk, +}; + +/// A builder for [`Vc`]. +pub struct NodeJsChunkingContextBuilder { + chunking_context: NodeJsChunkingContext, +} + +impl NodeJsChunkingContextBuilder { + pub fn asset_prefix(mut self, asset_prefix: Vc>) -> Self { + self.chunking_context.asset_prefix = asset_prefix; + self + } + + pub fn minify_type(mut self, minify_type: MinifyType) -> Self { + self.chunking_context.minify_type = minify_type; + self + } + + pub fn runtime_type(mut self, runtime_type: RuntimeType) -> Self { + self.chunking_context.runtime_type = runtime_type; + self + } + + pub fn manifest_chunks(mut self, manifest_chunks: bool) -> Self { + self.chunking_context.manifest_chunks = manifest_chunks; + self + } + + /// Builds the chunking context. + pub fn build(self) -> Vc { + NodeJsChunkingContext::new(Value::new(self.chunking_context)) + } +} + +/// A chunking context for build mode. +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Debug, Clone, Hash)] +pub struct NodeJsChunkingContext { + /// This path get stripped off of chunk paths before generating output asset + /// paths. + context_path: Vc, + /// This path is used to compute the url to request chunks or assets from + output_root: Vc, + /// This path is used to compute the url to request chunks or assets from + client_root: Vc, + /// Chunks are placed at this path + chunk_root_path: Vc, + /// Static assets are placed at this path + asset_root_path: Vc, + /// Static assets requested from this url base + asset_prefix: Vc>, + /// The environment chunks will be evaluated in. + environment: Vc, + /// The kind of runtime to include in the output. + runtime_type: RuntimeType, + /// Whether to minify resulting chunks + minify_type: MinifyType, + /// Whether to use manifest chunks for lazy compilation + manifest_chunks: bool, +} + +impl NodeJsChunkingContext { + /// Creates a new chunking context builder. + pub fn builder( + context_path: Vc, + output_root: Vc, + client_root: Vc, + chunk_root_path: Vc, + asset_root_path: Vc, + environment: Vc, + runtime_type: RuntimeType, + ) -> NodeJsChunkingContextBuilder { + NodeJsChunkingContextBuilder { + chunking_context: NodeJsChunkingContext { + context_path, + output_root, + client_root, + chunk_root_path, + asset_root_path, + asset_prefix: Default::default(), + environment, + runtime_type, + minify_type: MinifyType::NoMinify, + manifest_chunks: false, + }, + } + } +} + +impl NodeJsChunkingContext { + /// Returns the kind of runtime to include in output chunks. + /// + /// This is defined directly on `NodeJsChunkingContext` so it is zero-cost + /// when `RuntimeType` has a single variant. + pub fn runtime_type(&self) -> RuntimeType { + self.runtime_type + } + + /// Returns the minify type. + pub fn minify_type(&self) -> MinifyType { + self.minify_type + } +} + +#[turbo_tasks::value_impl] +impl NodeJsChunkingContext { + #[turbo_tasks::function] + fn new(this: Value) -> Vc { + this.into_value().cell() + } + + #[turbo_tasks::function] + pub fn asset_prefix(&self) -> Vc> { + self.asset_prefix + } + + #[turbo_tasks::function] + async fn generate_chunk( + self: Vc, + chunk: Vc>, + ) -> Result>> { + Ok( + if let Some(ecmascript_chunk) = + Vc::try_resolve_downcast_type::(chunk).await? + { + Vc::upcast(EcmascriptBuildNodeChunk::new(self, ecmascript_chunk)) + } else if let Some(output_asset) = + Vc::try_resolve_sidecast::>(chunk).await? + { + output_asset + } else { + bail!("Unable to generate output asset for chunk"); + }, + ) + } +} + +#[turbo_tasks::value_impl] +impl ChunkingContext for NodeJsChunkingContext { + #[turbo_tasks::function] + fn name(&self) -> Vc { + Vc::cell("unknown".into()) + } + + #[turbo_tasks::function] + fn context_path(&self) -> Vc { + self.context_path + } + + #[turbo_tasks::function] + fn output_root(&self) -> Vc { + self.output_root + } + + #[turbo_tasks::function] + fn environment(&self) -> Vc { + self.environment + } + + #[turbo_tasks::function] + async fn asset_url(self: Vc, ident: Vc) -> Result> { + let this = self.await?; + let asset_path = ident.path().await?.to_string(); + let asset_path = asset_path + .strip_prefix(&format!("{}/", this.client_root.await?.path)) + .context("expected client root to contain asset path")?; + + Ok(Vc::cell( + format!( + "{}{}", + this.asset_prefix + .await? + .as_ref() + .map(|s| s.clone()) + .unwrap_or_else(|| "/".into()), + asset_path + ) + .into(), + )) + } + + #[turbo_tasks::function] + async fn chunk_path( + &self, + ident: Vc, + extension: RcStr, + ) -> Result> { + let root_path = self.chunk_root_path; + let name = ident.output_name(self.context_path, extension).await?; + Ok(root_path.join(name.clone_value())) + } + + #[turbo_tasks::function] + fn reference_chunk_source_maps(&self, _chunk: Vc>) -> Vc { + Vc::cell(true) + } + + #[turbo_tasks::function] + async fn asset_path( + &self, + content_hash: RcStr, + original_asset_ident: Vc, + ) -> Result> { + let source_path = original_asset_ident.path().await?; + let basename = source_path.file_name(); + let asset_path = match source_path.extension_ref() { + Some(ext) => format!( + "{basename}.{content_hash}.{ext}", + basename = &basename[..basename.len() - ext.len() - 1], + content_hash = &content_hash[..8] + ), + None => format!( + "{basename}.{content_hash}", + content_hash = &content_hash[..8] + ), + }; + Ok(self.asset_root_path.join(asset_path.into())) + } + + #[turbo_tasks::function] + async fn chunk_group( + self: Vc, + module: Vc>, + availability_info: Value, + ) -> Result> { + let span = tracing::info_span!( + "chunking", + module = module.ident().to_string().await?.to_string() + ); + async move { + let MakeChunkGroupResult { + chunks, + availability_info, + } = make_chunk_group( + Vc::upcast(self), + [Vc::upcast(module)], + availability_info.into_value(), + ) + .await?; + + let mut assets: Vec>> = chunks + .iter() + .map(|chunk| self.generate_chunk(*chunk)) + .collect(); + + // Resolve assets + for asset in assets.iter_mut() { + *asset = asset.resolve().await?; + } + + Ok(ChunkGroupResult { + assets: Vc::cell(assets), + availability_info, + } + .cell()) + } + .instrument(span) + .await + } + + /// Generates an output chunk that: + /// * evaluates the given assets; and + /// * exports the result of evaluating the given module as a CommonJS + /// default export. + #[turbo_tasks::function] + pub async fn entry_chunk_group( + self: Vc, + path: Vc, + module: Vc>, + evaluatable_assets: Vc, + availability_info: Value, + ) -> Result> { + let availability_info = availability_info.into_value(); + + let MakeChunkGroupResult { + chunks, + availability_info, + } = make_chunk_group( + Vc::upcast(self), + once(module).chain( + evaluatable_assets + .await? + .iter() + .map(|&asset| Vc::upcast(asset)), + ), + availability_info, + ) + .await?; + + let other_chunks: Vec<_> = chunks + .iter() + .map(|chunk| self.generate_chunk(*chunk)) + .collect(); + + let Some(module) = Vc::try_resolve_downcast(module).await? else { + bail!("module must be placeable in an ecmascript chunk"); + }; + + let asset = Vc::upcast(EcmascriptBuildNodeEntryChunk::new( + path, + self, + Vc::cell(other_chunks), + evaluatable_assets, + module, + )); + + Ok(EntryChunkGroupResult { + asset, + availability_info, + } + .cell()) + } + + #[turbo_tasks::function] + fn evaluated_chunk_group( + self: Vc, + _ident: Vc, + _evaluatable_assets: Vc, + _availability_info: Value, + ) -> Result> { + // TODO(alexkirsz) This method should be part of a separate trait that is + // only implemented for client/edge runtimes. + bail!("the build chunking context does not support evaluated chunk groups") + } + + #[turbo_tasks::function] + async fn async_loader_chunk_item( + self: Vc, + module: Vc>, + availability_info: Value, + ) -> Result>> { + Ok(if self.await?.manifest_chunks { + let manifest_asset = + ManifestAsyncModule::new(module, Vc::upcast(self), availability_info); + Vc::upcast(ManifestLoaderChunkItem::new( + manifest_asset, + Vc::upcast(self), + )) + } else { + let module = AsyncLoaderModule::new(module, Vc::upcast(self), availability_info); + Vc::upcast(module.as_chunk_item(Vc::upcast(self))) + }) + } + + #[turbo_tasks::function] + async fn async_loader_chunk_item_id( + self: Vc, + module: Vc>, + ) -> Result> { + Ok(if self.await?.manifest_chunks { + self.chunk_item_id_from_ident(ManifestLoaderChunkItem::asset_ident_for(module)) + } else { + self.chunk_item_id_from_ident(AsyncLoaderModule::asset_ident_for(module)) + }) + } +} diff --git a/turbopack/crates/turbopack-nodejs/src/ecmascript/mod.rs b/turbopack/crates/turbopack-nodejs/src/ecmascript/mod.rs new file mode 100644 index 0000000000000..6b3c8edd4cf78 --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/ecmascript/mod.rs @@ -0,0 +1 @@ +pub(crate) mod node; diff --git a/turbopack/crates/turbopack-nodejs/src/ecmascript/node/chunk.rs b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/chunk.rs new file mode 100644 index 0000000000000..a06e53d7ef58c --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/chunk.rs @@ -0,0 +1,155 @@ +use anyhow::Result; +use indexmap::IndexSet; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{Chunk, ChunkingContext}, + ident::AssetIdent, + introspect::{Introspectable, IntrospectableChildren}, + output::{OutputAsset, OutputAssets}, + source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset}, + version::VersionedContent, +}; +use turbopack_ecmascript::chunk::EcmascriptChunk; + +use super::content::EcmascriptBuildNodeChunkContent; +use crate::NodeJsChunkingContext; + +/// Production Ecmascript chunk targeting Node.js. +#[turbo_tasks::value(shared)] +pub(crate) struct EcmascriptBuildNodeChunk { + chunking_context: Vc, + chunk: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptBuildNodeChunk { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new( + chunking_context: Vc, + chunk: Vc, + ) -> Vc { + EcmascriptBuildNodeChunk { + chunking_context, + chunk, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptBuildNodeChunk { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("Ecmascript Build Node Chunk".into())) + } +} + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("ecmascript build node chunk".into()) +} + +#[turbo_tasks::value_impl] +impl EcmascriptBuildNodeChunk { + #[turbo_tasks::function] + async fn own_content(self: Vc) -> Result> { + let this = self.await?; + Ok(EcmascriptBuildNodeChunkContent::new( + this.chunking_context, + self, + this.chunk.chunk_content(), + )) + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptBuildNodeChunk { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + let ident = self.chunk.ident().with_modifier(modifier()); + AssetIdent::from_path(self.chunking_context.chunk_path(ident, ".js".into())) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let chunk_references = this.chunk.references().await?; + let include_source_map = *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await?; + let mut references = + Vec::with_capacity(chunk_references.len() + if include_source_map { 1 } else { 0 }); + + for reference in &*chunk_references { + references.push(*reference); + } + + if include_source_map { + references.push(Vc::upcast(SourceMapAsset::new(Vc::upcast(self)))); + } + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptBuildNodeChunk { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + self.own_content().content() + } + + #[turbo_tasks::function] + fn versioned_content(self: Vc) -> Vc> { + Vc::upcast(self.own_content()) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for EcmascriptBuildNodeChunk { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.own_content().generate_source_map() + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("ecmascript build node chunk".into()) +} + +#[turbo_tasks::function] +fn introspectable_details() -> Vc { + Vc::cell("generates a production EcmaScript chunk targeting Node.js".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for EcmascriptBuildNodeChunk { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + fn title(self: Vc) -> Vc { + self.ident().to_string() + } + + #[turbo_tasks::function] + fn details(&self) -> Vc { + introspectable_details() + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + let mut children = IndexSet::new(); + let introspectable_chunk = Vc::upcast::>(self.chunk) + .resolve() + .await?; + children.insert((Vc::cell("chunk".into()), introspectable_chunk)); + Ok(Vc::cell(children)) + } +} diff --git a/turbopack/crates/turbopack-nodejs/src/ecmascript/node/content.rs b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/content.rs new file mode 100644 index 0000000000000..e59f63591002d --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/content.rs @@ -0,0 +1,145 @@ +use std::io::Write; + +use anyhow::Result; +use indoc::writedoc; +use turbo_tasks::{ReadRef, TryJoinIterExt, Vc}; +use turbo_tasks_fs::File; +use turbopack_core::{ + asset::AssetContent, + chunk::{ChunkItemExt, ChunkingContext, MinifyType, ModuleId}, + code_builder::{Code, CodeBuilder}, + output::OutputAsset, + source_map::{GenerateSourceMap, OptionSourceMap}, + version::{Version, VersionedContent}, +}; +use turbopack_ecmascript::{ + chunk::{EcmascriptChunkContent, EcmascriptChunkItemExt}, + minify::minify, + utils::StringifyJs, +}; + +use super::{chunk::EcmascriptBuildNodeChunk, version::EcmascriptBuildNodeChunkVersion}; +use crate::NodeJsChunkingContext; + +#[turbo_tasks::value] +pub(super) struct EcmascriptBuildNodeChunkContent { + pub(super) content: Vc, + pub(super) chunking_context: Vc, + pub(super) chunk: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptBuildNodeChunkContent { + #[turbo_tasks::function] + pub(crate) async fn new( + chunking_context: Vc, + chunk: Vc, + content: Vc, + ) -> Result> { + Ok(EcmascriptBuildNodeChunkContent { + content, + chunking_context, + chunk, + } + .cell()) + } +} + +pub(super) async fn chunk_items( + content: Vc, +) -> Result, ReadRef)>> { + content + .await? + .chunk_items + .iter() + .map(|&(chunk_item, async_module_info)| async move { + Ok(( + chunk_item.id().await?, + chunk_item.code(async_module_info).await?, + )) + }) + .try_join() + .await +} + +#[turbo_tasks::value_impl] +impl EcmascriptBuildNodeChunkContent { + #[turbo_tasks::function] + async fn code(self: Vc) -> Result> { + let this = self.await?; + let chunk_path_vc = this.chunk.ident().path(); + let chunk_path = chunk_path_vc.await?; + + let mut code = CodeBuilder::default(); + + writedoc!( + code, + r#" + module.exports = {{ + + "#, + )?; + + for (id, item_code) in chunk_items(this.content).await? { + write!(code, "{}: ", StringifyJs(&id))?; + code.push_code(&item_code); + writeln!(code, ",")?; + } + + write!(code, "\n}};")?; + + if code.has_source_map() { + let filename = chunk_path.file_name(); + write!( + code, + "\n\n//# sourceMappingURL={}.map", + urlencoding::encode(filename) + )?; + } + + let code = code.build().cell(); + if matches!( + this.chunking_context.await?.minify_type(), + MinifyType::Minify + ) { + return Ok(minify(chunk_path_vc, code)); + } + + Ok(code) + } + + #[turbo_tasks::function] + pub(crate) async fn own_version(self: Vc) -> Result> { + let this = self.await?; + Ok(EcmascriptBuildNodeChunkVersion::new( + this.chunking_context.output_root(), + this.chunk.ident().path(), + this.content, + this.chunking_context.await?.minify_type(), + )) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for EcmascriptBuildNodeChunkContent { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.code().generate_source_map() + } +} + +#[turbo_tasks::value_impl] +impl VersionedContent for EcmascriptBuildNodeChunkContent { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let code = self.code().await?; + Ok(AssetContent::file( + File::from(code.source_code().clone()).into(), + )) + } + + #[turbo_tasks::function] + fn version(self: Vc) -> Vc> { + Vc::upcast(self.own_version()) + } +} diff --git a/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/chunk.rs b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/chunk.rs new file mode 100644 index 0000000000000..2ec6829da495d --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/chunk.rs @@ -0,0 +1,217 @@ +use std::io::Write; + +use anyhow::{bail, Result}; +use indoc::writedoc; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks_fs::{File, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkItemExt, ChunkableModule, ChunkingContext, EvaluatableAssets}, + code_builder::{Code, CodeBuilder}, + ident::AssetIdent, + output::{OutputAsset, OutputAssets}, + source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset}, +}; +use turbopack_ecmascript::{chunk::EcmascriptChunkPlaceable, utils::StringifyJs}; + +use super::runtime::EcmascriptBuildNodeRuntimeChunk; +use crate::NodeJsChunkingContext; + +/// An Ecmascript chunk that loads a list of parallel chunks, then instantiates +/// runtime entries. +#[turbo_tasks::value(shared)] +pub(crate) struct EcmascriptBuildNodeEntryChunk { + path: Vc, + chunking_context: Vc, + other_chunks: Vc, + evaluatable_assets: Vc, + exported_module: Vc>, +} + +#[turbo_tasks::value_impl] +impl EcmascriptBuildNodeEntryChunk { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new( + path: Vc, + chunking_context: Vc, + other_chunks: Vc, + evaluatable_assets: Vc, + exported_module: Vc>, + ) -> Vc { + EcmascriptBuildNodeEntryChunk { + path, + chunking_context, + other_chunks, + evaluatable_assets, + exported_module, + } + .cell() + } + + #[turbo_tasks::function] + async fn code(self: Vc) -> Result> { + let this = self.await?; + + let output_root = this.chunking_context.output_root().await?; + let chunk_path = self.ident().path().await?; + let chunk_directory = self.ident().path().parent().await?; + let runtime_path = self.runtime_chunk().ident().path().await?; + let runtime_relative_path = + if let Some(path) = chunk_directory.get_relative_path_to(&runtime_path) { + path + } else { + bail!( + "cannot find a relative path from the chunk ({}) to the runtime chunk ({})", + chunk_path.to_string(), + runtime_path.to_string(), + ); + }; + let chunk_public_path = if let Some(path) = output_root.get_path_to(&chunk_path) { + path + } else { + bail!( + "chunk path ({}) is not in output root ({})", + chunk_path.to_string(), + output_root.to_string() + ); + }; + + let mut code = CodeBuilder::default(); + + writedoc!( + code, + r#" + const CHUNK_PUBLIC_PATH = {}; + const runtime = require({}); + "#, + StringifyJs(chunk_public_path), + StringifyJs(&*runtime_relative_path) + )?; + + let other_chunks = this.other_chunks.await?; + for other_chunk in &*other_chunks { + let other_chunk_path = &*other_chunk.ident().path().await?; + if let Some(other_chunk_public_path) = output_root.get_path_to(other_chunk_path) { + writedoc!( + code, + // TODO(WEB-1112) This should call `require()` directly, perhaps as an argument + // to `loadChunk`. + r#" + runtime.loadChunk({}); + "#, + StringifyJs(&other_chunk_public_path) + )?; + } + } + + let evaluatable_assets = this.evaluatable_assets.await?; + for evaluatable_asset in &*evaluatable_assets { + if let Some(placeable) = + Vc::try_resolve_sidecast::>(*evaluatable_asset) + .await? + { + let runtime_module_id = placeable + .as_chunk_item(Vc::upcast(this.chunking_context)) + .id() + .await?; + + writedoc!( + code, + r#" + runtime.getOrInstantiateRuntimeModule({}, CHUNK_PUBLIC_PATH); + "#, + StringifyJs(&*runtime_module_id), + )?; + } + } + + let runtime_module_id = this + .exported_module + .as_chunk_item(Vc::upcast(this.chunking_context)) + .id() + .await?; + + writedoc!( + code, + r#" + module.exports = runtime.getOrInstantiateRuntimeModule({}, CHUNK_PUBLIC_PATH).exports; + "#, + StringifyJs(&*runtime_module_id), + )?; + + Ok(Code::cell(code.build())) + } + + #[turbo_tasks::function] + async fn runtime_chunk(self: Vc) -> Result> { + let this = self.await?; + Ok(EcmascriptBuildNodeRuntimeChunk::new(this.chunking_context)) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptBuildNodeEntryChunk { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("Ecmascript Build Node Evaluate Chunk".into())) + } +} + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("ecmascript build node evaluate chunk".into()) +} + +#[turbo_tasks::function] +fn chunk_reference_description() -> Vc { + Vc::cell("chunk".into()) +} + +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptBuildNodeEntryChunk { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + AssetIdent::from_path(self.path) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let mut references = vec![Vc::upcast(self.runtime_chunk())]; + + if *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await? + { + references.push(Vc::upcast(SourceMapAsset::new(Vc::upcast(self)))) + } + + let other_chunks = this.other_chunks.await?; + for &other_chunk in &*other_chunks { + references.push(Vc::upcast(other_chunk)); + } + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptBuildNodeEntryChunk { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let code = self.code().await?; + Ok(AssetContent::file( + File::from(code.source_code().clone()).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for EcmascriptBuildNodeEntryChunk { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.code().generate_source_map() + } +} diff --git a/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/mod.rs b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/mod.rs new file mode 100644 index 0000000000000..cd4d9271d1b59 --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod chunk; +pub(crate) mod runtime; diff --git a/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/runtime.rs b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/runtime.rs new file mode 100644 index 0000000000000..25e7f37ac389d --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/entry/runtime.rs @@ -0,0 +1,146 @@ +use std::io::Write; + +use anyhow::{bail, Result}; +use indoc::writedoc; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks_fs::{File, FileSystem}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::ChunkingContext, + code_builder::{Code, CodeBuilder}, + ident::AssetIdent, + output::{OutputAsset, OutputAssets}, + source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset}, +}; +use turbopack_ecmascript::utils::StringifyJs; +use turbopack_ecmascript_runtime::RuntimeType; + +use crate::NodeJsChunkingContext; + +/// An Ecmascript chunk that contains the Node.js runtime code. +#[turbo_tasks::value(shared)] +pub(crate) struct EcmascriptBuildNodeRuntimeChunk { + chunking_context: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptBuildNodeRuntimeChunk { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new(chunking_context: Vc) -> Vc { + EcmascriptBuildNodeRuntimeChunk { chunking_context }.cell() + } + + #[turbo_tasks::function] + async fn code(self: Vc) -> Result> { + let this = self.await?; + + let output_root = this.chunking_context.output_root().await?; + let runtime_path = self.ident().path().await?; + let runtime_public_path = if let Some(path) = output_root.get_path_to(&runtime_path) { + path + } else { + bail!( + "runtime path {} is not in output root {}", + runtime_path.to_string(), + output_root.to_string() + ); + }; + + let mut code = CodeBuilder::default(); + let output_root = output_root.to_string(); + let asset_prefix = this.chunking_context.asset_prefix().await?; + let asset_prefix = asset_prefix.as_deref().unwrap_or("/"); + + writedoc!( + code, + r#" + const RUNTIME_PUBLIC_PATH = {}; + const OUTPUT_ROOT = {}; + const ASSET_PREFIX = {}; + "#, + StringifyJs(runtime_public_path), + StringifyJs(output_root.as_str()), + StringifyJs(asset_prefix), + )?; + + match this.chunking_context.await?.runtime_type() { + RuntimeType::Development => { + let runtime_code = turbopack_ecmascript_runtime::get_nodejs_runtime_code( + this.chunking_context.environment(), + ); + code.push_code(&*runtime_code.await?); + } + RuntimeType::Production => { + let runtime_code = turbopack_ecmascript_runtime::get_nodejs_runtime_code( + this.chunking_context.environment(), + ); + code.push_code(&*runtime_code.await?); + } + #[cfg(feature = "test")] + RuntimeType::Dummy => { + let runtime_code = turbopack_ecmascript_runtime::get_dummy_runtime_code(); + code.push_code(&runtime_code); + } + } + + Ok(Code::cell(code.build())) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptBuildNodeRuntimeChunk { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("Ecmascript Build Node Runtime Chunk".into())) + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptBuildNodeRuntimeChunk { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + let ident = AssetIdent::from_path( + turbopack_ecmascript_runtime::embed_fs() + .root() + .join("runtime.js".into()), + ); + + AssetIdent::from_path(self.chunking_context.chunk_path(ident, ".js".into())) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let mut references = vec![]; + + if *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await? + { + references.push(Vc::upcast(SourceMapAsset::new(Vc::upcast(self)))) + } + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptBuildNodeRuntimeChunk { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let code = self.code().await?; + Ok(AssetContent::file( + File::from(code.source_code().clone()).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for EcmascriptBuildNodeRuntimeChunk { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.code().generate_source_map() + } +} diff --git a/turbopack/crates/turbopack-nodejs/src/ecmascript/node/mod.rs b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/mod.rs new file mode 100644 index 0000000000000..f5006f4d8ece3 --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/mod.rs @@ -0,0 +1,4 @@ +pub(crate) mod chunk; +pub(crate) mod content; +pub(crate) mod entry; +pub(crate) mod version; diff --git a/turbopack/crates/turbopack-nodejs/src/ecmascript/node/version.rs b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/version.rs new file mode 100644 index 0000000000000..be165f3757c7d --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/ecmascript/node/version.rs @@ -0,0 +1,66 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{RcStr, ReadRef, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbo_tasks_hash::{encode_hex, Xxh3Hash64Hasher}; +use turbopack_core::{ + chunk::{MinifyType, ModuleId}, + code_builder::Code, + version::Version, +}; +use turbopack_ecmascript::chunk::EcmascriptChunkContent; + +use super::content::chunk_items; + +#[turbo_tasks::value(serialization = "none")] +pub(super) struct EcmascriptBuildNodeChunkVersion { + chunk_path: String, + chunk_items: Vec<(ReadRef, ReadRef)>, + minify_type: MinifyType, +} + +#[turbo_tasks::value_impl] +impl EcmascriptBuildNodeChunkVersion { + #[turbo_tasks::function] + pub async fn new( + output_root: Vc, + chunk_path: Vc, + content: Vc, + minify_type: MinifyType, + ) -> Result> { + let output_root = output_root.await?; + let chunk_path = chunk_path.await?; + let chunk_path = if let Some(path) = output_root.get_path_to(&chunk_path) { + path + } else { + bail!( + "chunk path {} is not in client root {}", + chunk_path.to_string(), + output_root.to_string() + ); + }; + let chunk_items = chunk_items(content).await?; + Ok(EcmascriptBuildNodeChunkVersion { + chunk_path: chunk_path.to_string(), + chunk_items, + minify_type, + } + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl Version for EcmascriptBuildNodeChunkVersion { + #[turbo_tasks::function] + fn id(&self) -> Vc { + let mut hasher = Xxh3Hash64Hasher::new(); + hasher.write_ref(&self.chunk_path); + hasher.write_ref(&self.minify_type); + hasher.write_value(self.chunk_items.len()); + for (module_id, code) in &self.chunk_items { + hasher.write_value((module_id, code.source_code())); + } + let hash = hasher.finish(); + let hex_hash = encode_hex(hash); + Vc::cell(hex_hash.into()) + } +} diff --git a/turbopack/crates/turbopack-nodejs/src/lib.rs b/turbopack/crates/turbopack-nodejs/src/lib.rs new file mode 100644 index 0000000000000..42137e07b226e --- /dev/null +++ b/turbopack/crates/turbopack-nodejs/src/lib.rs @@ -0,0 +1,17 @@ +#![feature(lint_reasons)] +#![feature(iter_intersperse)] +#![feature(arbitrary_self_types)] + +pub(crate) mod chunking_context; +pub(crate) mod ecmascript; + +pub use chunking_context::{NodeJsChunkingContext, NodeJsChunkingContextBuilder}; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + turbopack_ecmascript_runtime::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-resolve/Cargo.toml b/turbopack/crates/turbopack-resolve/Cargo.toml new file mode 100644 index 0000000000000..8c26ee81ff2d9 --- /dev/null +++ b/turbopack/crates/turbopack-resolve/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "turbopack-resolve" +version = "0.1.0" +description = "Methods to create and modify resolver options" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +indexmap = { workspace = true, features = ["serde"] } +lazy_static = { workspace = true } +regex = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +tracing = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-resolve/build.rs b/turbopack/crates/turbopack-resolve/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-resolve/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-resolve/src/ecmascript.rs b/turbopack/crates/turbopack-resolve/src/ecmascript.rs new file mode 100644 index 0000000000000..9ccbcb72c0fc1 --- /dev/null +++ b/turbopack/crates/turbopack-resolve/src/ecmascript.rs @@ -0,0 +1,134 @@ +use anyhow::Result; +use turbo_tasks::{Value, Vc}; +use turbopack_core::{ + issue::{IssueSeverity, IssueSource}, + reference_type::{CommonJsReferenceSubType, EcmaScriptModulesReferenceSubType, ReferenceType}, + resolve::{ + handle_resolve_error, + options::{ + ConditionValue, ResolutionConditions, ResolveInPackage, ResolveIntoPackage, + ResolveOptions, + }, + origin::{ResolveOrigin, ResolveOriginExt}, + parse::Request, + ModuleResolveResult, + }, +}; +/// Retrieves the [ResolutionConditions] of both the "into" package (allowing a +/// package to control how it can be imported) and the "in" package (controlling +/// how this package imports others) resolution options, so that they can be +/// manipulated together. +pub fn get_condition_maps( + options: &mut ResolveOptions, +) -> impl Iterator { + options + .into_package + .iter_mut() + .filter_map(|item| { + if let ResolveIntoPackage::ExportsField { conditions, .. } = item { + Some(conditions) + } else { + None + } + }) + .chain(options.in_package.iter_mut().filter_map(|item| { + if let ResolveInPackage::ImportsField { conditions, .. } = item { + Some(conditions) + } else { + None + } + })) +} + +#[turbo_tasks::function] +pub async fn apply_esm_specific_options( + options: Vc, + reference_type: Value, +) -> Result> { + let mut options: ResolveOptions = options.await?.clone_value(); + // TODO set fully_specified when in strict ESM mode + // options.fully_specified = true; + for conditions in get_condition_maps(&mut options) { + conditions.insert("import".into(), ConditionValue::Set); + conditions.insert("require".into(), ConditionValue::Unset); + } + + if matches!( + reference_type.into_value(), + ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::ImportWithType(_)) + ) { + options.extensions.clear(); + } + + Ok(options.into()) +} + +#[turbo_tasks::function] +pub async fn apply_cjs_specific_options(options: Vc) -> Result> { + let mut options: ResolveOptions = options.await?.clone_value(); + for conditions in get_condition_maps(&mut options) { + conditions.insert("import".into(), ConditionValue::Unset); + conditions.insert("require".into(), ConditionValue::Set); + } + Ok(options.into()) +} + +#[turbo_tasks::function] +pub async fn esm_resolve( + origin: Vc>, + request: Vc, + ty: Value, + issue_severity: Vc, + issue_source: Option>, +) -> Result> { + let ty = Value::new(ReferenceType::EcmaScriptModules(ty.into_value())); + let options = apply_esm_specific_options(origin.resolve_options(ty.clone()), ty.clone()) + .resolve() + .await?; + specific_resolve(origin, request, options, ty, issue_severity, issue_source).await +} + +#[turbo_tasks::function] +pub async fn cjs_resolve( + origin: Vc>, + request: Vc, + issue_source: Option>, + issue_severity: Vc, +) -> Result> { + // TODO pass CommonJsReferenceSubType + let ty = Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)); + let options = apply_cjs_specific_options(origin.resolve_options(ty.clone())) + .resolve() + .await?; + specific_resolve(origin, request, options, ty, issue_severity, issue_source).await +} + +async fn specific_resolve( + origin: Vc>, + request: Vc, + options: Vc, + reference_type: Value, + issue_severity: Vc, + issue_source: Option>, +) -> Result> { + let result = origin.resolve_asset(request, options, reference_type.clone()); + + handle_resolve_error( + result, + reference_type, + origin.origin_path(), + request, + options, + issue_severity, + issue_source, + ) + .await +} + +pub fn try_to_severity(in_try: bool) -> Vc { + if in_try { + IssueSeverity::Warning.cell() + } else { + IssueSeverity::Error.cell() + } +} diff --git a/turbopack/crates/turbopack-resolve/src/lib.rs b/turbopack/crates/turbopack-resolve/src/lib.rs new file mode 100644 index 0000000000000..2eab414c0be00 --- /dev/null +++ b/turbopack/crates/turbopack-resolve/src/lib.rs @@ -0,0 +1,14 @@ +#![feature(arbitrary_self_types)] + +pub mod ecmascript; +pub mod node_native_binding; +pub mod resolve; +pub mod resolve_options_context; +pub mod typescript; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-resolve/src/node_native_binding.rs b/turbopack/crates/turbopack-resolve/src/node_native_binding.rs new file mode 100644 index 0000000000000..8216a9da9743d --- /dev/null +++ b/turbopack/crates/turbopack-resolve/src/node_native_binding.rs @@ -0,0 +1,419 @@ +use anyhow::Result; +use indexmap::IndexMap; +use lazy_static::lazy_static; +use regex::Regex; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{RcStr, TryFlatJoinIterExt, ValueToString, Vc}; +use turbo_tasks_fs::{ + glob::Glob, json::parse_json_rope_with_source_context, DirectoryEntry, FileContent, + FileSystemEntryType, FileSystemPath, +}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + file_source::FileSource, + raw_module::RawModule, + reference::ModuleReference, + resolve::{pattern::Pattern, resolve_raw, ModuleResolveResult, RequestKey, ResolveResultItem}, + source::Source, + target::{CompileTarget, Platform}, +}; + +#[derive(Serialize, Deserialize, Debug)] +struct NodePreGypConfigJson { + binary: NodePreGypConfig, +} + +#[derive(Serialize, Deserialize, Debug)] +struct NodePreGypConfig { + module_name: String, + module_path: String, + napi_versions: Vec, +} + +#[turbo_tasks::value] +#[derive(Hash, Clone, Debug)] +pub struct NodePreGypConfigReference { + pub context_dir: Vc, + pub config_file_pattern: Vc, + pub compile_target: Vc, +} + +#[turbo_tasks::value_impl] +impl NodePreGypConfigReference { + #[turbo_tasks::function] + pub fn new( + context_dir: Vc, + config_file_pattern: Vc, + compile_target: Vc, + ) -> Vc { + Self::cell(NodePreGypConfigReference { + context_dir, + config_file_pattern, + compile_target, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for NodePreGypConfigReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + resolve_node_pre_gyp_files( + self.context_dir, + self.config_file_pattern, + self.compile_target, + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for NodePreGypConfigReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + let context_dir = self.context_dir.to_string().await?; + let config_file_pattern = self.config_file_pattern.to_string().await?; + let compile_target = self.compile_target.await?; + Ok(Vc::cell( + format!( + "node-gyp in {} with {} for {}", + context_dir, config_file_pattern, compile_target + ) + .into(), + )) + } +} + +#[turbo_tasks::function] +pub async fn resolve_node_pre_gyp_files( + context_dir: Vc, + config_file_pattern: Vc, + compile_target: Vc, +) -> Result> { + lazy_static! { + static ref NAPI_VERSION_TEMPLATE: Regex = + Regex::new(r"\{(napi_build_version|node_napi_label)\}") + .expect("create napi_build_version regex failed"); + static ref PLATFORM_TEMPLATE: Regex = + Regex::new(r"\{platform\}").expect("create node_platform regex failed"); + static ref ARCH_TEMPLATE: Regex = + Regex::new(r"\{arch\}").expect("create node_arch regex failed"); + static ref LIBC_TEMPLATE: Regex = + Regex::new(r"\{libc\}").expect("create node_libc regex failed"); + } + let config = resolve_raw(context_dir, config_file_pattern, true) + .first_source() + .await?; + let compile_target = compile_target.await?; + if let Some(config_asset) = *config { + if let AssetContent::File(file) = &*config_asset.content().await? { + if let FileContent::Content(ref config_file) = &*file.await? { + let config_file_path = config_asset.ident().path(); + let mut affecting_paths = vec![config_file_path]; + let config_file_dir = config_file_path.parent(); + let node_pre_gyp_config: NodePreGypConfigJson = + parse_json_rope_with_source_context(config_file.content())?; + let mut sources: IndexMap>> = IndexMap::new(); + for version in node_pre_gyp_config.binary.napi_versions.iter() { + let native_binding_path = NAPI_VERSION_TEMPLATE.replace( + node_pre_gyp_config.binary.module_path.as_str(), + format!("{}", version), + ); + let platform = compile_target.platform; + let native_binding_path = + PLATFORM_TEMPLATE.replace(&native_binding_path, platform.as_str()); + let native_binding_path = + ARCH_TEMPLATE.replace(&native_binding_path, compile_target.arch.as_str()); + let native_binding_path: RcStr = LIBC_TEMPLATE + .replace( + &native_binding_path, + // node-pre-gyp only cares about libc on linux + if platform == Platform::Linux { + compile_target.libc.as_str() + } else { + "unknown" + }, + ) + .into(); + + for (key, entry) in config_file_dir + .join(native_binding_path.clone()) + .read_glob( + Glob::new(format!("*.{}", compile_target.dylib_ext()).into()), + false, + ) + .await? + .results + .iter() + { + if let &DirectoryEntry::File(dylib) | &DirectoryEntry::Symlink(dylib) = + entry + { + sources.insert( + format!("{native_binding_path}/{key}").into(), + Vc::upcast(FileSource::new(dylib)), + ); + } + } + + let node_file_path: RcStr = format!( + "{}/{}.node", + native_binding_path, node_pre_gyp_config.binary.module_name + ) + .into(); + let resolved_file_vc = config_file_dir.join(node_file_path.clone()); + sources.insert( + node_file_path, + Vc::upcast(FileSource::new(resolved_file_vc)), + ); + } + for (key, entry) in config_file_dir + // TODO + // read the dependencies path from `bindings.gyp` + .join("deps/lib".into()) + .read_glob(Glob::new("*".into()), false) + .await? + .results + .iter() + { + match *entry { + DirectoryEntry::File(dylib) => { + sources.insert( + format!("deps/lib/{key}").into(), + Vc::upcast(FileSource::new(dylib)), + ); + } + DirectoryEntry::Symlink(dylib) => { + let realpath_with_links = dylib.realpath_with_links().await?; + for &symlink in realpath_with_links.symlinks.iter() { + affecting_paths.push(symlink); + } + sources.insert( + format!("deps/lib/{key}").into(), + Vc::upcast(FileSource::new(realpath_with_links.path)), + ); + } + _ => {} + } + } + return Ok(ModuleResolveResult::modules_with_affecting_sources( + sources.into_iter().map(|(key, source)| { + (RequestKey::new(key), Vc::upcast(RawModule::new(source))) + }), + affecting_paths + .into_iter() + .map(|p| Vc::upcast(FileSource::new(p))) + .collect(), + ) + .into()); + } + }; + } + Ok(ModuleResolveResult::unresolveable().into()) +} + +#[turbo_tasks::value] +#[derive(Hash, Clone, Debug)] +pub struct NodeGypBuildReference { + pub context_dir: Vc, + pub compile_target: Vc, +} + +#[turbo_tasks::value_impl] +impl NodeGypBuildReference { + #[turbo_tasks::function] + pub fn new(context_dir: Vc, target: Vc) -> Vc { + Self::cell(NodeGypBuildReference { + context_dir, + compile_target: target, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for NodeGypBuildReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + resolve_node_gyp_build_files(self.context_dir, self.compile_target) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for NodeGypBuildReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + let context_dir = self.context_dir.to_string().await?; + let compile_target = self.compile_target.await?; + Ok(Vc::cell( + format!("node-gyp in {} for {}", context_dir, compile_target).into(), + )) + } +} + +#[turbo_tasks::function] +pub async fn resolve_node_gyp_build_files( + context_dir: Vc, + compile_target: Vc, +) -> Result> { + lazy_static! { + // TODO Proper parser + static ref GYP_BUILD_TARGET_NAME: Regex = + Regex::new(r#"['"]target_name['"]\s*:\s*(?:"(.*?)"|'(.*?)')"#) + .expect("create napi_build_version regex failed"); + } + let binding_gyp_pat = Pattern::new(Pattern::Constant("binding.gyp".into())); + let gyp_file = resolve_raw(context_dir, binding_gyp_pat, true); + if let [binding_gyp] = &gyp_file.primary_sources().await?[..] { + let mut merged_affecting_sources = + gyp_file.await?.get_affecting_sources().collect::>(); + if let AssetContent::File(file) = &*binding_gyp.content().await? { + if let FileContent::Content(config_file) = &*file.await? { + if let Some(captured) = + GYP_BUILD_TARGET_NAME.captures(&config_file.content().to_str()?) + { + let mut resolved: IndexMap>> = + IndexMap::with_capacity(captured.len()); + for found in captured.iter().skip(1).flatten() { + let name = found.as_str(); + let target_path = context_dir.join("build/Release".into()); + let resolved_prebuilt_file = resolve_raw( + target_path, + Pattern::new(Pattern::Constant(format!("{}.node", name).into())), + true, + ) + .await?; + if let Some((_, ResolveResultItem::Source(source))) = + resolved_prebuilt_file.primary.first() + { + resolved.insert( + format!("build/Release/{name}.node").into(), + source.resolve().await?, + ); + merged_affecting_sources + .extend(resolved_prebuilt_file.affecting_sources.iter().copied()); + } + } + if !resolved.is_empty() { + return Ok(ModuleResolveResult::modules_with_affecting_sources( + resolved.into_iter().map(|(key, source)| { + (RequestKey::new(key), Vc::upcast(RawModule::new(source))) + }), + merged_affecting_sources, + ) + .into()); + } + } + } + } + } + let compile_target = compile_target.await?; + let arch = compile_target.arch; + let platform = compile_target.platform; + let prebuilt_dir = format!("{}-{}", platform, arch); + Ok(resolve_raw( + context_dir, + Pattern::new(Pattern::Concatenation(vec![ + Pattern::Constant(format!("prebuilds/{}/", prebuilt_dir).into()), + Pattern::Dynamic, + Pattern::Constant(".node".into()), + ])), + true, + ) + .as_raw_module_result()) +} + +#[turbo_tasks::value] +#[derive(Hash, Clone, Debug)] +pub struct NodeBindingsReference { + pub context_dir: Vc, + pub file_name: RcStr, +} + +#[turbo_tasks::value_impl] +impl NodeBindingsReference { + #[turbo_tasks::function] + pub fn new(context_dir: Vc, file_name: RcStr) -> Vc { + Self::cell(NodeBindingsReference { + context_dir, + file_name, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for NodeBindingsReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + resolve_node_bindings_files(self.context_dir, self.file_name.clone()) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for NodeBindingsReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("bindings in {}", self.context_dir.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::function] +pub async fn resolve_node_bindings_files( + context_dir: Vc, + file_name: RcStr, +) -> Result> { + lazy_static! { + static ref BINDINGS_TRY: [&'static str; 5] = [ + "build/bindings", + "build/Release", + "build/Release/bindings", + "out/Release/bindings", + "Release/bindings", + ]; + } + let mut root_context_dir = context_dir; + loop { + let resolved = resolve_raw( + root_context_dir, + Pattern::new(Pattern::Constant("package.json".into())), + true, + ) + .first_source() + .await?; + if let Some(asset) = *resolved { + if let AssetContent::File(file) = &*asset.content().await? { + if let FileContent::Content(_) = &*file.await? { + break; + } + } + }; + let current_context = root_context_dir.await?; + let parent = root_context_dir.parent(); + let parent_context = parent.await?; + if parent_context.path == current_context.path { + break; + } + root_context_dir = parent; + } + + let try_path = |sub_path: RcStr| async move { + let path = root_context_dir.join(sub_path.clone()); + Ok( + if matches!(*path.get_type().await?, FileSystemEntryType::File) { + Some(( + RequestKey::new(sub_path), + Vc::upcast(RawModule::new(Vc::upcast(FileSource::new(path)))), + )) + } else { + None + }, + ) + }; + + let modules = BINDINGS_TRY + .iter() + .map(|try_dir| try_path(format!("{}/{}", try_dir, &file_name).into())) + .try_flat_join() + .await?; + Ok(ModuleResolveResult::modules(modules).cell()) +} diff --git a/turbopack/crates/turbopack-resolve/src/resolve.rs b/turbopack/crates/turbopack-resolve/src/resolve.rs new file mode 100644 index 0000000000000..9f65b51b9226a --- /dev/null +++ b/turbopack/crates/turbopack-resolve/src/resolve.rs @@ -0,0 +1,299 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_fs::{FileSystem, FileSystemPath}; +use turbopack_core::resolve::{ + find_context_file, + options::{ + ConditionValue, ImportMap, ImportMapping, ResolutionConditions, ResolveInPackage, + ResolveIntoPackage, ResolveModules, ResolveOptions, + }, + AliasMap, AliasPattern, ExternalType, FindContextFileResult, +}; + +use crate::{ + resolve_options_context::ResolveOptionsContext, + typescript::{apply_tsconfig_resolve_options, tsconfig, tsconfig_resolve_options}, +}; + +const NODE_EXTERNALS: [&str; 51] = [ + "assert", + "async_hooks", + "buffer", + "child_process", + "cluster", + "console", + "constants", + "crypto", + "dgram", + "diagnostics_channel", + "dns", + "dns/promises", + "domain", + "events", + "fs", + "fs/promises", + "http", + "http2", + "https", + "inspector", + "module", + "net", + "os", + "path", + "path/posix", + "path/win32", + "perf_hooks", + "process", + "punycode", + "querystring", + "readline", + "repl", + "stream", + "stream/promises", + "stream/web", + "string_decoder", + "sys", + "timers", + "timers/promises", + "tls", + "trace_events", + "tty", + "url", + "util", + "util/types", + "v8", + "vm", + "wasi", + "worker_threads", + "zlib", + "pnpapi", +]; + +const EDGE_NODE_EXTERNALS: [&str; 5] = ["buffer", "events", "assert", "util", "async_hooks"]; + +#[turbo_tasks::function] +async fn base_resolve_options( + resolve_path: Vc, + options_context: Vc, +) -> Result> { + let parent = resolve_path.parent().resolve().await?; + if parent != resolve_path { + return Ok(base_resolve_options(parent, options_context)); + } + let resolve_path_value = resolve_path.await?; + let opt = options_context.await?; + let emulating = opt.emulate_environment; + let root = resolve_path_value.fs.root(); + let mut direct_mappings = AliasMap::new(); + let node_externals = if let Some(environment) = emulating { + environment.node_externals().await?.clone_value() + } else { + opt.enable_node_externals + }; + if node_externals { + for req in NODE_EXTERNALS { + direct_mappings.insert( + AliasPattern::exact(req), + ImportMapping::External(None, ExternalType::CommonJs).into(), + ); + direct_mappings.insert( + AliasPattern::exact(format!("node:{req}")), + ImportMapping::External(None, ExternalType::CommonJs).into(), + ); + } + } + if opt.enable_edge_node_externals { + for req in EDGE_NODE_EXTERNALS { + direct_mappings.insert( + AliasPattern::exact(req), + ImportMapping::External(Some(format!("node:{req}").into()), ExternalType::CommonJs) + .into(), + ); + direct_mappings.insert( + AliasPattern::exact(format!("node:{req}")), + ImportMapping::External(None, ExternalType::CommonJs).into(), + ); + } + } + + let mut import_map = ImportMap::new(direct_mappings); + if let Some(additional_import_map) = opt.import_map { + let additional_import_map = additional_import_map.await?; + import_map.extend_ref(&additional_import_map); + } + let import_map = import_map.cell(); + + let plugins = opt.after_resolve_plugins.clone(); + + let conditions = { + let mut conditions: ResolutionConditions = [ + ("import".into(), ConditionValue::Unknown), + ("require".into(), ConditionValue::Unknown), + ] + .into_iter() + .collect(); + if opt.browser { + conditions.insert("browser".into(), ConditionValue::Set); + } + if opt.module { + conditions.insert("module".into(), ConditionValue::Set); + } + if let Some(environment) = emulating { + for condition in environment.resolve_conditions().await?.iter() { + conditions.insert(condition.clone(), ConditionValue::Set); + } + } + for condition in opt.custom_conditions.iter() { + conditions.insert(condition.clone(), ConditionValue::Set); + } + // Infer some well-known conditions + let dev = conditions.get("development").cloned(); + let prod = conditions.get("production").cloned(); + if prod.is_none() { + conditions.insert( + "production".into(), + if matches!(dev, Some(ConditionValue::Set)) { + ConditionValue::Unset + } else { + ConditionValue::Unknown + }, + ); + } + if dev.is_none() { + conditions.insert( + "development".into(), + if matches!(prod, Some(ConditionValue::Set)) { + ConditionValue::Unset + } else { + ConditionValue::Unknown + }, + ); + } + conditions + }; + + let extensions = if let Some(custom_extension) = &opt.custom_extensions { + custom_extension.clone() + } else if let Some(environment) = emulating { + environment.resolve_extensions().await?.clone_value() + } else { + let mut ext = Vec::new(); + if opt.enable_typescript && opt.enable_react { + ext.push(".tsx".into()); + } + if opt.enable_typescript { + ext.push(".ts".into()); + } + if opt.enable_react { + ext.push(".jsx".into()); + } + ext.push(".js".into()); + if opt.enable_mjs_extension { + ext.push(".mjs".into()); + } + if opt.enable_node_native_modules { + ext.push(".node".into()); + } + ext.push(".json".into()); + ext + }; + Ok(ResolveOptions { + extensions, + modules: if let Some(environment) = emulating { + if *environment.resolve_node_modules().await? { + vec![ResolveModules::Nested(root, vec!["node_modules".into()])] + } else { + Vec::new() + } + } else { + let mut mods = Vec::new(); + if let Some(dir) = opt.enable_node_modules { + mods.push(ResolveModules::Nested(dir, vec!["node_modules".into()])); + } + mods + }, + into_package: { + let mut resolve_into = vec![ResolveIntoPackage::ExportsField { + conditions: conditions.clone(), + unspecified_conditions: ConditionValue::Unset, + }]; + if opt.browser { + resolve_into.push(ResolveIntoPackage::MainField { + field: "browser".into(), + }); + } + if opt.module { + resolve_into.push(ResolveIntoPackage::MainField { + field: "module".into(), + }); + } + resolve_into.push(ResolveIntoPackage::MainField { + field: "main".into(), + }); + resolve_into + }, + in_package: { + let mut resolve_in = vec![ResolveInPackage::ImportsField { + conditions, + unspecified_conditions: ConditionValue::Unset, + }]; + if opt.browser { + resolve_in.push(ResolveInPackage::AliasField("browser".into())); + } + resolve_in + }, + default_files: vec!["index".into()], + import_map: Some(import_map), + resolved_map: opt.resolved_map, + plugins, + before_resolve_plugins: opt.before_resolve_plugins.clone(), + ..Default::default() + } + .into()) +} + +#[turbo_tasks::function] +pub async fn resolve_options( + resolve_path: Vc, + options_context: Vc, +) -> Result> { + let options_context_value = options_context.await?; + if !options_context_value.rules.is_empty() { + let context_value = &*resolve_path.await?; + for (condition, new_options_context) in options_context_value.rules.iter() { + if condition.matches(context_value).await? { + return Ok(resolve_options(resolve_path, *new_options_context)); + } + } + } + + let resolve_options = base_resolve_options(resolve_path, options_context); + + let resolve_options = if options_context_value.enable_typescript { + let tsconfig = find_context_file(resolve_path, tsconfig()).await?; + match *tsconfig { + FindContextFileResult::Found(path, _) => { + apply_tsconfig_resolve_options(resolve_options, tsconfig_resolve_options(path)) + } + FindContextFileResult::NotFound(_) => resolve_options, + } + } else { + resolve_options + }; + + // Make sure to always apply `options_context.import_map` last, so it properly + // overwrites any other mappings. + let resolve_options = options_context_value + .import_map + .map(|import_map| resolve_options.with_extended_import_map(import_map)) + .unwrap_or(resolve_options); + // And the same for the fallback_import_map + let resolve_options = options_context_value + .fallback_import_map + .map(|fallback_import_map| { + resolve_options.with_extended_fallback_import_map(fallback_import_map) + }) + .unwrap_or(resolve_options); + + Ok(resolve_options) +} diff --git a/turbopack/crates/turbopack-resolve/src/resolve_options_context.rs b/turbopack/crates/turbopack-resolve/src/resolve_options_context.rs new file mode 100644 index 0000000000000..2615a3ae5290a --- /dev/null +++ b/turbopack/crates/turbopack-resolve/src/resolve_options_context.rs @@ -0,0 +1,132 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, ValueDefault, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + condition::ContextCondition, + environment::Environment, + resolve::{ + options::{ImportMap, ResolvedMap}, + plugin::{AfterResolvePlugin, BeforeResolvePlugin}, + }, +}; + +#[turbo_tasks::value(shared)] +#[derive(Default, Clone)] +pub struct ResolveOptionsContext { + #[serde(default)] + pub emulate_environment: Option>, + #[serde(default)] + pub enable_types: bool, + #[serde(default)] + pub enable_typescript: bool, + #[serde(default)] + pub enable_react: bool, + #[serde(default)] + pub enable_node_native_modules: bool, + #[serde(default)] + // Enable resolving of .mjs files without the .mjs extension + pub enable_mjs_extension: bool, + #[serde(default)] + /// Enable resolving of the node_modules folder when within the provided + /// directory + pub enable_node_modules: Option>, + #[serde(default)] + /// Mark well-known Node.js modules as external imports and load them using + /// native `require`. e.g. url, querystring, os + pub enable_node_externals: bool, + /// Mark well-known Edge modules as external imports and load them using + /// native `require`. e.g. buffer, events, assert + pub enable_edge_node_externals: bool, + #[serde(default)] + /// Enables the "browser" field and export condition in package.json + pub browser: bool, + #[serde(default)] + /// Enables the "module" field and export condition in package.json + pub module: bool, + #[serde(default)] + pub custom_conditions: Vec, + #[serde(default)] + pub custom_extensions: Option>, + #[serde(default)] + /// An additional import map to use when resolving modules. + /// + /// If set, this import map will be applied to `ResolveOption::import_map`. + /// It is always applied last, so any mapping defined within will take + /// precedence over any other (e.g. tsconfig.json `compilerOptions.paths`). + pub import_map: Option>, + #[serde(default)] + /// An import map to fall back to when a request could not be resolved. + /// + /// If set, this import map will be applied to + /// `ResolveOption::fallback_import_map`. It is always applied last, so + /// any mapping defined within will take precedence over any other. + pub fallback_import_map: Option>, + #[serde(default)] + /// An additional resolved map to use after modules have been resolved. + pub resolved_map: Option>, + #[serde(default)] + /// A list of rules to use a different resolve option context for certain + /// context paths. The first matching is used. + pub rules: Vec<(ContextCondition, Vc)>, + #[serde(default)] + /// Plugins which get applied before and after resolving. + pub after_resolve_plugins: Vec>>, + pub before_resolve_plugins: Vec>>, + #[serde(default)] + pub placeholder_for_future_extensions: (), +} + +#[turbo_tasks::value_impl] +impl ResolveOptionsContext { + #[turbo_tasks::function] + pub async fn with_types_enabled(self: Vc) -> Result> { + let mut clone = self.await?.clone_value(); + clone.enable_types = true; + clone.enable_typescript = true; + Ok(Self::cell(clone)) + } + + /// Returns a new [Vc] with its import map extended + /// to include the given import map. + #[turbo_tasks::function] + pub async fn with_extended_import_map( + self: Vc, + import_map: Vc, + ) -> Result> { + let mut resolve_options_context = self.await?.clone_value(); + resolve_options_context.import_map = Some( + resolve_options_context + .import_map + .map(|current_import_map| current_import_map.extend(import_map)) + .unwrap_or(import_map), + ); + Ok(resolve_options_context.into()) + } + + /// Returns a new [Vc] with its fallback import map + /// extended to include the given import map. + #[turbo_tasks::function] + pub async fn with_extended_fallback_import_map( + self: Vc, + fallback_import_map: Vc, + ) -> Result> { + let mut resolve_options_context = self.await?.clone_value(); + resolve_options_context.fallback_import_map = Some( + resolve_options_context + .fallback_import_map + .map(|current_fallback_import_map| { + current_fallback_import_map.extend(fallback_import_map) + }) + .unwrap_or(fallback_import_map), + ); + Ok(resolve_options_context.into()) + } +} + +#[turbo_tasks::value_impl] +impl ValueDefault for ResolveOptionsContext { + #[turbo_tasks::function] + fn value_default() -> Vc { + Self::cell(Default::default()) + } +} diff --git a/turbopack/crates/turbopack-resolve/src/typescript.rs b/turbopack/crates/turbopack-resolve/src/typescript.rs new file mode 100644 index 0000000000000..0a3282f7dffe4 --- /dev/null +++ b/turbopack/crates/turbopack-resolve/src/typescript.rs @@ -0,0 +1,517 @@ +use std::{collections::HashMap, fmt::Write, mem::take}; + +use anyhow::Result; +use serde_json::Value as JsonValue; +use turbo_tasks::{RcStr, Value, ValueDefault, Vc}; +use turbo_tasks_fs::{FileContent, FileJsonContent, FileSystemPath}; +use turbopack_core::{ + asset::Asset, + context::AssetContext, + file_source::FileSource, + ident::AssetIdent, + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, + reference_type::{ReferenceType, TypeScriptReferenceSubType}, + resolve::{ + handle_resolve_error, + node::node_cjs_resolve_options, + options::{ + ConditionValue, ImportMap, ImportMapping, ResolveIntoPackage, ResolveModules, + ResolveOptions, + }, + origin::{ResolveOrigin, ResolveOriginExt}, + parse::Request, + pattern::Pattern, + resolve, AliasPattern, ModuleResolveResult, + }, + source::{OptionSource, Source}, +}; + +use crate::ecmascript::get_condition_maps; + +#[turbo_tasks::value(shared)] +pub struct TsConfigIssue { + pub severity: Vc, + pub source_ident: Vc, + pub message: RcStr, +} + +#[turbo_tasks::function] +async fn json_only(resolve_options: Vc) -> Result> { + let mut opts = resolve_options.await?.clone_value(); + opts.extensions = vec![".json".into()]; + Ok(opts.cell()) +} + +type TsConfigs = Vec<(Vc, Vc>)>; + +#[tracing::instrument(skip_all)] +pub async fn read_tsconfigs( + mut data: Vc, + mut tsconfig: Vc>, + resolve_options: Vc, +) -> Result { + let mut configs = Vec::new(); + let resolve_options = json_only(resolve_options); + loop { + let parsed_data = data.parse_json_with_comments(); + match &*parsed_data.await? { + FileJsonContent::Unparseable(e) => { + let mut message = "tsconfig is not parseable: invalid JSON: ".to_string(); + if let FileContent::Content(content) = &*data.await? { + let text = content.content().to_str()?; + e.write_with_content(&mut message, text.as_ref())?; + } else { + write!(message, "{}", e)?; + } + TsConfigIssue { + severity: IssueSeverity::Error.into(), + source_ident: tsconfig.ident(), + message: message.into(), + } + .cell() + .emit(); + } + FileJsonContent::NotFound => { + TsConfigIssue { + severity: IssueSeverity::Error.into(), + source_ident: tsconfig.ident(), + message: "tsconfig not found".into(), + } + .cell() + .emit(); + } + FileJsonContent::Content(json) => { + configs.push((parsed_data, tsconfig)); + if let Some(extends) = json["extends"].as_str() { + let resolved = resolve_extends(tsconfig, extends, resolve_options).await?; + if let Some(source) = *resolved.await? { + data = source.content().file_content(); + tsconfig = source; + continue; + } else { + TsConfigIssue { + severity: IssueSeverity::Error.into(), + source_ident: tsconfig.ident(), + message: format!("extends: \"{}\" doesn't resolve correctly", extends) + .into(), + } + .cell() + .emit(); + } + } + } + } + break; + } + Ok(configs) +} + +/// Resolves tsconfig files according to TS's implementation: +/// https://github.com/microsoft/TypeScript/blob/611a912d/src/compiler/commandLineParser.ts#L3294-L3326 +#[tracing::instrument(skip_all)] +async fn resolve_extends( + tsconfig: Vc>, + extends: &str, + resolve_options: Vc, +) -> Result> { + let parent_dir = tsconfig.ident().path().parent(); + let request = Request::parse_string(extends.into()); + + // TS's resolution is weird, and has special behavior for different import + // types. There might be multiple alternatives like + // "some/path/node_modules/xyz/abc.json" and "some/node_modules/xyz/abc.json". + // We only want to use the first one. + match &*request.await? { + // TS has special behavior for "rooted" paths (absolute paths): + // https://github.com/microsoft/TypeScript/blob/611a912d/src/compiler/commandLineParser.ts#L3303-L3313 + Request::Windows { path: Pattern::Constant(path), .. } | + // Server relative is treated as absolute + Request::ServerRelative { path: Pattern::Constant(path), .. } => { + resolve_extends_rooted_or_relative(parent_dir, request, resolve_options, path).await + } + + // TS has special behavior for (explicitly) './' and '../', but not '.' nor '..': + // https://github.com/microsoft/TypeScript/blob/611a912d/src/compiler/commandLineParser.ts#L3303-L3313 + Request::Relative { + path: Pattern::Constant(path), + .. + } if path.starts_with("./") || path.starts_with("../") => { + resolve_extends_rooted_or_relative(parent_dir, request, resolve_options, path).await + } + + // An empty extends is treated as "./tsconfig" + Request::Empty => { + let request = Request::parse_string("./tsconfig".into()); + Ok(resolve(parent_dir, + Value::new(ReferenceType::TypeScript(TypeScriptReferenceSubType::Undefined)), request, resolve_options).first_source()) + } + + // All other types are treated as module imports, and potentially joined with + // "tsconfig.json". This includes "relative" imports like '.' and '..'. + _ => { + let mut result = resolve(parent_dir, Value::new(ReferenceType::TypeScript(TypeScriptReferenceSubType::Undefined)), request, resolve_options).first_source(); + if result.await?.is_none() { + let request = Request::parse_string(format!("{extends}/tsconfig").into()); + result = resolve(parent_dir, Value::new(ReferenceType::TypeScript(TypeScriptReferenceSubType::Undefined)), request, resolve_options).first_source(); + } + Ok(result) + } + } +} + +async fn resolve_extends_rooted_or_relative( + lookup_path: Vc, + request: Vc, + resolve_options: Vc, + path: &str, +) -> Result> { + let mut result = resolve( + lookup_path, + Value::new(ReferenceType::TypeScript( + TypeScriptReferenceSubType::Undefined, + )), + request, + resolve_options, + ) + .first_source(); + + // If the file doesn't end with ".json" and we can't find the file, then we have + // to try again with it. + // https://github.com/microsoft/TypeScript/blob/611a912d/src/compiler/commandLineParser.ts#L3305 + if !path.ends_with(".json") && result.await?.is_none() { + let request = Request::parse_string(format!("{path}.json").into()); + result = resolve( + lookup_path, + Value::new(ReferenceType::TypeScript( + TypeScriptReferenceSubType::Undefined, + )), + request, + resolve_options, + ) + .first_source(); + } + Ok(result) +} + +type Config = (Vc, Vc>); + +pub async fn read_from_tsconfigs( + configs: &[Config], + accessor: impl Fn(&JsonValue, Vc>) -> Option, +) -> Result> { + for (config, source) in configs.iter() { + if let FileJsonContent::Content(json) = &*config.await? { + if let Some(result) = accessor(json, *source) { + return Ok(Some(result)); + } + } + } + Ok(None) +} + +/// Resolve options specific to tsconfig.json. +#[turbo_tasks::value] +#[derive(Default)] +pub struct TsConfigResolveOptions { + base_url: Option>, + import_map: Option>, +} + +#[turbo_tasks::value_impl] +impl ValueDefault for TsConfigResolveOptions { + #[turbo_tasks::function] + fn value_default() -> Vc { + Self::default().cell() + } +} + +/// Returns the resolve options +#[turbo_tasks::function] +pub async fn tsconfig_resolve_options( + tsconfig: Vc, +) -> Result> { + let configs = read_tsconfigs( + tsconfig.read(), + Vc::upcast(FileSource::new(tsconfig)), + node_cjs_resolve_options(tsconfig.root()), + ) + .await?; + + if configs.is_empty() { + return Ok(Default::default()); + } + + let base_url = if let Some(base_url) = read_from_tsconfigs(&configs, |json, source| { + json["compilerOptions"]["baseUrl"] + .as_str() + .map(|base_url| source.ident().path().parent().try_join(base_url.into())) + }) + .await? + { + *base_url.await? + } else { + None + }; + + let mut all_paths = HashMap::new(); + for (content, source) in configs.iter().rev() { + if let FileJsonContent::Content(json) = &*content.await? { + if let JsonValue::Object(paths) = &json["compilerOptions"]["paths"] { + let mut context_dir = source.ident().path().parent(); + if let Some(base_url) = json["compilerOptions"]["baseUrl"].as_str() { + if let Some(new_context) = *context_dir.try_join(base_url.into()).await? { + context_dir = new_context; + } + }; + for (key, value) in paths.iter() { + if let JsonValue::Array(vec) = value { + let entries = vec + .iter() + .filter_map(|entry| { + let entry = entry.as_str(); + + if entry.map(|e| e.ends_with(".d.ts")).unwrap_or_default() { + return None; + } + + entry.map(|s| { + // tsconfig paths are always relative requests + if s.starts_with("./") || s.starts_with("../") { + s.into() + } else { + format!("./{s}").into() + } + }) + }) + .collect(); + all_paths.insert( + key.to_string(), + ImportMapping::primary_alternatives(entries, Some(context_dir)), + ); + } else { + TsConfigIssue { + severity: IssueSeverity::Warning.cell(), + source_ident: source.ident(), + message: format!( + "compilerOptions.paths[{key}] doesn't contains an array as \ + expected\n{key}: {value:#}", + key = serde_json::to_string(key)?, + value = value + ) + .into(), + } + .cell() + .emit() + } + } + } + } + } + + let import_map = if !all_paths.is_empty() { + let mut import_map = ImportMap::empty(); + for (key, value) in all_paths { + import_map.insert_alias(AliasPattern::parse(key), value.into()); + } + Some(import_map.cell()) + } else { + None + }; + + Ok(TsConfigResolveOptions { + base_url, + import_map, + } + .cell()) +} + +#[turbo_tasks::function] +pub fn tsconfig() -> Vc> { + Vc::cell(vec!["tsconfig.json".into(), "jsconfig.json".into()]) +} + +#[turbo_tasks::function] +pub async fn apply_tsconfig_resolve_options( + resolve_options: Vc, + tsconfig_resolve_options: Vc, +) -> Result> { + let tsconfig_resolve_options = tsconfig_resolve_options.await?; + let mut resolve_options = resolve_options.await?.clone_value(); + if let Some(base_url) = tsconfig_resolve_options.base_url { + // We want to resolve in `compilerOptions.baseUrl` first, then in other + // locations as a fallback. + resolve_options + .modules + .insert(0, ResolveModules::Path(base_url)); + } + if let Some(tsconfig_import_map) = tsconfig_resolve_options.import_map { + resolve_options.import_map = Some( + resolve_options + .import_map + .map(|import_map| import_map.extend(tsconfig_import_map)) + .unwrap_or(tsconfig_import_map), + ); + } + Ok(resolve_options.cell()) +} + +#[turbo_tasks::function] +pub async fn type_resolve( + origin: Vc>, + request: Vc, +) -> Result> { + let ty = Value::new(ReferenceType::TypeScript( + TypeScriptReferenceSubType::Undefined, + )); + let context_path = origin.origin_path().parent(); + let options = origin.resolve_options(ty.clone()); + let options = apply_typescript_types_options(options); + let types_request = if let Request::Module { + module: m, + path: p, + query: _, + fragment: _, + } = &*request.await? + { + let m = if let Some(stripped) = m.strip_prefix('@') { + stripped.replace('/', "__").into() + } else { + m.clone() + }; + Some(Request::module( + format!("@types/{m}").into(), + Value::new(p.clone()), + Vc::::default(), + Vc::::default(), + )) + } else { + None + }; + let context_path = context_path.resolve().await?; + let result = if let Some(types_request) = types_request { + let result1 = resolve( + context_path, + Value::new(ReferenceType::TypeScript( + TypeScriptReferenceSubType::Undefined, + )), + request, + options, + ); + if !*result1.is_unresolveable().await? { + result1 + } else { + resolve( + context_path, + Value::new(ReferenceType::TypeScript( + TypeScriptReferenceSubType::Undefined, + )), + types_request, + options, + ) + } + } else { + resolve( + context_path, + Value::new(ReferenceType::TypeScript( + TypeScriptReferenceSubType::Undefined, + )), + request, + options, + ) + }; + let result = as_typings_result( + origin + .asset_context() + .process_resolve_result(result, ty.clone()), + ); + handle_resolve_error( + result, + ty, + origin.origin_path(), + request, + options, + IssueSeverity::Error.cell(), + None, + ) + .await +} + +#[turbo_tasks::function] +pub async fn as_typings_result(result: Vc) -> Result> { + let mut result = result.await?.clone_value(); + result.primary = take(&mut result.primary) + .into_iter() + .map(|(mut k, v)| { + k.conditions.insert("types".to_string(), true); + (k, v) + }) + .collect(); + Ok(result.cell()) +} + +#[turbo_tasks::function] +async fn apply_typescript_types_options( + resolve_options: Vc, +) -> Result> { + let mut resolve_options = resolve_options.await?.clone_value(); + resolve_options.extensions = vec![".tsx".into(), ".ts".into(), ".d.ts".into()]; + resolve_options.into_package = resolve_options + .into_package + .drain(..) + .filter_map(|into| { + if let ResolveIntoPackage::ExportsField { + mut conditions, + unspecified_conditions, + } = into + { + conditions.insert("types".into(), ConditionValue::Set); + Some(ResolveIntoPackage::ExportsField { + conditions, + unspecified_conditions, + }) + } else { + None + } + }) + .collect(); + resolve_options + .into_package + .push(ResolveIntoPackage::MainField { + field: "types".into(), + }); + for conditions in get_condition_maps(&mut resolve_options) { + conditions.insert("types".into(), ConditionValue::Set); + } + Ok(resolve_options.into()) +} + +#[turbo_tasks::value_impl] +impl Issue for TsConfigIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + self.severity + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + Ok( + StyledString::Text("An issue occurred while parsing a tsconfig.json file.".into()) + .cell(), + ) + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.source_ident.path() + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some(StyledString::Text(self.message.clone()).cell())) + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Analysis.cell() + } +} diff --git a/turbopack/crates/turbopack-static/Cargo.toml b/turbopack/crates/turbopack-static/Cargo.toml new file mode 100644 index 0000000000000..4d0f18a899f2f --- /dev/null +++ b/turbopack/crates/turbopack-static/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "turbopack-static" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } + +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-hash = { workspace = true } +turbopack-core = { workspace = true } +turbopack-css = { workspace = true } +turbopack-ecmascript = { workspace = true } + +serde = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-static/build.rs b/turbopack/crates/turbopack-static/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-static/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-static/src/fixed.rs b/turbopack/crates/turbopack-static/src/fixed.rs new file mode 100644 index 0000000000000..b5c2831e1ba9f --- /dev/null +++ b/turbopack/crates/turbopack-static/src/fixed.rs @@ -0,0 +1,45 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + asset::{Asset, AssetContent}, + ident::AssetIdent, + output::OutputAsset, + source::Source, +}; + +/// A static asset that is served at a fixed output path. It won't use +/// content hashing to generate a long term cacheable URL. +#[turbo_tasks::value] +pub struct FixedStaticAsset { + output_path: Vc, + source: Vc>, +} + +#[turbo_tasks::value_impl] +impl FixedStaticAsset { + #[turbo_tasks::function] + pub fn new(output_path: Vc, source: Vc>) -> Vc { + FixedStaticAsset { + output_path, + source, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for FixedStaticAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + Ok(AssetIdent::from_path(self.output_path)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for FixedStaticAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} diff --git a/turbopack/crates/turbopack-static/src/lib.rs b/turbopack/crates/turbopack-static/src/lib.rs new file mode 100644 index 0000000000000..dac5336fe4d8c --- /dev/null +++ b/turbopack/crates/turbopack-static/src/lib.rs @@ -0,0 +1,199 @@ +//! Static asset support for turbopack. +//! +//! Static assets are copied directly to the output folder. +//! +//! When imported from ES modules, they produce a thin module that simply +//! exports the asset's path. +//! +//! When referred to from CSS assets, the reference is replaced with the asset's +//! path. + +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +pub mod fixed; +pub mod output_asset; + +use anyhow::Result; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext}, + context::AssetContext, + ident::AssetIdent, + module::Module, + output::OutputAsset, + reference::{ModuleReferences, SingleOutputAssetReference}, + source::Source, +}; +use turbopack_css::embed::CssEmbed; +use turbopack_ecmascript::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkType, EcmascriptExports, + }, + utils::StringifyJs, +}; + +use self::output_asset::StaticAsset; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("static".into()) +} + +#[turbo_tasks::value] +#[derive(Clone)] +pub struct StaticModuleAsset { + pub source: Vc>, + pub asset_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl StaticModuleAsset { + #[turbo_tasks::function] + pub fn new(source: Vc>, asset_context: Vc>) -> Vc { + Self::cell(StaticModuleAsset { + source, + asset_context, + }) + } + + #[turbo_tasks::function] + async fn static_asset( + self: Vc, + chunking_context: Vc>, + ) -> Result> { + Ok(StaticAsset::new(chunking_context, self.await?.source)) + } +} + +#[turbo_tasks::value_impl] +impl Module for StaticModuleAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source + .ident() + .with_modifier(modifier()) + .with_layer(self.asset_context.layer()) + } +} + +#[turbo_tasks::value_impl] +impl Asset for StaticModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for StaticModuleAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast(ModuleChunkItem::cell(ModuleChunkItem { + module: self, + chunking_context, + static_asset: self.static_asset(Vc::upcast(chunking_context)), + }))) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for StaticModuleAsset { + #[turbo_tasks::function] + fn get_exports(&self) -> Vc { + EcmascriptExports::Value.into() + } +} + +#[turbo_tasks::value] +struct ModuleChunkItem { + module: Vc, + chunking_context: Vc>, + static_asset: Vc, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for ModuleChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + Ok(Vc::cell(vec![Vc::upcast(SingleOutputAssetReference::new( + Vc::upcast(self.static_asset), + Vc::cell( + format!( + "static(url) {}", + self.static_asset.ident().to_string().await? + ) + .into(), + ), + ))])) + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for ModuleChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn content(&self) -> Result> { + Ok(EcmascriptChunkItemContent { + inner_code: format!( + "__turbopack_export_value__({path});", + path = StringifyJs( + &self + .chunking_context + .asset_url(self.static_asset.ident()) + .await? + ) + ) + .into(), + ..Default::default() + } + .into()) + } +} + +#[turbo_tasks::value_impl] +impl CssEmbed for ModuleChunkItem { + #[turbo_tasks::function] + fn embedded_asset(&self) -> Vc> { + Vc::upcast(self.static_asset) + } +} + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-static/src/output_asset.rs b/turbopack/crates/turbopack-static/src/output_asset.rs new file mode 100644 index 0000000000000..d7a99a57b9ed2 --- /dev/null +++ b/turbopack/crates/turbopack-static/src/output_asset.rs @@ -0,0 +1,59 @@ +use anyhow::{anyhow, Result}; +use turbo_tasks::Vc; +use turbo_tasks_fs::FileContent; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::ChunkingContext, + ident::AssetIdent, + output::OutputAsset, + source::Source, +}; +#[turbo_tasks::value] +pub struct StaticAsset { + chunking_context: Vc>, + source: Vc>, +} + +#[turbo_tasks::value_impl] +impl StaticAsset { + #[turbo_tasks::function] + pub fn new( + chunking_context: Vc>, + source: Vc>, + ) -> Vc { + Self::cell(StaticAsset { + chunking_context, + source, + }) + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for StaticAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let content = self.source.content(); + let content_hash = if let AssetContent::File(file) = &*content.await? { + if let FileContent::Content(file) = &*file.await? { + turbo_tasks_hash::hash_xxh3_hash64(file.content()) + } else { + return Err(anyhow!("StaticAsset::path: not found")); + } + } else { + return Err(anyhow!("StaticAsset::path: unsupported file content")); + }; + let content_hash_b16 = turbo_tasks_hash::encode_hex(content_hash); + let asset_path = self + .chunking_context + .asset_path(content_hash_b16.into(), self.source.ident()); + Ok(AssetIdent::from_path(asset_path)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for StaticAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} diff --git a/turbopack/crates/turbopack-swc-ast-explorer/Cargo.toml b/turbopack/crates/turbopack-swc-ast-explorer/Cargo.toml new file mode 100644 index 0000000000000..3e682150d9251 --- /dev/null +++ b/turbopack/crates/turbopack-swc-ast-explorer/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "swc-ast-explorer" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" + +# don't publish this crate (for now) +publish = false + +[[bin]] +name = "swc-ast-explorer" +path = "src/main.rs" +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, features = ["derive"] } +owo-colors = { workspace = true } +regex = { workspace = true } +swc_core = { workspace = true, features = [ + "base", + "common", + "ecma_ast", + "ecma_parser", +] } diff --git a/turbopack/crates/turbopack-swc-ast-explorer/README.md b/turbopack/crates/turbopack-swc-ast-explorer/README.md new file mode 100644 index 0000000000000..4c92e196d30ef --- /dev/null +++ b/turbopack/crates/turbopack-swc-ast-explorer/README.md @@ -0,0 +1,59 @@ +# swc-ast-explorer + +A small binary to print out SWC Abtract Syntax Trees. + +```shell +echo "console.log('hello')" | cargo run -p swc-ast-explorer +``` + +```rust +Script( + Script { + body: [ + Expr( + ExprStmt { + expr: Call( + CallExpr { + callee: Expr( + Member( + MemberExpr { + obj: Ident( + Ident { + sym: Atom('console' type=inline), + optional: false, + }, + ), + prop: Ident( + Ident { + sym: Atom('log' type=inline), + optional: false, + }, + ), + }, + ), + ), + args: [ + ExprOrSpread { + spread: None, + expr: Lit( + Str( + Str { + value: Atom('hello' type=inline), + raw: Some( + "'hello'", + ), + }, + ), + ), + }, + ], + type_args: None, + }, + ), + }, + ), + ], + shebang: None, + }, +) +``` diff --git a/turbopack/crates/turbopack-swc-ast-explorer/src/main.rs b/turbopack/crates/turbopack-swc-ast-explorer/src/main.rs new file mode 100644 index 0000000000000..bb8809614afe2 --- /dev/null +++ b/turbopack/crates/turbopack-swc-ast-explorer/src/main.rs @@ -0,0 +1,75 @@ +use std::{io::stdin, sync::Arc}; + +use anyhow::Result; +use clap::Parser; +use owo_colors::OwoColorize; +use regex::{NoExpand, Regex}; +use swc_core::{ + base::{config::IsModule, try_with_handler, Compiler, HandlerOpts}, + common::{errors::ColorConfig, source_map::FileName, Globals, SourceMap, GLOBALS}, + ecma::{ + ast::EsVersion, + parser::{Syntax, TsSyntax}, + }, +}; + +#[derive(Parser, Debug)] +#[clap(author, version, about, long_about = None)] +struct Args { + /// Whether to keep Span (location) markers + #[clap(long, value_parser, default_value_t = false)] + spans: bool, +} + +fn main() -> Result<()> { + let args = Args::parse(); + + let mut contents = String::new(); + stdin().read_line(&mut contents)?; + + let sm = Arc::new(SourceMap::default()); + let file = sm.new_source_file(FileName::Anon, contents); + let target = EsVersion::latest(); + let syntax = Syntax::Typescript(TsSyntax { + tsx: true, + decorators: false, + dts: false, + no_early_errors: true, + disallow_ambiguous_jsx_like: false, + }); + + let compiler = Compiler::new(sm.clone()); + let res = GLOBALS.set(&Globals::new(), || { + try_with_handler( + sm, + HandlerOpts { + color: ColorConfig::Always, + skip_filename: false, + }, + |handler| compiler.parse_js(file, handler, target, syntax, IsModule::Unknown, None), + ) + }); + + let print = format!("{:#?}", res?); + + let stripped = if args.spans { + print + } else { + let span = Regex::new(r"(?m)^\s+\w+: Span \{[^}]*\},\n").unwrap(); + span.replace_all(&print, NoExpand("")).to_string() + }; + + let alernate_ws = Regex::new(r" {8}").unwrap(); + let alternating = alernate_ws.replace_all( + &stripped, + NoExpand(&format!( + "{}{}", + " ".on_default_color(), + " ".on_black() + )), + ); + let ws = Regex::new(r" {4}").unwrap(); + println!("{}", ws.replace_all(&alternating, NoExpand(" "))); + + Ok(()) +} diff --git a/turbopack/crates/turbopack-swc-utils/Cargo.toml b/turbopack/crates/turbopack-swc-utils/Cargo.toml new file mode 100644 index 0000000000000..71dc4e0730eb7 --- /dev/null +++ b/turbopack/crates/turbopack-swc-utils/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "turbopack-swc-utils" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +turbo-tasks = { workspace = true } +turbopack-core = { workspace = true } + +swc_core = { workspace = true, features = [ + "base", + "common", + "common_concurrent", + "common_sourcemap", +] } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-swc-utils/build.rs b/turbopack/crates/turbopack-swc-utils/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-swc-utils/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-swc-utils/src/emitter.rs b/turbopack/crates/turbopack-swc-utils/src/emitter.rs new file mode 100644 index 0000000000000..ae1db280c35de --- /dev/null +++ b/turbopack/crates/turbopack-swc-utils/src/emitter.rs @@ -0,0 +1,89 @@ +use std::sync::Arc; + +use swc_core::common::{ + errors::{DiagnosticBuilder, DiagnosticId, Emitter, Level}, + source_map::Pos, + SourceMap, +}; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::{ + issue::{analyze::AnalyzeIssue, IssueExt, IssueSeverity, IssueSource, StyledString}, + source::Source, +}; + +#[derive(Clone)] +pub struct IssueEmitter { + pub source: Vc>, + pub source_map: Arc, + pub title: Option, + pub emitted_issues: Vec>, +} + +impl IssueEmitter { + pub fn new( + source: Vc>, + source_map: Arc, + title: Option, + ) -> Self { + Self { + source, + source_map, + title, + emitted_issues: vec![], + } + } +} + +impl Emitter for IssueEmitter { + fn emit(&mut self, db: &DiagnosticBuilder<'_>) { + let level = db.level; + let mut message = db + .message + .iter() + .map(|s| s.0.as_ref()) + .collect::>() + .join(""); + let code = db.code.as_ref().map(|d| match d { + DiagnosticId::Error(s) => format!("error {s}").into(), + DiagnosticId::Lint(s) => format!("lint {s}").into(), + }); + + let title; + if let Some(t) = self.title.as_ref() { + title = t.clone(); + } else { + let mut message_split = message.split('\n'); + title = message_split.next().unwrap().to_string().into(); + message = message_split.remainder().unwrap_or("").to_string(); + } + + let source = db.span.primary_span().map(|span| { + IssueSource::from_swc_offsets(self.source, span.lo.to_usize(), span.hi.to_usize()) + }); + // TODO add other primary and secondary spans with labels as sub_issues + + let issue = AnalyzeIssue { + severity: match level { + Level::Bug => IssueSeverity::Bug, + Level::Fatal | Level::PhaseFatal => IssueSeverity::Fatal, + Level::Error => IssueSeverity::Error, + Level::Warning => IssueSeverity::Warning, + Level::Note => IssueSeverity::Note, + Level::Help => IssueSeverity::Hint, + Level::Cancelled => IssueSeverity::Error, + Level::FailureNote => IssueSeverity::Note, + } + .cell(), + source_ident: self.source.ident(), + title: Vc::cell(title), + message: StyledString::Text(message.into()).cell(), + code, + source, + } + .cell(); + + self.emitted_issues.push(issue); + + issue.emit(); + } +} diff --git a/turbopack/crates/turbopack-swc-utils/src/lib.rs b/turbopack/crates/turbopack-swc-utils/src/lib.rs new file mode 100644 index 0000000000000..3f961f3b4c4cc --- /dev/null +++ b/turbopack/crates/turbopack-swc-utils/src/lib.rs @@ -0,0 +1,4 @@ +#![feature(min_specialization)] +#![feature(str_split_remainder)] + +pub mod emitter; diff --git a/turbopack/crates/turbopack-test-utils/Cargo.toml b/turbopack/crates/turbopack-test-utils/Cargo.toml new file mode 100644 index 0000000000000..d6a6a108611f7 --- /dev/null +++ b/turbopack/crates/turbopack-test-utils/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "turbopack-test-utils" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +once_cell = { workspace = true } +regex = { workspace = true, features = ["pattern"] } +serde = { workspace = true } +similar = "2.2.0" +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-hash = { workspace = true } +turbopack-cli-utils = { workspace = true } +turbopack-core = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-test-utils/build.rs b/turbopack/crates/turbopack-test-utils/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-test-utils/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-test-utils/src/jest.rs b/turbopack/crates/turbopack-test-utils/src/jest.rs new file mode 100644 index 0000000000000..297fd705680fa --- /dev/null +++ b/turbopack/crates/turbopack-test-utils/src/jest.rs @@ -0,0 +1,19 @@ +use serde::{Deserialize, Serialize}; + +// Defines common structures returned by jest/jest-circus. Shared across turbo +// and next.js repos. + +/// The serialized form of the JS object returned from jest.run() +/// describing results. +#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct JestRunResult { + pub test_results: Vec, +} + +#[derive(Clone, Debug, Serialize, Deserialize, Eq, PartialEq)] +#[serde(rename_all = "camelCase")] +pub struct JestTestResult { + pub test_path: Vec, + pub errors: Vec, +} diff --git a/turbopack/crates/turbopack-test-utils/src/lib.rs b/turbopack/crates/turbopack-test-utils/src/lib.rs new file mode 100644 index 0000000000000..050f83fa2bbb0 --- /dev/null +++ b/turbopack/crates/turbopack-test-utils/src/lib.rs @@ -0,0 +1,5 @@ +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +pub mod jest; +pub mod snapshot; diff --git a/turbopack/crates/turbopack-test-utils/src/snapshot.rs b/turbopack/crates/turbopack-test-utils/src/snapshot.rs new file mode 100644 index 0000000000000..c8d34ef86b2f0 --- /dev/null +++ b/turbopack/crates/turbopack-test-utils/src/snapshot.rs @@ -0,0 +1,239 @@ +use std::{ + collections::{HashMap, HashSet}, + env, fs, + path::PathBuf, +}; + +use anyhow::{anyhow, bail, Context, Result}; +use once_cell::sync::Lazy; +use regex::Regex; +use similar::TextDiff; +use turbo_tasks::{RcStr, ReadRef, TryJoinIterExt, ValueToString, Vc}; +use turbo_tasks_fs::{ + DirectoryContent, DirectoryEntry, DiskFileSystem, File, FileContent, FileSystemEntryType, + FileSystemPath, +}; +use turbo_tasks_hash::encode_hex; +use turbopack_cli_utils::issue::{format_issue, LogOptions}; +use turbopack_core::{ + asset::AssetContent, + issue::{IssueSeverity, PlainIssue, StyledString}, +}; + +// Updates the existing snapshot outputs with the actual outputs of this run. +// e.g. `UPDATE=1 cargo test -p turbopack-tests -- test_my_pattern` +static UPDATE: Lazy = Lazy::new(|| env::var("UPDATE").unwrap_or_default() == "1"); + +static ANSI_REGEX: Lazy = Lazy::new(|| Regex::new(r"\x1b\[\d+m").unwrap()); + +pub async fn snapshot_issues>>( + captured_issues: I, + issues_path: Vc, + workspace_root: &str, +) -> Result<()> { + let expected_issues = expected(issues_path).await?; + let mut seen = HashSet::new(); + for plain_issue in captured_issues.into_iter() { + let title = styled_string_to_file_safe_string(&plain_issue.title) + .replace('/', "__") + // We replace "*", "?", and '"' because they're not allowed in filenames on Windows. + .replace('*', "__star__") + .replace('"', "__quo__") + .replace('?', "__q__") + .replace(':', "__c__"); + let title = if title.len() > 50 { + &title[0..50] + } else { + &title + }; + let hash = encode_hex(plain_issue.internal_hash_ref(true)); + + let path = issues_path.join(format!("{title}-{}.txt", &hash[0..6]).into()); + if !seen.insert(path) { + continue; + } + + let formatted = format_issue( + &plain_issue, + None, + &LogOptions { + current_dir: PathBuf::new(), + project_dir: PathBuf::new(), + show_all: true, + log_detail: true, + log_level: IssueSeverity::Info, + }, + ); + + // Annoyingly, the PlainIssue.source -> PlainIssueSource.asset -> + // PlainSource.path -> FileSystemPath.fs -> DiskFileSystem.root changes + // for everyone. + let content: RcStr = formatted + .as_str() + .replace(workspace_root, "WORKSPACE_ROOT") + .replace(&*ANSI_REGEX, "") + // Normalize syspaths from Windows. These appear in stack traces. + .replace("\\\\", "/") + .into(); + + let asset = AssetContent::file(File::from(content).into()); + + diff(path, asset).await?; + } + + matches_expected(expected_issues, seen).await +} + +pub async fn expected(dir: Vc) -> Result>> { + let mut expected = HashSet::new(); + let entries = dir.read_dir().await?; + if let DirectoryContent::Entries(entries) = &*entries { + for (file, entry) in entries { + match entry { + DirectoryEntry::File(file) => { + expected.insert(*file); + } + _ => bail!( + "expected file at {}, found {:?}", + file, + FileSystemEntryType::from(entry) + ), + } + } + } + Ok(expected) +} + +pub async fn matches_expected( + expected: HashSet>, + seen: HashSet>, +) -> Result<()> { + for path in diff_paths(&expected, &seen).await? { + let p = &path.await?.path; + if *UPDATE { + remove_file(path).await?; + println!("removed file {}", p); + } else { + bail!("expected file {}, but it was not emitted", p); + } + } + Ok(()) +} + +pub async fn diff(path: Vc, actual: Vc) -> Result<()> { + let path_str = &path.await?.path; + let expected = AssetContent::file(path.read()); + + let actual = get_contents(actual, path).await?; + let expected = get_contents(expected, path).await?; + + if actual != expected { + if let Some(actual) = actual { + if *UPDATE { + let content = File::from(RcStr::from(actual)).into(); + path.write(content).await?; + println!("updated contents of {}", path_str); + } else { + if expected.is_none() { + eprintln!("new file {path_str} detected:"); + } else { + eprintln!("contents of {path_str} did not match:"); + } + let expected = expected.unwrap_or_default(); + let diff = TextDiff::from_lines(&expected, &actual); + eprintln!( + "{}", + diff.unified_diff() + .context_radius(3) + .header("expected", "actual") + ); + bail!("contents of {path_str} did not match"); + } + } else { + bail!("{path_str} was not generated"); + } + } + + Ok(()) +} + +async fn get_contents(file: Vc, path: Vc) -> Result> { + Ok( + match &*file.await.context(format!( + "Unable to read AssetContent of {}", + path.to_string().await? + ))? { + AssetContent::File(file) => match &*file.await.context(format!( + "Unable to read FileContent of {}", + path.to_string().await? + ))? { + FileContent::NotFound => None, + FileContent::Content(expected) => { + Some(expected.content().to_str()?.trim().to_string()) + } + }, + AssetContent::Redirect { target, link_type } => Some(format!( + "Redirect {{ target: {target}, link_type: {:?} }}", + link_type + )), + }, + ) +} + +async fn remove_file(path: Vc) -> Result<()> { + let fs = Vc::try_resolve_downcast_type::(path.fs()) + .await? + .context(anyhow!("unexpected fs type"))? + .await?; + let sys_path = fs.to_sys_path(path).await?; + fs::remove_file(&sys_path).context(format!("remove file {} error", sys_path.display()))?; + Ok(()) +} + +/// Values in left that are not in right. +/// Vc hashes as a Vc, not as the file path, so we need to get +/// the path to properly diff. +async fn diff_paths( + left: &HashSet>, + right: &HashSet>, +) -> Result>> { + let mut map = left + .iter() + .map(|p| async move { Ok((p.await?.path.clone(), *p)) }) + .try_join() + .await? + .iter() + .cloned() + .collect::>(); + for p in right { + map.remove(&p.await?.path); + } + Ok(map.values().copied().collect()) +} + +fn styled_string_to_file_safe_string(styled_string: &StyledString) -> String { + match styled_string { + StyledString::Line(parts) => { + let mut string = String::new(); + string += "__l_"; + for part in parts { + string.push_str(&styled_string_to_file_safe_string(part)); + } + string += "__"; + string + } + StyledString::Stack(parts) => { + let mut string = String::new(); + string += "__s_"; + for part in parts { + string.push_str(&styled_string_to_file_safe_string(part)); + string.push('_'); + } + string += "__"; + string + } + StyledString::Text(string) => string.to_string(), + StyledString::Code(string) => format!("__c_{}__", string), + StyledString::Strong(string) => format!("__{}__", string), + } +} diff --git a/turbopack/crates/turbopack-tests/.gitignore b/turbopack/crates/turbopack-tests/.gitignore new file mode 100644 index 0000000000000..7932e8715ab95 --- /dev/null +++ b/turbopack/crates/turbopack-tests/.gitignore @@ -0,0 +1,4 @@ +tests/execution/**/*/output/ +tests/snapshot/**/output/ +!tests/execution/**/*/node_modules +!tests/snapshot/**/*/node_modules diff --git a/turbopack/crates/turbopack-tests/Cargo.toml b/turbopack/crates/turbopack-tests/Cargo.toml new file mode 100644 index 0000000000000..9c1d21604bab0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/Cargo.toml @@ -0,0 +1,47 @@ +[package] +name = "turbopack-tests" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +# don't publish this crate +publish = false + +[lints] +workspace = true + +[dependencies] +turbopack = { workspace = true } + +[dev-dependencies] +anyhow = { workspace = true } +dunce = { workspace = true } +futures = { workspace = true } +indexmap = { workspace = true } +once_cell = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +testing = { workspace = true } +tokio = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-bytes = { workspace = true } +turbo-tasks-env = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-memory = { workspace = true } +turbopack-browser = { workspace = true, features = ["test"] } +turbopack-cli-utils = { workspace = true } +turbopack-core = { workspace = true, features = ["issue_path"] } +turbopack-ecmascript-plugins = { workspace = true, features = [ + "transform_emotion", +] } +turbopack-ecmascript-runtime = { workspace = true } +turbopack-env = { workspace = true } +turbopack-node = { workspace = true } +turbopack-nodejs = { workspace = true, features = ["test"] } +turbopack-resolve = { workspace = true } +turbopack-test-utils = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-tests/README.md b/turbopack/crates/turbopack-tests/README.md new file mode 100644 index 0000000000000..93b71d0ff48b8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/README.md @@ -0,0 +1,26 @@ +# turbopack-tests + +An extracted create to perform snapshot tests on turbopack. + +## Testing + +It's possible to only run the snapshot tests using [nextest][]'s filter +expressions: + +```bash +cargo nextest run -E 'test(snapshot)' +``` + +The filter supports any substring, and only test names which contain +that substring will run. + +## Updating Snapshot + +If you've made a change that requires many snapshot updates, you can +automatically update all outputs using the `UPDATE` command line env: + +```bash +UPDATE=1 cargo nextest run -E 'test(snapshot)' +``` + +[nextest]: https://nexte.st/ diff --git a/turbopack/crates/turbopack-tests/build.rs b/turbopack/crates/turbopack-tests/build.rs new file mode 100644 index 0000000000000..dff0f12de7bad --- /dev/null +++ b/turbopack/crates/turbopack-tests/build.rs @@ -0,0 +1,9 @@ +use turbo_tasks_build::{generate_register, rerun_if_glob}; + +fn main() { + generate_register(); + // The test/snapshot crate need to be rebuilt if any snapshots are added. + rerun_if_glob("tests/execution/*/*/*", "tests/execution"); + rerun_if_glob("tests/execution/*/*/__skipped__/*", "tests/execution"); + rerun_if_glob("tests/snapshot/*/*", "tests/snapshot"); +} diff --git a/turbopack/crates/turbopack-tests/index.d.ts b/turbopack/crates/turbopack-tests/index.d.ts new file mode 100644 index 0000000000000..28760b9c833ec --- /dev/null +++ b/turbopack/crates/turbopack-tests/index.d.ts @@ -0,0 +1,12 @@ +import * as expectMod from "./tests/execution/node_modules/expect"; +import * as jest from "./tests/execution/node_modules/jest-circus"; + +export {}; + +declare global { + var describe: typeof jest.describe; + var expect: typeof expectMod.expect; + var it: typeof jest.it; + var test: typeof jest.test; + var nsObj: (obj: Object) => Object; +} diff --git a/turbopack/crates/turbopack-tests/js/jest-entry.ts b/turbopack/crates/turbopack-tests/js/jest-entry.ts new file mode 100644 index 0000000000000..6a31422b25a79 --- /dev/null +++ b/turbopack/crates/turbopack-tests/js/jest-entry.ts @@ -0,0 +1,47 @@ +/// + +const jest = __turbopack_external_require__("jest-circus"); +const expectMod = __turbopack_external_require__("expect"); + +function setupGlobals() { + globalThis.describe = jest.describe; + globalThis.it = jest.it; + globalThis.test = jest.test; + globalThis.expect = expectMod.expect; + + // From https://github.com/webpack/webpack/blob/9fcaa243573005d6fdece9a3f8d89a0e8b399613/test/TestCases.template.js#L422 + globalThis.nsObj = function nsObj(obj) { + Object.defineProperty(obj, Symbol.toStringTag, { + value: "Module", + }); + return obj; + }; +} + +const uncaughtExceptions: string[] = []; +const unhandledRejections: string[] = []; + +process.on("uncaughtException", (e) => { + uncaughtExceptions.push(String(e)); +}); + +process.on("unhandledRejection", (e) => { + unhandledRejections.push(String(e)); +}); + +export default async function run() { + setupGlobals(); + + await import("TESTS"); + + const jestResult = await jest.run(); + + // Wait a full tick for unhandledRejection handlers to run -- a microtask is not sufficient. + await new Promise((resolve) => setTimeout(resolve, 0)); + + return { + jestResult, + uncaughtExceptions, + unhandledRejections, + }; +} diff --git a/turbopack/crates/turbopack-tests/js/types.d.ts b/turbopack/crates/turbopack-tests/js/types.d.ts new file mode 100644 index 0000000000000..46f543b0c5054 --- /dev/null +++ b/turbopack/crates/turbopack-tests/js/types.d.ts @@ -0,0 +1,3 @@ +declare const __turbopack_external_require__: (id: string) => any; + +declare module "TESTS"; diff --git a/turbopack/crates/turbopack-tests/tests/.eslintrc.json b/turbopack/crates/turbopack-tests/tests/.eslintrc.json new file mode 100644 index 0000000000000..d5ba8f9d9ca87 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "rules": { + "no-console": "off" + } +} diff --git a/turbopack/crates/turbopack-tests/tests/.gitignore b/turbopack/crates/turbopack-tests/tests/.gitignore new file mode 100644 index 0000000000000..08fbae31e6e59 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/.gitignore @@ -0,0 +1,4 @@ +!/node_modules +# include everything in the snapshots dir +!snapshot/** +.DS_Store diff --git a/turbopack/crates/turbopack-tests/tests/execution.rs b/turbopack/crates/turbopack-tests/tests/execution.rs new file mode 100644 index 0000000000000..e44f28072203c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution.rs @@ -0,0 +1,413 @@ +#![cfg(test)] +#![feature(arbitrary_self_types)] + +mod util; + +use std::{collections::HashMap, path::PathBuf}; + +use anyhow::{Context, Result}; +use dunce::canonicalize; +use indexmap::indexmap; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{ + debug::ValueDebugFormat, trace::TraceRawVcs, Completion, RcStr, TryJoinIterExt, TurboTasks, + Value, Vc, +}; +use turbo_tasks_bytes::stream::SingleValue; +use turbo_tasks_env::CommandLineProcessEnv; +use turbo_tasks_fs::{ + json::parse_json_with_source_context, util::sys_to_unix, DiskFileSystem, FileContent, + FileSystem, FileSystemEntryType, FileSystemPath, +}; +use turbo_tasks_memory::MemoryBackend; +use turbopack::{ + ecmascript::TreeShakingMode, module_options::ModuleOptionsContext, ModuleAssetContext, +}; +use turbopack_core::{ + compile_time_defines, + compile_time_info::CompileTimeInfo, + condition::ContextCondition, + context::AssetContext, + environment::{Environment, ExecutionEnvironment, NodeJsEnvironment}, + file_source::FileSource, + issue::{Issue, IssueDescriptionExt}, + reference_type::{InnerAssets, ReferenceType}, + resolve::{ + options::{ImportMap, ImportMapping}, + ExternalType, + }, + source::Source, +}; +use turbopack_ecmascript_runtime::RuntimeType; +use turbopack_node::{debug::should_debug, evaluate::evaluate}; +use turbopack_nodejs::NodeJsChunkingContext; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; +use turbopack_test_utils::jest::JestRunResult; + +use crate::util::REPO_ROOT; + +#[turbo_tasks::value] +struct RunTestResult { + js_result: Vc, + path: Vc, +} + +#[turbo_tasks::value] +#[derive(Clone)] +#[serde(rename_all = "camelCase")] +struct JsResult { + uncaught_exceptions: Vec, + unhandled_rejections: Vec, + #[turbo_tasks(trace_ignore)] + jest_result: JestRunResult, +} + +enum IssueSnapshotMode { + Snapshots, + NoSnapshots, +} + +fn register() { + turbo_tasks::register(); + turbo_tasks_env::register(); + turbo_tasks_fs::register(); + turbopack::register(); + turbopack_nodejs::register(); + turbopack_env::register(); + turbopack_ecmascript_plugins::register(); + turbopack_resolve::register(); + include!(concat!(env!("OUT_DIR"), "/register_test_execution.rs")); +} + +// To minimize test path length and consistency with snapshot tests, +// node_modules is stored as a sibling of the test fixtures. Don't run +// it as a test. +// +// "Skip" directories named `__skipped__`, which include test directories to +// skip. +#[testing::fixture("tests/execution/*/*/*", exclude("node_modules|__skipped__"))] +fn test(resource: PathBuf) { + let messages = get_messages(run(resource, IssueSnapshotMode::Snapshots).unwrap()); + if !messages.is_empty() { + panic!( + "Failed with error(s) in the following test(s):\n\n{}", + messages.join("\n\n--\n") + ) + } +} + +#[testing::fixture("tests/execution/*/*/__skipped__/*/input")] +#[should_panic] +fn test_skipped_fails(resource: PathBuf) { + let resource = resource.parent().unwrap().to_path_buf(); + + let JsResult { + // Ignore uncaught exceptions for skipped tests. + uncaught_exceptions: _, + unhandled_rejections: _, + jest_result, + } = run(resource, IssueSnapshotMode::NoSnapshots).unwrap(); + + // Assert that this skipped test itself has at least one browser test which + // fails. + assert!( + // Skipped tests sometimes have errors (e.g. unsupported syntax) that prevent tests from + // running at all. Allow them to have empty results. + jest_result.test_results.is_empty() + || jest_result + .test_results + .into_iter() + .any(|r| !r.errors.is_empty()), + ); +} + +fn get_messages(js_results: JsResult) -> Vec { + let mut messages = vec![]; + + if js_results.jest_result.test_results.is_empty() { + messages.push("No tests were run.".into()); + } + + for test_result in js_results.jest_result.test_results { + // It's possible to fail multiple tests across these tests, + // so collect them and fail the respective test in Rust with + // an aggregate message. + if !test_result.errors.is_empty() { + messages.push(format!( + "\"{}\":\n{}", + test_result.test_path[1..].join(" > "), + test_result.errors.join("\n") + )); + } + } + + for uncaught_exception in js_results.uncaught_exceptions { + messages.push(format!("Uncaught exception: {}", uncaught_exception)); + } + + for unhandled_rejection in js_results.unhandled_rejections { + messages.push(format!("Unhandled rejection: {}", unhandled_rejection)); + } + + messages +} + +#[tokio::main(flavor = "current_thread")] +async fn run(resource: PathBuf, snapshot_mode: IssueSnapshotMode) -> Result { + register(); + + // Clean up old output files. + let output_path = resource.join("output"); + if output_path.exists() { + std::fs::remove_dir_all(&output_path)?; + } + + let tt = TurboTasks::new(MemoryBackend::default()); + tt.run_once(async move { + let resource_str = resource.to_str().unwrap(); + let prepared_test = prepare_test(resource_str.into()); + let run_result = run_test(prepared_test); + if matches!(snapshot_mode, IssueSnapshotMode::Snapshots) { + snapshot_issues(prepared_test, run_result).await?; + } + + Ok((*run_result.await.unwrap().js_result.await.unwrap()).clone()) + }) + .await +} + +#[derive(PartialEq, Eq, Debug, Default, Serialize, Deserialize, TraceRawVcs, ValueDebugFormat)] +#[serde(rename_all = "camelCase", deny_unknown_fields)] +struct TestOptions { + tree_shaking_mode: Option, +} + +#[turbo_tasks::value] +struct PreparedTest { + path: Vc, + project_path: Vc, + tests_path: Vc, + project_root: Vc, + options: TestOptions, +} + +#[turbo_tasks::function] +async fn prepare_test(resource: RcStr) -> Result> { + let resource_path = canonicalize(&resource)?; + assert!(resource_path.exists(), "{} does not exist", resource); + assert!( + resource_path.is_dir(), + "{} is not a directory. Execution tests must be directories.", + resource_path.to_str().unwrap() + ); + + let root_fs = DiskFileSystem::new("workspace".into(), REPO_ROOT.clone(), vec![]); + let project_fs = DiskFileSystem::new("project".into(), REPO_ROOT.clone(), vec![]); + let project_root = project_fs.root(); + + let relative_path = resource_path.strip_prefix(&*REPO_ROOT).context(format!( + "stripping repo root {:?} from resource path {:?}", + &*REPO_ROOT, + resource_path.display() + ))?; + let relative_path: RcStr = sys_to_unix(relative_path.to_str().unwrap()).into(); + let path = root_fs.root().join(relative_path.clone()); + let project_path = project_root.join(relative_path.clone()); + let tests_path = project_fs.root().join("crates/turbopack-tests".into()); + + let options_file = path.join("options.json".into()); + + let mut options = TestOptions::default(); + if matches!(*options_file.get_type().await?, FileSystemEntryType::File) { + if let FileContent::Content(content) = &*options_file.read().await? { + options = + serde_json::from_reader(content.read()).context("Unable to parse options.json")?; + } + } + + Ok(PreparedTest { + path, + project_path, + tests_path, + project_root, + options, + } + .cell()) +} + +#[turbo_tasks::function] +async fn run_test(prepared_test: Vc) -> Result> { + let PreparedTest { + path, + project_path, + tests_path, + project_root, + ref options, + } = *prepared_test.await?; + + let jest_entry_path = tests_path.join("js/jest-entry.ts".into()); + let test_path = project_path.join("input/index.js".into()); + + let chunk_root_path = path.join("output".into()); + let static_root_path = path.join("static".into()); + + let env = Environment::new(Value::new(ExecutionEnvironment::NodeJsBuildTime( + NodeJsEnvironment::default().into(), + ))); + + let compile_time_info = CompileTimeInfo::builder(env) + .defines( + compile_time_defines!( + process.turbopack = true, + process.env.TURBOPACK = true, + process.env.NODE_ENV = "development", + ) + .cell(), + ) + .cell(); + + let mut import_map = ImportMap::empty(); + import_map.insert_wildcard_alias( + "esm-external/", + ImportMapping::External(Some("*".into()), ExternalType::EcmaScriptModule).cell(), + ); + + let asset_context: Vc> = Vc::upcast(ModuleAssetContext::new( + Vc::cell(HashMap::new()), + compile_time_info, + ModuleOptionsContext { + enable_typescript_transform: Some(Default::default()), + preset_env_versions: Some(env), + tree_shaking_mode: options.tree_shaking_mode, + import_externals: true, + rules: vec![( + ContextCondition::InDirectory("node_modules".into()), + ModuleOptionsContext { + tree_shaking_mode: options.tree_shaking_mode, + ..Default::default() + } + .cell(), + )], + ..Default::default() + } + .into(), + ResolveOptionsContext { + enable_typescript: true, + enable_node_modules: Some(project_root), + custom_conditions: vec!["development".into()], + rules: vec![( + ContextCondition::InDirectory("node_modules".into()), + ResolveOptionsContext { + enable_node_modules: Some(project_root), + custom_conditions: vec!["development".into()], + browser: true, + ..Default::default() + } + .cell(), + )], + browser: true, + module: true, + import_map: Some(import_map.cell()), + ..Default::default() + } + .cell(), + Vc::cell("test".into()), + )); + + let chunking_context = NodeJsChunkingContext::builder( + project_root, + chunk_root_path, + static_root_path, + chunk_root_path, + static_root_path, + env, + RuntimeType::Development, + ) + .build(); + + let jest_entry_source = FileSource::new(jest_entry_path); + let test_source = FileSource::new(test_path); + + let test_asset = asset_context + .process( + Vc::upcast(test_source), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) + .module(); + + let jest_entry_asset = asset_context + .process( + Vc::upcast(jest_entry_source), + Value::new(ReferenceType::Internal(Vc::cell(indexmap! { + "TESTS".into() => test_asset, + }))), + ) + .module(); + + let res = evaluate( + jest_entry_asset, + path, + Vc::upcast(CommandLineProcessEnv::new()), + test_source.ident(), + asset_context, + Vc::upcast(chunking_context), + None, + vec![], + Completion::immutable(), + should_debug("execution_test"), + ) + .await?; + + let single = res + .try_into_single() + .await + .context("test node result did not emit anything")?; + + let SingleValue::Single(bytes) = single else { + return Ok(RunTestResult { + js_result: JsResult { + uncaught_exceptions: vec![], + unhandled_rejections: vec![], + jest_result: JestRunResult { + test_results: vec![], + }, + } + .cell(), + path, + } + .cell()); + }; + + Ok(RunTestResult { + js_result: JsResult::cell(parse_json_with_source_context(bytes.to_str()?)?), + path, + } + .cell()) +} + +#[turbo_tasks::function] +async fn snapshot_issues( + prepared_test: Vc, + run_result: Vc, +) -> Result> { + let PreparedTest { path, .. } = *prepared_test.await?; + let _ = run_result.resolve_strongly_consistent().await; + + let captured_issues = run_result.peek_issues_with_path().await?; + + let plain_issues = captured_issues + .iter_with_shortest_path() + .map(|(issue_vc, path)| async move { issue_vc.into_plain(path).await }) + .try_join() + .await?; + + turbopack_test_utils::snapshot::snapshot_issues( + plain_issues, + path.join("issues".into()), + &REPO_ROOT, + ) + .await + .context("Unable to handle issues")?; + + Ok(Default::default()) +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/package.json b/turbopack/crates/turbopack-tests/tests/execution/package.json new file mode 100644 index 0000000000000..8453f2d46c3ca --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/package.json @@ -0,0 +1,11 @@ +{ + "private": true, + "name": "execution-test", + "dependencies": { + "expect": "29.5.0", + "jest-circus": "29.5.0", + "react": "18.2.0", + "react-test-renderer": "18.2.0", + "styled-jsx": "^5.1.2" + } +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js new file mode 100644 index 0000000000000..2753ed2e59660 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/index.js @@ -0,0 +1,37 @@ +import { a as a1, b as b1, c as c1 } from "./side-effects/reexport-internal.js"; + +const cases = { + "async module with side effects via dynamic import": () => + import("./side-effects/reexport-internal.js"), + "async module with side effects via esm import": async () => + (await import("./side-effects/reexport-internal-test.js")).default, + "async module with side effects via require": () => + require("./side-effects/reexport-internal.js"), + "async module flagged side-effect-free via dynamic import": () => + import("./side-effect-free/reexport-internal.js"), + "async module flagged side-effect-free via esm import": async () => + (await import("./side-effect-free/reexport-internal-test.js")).default, + "async module flagged side-effect-free via require": () => + require("./side-effect-free/reexport-internal.js"), + "module with externals with side effects via dynamic import": () => + import("./side-effects/reexport-external.js"), + "module with externals with side effects via esm import": async () => + (await import("./side-effects/reexport-external-test.js")).default, + "module with externals with side effects via require": () => + require("./side-effects/reexport-external.js"), + "module with externals flagged side-effect-free via dynamic import": () => + import("./side-effect-free/reexport-external.js"), + "module with externals flagged side-effect-free via esm import": async () => + (await import("./side-effect-free/reexport-external-test.js")).default, + "module with externals flagged side-effect-free via require": () => + require("./side-effect-free/reexport-external.js"), +}; + +for (const [name, fn] of Object.entries(cases)) { + it(`should reexport a ${name} with side effects optimization`, async () => { + const { a, b, c } = await fn(); + expect(a).toBe("a"); + expect(b).toBe("b"); + expect(c).toBe("c"); + }); +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/inner.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/inner.js new file mode 100644 index 0000000000000..57ef84689a0e7 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/inner.js @@ -0,0 +1,4 @@ +await 1; + +export const a = "a"; +export const b = "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/package.json new file mode 100644 index 0000000000000..a43829151e142 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-external-test.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-external-test.js new file mode 100644 index 0000000000000..f8ede4b7c9f14 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-external-test.js @@ -0,0 +1,7 @@ +import { a, b, c } from "./reexport-external.js"; + +export default { + a, + b, + c, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-external.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-external.js new file mode 100644 index 0000000000000..37fe508f9ed30 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-external.js @@ -0,0 +1,3 @@ +import { a, b } from "esm-external/package"; +export { a, b }; +export const c = "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-internal-test.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-internal-test.js new file mode 100644 index 0000000000000..47089253329de --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-internal-test.js @@ -0,0 +1,7 @@ +import { a, b, c } from "./reexport-internal.js"; + +export default { + a, + b, + c, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-internal.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-internal.js new file mode 100644 index 0000000000000..52be0e3be87ed --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effect-free/reexport-internal.js @@ -0,0 +1,3 @@ +import { a, b } from "./inner.js"; +export { a, b }; +export const c = "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/inner.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/inner.js new file mode 100644 index 0000000000000..57ef84689a0e7 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/inner.js @@ -0,0 +1,4 @@ +await 1; + +export const a = "a"; +export const b = "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/package.json new file mode 100644 index 0000000000000..3802144dedbda --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": true +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external-test.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external-test.js new file mode 100644 index 0000000000000..f8ede4b7c9f14 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external-test.js @@ -0,0 +1,7 @@ +import { a, b, c } from "./reexport-external.js"; + +export default { + a, + b, + c, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external.js new file mode 100644 index 0000000000000..37fe508f9ed30 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-external.js @@ -0,0 +1,3 @@ +import { a, b } from "esm-external/package"; +export { a, b }; +export const c = "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal-test.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal-test.js new file mode 100644 index 0000000000000..47089253329de --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal-test.js @@ -0,0 +1,7 @@ +import { a, b, c } from "./reexport-internal.js"; + +export default { + a, + b, + c, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal.js new file mode 100644 index 0000000000000..52be0e3be87ed --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/input/side-effects/reexport-internal.js @@ -0,0 +1,3 @@ +import { a, b } from "./inner.js"; +export { a, b }; +export const c = "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/node_modules/package/index.mjs b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/node_modules/package/index.mjs new file mode 100644 index 0000000000000..75fab4cabd134 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/node_modules/package/index.mjs @@ -0,0 +1,2 @@ +export const a = "a"; +export const b = "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/node_modules/package/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/node_modules/package/package.json new file mode 100644 index 0000000000000..aa988430b3cd2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/node_modules/package/package.json @@ -0,0 +1,3 @@ +{ + "main": "./index.mjs" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/options.json new file mode 100644 index 0000000000000..af13697f09f93 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/async-reexport-side-effects-split/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "reexports-only" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/input/index.js new file mode 100644 index 0000000000000..34914ae907463 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/input/index.js @@ -0,0 +1,8 @@ +import { a, b, default as def } from "esm-external/package"; + +it(`should reexport all exports from an external esm module`, async () => { + expect(def).toBe("default"); + + expect(a).toBe("a"); + expect(b).toBe("b"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/node_modules/package/index.mjs b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/node_modules/package/index.mjs new file mode 100644 index 0000000000000..7a7b7942c0579 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/node_modules/package/index.mjs @@ -0,0 +1,4 @@ +export default 'default' + +export const a = 'a' +export const b = 'b' diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/node_modules/package/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/node_modules/package/package.json new file mode 100644 index 0000000000000..aa988430b3cd2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/esm-external/node_modules/package/package.json @@ -0,0 +1,3 @@ +{ + "main": "./index.mjs" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/exports.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/exports.js new file mode 100644 index 0000000000000..474eabac82741 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/exports.js @@ -0,0 +1,4 @@ +module.exports = {}; + +module.exports.a = "export-a"; +module.exports.b = "export-b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/index.js new file mode 100644 index 0000000000000..b0ee892b62049 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/index.js @@ -0,0 +1,9 @@ +import { a, b, single } from "./tla"; + +it("should handle export all from cjs modules in modules with top level await", async () => { + expect(a).toBe("export-a"); + expect(b).toBe("export-b"); + expect(single).toMatchObject({ + single: 1, + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/single.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/single.js new file mode 100644 index 0000000000000..11cebbf56bd53 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/single.js @@ -0,0 +1 @@ +export const single = 1; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/tla.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/tla.js new file mode 100644 index 0000000000000..4a607dded2a05 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/tla.js @@ -0,0 +1,3 @@ +export const single = await import("./single"); + +export * from "./exports"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/issues/unexpected export __star__-2ea3bf.txt b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/issues/unexpected export __star__-2ea3bf.txt new file mode 100644 index 0000000000000..7b31421812d04 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/issues/unexpected export __star__-2ea3bf.txt @@ -0,0 +1,3 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/exports.js unexpected export * + export * used with module [project]/crates/turbopack-tests/tests/execution/turbopack/async-modules/export-all/input/exports.js [test] (ecmascript) which is a CommonJS module with exports only available at runtime + List all export names manually (`export { a, b, c } from "...") or rewrite the module to ESM, to avoid the additional runtime code.` \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/index.js new file mode 100644 index 0000000000000..54d1ccabee9ad --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/index.js @@ -0,0 +1,6 @@ +it("should not hang", async () => { + debugger; + const { test } = await import("./wrapper"); + + expect(test()).toBe(5); +}, 1000); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/repro.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/repro.js new file mode 100644 index 0000000000000..3adca1fbb53cc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/repro.js @@ -0,0 +1,7 @@ +export const x = 5; + +const a = 10; +if (a !== 10) { + // intentionally nothing, the skipped await point causes the problem + await 0; +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/wrapper.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/wrapper.js new file mode 100644 index 0000000000000..f7d252eabb32a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/pack-3039-top-level-await/input/wrapper.js @@ -0,0 +1,5 @@ +import { x } from "./repro.js"; + +export function test() { + return x; +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/Actions.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/Actions.js new file mode 100644 index 0000000000000..0628b7be26331 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/Actions.js @@ -0,0 +1,28 @@ +// import() doesn't care about whether a module is an async module or not +const UserApi = import("./UserAPI.js"); + +export const CreateUserAction = async (name) => { + console.log("Creating user", name); + // These are normal awaits, because they are in an async function + const { createUser } = await UserApi; + return await createUser(name); +}; + +// You can place import() where you like +// Placing it at top-level will start loading and evaluating on +// module evaluation. +// see CreateUserAction above +// Here: Connecting to the DB starts when the application starts +// Placing it inside of an (async) function will start loading +// and evaluating when the function is called for the first time +// which basically makes it lazy-loaded. +// see AlternativeCreateUserAction below +// Here: Connecting to the DB starts when AlternativeCreateUserAction +// is called +export const AlternativeCreateUserAction = async (name) => { + const { createUser } = await import("./UserAPI.js"); + return await createUser(name); +}; + +// Note: Using await import() at top-level doesn't make much sense +// except in rare cases. It will import modules sequentially. diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/README.md b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/README.md new file mode 100644 index 0000000000000..723f730dc5110 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/README.md @@ -0,0 +1,2 @@ +Adapted from webpack +https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/examples/top-level-await/README.md diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/UserAPI.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/UserAPI.js new file mode 100644 index 0000000000000..8fd6a1ff927f0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/UserAPI.js @@ -0,0 +1,7 @@ +import { dbCall } from "./db-connection.js"; + +export const createUser = async (name) => { + const command = `CREATE USER ${name}`; + // This is a normal await, because it's in an async function + return await dbCall({ command }); +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/db-connection.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/db-connection.js new file mode 100644 index 0000000000000..8b5e6229f462c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/db-connection.js @@ -0,0 +1,18 @@ +const connectToDB = async (url) => { + console.log("connecting to db", url); + await new Promise((r) => setTimeout(r, 100)); +}; + +// This is a top-level-await +await connectToDB("my-sql://example.com"); + +export const dbCall = async (data) => { + console.log("dbCall", data); + // This is a normal await, because it's in an async function + await new Promise((r) => setTimeout(r, 100)); + return "fake data"; +}; + +export const close = () => { + console.log("closes the DB connection"); +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/index.js new file mode 100644 index 0000000000000..c0fd41050c19f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/async-modules/top-level-await/input/index.js @@ -0,0 +1,11 @@ +import { CreateUserAction, AlternativeCreateUserAction } from "./Actions.js"; + +it("should handle top level await", async () => { + const res = await CreateUserAction("John"); + expect(res).toBe("fake data"); +}); + +it("should handle top level await (alternative)", async () => { + const res = await AlternativeCreateUserAction("John"); + expect(res).toBe("fake data"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js new file mode 100644 index 0000000000000..58e928ec46561 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js @@ -0,0 +1,168 @@ +it("importing a not existing file should throw", () => { + // This is a check to make sure that the following tests would fail if they require("fail") + expect(() => { + require("./not-existing-file"); + }).toThrow(); +}); + +function maybeReturn(x) { + if (x) { + return true; + } +} + +function func() { + if (false) { + require("fail"); + import("fail"); + } + if (true) { + require("./ok"); + } + if (true) { + require("./ok"); + } else { + require("fail"); + import("fail"); + } + if (false) { + require("fail"); + import("fail"); + } else { + require("./ok"); + } +} + +it("should not follow conditional references", () => { + func(); + + expect(func.toString()).not.toContain("import("); +}); + +function funcTenary() { + false ? require("fail") : undefined; + false ? import("fail") : undefined; + true ? require("./ok") : undefined; + true ? require("./ok") : require("fail"); + true ? require("./ok") : (require("fail"), import("fail")); + true + ? require("./ok") + : (() => { + require("fail"); + import("fail"); + })(); + const value = false + ? (() => { + require("fail"); + import("fail"); + })() + : require("./ok"); +} + +it("should not follow conditional tenary references", () => { + funcTenary(); + + expect(funcTenary.toString()).not.toContain("import("); +}); + +it("should allow to mutate objects", () => { + const obj = { a: true, b: false }; + if (!obj.a) { + throw new Error("should not be executed"); + } + if (obj.b) { + throw new Error("should not be executed"); + } + function changeIt(o) { + o.a = false; + o.b = true; + } + changeIt(obj); + if (obj.a) { + throw new Error("should not be executed"); + } + if (!obj.b) { + throw new Error("should not be executed"); + } +}); + +it("should allow replacements in IIFEs", () => { + (function func() { + if (false) { + require("fail"); + import("fail"); + } + })(); +}); + +it("should support functions that only sometimes return", () => { + let ok = false; + if (maybeReturn(true)) { + ok = true; + } + expect(ok).toBe(true); +}); + +it("should evaluate process.turbopack", () => { + let ok = false; + if (process.turbopack) { + ok = true; + } else { + require("fail"); + import("fail"); + } + expect(ok).toBe(true); +}); + +it("should evaluate !process.turbopack", () => { + if (!process.turbopack) { + require("fail"); + import("fail"); + } +}); + +it("should evaluate NODE_ENV", () => { + if (process.env.NODE_ENV !== "development") { + require("fail"); + import("fail"); + } +}); + +it("should keep side-effects in if statements", () => { + { + let ok = false; + let ok2 = true; + if (((ok = true), false)) { + ok2 = false; + // TODO improve static analysis to detect that this is unreachable + // require("fail"); + } + expect(ok).toBe(true); + expect(ok2).toBe(true); + } + { + let ok = false; + let ok2 = false; + let ok3 = true; + if (((ok = true), true)) { + ok2 = true; + } else { + ok3 = false; + // TODO improve static analysis to detect that this is unreachable + // require("fail"); + } + expect(ok).toBe(true); + expect(ok2).toBe(true); + expect(ok3).toBe(true); + } + { + let ok = 0; + if ((ok++, true)) { + ok++; + } else { + // TODO improve static analysis to detect that this is unreachable + // require("fail"); + } + expect(ok).toBe(2); + } +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/next.config.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/next.config.js new file mode 100644 index 0000000000000..343cc2aa42b49 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/next.config.js @@ -0,0 +1,16 @@ +module.exports = {}; + +function f() { + if (!process.turbopack) { + throw new Error("Turbopack is not enabled"); + } + if (process.env.NODE_ENV !== "development") { + throw new Error("NODE_ENV is not development"); + } +} + +f(); + +// if (f.toString().includes("process.turbopack")) { +// throw new Error("process.turbopack is not replaced"); +// } diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/ok.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/ok.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/__l___Module not found____c__ Can't resolve '__c_.-8f66b2.txt b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/__l___Module not found____c__ Can't resolve '__c_.-8f66b2.txt new file mode 100644 index 0000000000000..8460ada84140b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/issues/__l___Module not found____c__ Can't resolve '__c_.-8f66b2.txt @@ -0,0 +1,20 @@ +error - [resolve] [project]/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js /crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js:4:4 Module not found: Can't resolve './not-existing-file' + + 1 | it("importing a not existing file should throw", () => { + 2 | // This is a check to make sure that the following tests would fail if they require("fail") + 3 | expect(() => { + + v----------------------------v + 4 + require("./not-existing-file"); + + ^----------------------------^ + 5 | }).toThrow(); + 6 | }); + 7 | + 8 | function maybeReturn(x) { + + + + | It was not possible to find the requested file. + | Parsed request as written in source code: relative "./not-existing-file" + | Path where resolving has started: [project]/crates/turbopack-tests/tests/execution/turbopack/basic/comptime/input/index.js + | Type of request: commonjs request + | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/input/broken.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/input/broken.js new file mode 100644 index 0000000000000..2d547a5bddc4c Binary files /dev/null and b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/input/broken.js differ diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/input/index.js new file mode 100644 index 0000000000000..76868cb8e8926 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/input/index.js @@ -0,0 +1,5 @@ +it("should throw a good error when parsing file fails", async () => { + await expect(import("./broken")).rejects.toThrow( + "Could not parse module '[project]/crates/turbopack-tests/tests/execution/turbopack/basic/error/input/broken.js'" + ); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/issues/Reading source code for parsing failed-ae17dd.txt b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/issues/Reading source code for parsing failed-ae17dd.txt new file mode 100644 index 0000000000000..336ee5608510d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/error/issues/Reading source code for parsing failed-ae17dd.txt @@ -0,0 +1,5 @@ +error - [load] [project]/crates/turbopack-tests/tests/execution/turbopack/basic/error/input/broken.js Reading source code for parsing failed + An unexpected error happened while trying to read the source code to parse: failed to convert rope into string + + Caused by: + - invalid utf-8 sequence of 1 bytes from index 1 \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/esm-interop/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/esm-interop/input/index.js new file mode 100644 index 0000000000000..b7673d91983a2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/esm-interop/input/index.js @@ -0,0 +1,17 @@ +import * as ns from "./non-enumerable.js"; + +it("should allow to access non-enumerable inherited properties", () => { + const test = Object(ns); + expect(test.named).toEqual("named"); + expect(test.default).toMatchObject({ + named: "named", + default: "default", + }); + expect(test).toMatchObject({ + named: "named", + default: expect.objectContaining({ + named: "named", + default: "default", + }), + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/esm-interop/input/non-enumerable.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/esm-interop/input/non-enumerable.js new file mode 100644 index 0000000000000..e9a310f5770e1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/esm-interop/input/non-enumerable.js @@ -0,0 +1,11 @@ +class X { + get named() { + return "named"; + } + + get default() { + return "default"; + } +} + +module.exports = new X(); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/export-undefined/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/export-undefined/input/index.js new file mode 100644 index 0000000000000..4818df70dc31c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/export-undefined/input/index.js @@ -0,0 +1,7 @@ +import * as module from "./module.js"; +import mod from "./module.js"; + +it("should allow to export undefined", () => { + expect(module).toHaveProperty("default", undefined); + expect(mod).toBe(undefined); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/export-undefined/input/module.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/export-undefined/input/module.js new file mode 100644 index 0000000000000..d0f5f3a7fc4a5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/export-undefined/input/module.js @@ -0,0 +1 @@ +module.exports = undefined; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/index.js new file mode 100644 index 0000000000000..a45c9416309ab --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/index.js @@ -0,0 +1,6 @@ +import { file, file2 } from "package"; + +it("should ignore the package", async () => { + await expect(file).resolves.toEqual({}); + expect(file2).toEqual({}); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/file.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/file.js new file mode 100644 index 0000000000000..7748209324d82 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/file.js @@ -0,0 +1 @@ +module.exports = "wrong"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/file2.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/file2.js new file mode 100644 index 0000000000000..7748209324d82 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/file2.js @@ -0,0 +1 @@ +module.exports = "wrong"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/index.js new file mode 100644 index 0000000000000..91898a1ce0536 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/index.js @@ -0,0 +1,3 @@ +import "./file"; +export const file = import("./file"); +export const file2 = require("./file2"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/package.json new file mode 100644 index 0000000000000..d04bd78934384 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/ignore/input/node_modules/package/package.json @@ -0,0 +1,6 @@ +{ + "browser": { + "./file.js": false, + "./file2.js": false + } +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/index.js new file mode 100644 index 0000000000000..612958af87dfe --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/index.js @@ -0,0 +1,37 @@ +import { esm, esmPlain, loadInvalidCjs, loadInvalidEsm } from "esm-package"; +import { auto, autoPlain } from "auto-package"; + +it("should have the commonjs module as default export in specified ESM", () => { + expect(esm).toMatchObject({ + __esModule: true, + named: "named", + }); + expect(esmPlain).toMatchObject({ + named: "named", + }); +}); + +it("should not have the commonjs module as default export in specified ESM", () => { + expect(auto).toMatchObject({ + __esModule: true, + named: "named", + }); + expect(autoPlain).toMatchObject({ + named: "named", + }); +}); + +it("should error for invalid esm exports", async () => { + let value = await loadInvalidEsm(); + expect(value).toMatchObject({ + __esModule: true, + }); +}); + +it("should error for invalid cjs exports", async () => { + let value = await loadInvalidCjs(); + expect(value).toMatchObject({ + __esModule: true, + named: "named", + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/commonjs.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/commonjs.js new file mode 100644 index 0000000000000..d27de1b161799 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/commonjs.js @@ -0,0 +1,2 @@ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.named = "named"; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/index.js new file mode 100644 index 0000000000000..f6c50f94615c5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/index.js @@ -0,0 +1,5 @@ +import m from "./commonjs.js"; +import m2 from "./plain.js"; + +export const auto = m; +export const autoPlain = m2; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/package.json new file mode 100644 index 0000000000000..9e26dfeeb6e64 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/package.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/plain.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/plain.js new file mode 100644 index 0000000000000..6ee12354d7f08 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/auto-package/plain.js @@ -0,0 +1 @@ +exports.named = "named"; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/commonjs.cjs b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/commonjs.cjs new file mode 100644 index 0000000000000..d27de1b161799 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/commonjs.cjs @@ -0,0 +1,2 @@ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.named = "named"; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/index.js new file mode 100644 index 0000000000000..bf0a5164162ad --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/index.js @@ -0,0 +1,11 @@ +import m from "./commonjs.cjs"; +import m2 from "./plain.cjs"; + +export const esm = m; +export const esmPlain = m2; +export function loadInvalidEsm() { + return import("./invalid-exports.js"); +} +export function loadInvalidCjs() { + return import("./invalid-exports.cjs"); +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/invalid-exports.cjs b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/invalid-exports.cjs new file mode 100644 index 0000000000000..86137bf96eaf1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/invalid-exports.cjs @@ -0,0 +1 @@ +export const named = "named"; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/invalid-exports.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/invalid-exports.js new file mode 100644 index 0000000000000..6ee12354d7f08 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/invalid-exports.js @@ -0,0 +1 @@ +exports.named = "named"; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/package.json new file mode 100644 index 0000000000000..aead43de364cd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/plain.cjs b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/plain.cjs new file mode 100644 index 0000000000000..6ee12354d7f08 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/plain.cjs @@ -0,0 +1 @@ +exports.named = "named"; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/issues/Specified module format (CommonJs) is not matching-bae6b2.txt b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/issues/Specified module format (CommonJs) is not matching-bae6b2.txt new file mode 100644 index 0000000000000..f469aaa645eaa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/issues/Specified module format (CommonJs) is not matching-bae6b2.txt @@ -0,0 +1,4 @@ +error - [analysis] [project]/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/invalid-exports.cjs Specified module format (CommonJs) is not matching the module format of the source code (EcmaScript Modules) + The CommonJs module format was specified in the package.json that is affecting this source file or by using an special extension, but Ecmascript import/export syntax is used in the source code. + The module was automatically converted to an EcmaScript module, but that is in conflict with the specified module format. Either change the "type" field in the package.json or replace EcmaScript import/export syntax with CommonJs syntas in the source file. + In some cases EcmaScript import/export syntax is added by an transform and isn't actually part of the source code. In these cases revisit transformation options to inject the correct syntax. \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/issues/Specified module format (EcmaScript Modules) is no-5759f6.txt b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/issues/Specified module format (EcmaScript Modules) is no-5759f6.txt new file mode 100644 index 0000000000000..e1d7a93d9d406 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/issues/Specified module format (EcmaScript Modules) is no-5759f6.txt @@ -0,0 +1,3 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/execution/turbopack/basic/node-default-import/input/node_modules/esm-package/invalid-exports.js Specified module format (EcmaScript Modules) is not matching the module format of the source code (CommonJs) + The EcmaScript module format was specified in the package.json that is affecting this source file or by using an special extension, but it looks like that CommonJs syntax is used in the source code. + Exports made by CommonJs syntax will lead to a runtime error, since the module is in EcmaScript mode. Either change the "type" field in the package.json or replace CommonJs syntax with EcmaScript import/export syntax in the source file. \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/polyfill/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/polyfill/input/index.js new file mode 100644 index 0000000000000..6e999067360b7 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/polyfill/input/index.js @@ -0,0 +1,3 @@ +it("polyfills `global` to `globalThis`", () => { + expect(global).toBe(globalThis); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/index.js new file mode 100644 index 0000000000000..4d899188fc0e9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/index.js @@ -0,0 +1,52 @@ +import def, { named } from "./module.js"; +import { + nested, + nested2, + nested_with_identity, + nested_with_identity2, + double_nested, + double_nested2, + double_nested_with_identity, + double_nested_with_identity2, +} from "./reexport.js"; + +it("support imports in shorthand properties", () => { + expect(def).toBe("default"); + expect(named).toBe("named"); + expect({ def }).toStrictEqual({ def: "default" }); + expect({ named }).toStrictEqual({ named: "named" }); + expect(nested).toStrictEqual({ def: "default", named: "named" }); + expect(nested2).toStrictEqual({ def: "default", named: "named" }); + expect(nested_with_identity).toStrictEqual({ + def: "default", + named: "named", + }); + expect(nested_with_identity2).toStrictEqual({ + def: "default", + named: "named", + }); + expect(double_nested).toStrictEqual({ + nested: { + def: "default", + named: "named", + }, + }); + expect(double_nested2).toStrictEqual({ + nested: { + def: "default", + named: "named", + }, + }); + expect(double_nested_with_identity).toStrictEqual({ + nested: { + def: "default", + named: "named", + }, + }); + expect(double_nested_with_identity2).toStrictEqual({ + nested: { + def: "default", + named: "named", + }, + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/module.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/module.js new file mode 100644 index 0000000000000..9b97b525657bc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/module.js @@ -0,0 +1,5 @@ +export const named = "named"; +export default "default"; +export function identity(x) { + return x; +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/reexport.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/reexport.js new file mode 100644 index 0000000000000..467b3f98da6b7 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/shorthand-props/input/reexport.js @@ -0,0 +1,56 @@ +import def, { named, identity } from "./module.js"; + +const nested = { + def, + named, +}; + +export const nested2 = { + def, + named, +}; + +const nested_with_identity = identity({ + def, + named, +}); + +export const nested_with_identity2 = identity({ + def, + named, +}); + +const double_nested = { + nested: { + def, + named, + }, +}; + +export const double_nested2 = { + nested: { + def, + named, + }, +}; + +const double_nested_with_identity = { + nested: identity({ + def, + named, + }), +}; + +export const double_nested_with_identity2 = { + nested: identity({ + def, + named, + }), +}; + +export { + nested, + nested_with_identity, + double_nested, + double_nested_with_identity, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/simple/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/simple/input/index.js new file mode 100644 index 0000000000000..bf9b0f60b565a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/basic/simple/input/index.js @@ -0,0 +1,19 @@ +it("runs sync tests", () => { + expect(true).toBe(true); +}); + +it("runs async tests", async () => { + await Promise.resolve(); + expect(true).toBe(true); +}); + +describe("nested describe", () => { + it("runs sync tests", () => { + expect(true).toBe(true); + }); + + it("runs async tests", async () => { + await Promise.resolve(); + expect(true).toBe(true); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/a.js new file mode 100644 index 0000000000000..1947ccd43bcd9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/a.js @@ -0,0 +1,5 @@ +export function test() { + return import("./b.js"); +} + +export const ok = "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/b.js new file mode 100644 index 0000000000000..66b173f27c361 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/b.js @@ -0,0 +1 @@ +export const ok = "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/index.js new file mode 100644 index 0000000000000..b3e337767052a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-already-available/input/index.js @@ -0,0 +1,9 @@ +import { ok as bOk } from "./b"; + +it("should generate correct code on dynamic import of already available module", async () => { + expect(bOk).toBe("b"); + const a1 = await import("./a.js"); + expect(a1.ok).toBe("a"); + const b1 = await a1.test(); + expect(b1.ok).toBe("b"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/a.js new file mode 100644 index 0000000000000..1947ccd43bcd9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/a.js @@ -0,0 +1,5 @@ +export function test() { + return import("./b.js"); +} + +export const ok = "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/b.js new file mode 100644 index 0000000000000..3dc5122475c78 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/b.js @@ -0,0 +1,5 @@ +export function test() { + return import("./a.js"); +} + +export const ok = "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/index.js new file mode 100644 index 0000000000000..18fccc3d99c3e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/chunking/dynamic-import-cycle/input/index.js @@ -0,0 +1,9 @@ +it("should not crash on dynamic import cycle", async () => { + const a1 = await import("./a.js"); + expect(a1.ok).toBe("a"); + const b1 = await a1.test(); + expect(b1.ok).toBe("b"); + const a2 = await b1.test(); + expect(a2.ok).toBe("a"); + expect(a2).toBe(a1); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/code-gen/this-context-import/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/code-gen/this-context-import/input/index.js new file mode 100644 index 0000000000000..d225fdb70a981 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/code-gen/this-context-import/input/index.js @@ -0,0 +1,19 @@ +import { getThis } from "./module.js"; +import * as module from "./module.js"; + +it("should not have this context when calling a binding", () => { + expect(getThis()).toBe(undefined); +}); + +it("should have this context when calling a property of an imported module", () => { + expect(module.getThis()).toBe(module); +}); + +it("should still be possible to call the function with a different context", () => { + expect(getThis.call(module)).toBe(module); + expect(module.getThis.call(module)).toBe(module); + const obj = {}; + expect(getThis.call(obj)).toBe(obj); + expect(module.getThis.call(obj)).toBe(obj); + expect((0, module.getThis)()).toBe(undefined); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/code-gen/this-context-import/input/module.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/code-gen/this-context-import/input/module.js new file mode 100644 index 0000000000000..62bc648f04485 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/code-gen/this-context-import/input/module.js @@ -0,0 +1,3 @@ +export function getThis() { + return this; +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/b.ts b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/b.ts new file mode 100644 index 0000000000000..eeaa004ee4f30 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/b.ts @@ -0,0 +1,3 @@ +export type Test = "b" | "bb"; + +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/c.module.css b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/c.module.css new file mode 100644 index 0000000000000..19fce7392149e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/c.module.css @@ -0,0 +1,3 @@ +.class { + color: red; +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/d.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/d.js new file mode 100644 index 0000000000000..0a281018ca167 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/dir/d.js @@ -0,0 +1 @@ +module.exports = "d"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/index.js new file mode 100644 index 0000000000000..9d272d883f96b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/dynamic-requests/basic/input/index.js @@ -0,0 +1,105 @@ +import * as a from "./dir/a.js"; +import * as b from "./dir/b.ts"; + +const requireTemplate = (key) => require(`./dir/${key}`); +const requireAdd = (key) => require("./dir/" + key); +const requireConcat = (key) => require("./dir/".concat(key)); +const importTemplate = (key) => import(`./dir/${key}`); +const importTemplateSuffix = (key) => import(`./dir/${key}.js`); +const importAdd = (key) => import("./dir/" + key); +const importAddSuffix = (key) => import("./dir/" + key + ".js"); +const importConcat = (key) => import("./dir/".concat(key)); +const importConcatSuffix = (key) => import("./dir/".concat(key, ".js")); + +it("should support dynamic requests in require with template literals", () => { + expect(requireTemplate("a.js")).toBe(a); + expect(requireTemplate("b.ts")).toBe(b); + expect(requireTemplate("c.module.css")).toHaveProperty("class"); + expect(requireTemplate("d.js")).toBe("d"); +}); + +it("should support dynamic requests in require with addition", () => { + expect(requireAdd("a.js")).toBe(a); + expect(requireAdd("b.ts")).toBe(b); + expect(requireAdd("c.module.css")).toHaveProperty("class"); + expect(requireAdd("d.js")).toBe("d"); +}); + +it("should support dynamic requests in require with concatenation", () => { + expect(requireConcat("a.js")).toBe(a); + expect(requireConcat("b.ts")).toBe(b); + expect(requireConcat("c.module.css")).toHaveProperty("class"); + expect(requireConcat("d.js")).toBe("d"); +}); + +it("should support dynamic requests in import with template literals", async () => { + await expect(importTemplate("a.js")).resolves.toBe(a); + await expect(importTemplate("b.ts")).resolves.toBe(b); + await expect(importTemplate("c.module.css")).resolves.toHaveProperty("class"); + await expect(importTemplate("d.js")).resolves.toHaveProperty("default", "d"); +}); + +it("should support dynamic requests in import with template literals and suffix", async () => { + await expect(importTemplateSuffix("a")).resolves.toBe(a); + await expect(importTemplateSuffix("d")).resolves.toHaveProperty( + "default", + "d" + ); +}); + +it("should support dynamic requests in import with addition", async () => { + await expect(importAdd("a.js")).resolves.toBe(a); + await expect(importAdd("b.ts")).resolves.toBe(b); + await expect(importAdd("c.module.css")).resolves.toHaveProperty("class"); + await expect(importAdd("d.js")).resolves.toHaveProperty("default", "d"); +}); + +it("should support dynamic requests in import with concatenation", async () => { + await expect(importConcat("a.js")).resolves.toBe(a); + await expect(importConcat("b.ts")).resolves.toBe(b); + await expect(importConcat("c.module.css")).resolves.toHaveProperty("class"); + await expect(importConcat("d.js")).resolves.toHaveProperty("default", "d"); +}); + +it("should support dynamic requests in import with addition and suffix", async () => { + await expect(importAddSuffix("a")).resolves.toBe(a); + await expect(importAddSuffix("d")).resolves.toHaveProperty("default", "d"); +}); + +it("should support dynamic requests in import with concatenation and suffix", async () => { + await expect(importConcatSuffix("a")).resolves.toBe(a); + await expect(importConcatSuffix("d")).resolves.toHaveProperty("default", "d"); +}); + +it("should throw an error when requesting a non-existent file", async () => { + expect(() => requireTemplate("e.js")).toThrowError(); + expect(() => requireAdd("e.js")).toThrowError(); + expect(() => requireConcat("e.js")).toThrowError(); + await expect(importTemplate("e.js")).rejects.toThrowError(); + await expect(importAdd("e.js")).rejects.toThrowError(); + await expect(importConcat("e.js")).rejects.toThrowError(); +}); + +it("should support dynamic requests without the extension", async () => { + expect(requireTemplate("a")).toBe(a); + expect(requireAdd("a")).toBe(a); + expect(requireConcat("a")).toBe(a); + expect(requireTemplate("d")).toBe("d"); + expect(requireAdd("d")).toBe("d"); + expect(requireConcat("d")).toBe("d"); + await expect(importTemplate("a")).resolves.toBe(a); + await expect(importTemplate("d")).resolves.toHaveProperty("default", "d"); + await expect(importAdd("a")).resolves.toBe(a); + await expect(importAdd("d")).resolves.toHaveProperty("default", "d"); + await expect(importConcat("a")).resolves.toBe(a); + await expect(importConcat("d")).resolves.toHaveProperty("default", "d"); +}); + +it("should not support dynamic requests with double extension", async () => { + await expect(importTemplateSuffix("a.js")).rejects.toThrowError(); + await expect(importTemplateSuffix("d.js")).rejects.toThrowError(); + await expect(importAddSuffix("a.js")).rejects.toThrowError(); + await expect(importAddSuffix("d.js")).rejects.toThrowError(); + await expect(importConcatSuffix("a.js")).rejects.toThrowError(); + await expect(importConcatSuffix("d.js")).rejects.toThrowError(); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/minification/paren-remover/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/minification/paren-remover/input/index.js new file mode 100644 index 0000000000000..6ccacca94d8e9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/minification/paren-remover/input/index.js @@ -0,0 +1,34 @@ +function toFixed(value, maxDecimals, roundingFunction, optionals) { + var splitValue = value.toString().split("."), + minDecimals = maxDecimals - (optionals || 0), + optionalsRegExp, + power, + output; + var boundedPrecisions; + // var unused = 'xxxx'; + // Use the smallest precision value possible to avoid errors from floating point representation + if (splitValue.length === 2) { + boundedPrecisions = Math.min( + Math.max(splitValue[1].length, minDecimals), + maxDecimals + ); + } else { + boundedPrecisions = minDecimals; + } + power = Math.pow(10, boundedPrecisions); + // Multiply up by precision, round accurately, then divide and use native toFixed(): + output = (roundingFunction(value + "e+" + boundedPrecisions) / power).toFixed( + boundedPrecisions + ); + if (optionals > maxDecimals - boundedPrecisions) { + optionalsRegExp = new RegExp( + "\\.?0{1," + (optionals - (maxDecimals - boundedPrecisions)) + "}$" + ); + output = output.replace(optionalsRegExp, ""); + } + return output; +} + +it("should work", () => { + expect(toFixed(1.2345, 2, Math.round, 1)).toBe("1.23"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/index.js new file mode 100644 index 0000000000000..fc5bb93e255c1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/index.js @@ -0,0 +1,27 @@ +import { file1, file2, file3, file4, file5 } from "package/dir"; + +it("should follow the alias field for a resolved file", () => { + expect(file1).toBe("file1"); +}); + +it("should follow the alias field for a raw request", () => { + expect(file2).toBe("file2"); +}); + +it("should follow the alias field for a resolved file without ./ prefix", () => { + expect(file3).toBe("file3"); +}); + +it("should follow the alias field for a module request", () => { + expect(file4).toBe("file4"); +}); + +it("should follow the alias field for a module request with subpath", () => { + expect(file5).toBe("file5"); +}); + +import { otherPackage, otherPackageSubPath } from "package/dir"; +it("should not cycle when following the alias field", () => { + expect(otherPackage).toBe("other-package/index"); + expect(otherPackageSubPath).toBe("other-package/sub-path"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/other-package/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/other-package/index.js new file mode 100644 index 0000000000000..b664d20608df4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/other-package/index.js @@ -0,0 +1 @@ +export default "other-package/index" diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/other-package/sub-path.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/other-package/sub-path.js new file mode 100644 index 0000000000000..8a5d603cf5261 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/other-package/sub-path.js @@ -0,0 +1 @@ +export default "other-package/sub-path" diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/file1.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/file1.js new file mode 100644 index 0000000000000..b34734115cff1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/file1.js @@ -0,0 +1 @@ +export default "wrong-file1"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/file3.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/file3.js new file mode 100644 index 0000000000000..25bf4aae53027 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/file3.js @@ -0,0 +1 @@ +export default "wrong-file3"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/index.js new file mode 100644 index 0000000000000..cfa475ffbf2d2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/dir/index.js @@ -0,0 +1,7 @@ +export { default as file1 } from "./file1"; +export { default as file2 } from "./file2"; +export { default as file3 } from "./file3"; +export { default as file4 } from "file4"; +export { default as file5 } from "file4/file5"; +export { default as otherPackage } from "other-package"; +export { default as otherPackageSubPath } from "other-package/sub-path"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/package.json new file mode 100644 index 0000000000000..2b776acbf5f71 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/package.json @@ -0,0 +1,10 @@ +{ + "browser": { + "./dir/file1.js": "./replaced/file1.js", + "./dir/file2": "./replaced/file2", + "dir/file3.js": "./replaced/file3.js", + "file4": "./replaced/file4", + "file4/file5": "./replaced/file5", + "other-package": "other-package" + } +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file1.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file1.js new file mode 100644 index 0000000000000..c5eefcc01645d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file1.js @@ -0,0 +1 @@ +export default "file1"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file2.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file2.js new file mode 100644 index 0000000000000..ee078d0bca492 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file2.js @@ -0,0 +1 @@ +export default "file2"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file3.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file3.js new file mode 100644 index 0000000000000..c1480281a6f50 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file3.js @@ -0,0 +1 @@ +export default "file3"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file4.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file4.js new file mode 100644 index 0000000000000..e44040091752e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file4.js @@ -0,0 +1 @@ +export default "file4"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file5.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file5.js new file mode 100644 index 0000000000000..147acc7e5e5ca --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/alias-field/input/node_modules/package/replaced/file5.js @@ -0,0 +1 @@ +export default "file5"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/client#component.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/client#component.js new file mode 100644 index 0000000000000..25e4ca52d3594 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/client#component.js @@ -0,0 +1 @@ +export default "client#component"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/index.js new file mode 100644 index 0000000000000..796114b1265f0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/index.js @@ -0,0 +1,20 @@ +import client from "./client#component"; +import nofrag from "./nofrag#frag"; +import client2 from "./client#component.js"; +import nofrag2 from "./nofrag.js#frag"; + +it("should resolve to a file with a fragment", () => { + expect(client).toBe("client#component"); +}); + +it("should resolve to a file without a fragment", () => { + expect(nofrag).toBe("nofrag"); +}); + +it("should resolve to a file with a fragment and an extension", () => { + expect(client2).toBe("client#component"); +}); + +it("should resolve to a file without a fragment but with an extension", () => { + expect(nofrag2).toBe("nofrag"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/nofrag.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/nofrag.js new file mode 100644 index 0000000000000..eae04e33cd162 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/fragment/input/nofrag.js @@ -0,0 +1 @@ +export default "nofrag"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/exports.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/exports.js new file mode 100644 index 0000000000000..c46e5230c9b61 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/exports.js @@ -0,0 +1 @@ +export default "exports"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/index.js new file mode 100644 index 0000000000000..95ec6bb65ed73 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/index.js @@ -0,0 +1 @@ +export default "index"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/package.json new file mode 100644 index 0000000000000..f20cecb2cd6df --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder1/package.json @@ -0,0 +1,3 @@ +{ + "exports": "./exports.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/exports.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/exports.js new file mode 100644 index 0000000000000..c46e5230c9b61 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/exports.js @@ -0,0 +1 @@ +export default "exports"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/index.js new file mode 100644 index 0000000000000..95ec6bb65ed73 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/index.js @@ -0,0 +1 @@ +export default "index"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/main.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/main.js new file mode 100644 index 0000000000000..b515913d5d902 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/main.js @@ -0,0 +1 @@ +export default "main"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/package.json new file mode 100644 index 0000000000000..78554da32a4b0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/folder2/package.json @@ -0,0 +1,4 @@ +{ + "main": "./main.js", + "exports": "./exports.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/index.js new file mode 100644 index 0000000000000..38282b287b206 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-exports-field-in-folder/input/index.js @@ -0,0 +1,11 @@ +import folder1 from "./folder1"; +it("should not apply the exports field in a folder", () => { + expect(folder1).toBe("index"); + expect(require("./folder1")).toHaveProperty("default", "index"); +}); + +import folder2 from "./folder2"; +it("should not apply the exports field in a folder but the main field", () => { + expect(folder2).toBe("main"); + expect(require("./folder2")).toHaveProperty("default", "main"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/dir/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/dir/index.js new file mode 100644 index 0000000000000..829a0edcded95 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/dir/index.js @@ -0,0 +1 @@ +import "the-package"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/dir/node_modules/the-package/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/dir/node_modules/the-package/index.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/index.js new file mode 100644 index 0000000000000..0715720a346c3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/index.js @@ -0,0 +1,74 @@ +import "./dir"; +import "package-with-exports/entry1"; + +it("should not bundle the root level package", () => { + const modules = Object.keys(__turbopack_modules__); + expect(modules).toContainEqual( + expect.stringMatching(/input\/dir\/node_modules\/the-package\/index/) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/the-package\/index/) + ); +}); + +it("should not bundle the other exports conditions", () => { + require("package-with-exports/entry2"); + const modules = Object.keys(__turbopack_modules__); + expect(modules).toContainEqual( + expect.stringMatching(/input\/node_modules\/package-with-exports\/a/) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/package-with-exports\/index/) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/package-with-exports\/b/) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/package-with-exports\/c/) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/package-with-exports\/entry1/) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/package-with-exports\/entry2/) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/package-with-exports\/main/) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/package-with-exports\/module/) + ); +}); + +it("should not bundle the other alternatives", () => { + require("package-without-exports/entry3"); + const modules = Object.keys(__turbopack_modules__); + expect(modules).toContainEqual( + expect.stringMatching( + /input\/node_modules\/package-without-exports\/entry3\.js/ + ) + ); + expect(modules).not.toContainEqual( + expect.stringMatching( + /input\/node_modules\/package-without-exports\/entry3\/index/ + ) + ); +}); + +it("should not bundle the other alternatives", () => { + require("package-without-exports"); + const modules = Object.keys(__turbopack_modules__); + expect(modules).toContainEqual( + expect.stringMatching( + /input\/node_modules\/package-without-exports\/module\.js/ + ) + ); + expect(modules).not.toContainEqual( + expect.stringMatching( + /input\/node_modules\/package-without-exports\/main\.js/ + ) + ); + expect(modules).not.toContainEqual( + expect.stringMatching(/input\/node_modules\/package-without-exports\/index/) + ); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/a.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/b.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/c.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/c.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/entry1.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/entry1.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/entry2-replaced.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/entry2-replaced.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/entry2/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/entry2/package.json new file mode 100644 index 0000000000000..5b7dd81972297 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/entry2/package.json @@ -0,0 +1,3 @@ +{ + "main": "../entry2-replaced.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/index.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/main.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/main.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/module.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/module.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/package.json new file mode 100644 index 0000000000000..c048d52fc65b0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-with-exports/package.json @@ -0,0 +1,16 @@ +{ + "module": "module.js", + "main": "main.js", + "exports": { + "./entry1": { + "import": "./a.js", + "require": "./b.js", + "default": "./c.js" + }, + "./entry2": { + "import": "./b.js", + "require": "./a.js", + "default": "./c.js" + } + } +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/entry3.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/entry3.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/entry3/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/entry3/index.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/index.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/main.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/main.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/module.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/module.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/package.json new file mode 100644 index 0000000000000..56294c89b9578 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/package-without-exports/package.json @@ -0,0 +1,4 @@ +{ + "module": "module.js", + "main": "main.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/the-package/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/no-same-key-alternatives/input/node_modules/the-package/index.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/require-resolve/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/require-resolve/input/index.js new file mode 100644 index 0000000000000..fa0ce32299eea --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/require-resolve/input/index.js @@ -0,0 +1,11 @@ +it("should support require.resolve", () => { + expect(require.resolve("./resolved.js")).toBe( + "[project]/crates/turbopack-tests/tests/execution/turbopack/resolving/require-resolve/input/resolved.js [test] (ecmascript)" + ); +}); + +it("should support require.resolve with extensions", () => { + expect(require.resolve("./resolved")).toBe( + "[project]/crates/turbopack-tests/tests/execution/turbopack/resolving/require-resolve/input/resolved.js [test] (ecmascript)" + ); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/require-resolve/input/resolved.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/require-resolve/input/resolved.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/index.js new file mode 100644 index 0000000000000..9a1ab2634973a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/index.js @@ -0,0 +1,5 @@ +import foo from "foo"; + +it("should resolve modules in the baseUrl", () => { + expect(foo).toBe("foo"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/src/foo.ts b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/src/foo.ts new file mode 100644 index 0000000000000..60c6c8d8b04f9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/src/foo.ts @@ -0,0 +1 @@ +export default "foo"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/tsconfig.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/tsconfig.json new file mode 100644 index 0000000000000..738e8a46502e1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-baseurl/input/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "baseUrl": "./src" + } +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/index.js new file mode 100644 index 0000000000000..d821a3aaa6c2d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/index.js @@ -0,0 +1,24 @@ +import foo from "@foo"; +import fooBar from "@foo/bar"; +import bazFoo from "@baz/foo"; +import srcBazFoo from "@src/baz/foo"; + +it("should resolve an alias to a local file", () => { + expect(foo).toBe("foo"); + expect(require("@foo")).toHaveProperty("default", "foo"); +}); + +it("should fallback from an alias", () => { + expect(fooBar).toBe("@foo/bar"); + expect(require("@foo/bar")).toHaveProperty("default", "@foo/bar"); +}); + +it("should prefer alias over normal resolving", () => { + expect(bazFoo).toBe("baz/foo"); + expect(require("@baz/foo")).toHaveProperty("default", "baz/foo"); +}); + +it("should resolve the alternative alias value", () => { + expect(srcBazFoo).toBe("baz/foo"); + expect(require("@src/baz/foo")).toHaveProperty("default", "baz/foo"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@baz/foo/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@baz/foo/index.js new file mode 100644 index 0000000000000..742ba7f31e70d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@baz/foo/index.js @@ -0,0 +1 @@ +export default "@baz/foo" diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@baz/foo/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@baz/foo/package.json new file mode 100644 index 0000000000000..1b902589ae1ed --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@baz/foo/package.json @@ -0,0 +1,3 @@ +{ + "name": "@baz/foo" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@foo/bar/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@foo/bar/index.js new file mode 100644 index 0000000000000..1fafc47e5ad4e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@foo/bar/index.js @@ -0,0 +1 @@ +export default "@foo/bar" diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@foo/bar/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@foo/bar/package.json new file mode 100644 index 0000000000000..a9b4c53bd6e25 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/node_modules/@foo/bar/package.json @@ -0,0 +1,3 @@ +{ + "name": "@foo/bar" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/src/baz/foo.ts b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/src/baz/foo.ts new file mode 100644 index 0000000000000..51d654174df28 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/src/baz/foo.ts @@ -0,0 +1 @@ +export default "baz/foo"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/src/foo.ts b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/src/foo.ts new file mode 100644 index 0000000000000..60c6c8d8b04f9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/src/foo.ts @@ -0,0 +1 @@ +export default "foo"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/tsconfig.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/tsconfig.json new file mode 100644 index 0000000000000..ba498258507e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/resolving/tsconfig-fallback/input/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "paths": { + "@*": ["./src/*", "./*"] + } + } +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/index.js new file mode 100644 index 0000000000000..5c0a0cb8a2b33 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/index.js @@ -0,0 +1,147 @@ +import { + a as a1, + b as b1, + c as c1, + d as d1, + e as e1, + local as local1, + default as default1, + def as def1, +} from "package-named"; +it("should optimize named reexports from side effect free module", () => { + expect(a1).toBe("a"); + expect(b1).toBe("b"); + expect(c1).toBe("x"); + expect(d1).toBe("y"); + expect(e1).toBe("x"); + expect(local1).toBe("local"); + expect(default1).toBe("local-default"); + expect(def1).toBe("default"); +}); + +import { a as a2, b as b2, local as local2 } from "package-star"; +it("should optimize star reexports from side effect free module", () => { + expect(a2).toBe("a"); + expect(b2).toBe("b"); + expect(local2).toBe("local"); +}); + +import { + a as a3, + b as b3, + local as local3, + outer as outer3, +} from "package-reexport"; +it("should optimize a used star reexport from module with side effects", () => { + expect(a3).toBe("a"); + expect(b3).toBe("b"); + expect(local3).toBe("local"); + expect(outer3).toBe("outer"); +}); + +import { outer as outer4 } from "package-reexport-unused"; +it("should optimize a unused star reexport from module with side effects", () => { + expect(outer4).toBe("outer"); +}); + +import { c as c5 } from "package-full"; +it("should allow to import the whole module and pick without duplicating the module", () => { + expect(c5).toEqual({ c: 1 }); + const fullModule = require("package-full"); + expect(fullModule.a).toEqual("a"); + expect(fullModule.b).toEqual("b"); + expect(fullModule.c).toEqual({ c: 1 }); + expect(fullModule.local).toEqual("local"); + expect(fullModule.default).toEqual("local-default"); + expect(fullModule.def).toEqual("default"); + + // Check for identity + expect(fullModule.c).toBe(c5); +}); + +import { a as a6 } from "package-reexport-side-effect"; +import { effects as effects6 } from "package-reexport-side-effect/check-side-effect"; +it("should run side effects of a reexporting module with side effects", () => { + expect(a6).toBe("a"); + expect(effects6).toEqual(["side-effect.js", "side-effect2.js", "index.js"]); +}); + +import { a as a7 } from "package-reexport-tla-side-effect"; +import { effects as effects7 } from "package-reexport-tla-side-effect/check-side-effect"; +it("should run side effects of a reexporting module with side effects (async modules)", () => { + expect(a7).toBe("a"); + expect(effects7).toEqual(["side-effect.js", "side-effect2.js", "index.js"]); +}); + +import { effects as effects8 } from "package-require-side-effect/check-side-effect"; +it("should run side effects of a reexporting module with side effects (async modules)", () => { + expect(effects8).toEqual([]); + require("package-require-side-effect"); + expect(effects8).toEqual(["side-effect.js", "side-effect2.js", "index.js"]); +}); + +import { a as a9, b as b9 } from "package-partial"; +import { effects } from "package-partial/effect"; +it("should handle globs in sideEffects field", () => { + expect(a9).toBe("a"); + expect(b9).toBe("b"); + expect(effects).toEqual(["file.side.js", "dir/file.js"]); +}); + +it("should generate a correct facade from async modules", async () => { + expect(await import("tla/local")).toEqual( + expect.objectContaining({ + tla: "tla", + reexported: "reexported", + reexported2: "reexported", + }) + ); + expect(await import("tla/reexport")).toEqual( + expect.objectContaining({ + local: "local", + tlaReexported: "tla-reexported", + tlaReexported2: "tla-reexported", + }) + ); + expect(await import("tla/both")).toEqual( + expect.objectContaining({ + tla: "tla", + tlaReexported: "tla-reexported", + tlaReexported2: "tla-reexported", + }) + ); +}); + +import * as tlaLocal from "tla/local"; +import * as tlaReexport from "tla/reexport"; +import * as tlaBoth from "tla/both"; +it("should generate a correct namespace object from async modules", async () => { + expect(tlaLocal).toEqual( + expect.objectContaining({ + tla: "tla", + reexported: "reexported", + reexported2: "reexported", + }) + ); + expect(tlaReexport).toEqual( + expect.objectContaining({ + local: "local", + tlaReexported: "tla-reexported", + tlaReexported2: "tla-reexported", + }) + ); + expect(tlaBoth).toEqual( + expect.objectContaining({ + tla: "tla", + tlaReexported: "tla-reexported", + tlaReexported2: "tla-reexported", + }) + ); +}); + +import { tlaReexported2 as tlaReexported } from "tla/reexport"; +import { tlaReexported2 as tlaReexportedBoth } from "tla/both"; +it("should generate correct renaming facades from async modules", async () => { + expect(tlaReexported).toBe("tla-reexported"); + expect(tlaReexportedBoth).toBe("tla-reexported"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/a.js new file mode 100644 index 0000000000000..9233cce2f0e18 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/a.js @@ -0,0 +1 @@ +export const a = "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/b.js new file mode 100644 index 0000000000000..59d1689930e55 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/b.js @@ -0,0 +1 @@ +export const b = "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/c.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/c.js new file mode 100644 index 0000000000000..581a93664a7dd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/c.js @@ -0,0 +1 @@ +export const c = { c: 1 }; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/default.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/default.js new file mode 100644 index 0000000000000..17e060e96f9f2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/default.js @@ -0,0 +1 @@ +export default "default"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/index.js new file mode 100644 index 0000000000000..6024702385f75 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/index.js @@ -0,0 +1,7 @@ +export { a } from "./a.js"; +export * from "./b.js"; +export * from "./c.js"; +export { x as d } from "./x.js"; +export { default as def } from "./default.js"; +export const local = "local"; +export default "local-default"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/package.json new file mode 100644 index 0000000000000..a43829151e142 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/x.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/x.js new file mode 100644 index 0000000000000..59d1689930e55 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-full/x.js @@ -0,0 +1 @@ +export const b = "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/a.js new file mode 100644 index 0000000000000..9233cce2f0e18 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/a.js @@ -0,0 +1 @@ +export const a = "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/b.js new file mode 100644 index 0000000000000..79044b663db8b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/b.js @@ -0,0 +1,2 @@ +const myB = "b"; +export { myB as b }; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/default.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/default.js new file mode 100644 index 0000000000000..17e060e96f9f2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/default.js @@ -0,0 +1 @@ +export default "default"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/index.js new file mode 100644 index 0000000000000..b0f6fbe6d4214 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/index.js @@ -0,0 +1,14 @@ +export { notCompiled } from "./not-compiled.js"; +export { notExisting } from "./not-existing.js"; +export { notExecuted } from "./not-executed.js"; +export * from "./not-compiled.js"; +export * from "./not-existing.js"; +export * from "./not-executed.js"; +export { a } from "./a.js"; +export { b } from "./b.js"; +export { x as c } from "./x.js"; +export { y as d } from "./y.js"; +export { x as e } from "./y.js"; +export { default as def } from "./default.js"; +export const local = "local"; +export default "local-default"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/not-compiled.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/not-compiled.js new file mode 100644 index 0000000000000..850b713f4687f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/not-compiled.js @@ -0,0 +1 @@ +))) diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/not-executed.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/not-executed.js new file mode 100644 index 0000000000000..d7651bb289d5d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/not-executed.js @@ -0,0 +1 @@ +throw new Error("Module should not be executed"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/package.json new file mode 100644 index 0000000000000..a43829151e142 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/x.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/x.js new file mode 100644 index 0000000000000..985ed7b9d82e5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/x.js @@ -0,0 +1 @@ +export const x = "x"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/y.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/y.js new file mode 100644 index 0000000000000..7e92113032c4c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-named/y.js @@ -0,0 +1,3 @@ +export * from "./x.js"; + +export const y = "y"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/a.js new file mode 100644 index 0000000000000..9233cce2f0e18 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/a.js @@ -0,0 +1 @@ +export const a = "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/b.js new file mode 100644 index 0000000000000..79044b663db8b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/b.js @@ -0,0 +1,2 @@ +const myB = "b"; +export { myB as b }; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/dir/file.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/dir/file.js new file mode 100644 index 0000000000000..8372f1fc4ec1b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/dir/file.js @@ -0,0 +1,5 @@ +import { effects } from "../effect.js"; + +export const star = "star"; + +effects.push("dir/file.js"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/effect.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/effect.js new file mode 100644 index 0000000000000..8e4117f5864ae --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/effect.js @@ -0,0 +1 @@ +export const effects = []; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/file.side.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/file.side.js new file mode 100644 index 0000000000000..c34380771ada3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/file.side.js @@ -0,0 +1,5 @@ +import { effects } from "./effect.js"; + +export const named = "named"; + +effects.push("file.side.js"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/index.js new file mode 100644 index 0000000000000..cfeb3f198b75e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/index.js @@ -0,0 +1,10 @@ +export { notCompiled } from "./not-compiled.js"; +// export { notExisting } from "./not-existing.js"; +export { notExecuted } from "./not-executed.js"; +export * from "./not-compiled.js"; +// export * from "./not-existing.js"; +export * from "./not-executed.js"; +export * from "./file.side.js"; +export { named } from "./dir/file.js"; +export { a } from "./a.js"; +export { b } from "./b.js"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/not-compiled.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/not-compiled.js new file mode 100644 index 0000000000000..850b713f4687f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/not-compiled.js @@ -0,0 +1 @@ +))) diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/not-executed.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/not-executed.js new file mode 100644 index 0000000000000..d7651bb289d5d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/not-executed.js @@ -0,0 +1 @@ +throw new Error("Module should not be executed"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/package.json new file mode 100644 index 0000000000000..d81331b00423b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-partial/package.json @@ -0,0 +1,7 @@ +{ + "sideEffects": [ + "./index.js", + "*.side.js", + "./dir/*.js" + ] +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/check-side-effect.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/check-side-effect.js new file mode 100644 index 0000000000000..3d5e15fb40643 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/check-side-effect.js @@ -0,0 +1,5 @@ +export const effects = []; + +export function effect(name) { + effects.push(name); +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/index.js new file mode 100644 index 0000000000000..83037990e5ceb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/index.js @@ -0,0 +1,8 @@ +export * from "package-star"; +export * from "./side-effect.js"; +import "./side-effect2.js"; +export const outer = "outer"; + +import { effect } from "./check-side-effect.js"; + +effect("index.js"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/package.json new file mode 100644 index 0000000000000..3802144dedbda --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": true +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/side-effect.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/side-effect.js new file mode 100644 index 0000000000000..dfb0f889df4ff --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/side-effect.js @@ -0,0 +1,5 @@ +import { effect } from "./check-side-effect.js"; + +effect("side-effect.js"); + +export const sideEffectExport = "side-effect-export"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/side-effect2.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/side-effect2.js new file mode 100644 index 0000000000000..8ab8ff964785f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-side-effect/side-effect2.js @@ -0,0 +1,4 @@ +import { effect } from "./check-side-effect.js"; + +effect("side-effect2.js"); + diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/check-side-effect.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/check-side-effect.js new file mode 100644 index 0000000000000..de355e58250b1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/check-side-effect.js @@ -0,0 +1,7 @@ +await Promise.resolve(); + +export const effects = []; + +export function effect(name) { + effects.push(name); +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/index.js new file mode 100644 index 0000000000000..83037990e5ceb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/index.js @@ -0,0 +1,8 @@ +export * from "package-star"; +export * from "./side-effect.js"; +import "./side-effect2.js"; +export const outer = "outer"; + +import { effect } from "./check-side-effect.js"; + +effect("index.js"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/package.json new file mode 100644 index 0000000000000..3802144dedbda --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": true +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/side-effect.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/side-effect.js new file mode 100644 index 0000000000000..dfb0f889df4ff --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/side-effect.js @@ -0,0 +1,5 @@ +import { effect } from "./check-side-effect.js"; + +effect("side-effect.js"); + +export const sideEffectExport = "side-effect-export"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/side-effect2.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/side-effect2.js new file mode 100644 index 0000000000000..8ab8ff964785f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-tla-side-effect/side-effect2.js @@ -0,0 +1,4 @@ +import { effect } from "./check-side-effect.js"; + +effect("side-effect2.js"); + diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-unused/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-unused/index.js new file mode 100644 index 0000000000000..f4a21fd5bd2b9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-unused/index.js @@ -0,0 +1,3 @@ +export * from "package-star/not-compiled.js"; +export const outer = "outer"; + diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-unused/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-unused/package.json new file mode 100644 index 0000000000000..3802144dedbda --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport-unused/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": true +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport/index.js new file mode 100644 index 0000000000000..3dda3e6fd6c3f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport/index.js @@ -0,0 +1,3 @@ +export * from "package-star"; +export const outer = "outer"; + diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport/package.json new file mode 100644 index 0000000000000..3802144dedbda --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-reexport/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": true +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/check-side-effect.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/check-side-effect.js new file mode 100644 index 0000000000000..3d5e15fb40643 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/check-side-effect.js @@ -0,0 +1,5 @@ +export const effects = []; + +export function effect(name) { + effects.push(name); +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/index.js new file mode 100644 index 0000000000000..538279e54cc2e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/index.js @@ -0,0 +1,7 @@ +export * from "./side-effect.js"; +import "./side-effect2.js"; +export const local = "local"; + +import { effect } from "./check-side-effect.js"; + +effect("index.js"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/package.json new file mode 100644 index 0000000000000..3802144dedbda --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": true +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/side-effect.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/side-effect.js new file mode 100644 index 0000000000000..dfb0f889df4ff --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/side-effect.js @@ -0,0 +1,5 @@ +import { effect } from "./check-side-effect.js"; + +effect("side-effect.js"); + +export const sideEffectExport = "side-effect-export"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/side-effect2.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/side-effect2.js new file mode 100644 index 0000000000000..8ab8ff964785f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-require-side-effect/side-effect2.js @@ -0,0 +1,4 @@ +import { effect } from "./check-side-effect.js"; + +effect("side-effect2.js"); + diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/a.js new file mode 100644 index 0000000000000..9233cce2f0e18 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/a.js @@ -0,0 +1 @@ +export const a = "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/b.js new file mode 100644 index 0000000000000..59d1689930e55 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/b.js @@ -0,0 +1 @@ +export const b = "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/index.js new file mode 100644 index 0000000000000..ee0717661118d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/index.js @@ -0,0 +1,8 @@ +export { notCompiled } from "./not-compiled.js"; +export { notExisting } from "./not-existing.js"; +export { notExecuted } from "./not-executed.js"; +export * from "./not-executed.js"; +export * from "./a.js"; +export * from "./b.js"; +export const local = "local"; + diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/not-compiled.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/not-compiled.js new file mode 100644 index 0000000000000..850b713f4687f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/not-compiled.js @@ -0,0 +1 @@ +))) diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/not-executed.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/not-executed.js new file mode 100644 index 0000000000000..d7651bb289d5d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/not-executed.js @@ -0,0 +1 @@ +throw new Error("Module should not be executed"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/package.json new file mode 100644 index 0000000000000..a43829151e142 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/package-star/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/both.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/both.js new file mode 100644 index 0000000000000..3b6be057170ea --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/both.js @@ -0,0 +1,5 @@ +await 1; + +export { tlaReexported } from "./tla-reexported.js"; +export { tlaReexported as tlaReexported2 } from "./tla-reexported.js"; +export const tla = "tla"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/local.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/local.js new file mode 100644 index 0000000000000..30394b75dfa68 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/local.js @@ -0,0 +1,5 @@ +await 1; + +export { reexported } from "./reexported.js"; +export { reexported as reexported2 } from "./reexported.js"; +export const tla = "tla"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/package.json new file mode 100644 index 0000000000000..a43829151e142 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/reexport.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/reexport.js new file mode 100644 index 0000000000000..61ddf718c70ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/reexport.js @@ -0,0 +1,3 @@ +export { tlaReexported } from "./tla-reexported.js"; +export { tlaReexported as tlaReexported2 } from "./tla-reexported.js"; +export const local = "local"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/reexported.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/reexported.js new file mode 100644 index 0000000000000..8f8db5be12d6b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/reexported.js @@ -0,0 +1 @@ +export const reexported = "reexported"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/tla-reexported.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/tla-reexported.js new file mode 100644 index 0000000000000..6519255662b7b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/input/node_modules/tla/tla-reexported.js @@ -0,0 +1,3 @@ +await 1; + +export const tlaReexported = "tla-reexported"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/options.json new file mode 100644 index 0000000000000..af13697f09f93 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/basic/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "reexports-only" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/input/index.js new file mode 100644 index 0000000000000..30838b215a56e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/input/index.js @@ -0,0 +1,21 @@ +import * as NS1 from "mui-material/generateUtilityClass"; +import * as NS2 from "mui-utils"; +import * as NS3 from "mui-utils/generateUtilityClass"; + +it("should import renamed exports correctly", () => { + const ns = Object(NS1); + expect(typeof ns.default).toBe("function"); + expect(ns.default()).toBe("ok"); +}); + +it("should import renamed exports correctly", () => { + const ns = Object(NS2); + expect(typeof ns.unstable_generateUtilityClass).toBe("function"); + expect(ns.unstable_generateUtilityClass()).toBe("ok"); +}); + +it("should import renamed exports correctly", () => { + const ns = Object(NS3); + expect(typeof ns.default).toBe("function"); + expect(ns.default()).toBe("ok"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-material/generateUtilityClass/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-material/generateUtilityClass/index.js new file mode 100644 index 0000000000000..c7aa9189dbc32 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-material/generateUtilityClass/index.js @@ -0,0 +1 @@ +export { unstable_generateUtilityClass as default } from 'mui-utils'; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-material/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-material/package.json new file mode 100644 index 0000000000000..a43829151e142 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-material/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/generateUtilityClass/generateUtilityClass.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/generateUtilityClass/generateUtilityClass.js new file mode 100644 index 0000000000000..119b67cdc6680 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/generateUtilityClass/generateUtilityClass.js @@ -0,0 +1,3 @@ +export default function generateUtilityClass() { + return "ok"; +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/generateUtilityClass/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/generateUtilityClass/index.js new file mode 100644 index 0000000000000..88c77abc8d316 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/generateUtilityClass/index.js @@ -0,0 +1 @@ +export { default } from './generateUtilityClass'; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/index.js new file mode 100644 index 0000000000000..c6b784357bb4d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/index.js @@ -0,0 +1,3 @@ +export { default as unstable_generateUtilityClass } from './generateUtilityClass'; +export * from './generateUtilityClass'; +export { default } from "./not-correct.js" diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/not-correct.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/not-correct.js new file mode 100644 index 0000000000000..9960155767078 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/not-correct.js @@ -0,0 +1,3 @@ +export default function() { + return "fail"; +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/package.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/package.json new file mode 100644 index 0000000000000..a43829151e142 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/node_modules/mui-utils/package.json @@ -0,0 +1,3 @@ +{ + "sideEffects": false +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/options.json new file mode 100644 index 0000000000000..af13697f09f93 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/mui-utils/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "reexports-only" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/input/esm.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/input/esm.js new file mode 100644 index 0000000000000..9ff8c3a18aa5a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/input/esm.js @@ -0,0 +1,6 @@ +import * as self from "./esm"; +export * as self from "./esm"; + +export const getSelf = function getSelf() { + return self; +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/input/index.js new file mode 100644 index 0000000000000..7ebea6326beb5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/input/index.js @@ -0,0 +1,11 @@ +import { getSelf, self } from "./esm"; +import * as esm from "./esm"; +const requiredEsm = require("./esm"); + +it("should have the same identity on all namespace objects", async () => { + expect(getSelf()).toBe(esm); + expect(self).toBe(esm); + expect(requiredEsm).toBe(esm); + const importedEsm = await import("./esm"); + expect(importedEsm).toBe(esm); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/options.json new file mode 100644 index 0000000000000..af13697f09f93 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/side-effects-optimization/namespace-object-identity/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "reexports-only" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js new file mode 100644 index 0000000000000..b2a8a3837c2dc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/input/index.js @@ -0,0 +1 @@ +import "../../../side-effects-optimization/basic/input/index.js"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/.basic/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/cjs.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/cjs.js new file mode 100644 index 0000000000000..f745c705c66bd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/cjs.js @@ -0,0 +1,10 @@ +const state = {}; + +module.exports = { + getCjsState: function getCjsState(e) { + return state; + }, + getCjsState2: function getCjsState2(e) { + return state; + }, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/esm.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/esm.js new file mode 100644 index 0000000000000..c1befcf470b56 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/esm.js @@ -0,0 +1,9 @@ +const state = {}; + +export const getState = function getState(e) { + return state; +}; + +export const getState2 = function getState2(e) { + return state; +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/index.js new file mode 100644 index 0000000000000..34edc31f9f974 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/input/index.js @@ -0,0 +1,10 @@ +import { getCjsState, getCjsState2 } from "./cjs"; +import { getState, getState2 } from "./esm"; + +it("should not duplicate cjs modules", () => { + expect(getCjsState()).toBe(getCjsState2()); +}); + +it("should not duplicate ES modules", () => { + expect(getState()).toBe(getState2()); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/duplicate-modules/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/mui-utils/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/mui-utils/input/index.js new file mode 100644 index 0000000000000..d1ec2d616cfd1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/mui-utils/input/index.js @@ -0,0 +1 @@ +import "../../../side-effects-optimization/mui-utils/input/index.js"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/mui-utils/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/mui-utils/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/mui-utils/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/input/esm.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/input/esm.js new file mode 100644 index 0000000000000..e5072a48b7c38 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/input/esm.js @@ -0,0 +1,5 @@ +export const state = {}; + +export const getState = function getState(e) { + return state; +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/input/index.js new file mode 100644 index 0000000000000..2518ef44bc1ba --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/input/index.js @@ -0,0 +1,12 @@ +import { getState, state } from "./esm"; +import * as esm from "./esm"; + +it("should not allow to modify exports", () => { + const initialState = getState(); + expect(getState()).toBe(state); + expect(() => (esm.state = { not: "allowed" })).toThrow(); + expect(() => (esm.newExport = { not: "allowed" })).toThrow(); + expect(getState()).toBe(initialState); + expect(state).toBe(initialState); + expect(esm.state).toBe(initialState); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/no-write-access/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/a.js new file mode 100644 index 0000000000000..fd18d3bf7d373 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/a.js @@ -0,0 +1,3 @@ +import { a } from "./module"; + +export default a; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/b.js new file mode 100644 index 0000000000000..bd9f02cc977cd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/b.js @@ -0,0 +1,3 @@ +import { b } from "./module"; + +export default b; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/index.js new file mode 100644 index 0000000000000..9760696a5c287 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/index.js @@ -0,0 +1,14 @@ +it("should load chunk a and b with shared state", async () => { + let a = await import("./a"); + expect(a.default).toHaveProperty("a", "aaaaaaaaaaa"); + let b = await import("./b"); + expect(b.default).toHaveProperty("b", "bbbbbbbbbbb"); + let aShared = a.shared; + let bShared = b.shared; + expect(aShared).toBe(bShared); +}); + +it("should execute side effects in the correct order", async () => { + let module = await import("./module"); + expect(module.order).toEqual(["a", "b", "c"]); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/module.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/module.js new file mode 100644 index 0000000000000..74a6147c0837a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/module.js @@ -0,0 +1,9 @@ +export const order = []; + +order.push("a"); +const random = Math.random(); +const shared = { random, effect: order.push("b") }; +order.push("c"); + +export const a = { shared, a: "aaaaaaaaaaa" }; +export const b = { shared, b: "bbbbbbbbbbb" }; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/order.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/order.js new file mode 100644 index 0000000000000..0ec382c3decc1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/input/order.js @@ -0,0 +1,3 @@ +import { order } from "./module"; + +export default order; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks-shared-state/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/a.js new file mode 100644 index 0000000000000..fd18d3bf7d373 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/a.js @@ -0,0 +1,3 @@ +import { a } from "./module"; + +export default a; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/b.js new file mode 100644 index 0000000000000..bd9f02cc977cd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/b.js @@ -0,0 +1,3 @@ +import { b } from "./module"; + +export default b; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/index.js new file mode 100644 index 0000000000000..795af19e9215f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/index.js @@ -0,0 +1,7 @@ +it("should load chunk a", async () => { + await expect(import("./a")).resolves.toHaveProperty("default", "aaaaaaaaaaa"); +}); + +it("should load chunk b", async () => { + await expect(import("./b")).resolves.toHaveProperty("default", "bbbbbbbbbbb"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/module.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/module.js new file mode 100644 index 0000000000000..bb2e3b95a0e6a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/input/module.js @@ -0,0 +1,2 @@ +export const a = "aaaaaaaaaaa"; +export const b = "bbbbbbbbbbb"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/options.json b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/tree-shaking/split-chunks/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/README.md b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/README.md new file mode 100644 index 0000000000000..bcbae787a266d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/README.md @@ -0,0 +1,2 @@ +Adapted from webpack +https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/examples/wasm-complex/README.md diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/index.js new file mode 100644 index 0000000000000..6c6bb22690523 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/index.js @@ -0,0 +1,22 @@ +const magicAsyncModule = require("./magic"); + +describe("complex wasm", () => { + it("should be possible to use imported memory", async () => { + // magic.js is an async module, so we require it and await inside this function to make sure the entrypoint isn't async. + const { get, set } = await magicAsyncModule; + + set(42); + expect(get()).toEqual(42); + set(123); + expect(get()).toEqual(123); + }); + + it("should be possible to use imported functions", async () => { + // magic.js is an async module, so we require it and await inside this function to make sure the entrypoint isn't async. + const { getNumber } = await magicAsyncModule; + + // random numbers + expect(getNumber()).toBeGreaterThanOrEqual(0); + expect(getNumber()).toBeGreaterThanOrEqual(0); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic-number.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic-number.js new file mode 100644 index 0000000000000..a84dabf399d66 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic-number.js @@ -0,0 +1,7 @@ +export function getNumber() { + return 42; +} + +export function getRandomNumber() { + return Math.floor(Math.random() * 256); +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic.js new file mode 100644 index 0000000000000..233b3b85d353a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic.js @@ -0,0 +1,2 @@ +// reexporting +export * from "./magic.wat"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic.wat b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic.wat new file mode 100644 index 0000000000000..9032993cac3fa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/magic.wat @@ -0,0 +1,15 @@ +(module + (type $t0 (func (result i32))) + (type $t1 (func (param i32))) + (import "./memory.js" "memory" (memory 1)) + (import "./magic-number.js" "getRandomNumber" (func $getRandomNumber (type $t0))) + (func $get (export "get") (type $t0) (result i32) + (i32.load + (i32.const 0))) + (func $set (export "set") (type $t1) (param $p i32) + (i32.store + (i32.const 0) + (get_local $p))) + (func $getNumber (export "getNumber") (type $t0) (result i32) + (call $getRandomNumber)) +) diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/memory.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/memory.js new file mode 100644 index 0000000000000..42013f581909b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/complex/input/memory.js @@ -0,0 +1,7 @@ +async function getMemoryFromParentInWorker() { + await new Promise((r) => setTimeout(r, 200)); + // fake + return new WebAssembly.Memory({ initial: 1 }); +} + +export const memory = await getMemoryFromParentInWorker(); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/module/input/add.wasm b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/module/input/add.wasm new file mode 100644 index 0000000000000..357f72da7a0db Binary files /dev/null and b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/module/input/add.wasm differ diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/module/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/module/input/index.js new file mode 100644 index 0000000000000..f368a8a1e6b64 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/module/input/index.js @@ -0,0 +1,8 @@ +const wasm = require("./add.wasm?module"); + +it("should not instantiate wasm modules when the `module` query param is passed", async () => { + // add.wasm is loaded as an async module, so we require it and await inside this function to make sure the entrypoint isn't async. + const m = await wasm; + + expect(m.default).toBeInstanceOf(WebAssembly.Module); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/README.md b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/README.md new file mode 100644 index 0000000000000..d14828fe0a29b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/README.md @@ -0,0 +1,2 @@ +Adapted from webpack +https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/examples/wasm-simple/README.md diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/add.wasm b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/add.wasm new file mode 100644 index 0000000000000..357f72da7a0db Binary files /dev/null and b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/add.wasm differ diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/factorial.wasm b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/factorial.wasm new file mode 100644 index 0000000000000..0e0d759df538e Binary files /dev/null and b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/factorial.wasm differ diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/fibonacci.wasm b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/fibonacci.wasm new file mode 100644 index 0000000000000..cffb563bd92d4 Binary files /dev/null and b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/fibonacci.wasm differ diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/index.js new file mode 100644 index 0000000000000..35506e4347887 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/index.js @@ -0,0 +1,16 @@ +const mathAsyncModule = require("./math"); + +it("should handle wasm imports", async () => { + // math.js is an async module, so we require it and await inside this function to make sure the entrypoint isn't async. + const { + add, + factorial, + factorialJavascript, + fibonacci, + fibonacciJavascript, + } = await mathAsyncModule; + + expect(add(22, 2200)).toEqual(22 + 2200); + expect(factorial(10)).toEqual(factorialJavascript(10)); + expect(fibonacci(15)).toEqual(fibonacciJavascript(15)); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/math.js b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/math.js new file mode 100644 index 0000000000000..876d573b84a2b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/turbopack/wasm/simple/input/math.js @@ -0,0 +1,15 @@ +import { add } from "./add.wasm"; +import { factorial } from "./factorial.wasm"; +import { fibonacci } from "./fibonacci.wasm"; + +export { add, factorial, fibonacci }; + +export function factorialJavascript(i) { + if (i < 1) return 1; + return i * factorialJavascript(i - 1); +} + +export function fibonacciJavascript(i) { + if (i < 2) return 1; + return fibonacciJavascript(i - 1) + fibonacciJavascript(i - 2); +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/LICENSE-webpack b/turbopack/crates/turbopack-tests/tests/execution/webpack/LICENSE-webpack new file mode 100644 index 0000000000000..8c11fc7289b75 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/LICENSE-webpack @@ -0,0 +1,20 @@ +Copyright JS Foundation and other contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/async-unknown.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/async-unknown.js new file mode 100644 index 0000000000000..ca2eb248ac72c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/async-unknown.js @@ -0,0 +1,3 @@ +export * from "./unknown.js"; + +await 1; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/index.js new file mode 100644 index 0000000000000..a69f935bbcd6e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/index.js @@ -0,0 +1,3 @@ +it("should handle re-export from async modules correctly", async () => { + await import("./test.js"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/reexport-async-unknown.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/reexport-async-unknown.js new file mode 100644 index 0000000000000..49ae13b84c15f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/reexport-async-unknown.js @@ -0,0 +1,3 @@ +export * from "./async-unknown.js"; +export { a } from "./async-unknown.js"; +export default "default"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/test.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/test.js new file mode 100644 index 0000000000000..b237720975921 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/test.js @@ -0,0 +1,23 @@ +import * as ns from "./reexport-async-unknown.js?ns"; +import { a, b, c } from "./reexport-async-unknown.js?named"; +import value from "./reexport-async-unknown.js?default"; + +function nsObj(m) { + Object.defineProperty(m, Symbol.toStringTag, { value: "Module" }); + return m; +} + +expect(ns).toEqual( + nsObj({ + default: "default", + a: "a", + b: "b", + c: "c", + }) +); + +expect(a).toBe("a"); +expect(b).toBe("b"); +expect(c).toBe("c"); + +expect(value).toBe("default"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/unknown.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/unknown.js new file mode 100644 index 0000000000000..492bd719f4f31 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/.reexport-unknown/input/unknown.js @@ -0,0 +1,7 @@ +const o = { + a: "a", + b: "b", + c: "c", +}; + +module.exports = Object(o); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/a.js new file mode 100644 index 0000000000000..1f752aa2b5414 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/a.js @@ -0,0 +1,3 @@ +import x from "./shared"; + +export default x + " world"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/b.js new file mode 100644 index 0000000000000..1f752aa2b5414 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/b.js @@ -0,0 +1,3 @@ +import x from "./shared"; + +export default x + " world"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/index.js new file mode 100644 index 0000000000000..66e4809ec53fb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/index.js @@ -0,0 +1,4 @@ +it("should allow to import an async module twice", async () => { + const result = await require("./main"); + expect(result.default).toBe("hello world, hello world"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/main.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/main.js new file mode 100644 index 0000000000000..2bd775ed7523e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/main.js @@ -0,0 +1,4 @@ +import a from "./a"; +import b from "./b"; + +export default a + ", " + b; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/shared.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/shared.js new file mode 100644 index 0000000000000..6d4c734a406e8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/double-import/input/shared.js @@ -0,0 +1,3 @@ +await 1; +await 1; +export default "hello"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/issue-16097/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/issue-16097/input/index.js new file mode 100644 index 0000000000000..37668b723378c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/issue-16097/input/index.js @@ -0,0 +1,6 @@ +import i, { foo } from "./won't-run-tla"; + +it("should have value imported from won't-run-tla", async () => { + expect(i).toBe(42); + expect(foo).toBe(undefined); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/issue-16097/input/won't-run-tla.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/issue-16097/input/won't-run-tla.js new file mode 100644 index 0000000000000..e233080340cb5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/issue-16097/input/won't-run-tla.js @@ -0,0 +1,4 @@ +global.someNonExistentVariable && (await "test"); +const foo = global.otherSomeNonExistentVariable && (await 43); +export default 42; +export { foo }; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/a.js new file mode 100644 index 0000000000000..6c88c077d2526 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/a.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./async"; + +report("a"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/async.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/async.js new file mode 100644 index 0000000000000..55b880d32d7dd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/async.js @@ -0,0 +1,7 @@ +import { report } from "../tick"; + +report("async before"); +await 0; +report("async middle"); +await 0; +report("async after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/async2.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/async2.js new file mode 100644 index 0000000000000..a8c32bf207d93 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/async2.js @@ -0,0 +1,8 @@ +import { report } from "../tick"; +import "./d"; + +report("async2 before"); +await 0; +report("async2 middle"); +await 0; +report("async2 after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/b.js new file mode 100644 index 0000000000000..1050f1e6b0fa8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/b.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./async"; + +report("b"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/c.js new file mode 100644 index 0000000000000..27c7393a5e566 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/c.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./b"; + +report("c"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/d.js new file mode 100644 index 0000000000000..5504843a03a63 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/d.js @@ -0,0 +1,5 @@ +import { report } from "../tick"; +import "./c"; +import "./a"; + +report("d"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/e.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/e.js new file mode 100644 index 0000000000000..99a47c4012660 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/e.js @@ -0,0 +1,3 @@ +import { report } from "../tick"; + +report("e"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/f.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/f.js new file mode 100644 index 0000000000000..164afe36e7288 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-a/f.js @@ -0,0 +1,5 @@ +import { report } from "../tick"; +import "./e"; +import "./async2"; + +report("f"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/a.js new file mode 100644 index 0000000000000..1aab5f01bf9cd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/a.js @@ -0,0 +1,5 @@ +import { report } from "../tick"; +import "./async"; +import "./b"; + +report("a"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/async.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/async.js new file mode 100644 index 0000000000000..55b880d32d7dd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/async.js @@ -0,0 +1,7 @@ +import { report } from "../tick"; + +report("async before"); +await 0; +report("async middle"); +await 0; +report("async after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/b.js new file mode 100644 index 0000000000000..9293c13214e5c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/b.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./c"; + +report("b"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/c.js new file mode 100644 index 0000000000000..b5f21ba1d0fa3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/c.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./async"; + +report("c"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/d.js new file mode 100644 index 0000000000000..b3e9ae43b7adb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/d.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./c"; + +report("d"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/e.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/e.js new file mode 100644 index 0000000000000..9a4b1c21daecf --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-b/e.js @@ -0,0 +1,9 @@ +import { report } from "../tick"; +import "./a"; +import "./d"; + +report("async before"); +await 0; +report("async middle"); +await 0; +report("async after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-c/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-c/a.js new file mode 100644 index 0000000000000..877d993baaae9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-c/a.js @@ -0,0 +1,7 @@ +import { report } from "../tick"; +import "./b"; +import "./a"; + +report("a before"); +await 0; +report("a after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-c/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-c/b.js new file mode 100644 index 0000000000000..0df467a52891a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-c/b.js @@ -0,0 +1,3 @@ +import { report } from "../tick"; + +report("b"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/a.js new file mode 100644 index 0000000000000..4294285ef4f5b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/a.js @@ -0,0 +1,6 @@ +import { report } from "../tick"; +import "./b"; + +report("a before"); +await 0; +report("a after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/b.js new file mode 100644 index 0000000000000..36e0a25f17739 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/b.js @@ -0,0 +1,6 @@ +import { report } from "../tick"; +import "./c"; + +report("b before"); +await 0; +report("b after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/c.js new file mode 100644 index 0000000000000..c68d0d55dd3f1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/c.js @@ -0,0 +1,6 @@ +import { report } from "../tick"; +import "./a"; + +report("c before"); +await 0; +report("c after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/index.js new file mode 100644 index 0000000000000..4b95c3afa8060 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/index.js @@ -0,0 +1,5 @@ +import { report } from "../tick"; +import "./x"; +import "./y"; + +report("index"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/x.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/x.js new file mode 100644 index 0000000000000..225365bd07c98 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/x.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./a"; + +report("x"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/y.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/y.js new file mode 100644 index 0000000000000..bddaecf205fe9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-d/y.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./b"; + +report("y"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/a.js new file mode 100644 index 0000000000000..6c88c077d2526 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/a.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./async"; + +report("a"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/async.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/async.js new file mode 100644 index 0000000000000..55b880d32d7dd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/async.js @@ -0,0 +1,7 @@ +import { report } from "../tick"; + +report("async before"); +await 0; +report("async middle"); +await 0; +report("async after"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/b.js new file mode 100644 index 0000000000000..1050f1e6b0fa8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/b.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./async"; + +report("b"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/index.js new file mode 100644 index 0000000000000..fe9ae79963274 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/index.js @@ -0,0 +1,6 @@ +import { report } from "../tick"; +import "./a"; +import "./b"; +import "./x"; + +report("index"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/x.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/x.js new file mode 100644 index 0000000000000..225365bd07c98 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/case-e/x.js @@ -0,0 +1,4 @@ +import { report } from "../tick"; +import "./a"; + +report("x"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/index.js new file mode 100644 index 0000000000000..a5b73de862a20 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/index.js @@ -0,0 +1,74 @@ +import * as tick from "./tick"; + +it("should execute async modules in to correct order and without additional ticks (case a)", async () => { + tick.start(); + await require("./case-a/f"); + expect(tick.stop()).toEqual([ + "e 0", + "async before 0", + "async middle 1", + "async after 2", + "b 3", + "c 3", + "a 3", + "d 3", + "async2 before 3", + "async2 middle 4", + "async2 after 5", + "f 6", + ]); +}); + +it("should execute async modules in to correct order and without additional ticks (case b)", async () => { + tick.start(); + await require("./case-b/e"); + expect(tick.stop()).toEqual([ + "async before 0", + "async middle 1", + "async after 2", + "c 3", + "b 3", + "a 3", + "d 3", + "async before 3", + "async middle 4", + "async after 5", + ]); +}); + +it("should execute async modules in to correct order and without additional ticks (case c)", async () => { + tick.start(); + await require("./case-c/a"); + expect(tick.stop()).toEqual(["b 0", "a before 0", "a after 1"]); +}); + +it("should execute async modules in to correct order and without additional ticks (case d)", async () => { + tick.start(); + await require("./case-d/index"); + expect(tick.stop()).toEqual([ + "c before 0", + "c after 1", + "b before 2", + "b after 3", + "a before 4", + "a after 5", + "x 6", + "y 6", + "index 6", + ]); +}); + +it("should execute async modules in to correct order and without additional ticks (case e)", async () => { + tick.start(); + await require("./case-e/index"); + expect(tick.stop()).toEqual([ + "async before 0", + "async middle 1", + "async after 2", + "a 3", + // see https://github.com/tc39/proposal-top-level-await/issues/158 + "b 3", + "x 3", + "index 3", + ]); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/tick.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/tick.js new file mode 100644 index 0000000000000..02cd68a5831de --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/micro-ticks-parents/input/tick.js @@ -0,0 +1,23 @@ +export let entries = []; +export let currentTick = 0; + +let running = false; + +export async function start() { + entries = []; + running = true; + currentTick = 0; + while (running) { + await 0; + currentTick++; + } +} + +export function stop() { + running = false; + return entries; +} + +export function report(name) { + entries.push(`${name} ${currentTick}`); +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/async.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/async.js new file mode 100644 index 0000000000000..03ed4ae466317 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/async.js @@ -0,0 +1,2 @@ +await 1; +export default 1; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/index.js new file mode 100644 index 0000000000000..827a398a97541 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/index.js @@ -0,0 +1,5 @@ +it("should not take too long to evaluate nested async modules", async () => { + const start = Date.now(); + await import(/* webpackMode: "eager" */ "./loader.js?i=40!./loader.js"); + expect(Date.now() - start).toBeLessThan(100); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/loader.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/loader.js new file mode 100644 index 0000000000000..86c49ee826d23 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/runtime-performance/input/loader.js @@ -0,0 +1,14 @@ +/** @type {import("../../../../").LoaderDefinition<{ i: string }>} */ +module.exports = function () { + const options = this.getOptions(); + const i = +options.i; + let src = `import n from "./async.js";\n`; + if (i > 0) { + src += `import a from "./loader.js?i=${i - 1}&a!./loader.js";\n`; + src += `import b from "./loader.js?i=${i - 1}&b!./loader.js";\n`; + src += `export default n + a + b;\n`; + } else { + src += `export default n;\n`; + } + return src; +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/index.js new file mode 100644 index 0000000000000..7b2d0c2c17e47 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/index.js @@ -0,0 +1,6 @@ +it("should allow to use top-level-await", () => { + return import("./reexport").then(({ default: value, other }) => { + expect(value).toBe(42); + expect(other).toBe(42); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/module.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/module.js new file mode 100644 index 0000000000000..cec1b2b485747 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/module.js @@ -0,0 +1,3 @@ +await new Promise((r) => setTimeout(r, 100)); + +export default 42; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/reexport.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/reexport.js new file mode 100644 index 0000000000000..55f47925e2406 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-await/input/reexport.js @@ -0,0 +1,4 @@ +export { default } from "./module"; +import value from "./module"; + +export const other = value; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/counter.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/counter.js new file mode 100644 index 0000000000000..10b16f14ed68b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/counter.js @@ -0,0 +1,6 @@ +await 1; +let value = 0; +export const count = () => { + value++; + return value; +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/index.js new file mode 100644 index 0000000000000..dcd8229aa7fcd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/index.js @@ -0,0 +1,39 @@ +it("should allow to import an rejected async module again", async () => { + await expect(require("./main")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 1"), + }) + ); + await expect(require("./module")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 1"), + }) + ); + await expect(require("./module?2")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 2"), + }) + ); + await expect(require("./reexport?2")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 1"), + }) + ); + await Promise.all([ + expect(require("./module?3")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 3"), + }) + ), + expect(require("./module?4")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 4"), + }) + ), + expect(require("./module?5")).rejects.toEqual( + expect.objectContaining({ + message: expect.stringContaining("expected rejection 5"), + }) + ), + ]); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/main.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/main.js new file mode 100644 index 0000000000000..bfc4f032eea68 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/main.js @@ -0,0 +1,2 @@ +export { default as a } from "./reexport"; +export { default as b } from "./module?2"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/module.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/module.js new file mode 100644 index 0000000000000..e8096da821a8a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/module.js @@ -0,0 +1,6 @@ +import { count } from "./counter"; + +const c = count(); +throw new Error("expected rejection " + c); + +export default "ok"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/reexport.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/reexport.js new file mode 100644 index 0000000000000..b29130d0f5f94 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/async-modules/top-level-error/input/reexport.js @@ -0,0 +1 @@ +export { default as default } from "./module"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/dir/four.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/dir/four.js new file mode 100644 index 0000000000000..a9bbdd80578ef --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/dir/four.js @@ -0,0 +1 @@ +module.exports = 4; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/index.js new file mode 100644 index 0000000000000..75a66e397c3a8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/index.js @@ -0,0 +1,29 @@ +it("should not bundle context requires with asyncMode === 'weak'", function () { + var contextRequire = require.context(".", false, /two/, "weak"); + expect(function () { + contextRequire("./two"); + }).toThrowError(/not available/); +}); + +it("should not bundle context requires with asyncMode === 'weak' using import.meta.webpackContext", function () { + const contextRequire = import.meta.webpackContext(".", { + recursive: false, + regExp: /two/, + mode: "weak", + }); + expect(function () { + contextRequire("./two"); + }).toThrowError(/not available/); +}); + +it("should find module with asyncMode === 'weak' when required elsewhere", function () { + var contextRequire = require.context(".", false, /.+/, "weak"); + expect(contextRequire("./three")).toBe(3); + require("./three"); // in a real app would be served as a separate chunk +}); + +it("should find module with asyncMode === 'weak' when required elsewhere (recursive)", function () { + var contextRequire = require.context(".", true, /.+/, "weak"); + expect(contextRequire("./dir/four")).toBe(4); + require("./dir/four"); // in a real app would be served as a separate chunk +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/three.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/three.js new file mode 100644 index 0000000000000..690aad34a46dc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/three.js @@ -0,0 +1 @@ +module.exports = 3; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/two.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/two.js new file mode 100644 index 0000000000000..4bbffde104425 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context-weak/input/two.js @@ -0,0 +1 @@ +module.exports = 2; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context/input/index.js new file mode 100644 index 0000000000000..c2d5a1d9ebdb4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context/input/index.js @@ -0,0 +1,9 @@ +it("should also work in a chunk", function (done) { + require.ensure([], function (require) { + var contextRequire = require.context(".", false, /two/); + expect(contextRequire("./two")).toBe(2); + var tw = "tw"; + expect(require("." + "/" + tw + "o")).toBe(2); + done(); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context/input/two.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context/input/two.js new file mode 100644 index 0000000000000..4bbffde104425 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/context/input/two.js @@ -0,0 +1 @@ +module.exports = 2; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/one.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/one.js new file mode 100644 index 0000000000000..bd816eaba4ca3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/one.js @@ -0,0 +1 @@ +module.exports = 1; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/three.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/three.js new file mode 100644 index 0000000000000..690aad34a46dc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/three.js @@ -0,0 +1 @@ +module.exports = 3; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/two.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/two.js new file mode 100644 index 0000000000000..4bbffde104425 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir/two.js @@ -0,0 +1 @@ +module.exports = 2; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/one.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/one.js new file mode 100644 index 0000000000000..bd816eaba4ca3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/one.js @@ -0,0 +1 @@ +module.exports = 1; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/three.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/three.js new file mode 100644 index 0000000000000..690aad34a46dc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/three.js @@ -0,0 +1 @@ +module.exports = 3; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/two.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/two.js new file mode 100644 index 0000000000000..4bbffde104425 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/dir2/two.js @@ -0,0 +1 @@ +module.exports = 2; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/index.js new file mode 100644 index 0000000000000..f204b942a5813 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/import-context/input/index.js @@ -0,0 +1,42 @@ +function testCase(load, done) { + load("two", 2, function () { + var sync = true; + load("one", 1, function () { + expect(sync).toBe(false); + load("three", 3, function () { + var sync = true; + load("two", 2, function () { + expect(sync).toBe(true); + done(); + }); + Promise.resolve() + .then(function () {}) + .then(function () {}) + .then(function () { + sync = false; + }); + }); + }); + Promise.resolve().then(function () { + sync = false; + }); + }); +} + +it("should be able to use expressions in import", function (done) { + function load(name, expected, callback) { + import("./dir/" + name) + .then(function (result) { + expect(result).toEqual( + nsObj({ + default: expected, + }) + ); + callback(); + }) + .catch(function (err) { + done(err); + }); + } + testCase(load, done); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/d.js new file mode 100644 index 0000000000000..987d6d7e40168 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir1/d.js @@ -0,0 +1 @@ +export default "d"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir10/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir10/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir10/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir11/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir11/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir11/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir12/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir12/a.js new file mode 100644 index 0000000000000..880c38a198818 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir12/a.js @@ -0,0 +1,9 @@ +export const c = "c"; + +export const d = "d"; + +export const longnameforexport = "longnameforexport"; + +export default "default2"; + +export const usedExports = __webpack_exports_info__.usedExports; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir13/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir13/a.js new file mode 100644 index 0000000000000..fbeecbd206543 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir13/a.js @@ -0,0 +1,7 @@ +export const c = "c"; + +export const d = "d"; + +export default "default2"; + +export const usedExports = __webpack_exports_info__.usedExports; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir13/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir13/b.js new file mode 100644 index 0000000000000..b73c5a615daec --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir13/b.js @@ -0,0 +1,7 @@ +export const a = "a"; + +export const b = "b"; + +export default "default"; + +export const usedExports = __webpack_exports_info__.usedExports; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/d.js new file mode 100644 index 0000000000000..987d6d7e40168 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir2/d.js @@ -0,0 +1 @@ +export default "d"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/d.js new file mode 100644 index 0000000000000..987d6d7e40168 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir3/d.js @@ -0,0 +1 @@ +export default "d"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/d.js new file mode 100644 index 0000000000000..987d6d7e40168 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir4/d.js @@ -0,0 +1 @@ +export default "d"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/d.js new file mode 100644 index 0000000000000..987d6d7e40168 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir5/d.js @@ -0,0 +1 @@ +export default "d"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/d.js new file mode 100644 index 0000000000000..987d6d7e40168 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir6/d.js @@ -0,0 +1 @@ +export default "d"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/d.js new file mode 100644 index 0000000000000..987d6d7e40168 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir7/d.js @@ -0,0 +1 @@ +export default "d"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir8/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/a.js new file mode 100644 index 0000000000000..e94fef18587e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/a.js @@ -0,0 +1 @@ +export default "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/b.js new file mode 100644 index 0000000000000..eff703ff4657b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/b.js @@ -0,0 +1 @@ +export default "b"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/c.js new file mode 100644 index 0000000000000..5d50db5bc1513 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/dir9/c.js @@ -0,0 +1 @@ +export default "c"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/index.js new file mode 100644 index 0000000000000..2bea28ba32175 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/inline-options/input/index.js @@ -0,0 +1,226 @@ +it("should be able to use eager mode", function () { + function load(name) { + return import(/* webpackMode: "eager" */ "./dir1/" + name); + } + return testChunkLoading(load, true, true); +}); + +it("should be able to use lazy-once mode", function () { + function load(name) { + return import(/* webpackMode: "lazy-once" */ "./dir2/" + name); + } + return testChunkLoading(load, false, true); +}); + +it("should be able to use lazy-once mode with name", function () { + function load(name) { + return import( + /* webpackMode: "lazy-once", webpackChunkName: "name-lazy-once" */ "./dir3/" + + name + ); + } + return testChunkLoading(load, false, true); +}); + +it("should be able to use lazy mode", function () { + function load(name) { + return import(/* webpackMode: "lazy" */ "./dir4/" + name); + } + return testChunkLoading(load, false, false); +}); + +it("should be able to use lazy mode with name", function () { + function load(name) { + return import( + /* webpackMode: "lazy", webpackChunkName: "name-lazy" */ "./dir5/" + name + ); + } + return testChunkLoading(load, false, false); +}); + +it("should be able to use lazy mode with name and placeholder", function () { + function load(name) { + return import( + /* webpackMode: "lazy", webpackChunkName: "name-lazy-[request]" */ "./dir6/" + + name + ); + } + return testChunkLoading(load, false, false); +}); + +it("should be able to combine chunks by name", function () { + function load(name) { + switch (name) { + case "a": + return import(/* webpackMode: "eager" */ "./dir7/a"); + case "b": + return import(/* webpackChunkName: "name-3" */ "./dir7/b"); + case "c": + return import(/* webpackChunkName: "name-3" */ "./dir7/c"); + case "d": + return import(/* webpackChunkName: "name-3" */ "./dir7/d"); + default: + throw new Error("Unexpected test data"); + } + } + return testChunkLoading(load, false, true); +}); + +it("should be able to use weak mode", function () { + function load(name) { + return import(/* webpackMode: "weak" */ "./dir8/" + name); + } + require("./dir8/a"); // chunks served manually by the user + require("./dir8/b"); + require("./dir8/c"); + return testChunkLoading(load, true, true); +}); + +it("should be able to use weak mode (without context)", function () { + function load(name) { + switch (name) { + case "a": + return import(/* webpackMode: "weak" */ "./dir9/a"); + case "b": + return import(/* webpackMode: "weak" */ "./dir9/b"); + case "c": + return import(/* webpackMode: "weak" */ "./dir9/c"); + default: + throw new Error("Unexpected test data"); + } + } + require("./dir9/a"); // chunks served manually by the user + require("./dir9/b"); + require("./dir9/c"); + return testChunkLoading(load, true, true); +}); + +it("should not find module when mode is weak and chunk not served elsewhere", function () { + var name = "a"; + return import(/* webpackMode: "weak" */ "./dir10/" + name).catch(function ( + e + ) { + expect(e).toMatchObject({ + message: /not available/, + code: /MODULE_NOT_FOUND/, + }); + }); +}); + +it("should not find module when mode is weak and chunk not served elsewhere (without context)", function () { + return import(/* webpackMode: "weak" */ "./dir11/a").catch(function (e) { + expect(e).toMatchObject({ + message: /not available/, + code: /MODULE_NOT_FOUND/, + }); + }); +}); + +if (process.env.NODE_ENV === "production") { + it("should contain only one export from webpackExports from module", function () { + return import(/* webpackExports: "usedExports" */ "./dir12/a?1").then( + (module) => { + expect(module.usedExports).toEqual(["usedExports"]); + } + ); + }); + + it("should contain only webpackExports from module", function () { + return import( + /* webpackExports: ["a", "usedExports", "b"] */ "./dir12/a?2" + ).then((module) => { + expect(module.usedExports).toEqual(["a", "b", "usedExports"]); + }); + }); + + it("should contain only webpackExports from module in eager mode", function () { + return import( + /* + webpackMode: "eager", + webpackExports: ["a", "usedExports", "b"] + */ "./dir12/a?3" + ).then((module) => { + expect(module.usedExports).toEqual(["a", "b", "usedExports"]); + }); + }); + + it("should contain webpackExports from module in weak mode", function () { + require.resolve("./dir12/a?4"); + return import( + /* + webpackMode: "weak", + webpackExports: ["a", "usedExports", "b"] + */ "./dir12/a?4" + ).then((module) => { + expect(module.usedExports).toEqual(["a", "b", "usedExports"]); + }); + }); + + it("should not mangle webpackExports from module", function () { + return import(/* webpackExports: "longnameforexport" */ "./dir12/a?5").then( + (module) => { + expect(module).toHaveProperty("longnameforexport"); + } + ); + }); + + it("should not mangle default webpackExports from module", function () { + return import(/* webpackExports: "default" */ "./dir12/a?6").then( + (module) => { + expect(module).toHaveProperty("default"); + } + ); + }); + + it("should contain only webpackExports from module in context mode", function () { + const x = "b"; + return import(/* webpackExports: "usedExports" */ `./dir13/${x}`).then( + (module) => { + expect(module.usedExports).toEqual(["usedExports"]); + } + ); + }); +} + +function testChunkLoading(load, expectedSyncInitial, expectedSyncRequested) { + var sync = false; + var syncInitial = true; + var p = Promise.all([load("a"), load("b")]).then(function () { + expect(syncInitial).toBe(expectedSyncInitial); + sync = true; + var p = Promise.all([ + load("a").then(function (a) { + expect(a).toEqual( + nsObj({ + default: "a", + }) + ); + expect(sync).toBe(true); + }), + load("c").then(function (c) { + expect(c).toEqual( + nsObj({ + default: "c", + }) + ); + expect(sync).toBe(expectedSyncRequested); + }), + ]); + Promise.resolve() + .then(function () {}) + .then(function () {}) + .then(function () {}) + .then(function () { + sync = false; + }); + return p; + }); + Promise.resolve() + .then(function () {}) + .then(function () {}) + .then(function () {}) + .then(function () { + syncInitial = false; + }); + return p; +} diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/empty.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/empty.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/empty2.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/empty2.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/empty3.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/empty3.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/empty4.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/empty4.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/index.js new file mode 100644 index 0000000000000..10f5161687127 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/named-chunks/input/index.js @@ -0,0 +1,177 @@ +it("should handle named chunks", function (done) { + var sync = false; + require.ensure( + [], + function (require) { + require("./empty?a"); + require("./empty?b"); + testLoad(); + sync = true; + process.nextTick(function () { + sync = false; + }); + }, + "named-chunk" + ); + function testLoad() { + require.ensure( + [], + function (require) { + require("./empty?c"); + require("./empty?d"); + expect(sync).toBeTruthy(); + done(); + }, + "named-chunk" + ); + } +}); + +it("should handle empty named chunks", function (done) { + var sync = false; + require.ensure( + [], + function (require) { + expect(sync).toBeTruthy(); + }, + "empty-named-chunk" + ); + require.ensure( + [], + function (require) { + expect(sync).toBeTruthy(); + done(); + }, + "empty-named-chunk" + ); + sync = true; + setImmediate(function () { + sync = false; + }); +}); + +it("should handle named chunks when there is an error callback", function (done) { + var sync = false; + require.ensure( + [], + function (require) { + require("./empty?e"); + require("./empty?f"); + testLoad(); + sync = true; + process.nextTick(function () { + sync = false; + }); + }, + function (error) {}, + "named-chunk-for-error-callback" + ); + function testLoad() { + require.ensure( + [], + function (require) { + require("./empty?g"); + require("./empty?h"); + expect(sync).toBeTruthy(); + done(); + }, + function (error) {}, + "named-chunk-for-error-callback" + ); + } +}); + +it("should handle empty named chunks when there is an error callback", function (done) { + var sync = false; + require.ensure( + [], + function (require) { + expect(sync).toBeTruthy(); + }, + function (error) {}, + "empty-named-chunk-for-error-callback" + ); + require.ensure( + [], + function (require) { + expect(sync).toBeTruthy(); + done(); + }, + function (error) {}, + "empty-named-chunk-for-error-callback" + ); + sync = true; + setImmediate(function () { + sync = false; + }); +}); + +it("should be able to use named chunks in import()", function (done) { + var sync = false; + import( + "./empty?import1-in-chunk1" /* webpackChunkName: "import-named-chunk-1" */ + ).then(function (result) { + var i = 0; + import( + "./empty?import2-in-chunk1" /* webpackChunkName: "import-named-chunk-1" */ + ) + .then(function (result) { + expect(sync).toBeTruthy(); + if (i++ > 0) done(); + }) + .catch(function (err) { + done(err); + }); + import( + "./empty?import3-in-chunk2" /* webpackChunkName: "import-named-chunk-2" */ + ) + .then(function (result) { + expect(sync).toBeFalsy(); + if (i++ > 0) done(); + }) + .catch(function (err) { + done(err); + }); + sync = true; + Promise.resolve() + .then(function () {}) + .then(function () {}) + .then(function () { + sync = false; + }); + }); +}); + +it("should be able to use named chunk in context import()", function (done) { + // cspell:ignore mpty + var mpty = "mpty"; + var sync = false; + import("./e" + mpty + "2" /* webpackChunkName: "context-named-chunk" */).then( + function (result) { + var i = 0; + import("./e" + mpty + "3" /* webpackChunkName: "context-named-chunk" */) + .then(function (result) { + expect(sync).toBeTruthy(); + if (i++ > 0) done(); + }) + .catch(function (err) { + done(err); + }); + import("./e" + mpty + "4" /* webpackChunkName: "context-named-chunk-2" */) + .then(function (result) { + expect(sync).toBeFalsy(); + if (i++ > 0) done(); + }) + .catch(function (err) { + done(err); + }); + sync = true; + Promise.resolve() + .then(function () {}) + .then(function () {}) + .then(function () { + sync = false; + }); + } + ); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/nested-in-empty/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/nested-in-empty/input/a.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/nested-in-empty/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/nested-in-empty/input/b.js new file mode 100644 index 0000000000000..888cae37af95c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/nested-in-empty/input/b.js @@ -0,0 +1 @@ +module.exports = 42; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/nested-in-empty/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/nested-in-empty/input/index.js new file mode 100644 index 0000000000000..155e728ed41a9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/nested-in-empty/input/index.js @@ -0,0 +1,13 @@ +it("should include a chunk nested in an empty chunk", (done) => { + require.ensure(["./a"], () => { + require.ensure([], () => { + require.ensure(["./a"], () => { + require.ensure([], () => { + const b = require("./b"); + expect(b).toBe(42); + done(); + }); + }); + }); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/parsing/input/empty.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/parsing/input/empty.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/parsing/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/parsing/input/index.js new file mode 100644 index 0000000000000..960692c7ee48d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/parsing/input/index.js @@ -0,0 +1,49 @@ +it("should handle bound function expressions", function (done) { + require.ensure( + [], + function (require) { + expect(this).toEqual({ test: true }); + require("./empty?test"); + expect(process.nextTick).toBeTypeOf("function"); // check if injection still works + require.ensure( + [], + function (require) { + expect(this).toEqual({ test: true }); + done(); + }.bind(this) + ); + }.bind({ test: true }) + ); +}); + +it("should handle require.ensure without function expression", function (done) { + function f() { + done(); + } + require.ensure([], f); +}); + +it("should parse expression in require.ensure, which isn't a function expression", function (done) { + require.ensure( + [], + (function () { + expect(require("./empty?require.ensure:test")).toEqual({}); + return function f() { + done(); + }; + })() + ); +}); + +it("should accept an already included module", function (done) { + if (Math.random() < 0) require("./require.include"); + var value = null; + require.ensure([], function (require) { + value = require("./require.include"); + }); + setImmediate(function () { + expect(value).toBe("require.include"); + expect(value).toBe("require.include"); + done(); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/parsing/input/require.include.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/parsing/input/require.include.js new file mode 100644 index 0000000000000..5629abd04a65d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/parsing/input/require.include.js @@ -0,0 +1 @@ +module.exports = "require.include"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/a.js new file mode 100644 index 0000000000000..6cd1d0075d403 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/a.js @@ -0,0 +1 @@ +module.exports = "a"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/acircular.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/acircular.js new file mode 100644 index 0000000000000..9d55f62ced6ed --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/acircular.js @@ -0,0 +1,3 @@ +require.ensure(["./acircular2"], function (require) { + require("./acircular2"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/acircular2.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/acircular2.js new file mode 100644 index 0000000000000..61ae309602dca --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/acircular2.js @@ -0,0 +1,3 @@ +require.ensure(["./acircular"], function (require) { + require("./acircular"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/b.js new file mode 100644 index 0000000000000..d45a37c0b5720 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/b.js @@ -0,0 +1 @@ +module.exports = require("./a"); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/duplicate.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/duplicate.js new file mode 100644 index 0000000000000..d0f62131699ca --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/duplicate.js @@ -0,0 +1,3 @@ +require.ensure(["./a"], function (require) { + expect(require("./a")).toBe("a"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/duplicate2.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/duplicate2.js new file mode 100644 index 0000000000000..e7228b2b4e8fd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/duplicate2.js @@ -0,0 +1,3 @@ +require.ensure(["./b"], function (require) { + expect(require("./b")).toBe("a"); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/empty.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/empty.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/index.js new file mode 100644 index 0000000000000..02ef9177a56a6 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/index.js @@ -0,0 +1,54 @@ +/* globals it */ +it("should handle duplicate chunks", function (done) { + var firstOne = false, + secondOne = false; + require.ensure([], function (require) { + require("./acircular"); + require("./duplicate"); + require("./duplicate2"); + firstOne = true; + if (secondOne) done(); + }); + require.ensure([], function (require) { + require("./acircular2"); + require("./duplicate"); + require("./duplicate2"); + secondOne = true; + if (firstOne) done(); + }); +}); + +it("should not load a chunk which is included in a already loaded one", function (done) { + var asyncFlag = false; + require.ensure(["./empty?x", "./empty?y", "./empty?z"], function (require) { + try { + expect(asyncFlag).toBe(true); + loadChunk(); + } catch (e) { + done(e); + } + }); + Promise.resolve() + .then(function () {}) + .then(function () {}) + .then(function () { + asyncFlag = true; + }); + function loadChunk() { + var sync = true; + require.ensure(["./empty?x", "./empty?y"], function (require) { + try { + expect(sync).toBe(true); + done(); + } catch (e) { + done(e); + } + }); + Promise.resolve() + .then(function () {}) + .then(function () {}) + .then(function () { + sync = false; + }); + } +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/test.filter.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/test.filter.js new file mode 100644 index 0000000000000..1fb719fdd6125 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/runtime/input/test.filter.js @@ -0,0 +1,4 @@ +module.exports = function (config) { + // This test can't run in development mode as it depends on the flagIncludedChunks optimization + return config.mode !== "development"; +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/var-inject-error-handler/input/empty.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/var-inject-error-handler/input/empty.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/var-inject-error-handler/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/var-inject-error-handler/input/index.js new file mode 100644 index 0000000000000..76777f44c4042 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/var-inject-error-handler/input/index.js @@ -0,0 +1,12 @@ +it("should handle var injection in require.ensure with error callback", function (done) { + require.ensure( + [], + function (require) { + require("./empty"); + var x = module.x; + done(); + }, + function (error) {}, + "chunk-with-var-inject" + ); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/a.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/b.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/c.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/index.js new file mode 100644 index 0000000000000..ae551faeba787 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies-context/input/index.js @@ -0,0 +1,24 @@ +it("should not include a module with a weak dependency using context", function () { + var fileA = "a"; + var fileB = "b"; + var fileC = "c"; + + var resolveWeakA = require.resolveWeak("./" + fileA); + var resolveWeakB = require.resolveWeak("./" + fileB); + var resolveWeakC = require.resolveWeak("./" + fileC); + + var a = !!__webpack_modules__[resolveWeakA]; + var b = !!__webpack_modules__[resolveWeakB]; + var c = !!__webpack_modules__[resolveWeakC]; + + require(["./b"]); + require("./c"); + + expect(resolveWeakA).toBeDefined(); + expect(resolveWeakB).toBeDefined(); + expect(resolveWeakC).toBeDefined(); + + expect(a).toBe(false); + expect(b).toBe(false); + expect(c).toBe(true); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/a.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/b.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/b.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/c.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/c.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/d.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/d.js new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/index.js new file mode 100644 index 0000000000000..11a830afeaa01 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/__skipped__/weak-dependencies/input/index.js @@ -0,0 +1,13 @@ +it("should not include a module with a weak dependency", function () { + var a = !!__webpack_modules__[require.resolveWeak("./a")]; + var b = !!__webpack_modules__[require.resolve("./b")]; + var c = !!__webpack_modules__[require.resolveWeak("./c")]; + var d = !!__webpack_modules__[require.resolveWeak("./d")]; + require(["./c"]); + require("./d"); + + expect(a).toBe(false); + expect(b).toBe(true); + expect(c).toBe(false); + expect(d).toBe(true); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/index.js new file mode 100644 index 0000000000000..0a4107e021f82 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/index.js @@ -0,0 +1,11 @@ +import leftHelix from "./leftHelix"; +import rightHelix from "./rightHelix"; + +it("should import generate ensure function for this", () => { + return Promise.all([leftHelix.run(), rightHelix.run()]); +}); + +export default { + leftHelix, + rightHelix, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/leftHelix.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/leftHelix.js new file mode 100644 index 0000000000000..7a7babc0d2b40 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/leftHelix.js @@ -0,0 +1,6 @@ +import leftHelixPrime, { run } from "./leftHelixPrime"; + +export default { + leftHelixPrime, + run, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/leftHelixPrime.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/leftHelixPrime.js new file mode 100644 index 0000000000000..d669006b5a101 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/leftHelixPrime.js @@ -0,0 +1,9 @@ +import rightHelixPrime from "./rightHelixPrime"; + +export function run() { + return import(/* webpackChunkName: "left" */ "./leftHelix"); +} + +export default { + rightHelixPrime: () => rightHelixPrime, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/rightHelix.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/rightHelix.js new file mode 100644 index 0000000000000..9e668f76eae14 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/rightHelix.js @@ -0,0 +1,6 @@ +import rightHelixPrime, { run } from "./rightHelixPrime"; + +export default { + rightHelixPrime, + run, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/rightHelixPrime.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/rightHelixPrime.js new file mode 100644 index 0000000000000..7d59098187598 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-circle/input/rightHelixPrime.js @@ -0,0 +1,9 @@ +import leftHelixPrime from "./leftHelixPrime"; + +export function run() { + return import(/* webpackChunkName: "right" */ "./rightHelix"); +} + +export default { + leftHelixPrime: () => leftHelixPrime, +}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial-with-fake-map/initialModule.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial-with-fake-map/initialModule.js new file mode 100644 index 0000000000000..341b43e9dfaff --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial-with-fake-map/initialModule.js @@ -0,0 +1 @@ +export default "initialModuleDefault"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial-with-fake-map/initialModule2.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial-with-fake-map/initialModule2.js new file mode 100644 index 0000000000000..4c27d0e9f9a3d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial-with-fake-map/initialModule2.js @@ -0,0 +1 @@ +exports.default = "other"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial/initialModule.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial/initialModule.js new file mode 100644 index 0000000000000..341b43e9dfaff --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/dir-initial/initialModule.js @@ -0,0 +1 @@ +export default "initialModuleDefault"; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/index.js new file mode 100644 index 0000000000000..877672b6c3999 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import-context-exist-chunk/input/index.js @@ -0,0 +1,21 @@ +it("should resolve when import existed chunk (#8626)", function (done) { + require.context("./dir-initial/"); + const fileName = "initialModule"; + import(`./dir-initial/${fileName}`) + .then(({ default: m }) => { + expect(m).toBe("initialModuleDefault"); + done(); + }) + .catch(done); +}); + +it("should resolve when import existed chunk with fake maps", function (done) { + require.context("./dir-initial-with-fake-map/"); + const fileName = "initialModule"; + import(`./dir-initial-with-fake-map/${fileName}`) + .then(({ default: m }) => { + expect(m).toBe("initialModuleDefault"); + done(); + }) + .catch(done); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import/input/index.js new file mode 100644 index 0000000000000..cdc0d14813458 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import/input/index.js @@ -0,0 +1,14 @@ +it("should be able to use import", function (done) { + import("./two") + .then(function (two) { + expect(two).toEqual( + nsObj({ + default: 2, + }) + ); + done(); + }) + .catch(function (err) { + done(err); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import/input/two.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import/input/two.js new file mode 100644 index 0000000000000..4bbffde104425 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/import/input/two.js @@ -0,0 +1 @@ +module.exports = 2; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/one/file.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/one/file.js new file mode 100644 index 0000000000000..bd816eaba4ca3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/one/file.js @@ -0,0 +1 @@ +module.exports = 1; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/three/file.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/three/file.js new file mode 100644 index 0000000000000..690aad34a46dc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/three/file.js @@ -0,0 +1 @@ +module.exports = 3; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/two/file.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/two/file.js new file mode 100644 index 0000000000000..4bbffde104425 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/dir/two/file.js @@ -0,0 +1 @@ +module.exports = 2; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/index.js new file mode 100644 index 0000000000000..e9af6f942e016 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-2443/input/index.js @@ -0,0 +1,26 @@ +it("should be able to use expressions in import (directory)", function (done) { + function load(name, expected, callback) { + import("./dir/" + name + "/file.js") + .then(function (result) { + expect(result).toEqual( + nsObj({ + default: expected, + }) + ); + callback(); + }) + .catch(function (err) { + done(err); + }); + } + if (Math.random() < 0) require("./dir/three/file"); + load("one", 1, function () { + load("two", 2, function () { + load("three", 3, function () { + load("two", 2, function () { + done(); + }); + }); + }); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-5153/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-5153/input/index.js new file mode 100644 index 0000000000000..0afaf89cabbd5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-5153/input/index.js @@ -0,0 +1,7 @@ +import x from "./module"; + +it("should export the same binding", () => { + return import("./module").then((ns) => { + expect(x).toBe(ns.default); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-5153/input/module.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-5153/input/module.js new file mode 100644 index 0000000000000..ff8b4c56321a3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/issue-5153/input/module.js @@ -0,0 +1 @@ +export default {}; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/errors.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/errors.js new file mode 100644 index 0000000000000..a2434db4ca2b4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/errors.js @@ -0,0 +1,5 @@ +module.exports = [ + [ + /It's not allowed to load an initial chunk on demand\. The chunk name "main" is already used by an entrypoint\./, + ], +]; diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/index.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/index.js new file mode 100644 index 0000000000000..83704cff68716 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/index.js @@ -0,0 +1,10 @@ +it("should handle reference to entry chunk correctly", function (done) { + import(/* webpackChunkName: "main" */ "./module-a") + .then(function (result) { + expect(result.default).toBe("ok"); + done(); + }) + .catch(function (e) { + done(e); + }); +}); diff --git a/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/module-a.js b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/module-a.js new file mode 100644 index 0000000000000..5c6b89abfc84d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/execution/webpack/chunks/weird-reference-to-entry/input/module-a.js @@ -0,0 +1 @@ +export default "ok"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot.rs b/turbopack/crates/turbopack-tests/tests/snapshot.rs new file mode 100644 index 0000000000000..89960f1e3d259 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot.rs @@ -0,0 +1,476 @@ +#![cfg(test)] + +mod util; + +use std::{ + collections::{HashMap, HashSet, VecDeque}, + fs, + path::PathBuf, +}; + +use anyhow::{bail, Context, Result}; +use dunce::canonicalize; +use serde::Deserialize; +use serde_json::json; +use turbo_tasks::{RcStr, ReadRef, TryJoinIterExt, TurboTasks, Value, ValueToString, Vc}; +use turbo_tasks_env::DotenvProcessEnv; +use turbo_tasks_fs::{ + json::parse_json_with_source_context, util::sys_to_unix, DiskFileSystem, FileSystem, + FileSystemPath, +}; +use turbo_tasks_memory::MemoryBackend; +use turbopack::{ + ecmascript::{EcmascriptInputTransform, EcmascriptModuleAsset, TreeShakingMode}, + module_options::{ + JsxTransformOptions, ModuleOptionsContext, ModuleRule, ModuleRuleCondition, + ModuleRuleEffect, + }, + ModuleAssetContext, +}; +use turbopack_browser::BrowserChunkingContext; +use turbopack_core::{ + asset::Asset, + chunk::{ + availability_info::AvailabilityInfo, ChunkableModule, ChunkingContext, ChunkingContextExt, + EvaluatableAssetExt, EvaluatableAssets, MinifyType, + }, + compile_time_defines, + compile_time_info::CompileTimeInfo, + condition::ContextCondition, + context::AssetContext, + environment::{BrowserEnvironment, Environment, ExecutionEnvironment, NodeJsEnvironment}, + file_source::FileSource, + free_var_references, + issue::{Issue, IssueDescriptionExt}, + module::Module, + output::OutputAsset, + reference_type::{EntryReferenceSubType, ReferenceType}, + source::Source, +}; +use turbopack_ecmascript_plugins::transform::{ + emotion::{EmotionTransformConfig, EmotionTransformer}, + styled_components::{StyledComponentsTransformConfig, StyledComponentsTransformer}, +}; +use turbopack_ecmascript_runtime::RuntimeType; +use turbopack_env::ProcessEnvAsset; +use turbopack_nodejs::NodeJsChunkingContext; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; +use turbopack_test_utils::snapshot::{diff, expected, matches_expected, snapshot_issues}; + +use crate::util::REPO_ROOT; + +fn register() { + turbo_tasks::register(); + turbo_tasks_env::register(); + turbo_tasks_fs::register(); + turbopack::register(); + turbopack_nodejs::register(); + turbopack_browser::register(); + turbopack_env::register(); + turbopack_ecmascript_plugins::register(); + turbopack_ecmascript_runtime::register(); + turbopack_resolve::register(); + include!(concat!(env!("OUT_DIR"), "/register_test_snapshot.rs")); +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct SnapshotOptions { + #[serde(default = "default_browserslist")] + browserslist: String, + #[serde(default = "default_entry")] + entry: String, + #[serde(default)] + minify_type: MinifyType, + #[serde(default)] + runtime: Runtime, + #[serde(default = "default_runtime_type")] + runtime_type: RuntimeType, + #[serde(default)] + environment: SnapshotEnvironment, + #[serde(default)] + use_swc_css: bool, + #[serde(default)] + tree_shaking_mode: Option, +} + +#[derive(Debug, Deserialize, Default)] +enum Runtime { + #[default] + Browser, + NodeJs, +} + +#[derive(Debug, Deserialize, Default)] +enum SnapshotEnvironment { + #[default] + Browser, + NodeJs, +} + +impl Default for SnapshotOptions { + fn default() -> Self { + SnapshotOptions { + browserslist: default_browserslist(), + entry: default_entry(), + minify_type: Default::default(), + runtime: Default::default(), + runtime_type: default_runtime_type(), + environment: Default::default(), + use_swc_css: Default::default(), + tree_shaking_mode: Default::default(), + } + } +} + +fn default_browserslist() -> String { + // Use a specific version to avoid churn in transform over time as the + // preset_env crate data changes + "Chrome 102".to_owned() +} + +fn default_entry() -> String { + "input/index.js".to_owned() +} + +fn default_runtime_type() -> RuntimeType { + // We don't want all snapshot tests to also include the runtime every time, + // as this would be a lot of extra noise whenever we make a single change to + // the runtime. Instead, we only include the runtime in snapshots that + // specifically request it via "runtime": "Default". + RuntimeType::Dummy +} + +#[testing::fixture("tests/snapshot/*/*/", exclude("node_modules"))] +fn test(resource: PathBuf) { + let resource = canonicalize(resource).unwrap(); + // Separating this into a different function fixes my IDE's types for some + // reason... + run(resource).unwrap(); +} + +#[tokio::main(flavor = "current_thread")] +async fn run(resource: PathBuf) -> Result<()> { + register(); + + let tt = TurboTasks::new(MemoryBackend::default()); + let task = tt.spawn_once_task(async move { + let out = run_test(resource.to_str().unwrap().into()); + let _ = out.resolve_strongly_consistent().await?; + let captured_issues = out.peek_issues_with_path().await?; + + let plain_issues = captured_issues + .iter_with_shortest_path() + .map(|(issue_vc, path)| async move { issue_vc.into_plain(path).await }) + .try_join() + .await?; + + snapshot_issues(plain_issues, out.join("issues".into()), &REPO_ROOT) + .await + .context("Unable to handle issues")?; + Ok(Vc::<()>::default()) + }); + tt.wait_task_completion(task, true).await?; + + Ok(()) +} + +#[turbo_tasks::function] +async fn run_test(resource: RcStr) -> Result> { + let test_path = canonicalize(&resource)?; + assert!(test_path.exists(), "{} does not exist", resource); + assert!( + test_path.is_dir(), + "{} is not a directory. Snapshot tests must be directories.", + test_path.to_str().unwrap() + ); + + let options_file = fs::read_to_string(test_path.join("options.json")); + let options = match options_file { + Err(_) => SnapshotOptions::default(), + Ok(options_str) => parse_json_with_source_context(&options_str).unwrap(), + }; + let root_fs = DiskFileSystem::new("workspace".into(), REPO_ROOT.clone(), vec![]); + let project_fs = DiskFileSystem::new("project".into(), REPO_ROOT.clone(), vec![]); + let project_root = project_fs.root(); + + let relative_path = test_path.strip_prefix(&*REPO_ROOT)?; + let relative_path: RcStr = sys_to_unix(relative_path.to_str().unwrap()).into(); + let path = root_fs.root().join(relative_path.clone()); + let project_path = project_root.join(relative_path.clone()); + + let entry_asset = project_path.join(options.entry.into()); + + let env = Environment::new(Value::new(match options.environment { + SnapshotEnvironment::Browser => { + ExecutionEnvironment::Browser( + // TODO: load more from options.json + BrowserEnvironment { + dom: true, + web_worker: false, + service_worker: false, + browserslist_query: options.browserslist.into(), + } + .into(), + ) + } + SnapshotEnvironment::NodeJs => { + ExecutionEnvironment::NodeJsBuildTime( + // TODO: load more from options.json + NodeJsEnvironment::default().into(), + ) + } + })); + + let defines = compile_time_defines!( + process.turbopack = true, + process.env.TURBOPACK = true, + process.env.NODE_ENV = "development", + DEFINED_VALUE = "value", + DEFINED_TRUE = true, + A.VERY.LONG.DEFINED.VALUE = json!({ "test": true }), + ); + + let compile_time_info = CompileTimeInfo::builder(env) + .defines(defines.clone().cell()) + .free_var_references(free_var_references!(..defines.into_iter()).cell()) + .cell(); + + let conditions = ModuleRuleCondition::any(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".js".into()), + ModuleRuleCondition::ResourcePathEndsWith(".jsx".into()), + ModuleRuleCondition::ResourcePathEndsWith(".ts".into()), + ModuleRuleCondition::ResourcePathEndsWith(".tsx".into()), + ]); + + let custom_rules = ModuleRule::new( + conditions, + vec![ModuleRuleEffect::ExtendEcmascriptTransforms { + prepend: Vc::cell(vec![ + EcmascriptInputTransform::Plugin(Vc::cell(Box::new( + EmotionTransformer::new(&EmotionTransformConfig::default()) + .expect("Should be able to create emotion transformer"), + ) as _)), + EcmascriptInputTransform::Plugin(Vc::cell(Box::new( + StyledComponentsTransformer::new(&StyledComponentsTransformConfig::default()), + ) as _)), + ]), + append: Vc::cell(vec![]), + }], + ); + let asset_context: Vc> = Vc::upcast(ModuleAssetContext::new( + Vc::cell(HashMap::new()), + compile_time_info, + ModuleOptionsContext { + enable_jsx: Some(JsxTransformOptions::cell(JsxTransformOptions { + development: true, + ..Default::default() + })), + preset_env_versions: Some(env), + ignore_dynamic_requests: true, + use_swc_css: options.use_swc_css, + rules: vec![( + ContextCondition::InDirectory("node_modules".into()), + ModuleOptionsContext { + use_swc_css: options.use_swc_css, + ..Default::default() + } + .cell(), + )], + custom_rules: vec![custom_rules], + tree_shaking_mode: options.tree_shaking_mode, + ..Default::default() + } + .into(), + ResolveOptionsContext { + enable_typescript: true, + enable_react: true, + enable_node_modules: Some(project_root), + custom_conditions: vec!["development".into()], + rules: vec![( + ContextCondition::InDirectory("node_modules".into()), + ResolveOptionsContext { + enable_node_modules: Some(project_root), + custom_conditions: vec!["development".into()], + ..Default::default() + } + .cell(), + )], + ..Default::default() + } + .cell(), + Vc::cell("test".into()), + )); + + let runtime_entries = maybe_load_env(asset_context, project_path) + .await? + .map(|asset| EvaluatableAssets::one(asset.to_evaluatable(asset_context))); + + let chunk_root_path = path.join("output".into()); + let static_root_path = path.join("static".into()); + + let chunking_context: Vc> = match options.runtime { + Runtime::Browser => Vc::upcast( + BrowserChunkingContext::builder( + project_root, + path, + path, + chunk_root_path, + static_root_path, + env, + options.runtime_type, + ) + .build(), + ), + Runtime::NodeJs => Vc::upcast( + NodeJsChunkingContext::builder( + project_root, + path, + path, + chunk_root_path, + static_root_path, + env, + options.runtime_type, + ) + .minify_type(options.minify_type) + .build(), + ), + }; + + let expected_paths = expected(chunk_root_path) + .await? + .union(&expected(static_root_path).await?) + .copied() + .collect(); + + let entry_module = asset_context + .process( + Vc::upcast(FileSource::new(entry_asset)), + Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)), + ) + .module(); + + let chunks = if let Some(ecmascript) = + Vc::try_resolve_downcast_type::(entry_module).await? + { + // TODO: Load runtime entries from snapshots + match options.runtime { + Runtime::Browser => chunking_context.evaluated_chunk_group_assets( + ecmascript.ident(), + runtime_entries + .unwrap_or_else(EvaluatableAssets::empty) + .with_entry(Vc::upcast(ecmascript)), + Value::new(AvailabilityInfo::Root), + ), + Runtime::NodeJs => { + Vc::cell(vec![ + Vc::try_resolve_downcast_type::(chunking_context) + .await? + .unwrap() + .entry_chunk_group( + // `expected` expects a completely flat output directory. + chunk_root_path + .join( + entry_module + .ident() + .path() + .file_stem() + .await? + .as_deref() + .unwrap() + .into(), + ) + .with_extension("entry.js".into()), + Vc::upcast(ecmascript), + runtime_entries + .unwrap_or_else(EvaluatableAssets::empty) + .with_entry(Vc::upcast(ecmascript)), + Value::new(AvailabilityInfo::Root), + ) + .await? + .asset, + ]) + } + } + } else if let Some(chunkable) = + Vc::try_resolve_downcast::>(entry_module).await? + { + chunking_context.root_chunk_group_assets(chunkable) + } else { + // TODO convert into a serve-able asset + bail!("Entry module is not chunkable, so it can't be used to bootstrap the application") + }; + + let mut seen = HashSet::new(); + let mut queue: VecDeque<_> = chunks.await?.iter().copied().collect(); + + let output_path = path.await?; + while let Some(asset) = queue.pop_front() { + walk_asset(asset, &output_path, &mut seen, &mut queue) + .await + .context(format!( + "Failed to walk asset {}", + asset + .ident() + .to_string() + .await + .context("to_string failed")? + ))?; + } + + matches_expected(expected_paths, seen) + .await + .context("Actual assets doesn't match with expected assets")?; + + Ok(path) +} + +async fn walk_asset( + asset: Vc>, + output_path: &ReadRef, + seen: &mut HashSet>, + queue: &mut VecDeque>>, +) -> Result<()> { + let path = asset.ident().path().resolve().await?; + + if !seen.insert(path) { + return Ok(()); + } + + if path.await?.is_inside_ref(output_path) { + // Only consider assets that should be written to disk. + diff(path, asset.content()).await?; + } + + queue.extend( + asset + .references() + .await? + .iter() + .copied() + .map(|asset| async move { + Ok(Vc::try_resolve_downcast::>(asset).await?) + }) + .try_join() + .await? + .into_iter() + .flatten(), + ); + + Ok(()) +} + +async fn maybe_load_env( + _context: Vc>, + path: Vc, +) -> Result>>> { + let dotenv_path = path.join("input/.env".into()); + + if !dotenv_path.read().await?.is_content() { + return Ok(None); + } + + let env = DotenvProcessEnv::new(None, dotenv_path); + let asset = ProcessEnvAsset::new(dotenv_path, Vc::upcast(env)); + Ok(Some(Vc::upcast(asset))) +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/index.js new file mode 100644 index 0000000000000..cf2e6dc9fa6a2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/index.js @@ -0,0 +1,7 @@ +async function main() { + const lib = await import("./lib"); + console.log(lib.cat); +} + + +main() diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_029950.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_029950.js new file mode 100644 index 0000000000000..b092f891ef1d2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_029950.js @@ -0,0 +1,14 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_029950.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript, async loader) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__((__turbopack_import__) => { + return Promise.all([ + "output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js" +].map((chunk) => __turbopack_load__(chunk))).then(() => { + return __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); + }); +}); + +})()), +}]); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_029950.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_029950.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_029950.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js new file mode 100644 index 0000000000000..8823e0a199229 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js @@ -0,0 +1,325 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": [ + ()=>cat, + (v)=>cat = v + ] +}); +let cat = "cat"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getDog": [ + ()=>getDog, + (v)=>getDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +function getDog() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "setDog": [ + ()=>setDog, + (v)=>setDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +function setDog(newDog) { + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] = newDog; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": [ + ()=>dogRef, + (v)=>dogRef = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +; +; +const dogRef = { + initial: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"], + get: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__["getDog"], + set: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["setDog"] +}; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__["dogRef"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": [ + ()=>getChimera, + (v)=>getChimera = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +function getChimera() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__["getChimera"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": [ + ()=>initialCat, + (v)=>initialCat = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"]; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$dynamic$2d$import$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js.map new file mode 100644 index 0000000000000..10f307cc6f109 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_dynamic-import_input_lib_f28c6f.js.map @@ -0,0 +1,45 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,qOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,qOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,qOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,qOAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,qOAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,qOAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 113, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AA4BO,IAAI,MAAM"}}, + {"offset": {"line": 121, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 126, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 134, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 139, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAMA,SAAS;IACP,OAAO,qOAAA,CAAA,MAAG;AACZ"}}, + {"offset": {"line": 155, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 160, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAcA,SAAS,OAAO,MAAM;IACpB,qOAAA,CAAA,MAAG,GAAG;AACR"}}, + {"offset": {"line": 174, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 179, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBO,MAAM,SAAS;IACpB,SAAS,qOAAA,CAAA,MAAG;IACZ,KAAK,sOAAA,CAAA,SAAM;IACX,KAAK,qOAAA,CAAA,SAAM;AACb"}}, + {"offset": {"line": 203, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 208, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 216, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 221, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAgCO,SAAS;IACd,OAAO,qOAAA,CAAA,MAAG,GAAG,qOAAA,CAAA,MAAG;AAClB"}}, + {"offset": {"line": 240, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 245, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 253, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 258, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,aAAa,qOAAA,CAAA,MAAG"}}, + {"offset": {"line": 270, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 275, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 283, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 288, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 304, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 309, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 320, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/a587c_tests_snapshot_basic-tree-shake_dynamic-import_input_index_26d958.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/a587c_tests_snapshot_basic-tree-shake_dynamic-import_input_index_26d958.js new file mode 100644 index 0000000000000..58e10b6c798b3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/a587c_tests_snapshot_basic-tree-shake_dynamic-import_input_index_26d958.js @@ -0,0 +1,14 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_basic-tree-shake_dynamic-import_input_index_26d958.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +async function main() { + const lib = await __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/lib.js [test] (ecmascript, async loader) ")(__turbopack_import__); + console.log(lib.cat); +} +main(); + +}.call(this) }), +}]); + +//# sourceMappingURL=a587c_tests_snapshot_basic-tree-shake_dynamic-import_input_index_26d958.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/a587c_tests_snapshot_basic-tree-shake_dynamic-import_input_index_26d958.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/a587c_tests_snapshot_basic-tree-shake_dynamic-import_input_index_26d958.js.map new file mode 100644 index 0000000000000..6fd70ea1838f4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/output/a587c_tests_snapshot_basic-tree-shake_dynamic-import_input_index_26d958.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/dynamic-import/input/index.js"],"sourcesContent":["async function main() {\n const lib = await import(\"./lib\");\n console.log(lib.cat);\n}\n\n\nmain()\n"],"names":[],"mappings":"AAAA,eAAe;IACb,MAAM,MAAM;IACZ,QAAQ,GAAG,CAAC,IAAI,GAAG;AACrB;AAGA"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js new file mode 100644 index 0000000000000..715232bc56a60 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js @@ -0,0 +1,4 @@ +import { fakeCat } from "./module"; + + +console.log(fakeCat) diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js new file mode 100644 index 0000000000000..072af1e0a25e7 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js @@ -0,0 +1,2 @@ +export { cat as fakeCat } from './lib' + diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_35ea42._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_35ea42._.js new file mode 100644 index 0000000000000..6a1dbbb6d5274 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_35ea42._.js @@ -0,0 +1,243 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_35ea42._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": [ + ()=>cat, + (v)=>cat = v + ] +}); +let cat = "cat"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "__TURBOPACK__reexport__cat__": [ + ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__["cat"], + (v)=>$expr = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "fakeCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__["__TURBOPACK__reexport__cat__"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "fakeCat": [ + ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__fakeCat$3e$__["fakeCat"], + (v)=>$expr = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__fakeCat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/module.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__["fakeCat"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_35ea42._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_35ea42._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_35ea42._.js.map new file mode 100644 index 0000000000000..ca90b74fbc272 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_export-named_input_35ea42._.js.map @@ -0,0 +1,43 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,mOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,mOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,mOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,mOAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,mOAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,mOAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 112, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 116, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 120, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 125, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 129, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 133, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 138, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AA4BO,IAAI,MAAM"}}, + {"offset": {"line": 146, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 151, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 159, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 164, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 175, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 180, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 188, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 193, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 204, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 209, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-named/input/index.js"],"sourcesContent":["import { fakeCat } from \"./module\";\n\n\nconsole.log(fakeCat)\n"],"names":[],"mappings":";;;;;;;AAGA,QAAQ,GAAG,CAAC,qOAAA,CAAA,UAAO"}}, + {"offset": {"line": 217, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 221, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 228, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 233, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 238, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js new file mode 100644 index 0000000000000..ccbfaeaf89af9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js @@ -0,0 +1,3 @@ +import {lib} from './module' + +console.log(lib.cat) diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js new file mode 100644 index 0000000000000..389c321467ba8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js @@ -0,0 +1,2 @@ +export * as lib from './lib' + diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_c0eca6._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_c0eca6._.js new file mode 100644 index 0000000000000..594727e08542f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_c0eca6._.js @@ -0,0 +1,410 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_c0eca6._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": [ + ()=>cat, + (v)=>cat = v + ] +}); +let cat = "cat"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getDog": [ + ()=>getDog, + (v)=>getDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +function getDog() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "setDog": [ + ()=>setDog, + (v)=>setDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +function setDog(newDog) { + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] = newDog; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": [ + ()=>dogRef, + (v)=>dogRef = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +; +; +const dogRef = { + initial: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"], + get: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__["getDog"], + set: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["setDog"] +}; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__["dogRef"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": [ + ()=>getChimera, + (v)=>getChimera = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +function getChimera() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__["getChimera"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": [ + ()=>initialCat, + (v)=>initialCat = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"]; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "__TURBOPACK__reexport__lib__": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "lib": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__["__TURBOPACK__reexport__lib__"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "lib": [ + ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__lib$3e$__["lib"], + (v)=>$expr = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$module$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__lib$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/module.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__["lib"].cat); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$export$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_c0eca6._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_c0eca6._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_c0eca6._.js.map new file mode 100644 index 0000000000000..ecbbd9a255864 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_export-namespace_input_c0eca6._.js.map @@ -0,0 +1,61 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,uOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,uOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,uOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,uOAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,uOAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,uOAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 112, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 116, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 120, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 125, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 129, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 133, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 138, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AA4BO,IAAI,MAAM"}}, + {"offset": {"line": 146, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 151, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 159, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 164, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAMA,SAAS;IACP,OAAO,uOAAA,CAAA,MAAG;AACZ"}}, + {"offset": {"line": 180, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 185, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAcA,SAAS,OAAO,MAAM;IACpB,uOAAA,CAAA,MAAG,GAAG;AACR"}}, + {"offset": {"line": 199, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 204, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBO,MAAM,SAAS;IACpB,SAAS,uOAAA,CAAA,MAAG;IACZ,KAAK,wOAAA,CAAA,SAAM;IACX,KAAK,uOAAA,CAAA,SAAM;AACb"}}, + {"offset": {"line": 228, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 233, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 241, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 246, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAgCO,SAAS;IACd,OAAO,uOAAA,CAAA,MAAG,GAAG,uOAAA,CAAA,MAAG;AAClB"}}, + {"offset": {"line": 265, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 270, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 278, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 283, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,aAAa,uOAAA,CAAA,MAAG"}}, + {"offset": {"line": 295, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 300, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 308, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 313, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 329, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 334, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 342, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 347, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 355, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 360, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 371, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 376, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/export-namespace/input/index.js"],"sourcesContent":["import {lib} from './module'\n\nconsole.log(lib.cat)\n"],"names":[],"mappings":";;;;;;;AAEA,QAAQ,GAAG,CAAC,yOAAA,CAAA,MAAG,CAAC,GAAG"}}, + {"offset": {"line": 384, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 388, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 395, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 400, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 405, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js new file mode 100644 index 0000000000000..054969d300c94 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js @@ -0,0 +1,5 @@ +import {cat as c,dogRef,initialCat,getChimera} from './lib' + +console.log(c) + +// TODO: Execution diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_71b07f._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_71b07f._.js new file mode 100644 index 0000000000000..e9109a2fa526e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_71b07f._.js @@ -0,0 +1,198 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_71b07f._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": [ + ()=>cat, + (v)=>cat = v + ] +}); +let cat = "cat"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "c": [ + ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__["cat"], + (v)=>$expr = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__["c"]) // TODO: Execution +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2d$all$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_71b07f._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_71b07f._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_71b07f._.js.map new file mode 100644 index 0000000000000..ddb9d993ba781 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-named-all_input_71b07f._.js.map @@ -0,0 +1,35 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,0OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,0OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,0OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,0OAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,0OAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,0OAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 112, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 116, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 121, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AA4BO,IAAI,MAAM"}}, + {"offset": {"line": 129, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 134, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 142, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 147, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 158, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 163, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named-all/input/index.js"],"sourcesContent":["import {cat as c,dogRef,initialCat,getChimera} from './lib'\n\nconsole.log(c)\n\n// TODO: Execution\n"],"names":[],"mappings":";;;;;;;AAEA,QAAQ,GAAG,CAAC,4OAAA,CAAA,IAAC,EAEb,kBAAkB"}}, + {"offset": {"line": 172, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 176, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 183, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 188, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 193, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js new file mode 100644 index 0000000000000..4dcab2bb4c1a1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js @@ -0,0 +1,3 @@ +import {cat as c} from './lib' + +console.log(c) diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_ed0d99._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_ed0d99._.js new file mode 100644 index 0000000000000..20403fef71608 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_ed0d99._.js @@ -0,0 +1,197 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_ed0d99._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": [ + ()=>cat, + (v)=>cat = v + ] +}); +let cat = "cat"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "c": [ + ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__["cat"], + (v)=>$expr = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__["c"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$named$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_ed0d99._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_ed0d99._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_ed0d99._.js.map new file mode 100644 index 0000000000000..4860ec481e040 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/output/crates_turbopack-tests_tests_snapshot_basic-tree-shake_import-named_input_ed0d99._.js.map @@ -0,0 +1,35 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,mOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,mOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,mOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,mOAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,mOAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,mOAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 112, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 116, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 121, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AA4BO,IAAI,MAAM"}}, + {"offset": {"line": 129, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 134, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 142, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 147, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 158, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 163, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-named/input/index.js"],"sourcesContent":["import {cat as c} from './lib'\n\nconsole.log(c)\n"],"names":[],"mappings":";;;;;;;AAEA,QAAQ,GAAG,CAAC,qOAAA,CAAA,IAAC"}}, + {"offset": {"line": 171, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 175, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 182, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 187, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 192, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js new file mode 100644 index 0000000000000..e34da4ad41e81 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js @@ -0,0 +1,3 @@ +import * as lib from './lib' + +console.log(lib.cat) diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_351ad1._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_351ad1._.js new file mode 100644 index 0000000000000..36d4578916199 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_351ad1._.js @@ -0,0 +1,364 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_351ad1._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": [ + ()=>cat, + (v)=>cat = v + ] +}); +let cat = "cat"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getDog": [ + ()=>getDog, + (v)=>getDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +function getDog() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "setDog": [ + ()=>setDog, + (v)=>setDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +function setDog(newDog) { + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] = newDog; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": [ + ()=>dogRef, + (v)=>dogRef = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +; +; +const dogRef = { + initial: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"], + get: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__["getDog"], + set: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["setDog"] +}; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__["dogRef"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": [ + ()=>getChimera, + (v)=>getChimera = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +function getChimera() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__["getChimera"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": [ + ()=>initialCat, + (v)=>initialCat = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"]; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "lib": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__1$3e$__["lib"].cat); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$namespace$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_351ad1._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_351ad1._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_351ad1._.js.map new file mode 100644 index 0000000000000..ef61345235fd5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-namespace_input_351ad1._.js.map @@ -0,0 +1,53 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,uOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,uOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,uOAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,uOAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,uOAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,uOAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 112, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 116, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 121, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AA4BO,IAAI,MAAM"}}, + {"offset": {"line": 129, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 134, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 142, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 147, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAMA,SAAS;IACP,OAAO,uOAAA,CAAA,MAAG;AACZ"}}, + {"offset": {"line": 163, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 168, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAcA,SAAS,OAAO,MAAM;IACpB,uOAAA,CAAA,MAAG,GAAG;AACR"}}, + {"offset": {"line": 182, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 187, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBO,MAAM,SAAS;IACpB,SAAS,uOAAA,CAAA,MAAG;IACZ,KAAK,wOAAA,CAAA,SAAM;IACX,KAAK,uOAAA,CAAA,SAAM;AACb"}}, + {"offset": {"line": 211, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 216, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 224, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 229, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAgCO,SAAS;IACd,OAAO,uOAAA,CAAA,MAAG,GAAG,uOAAA,CAAA,MAAG;AAClB"}}, + {"offset": {"line": 248, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 253, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 261, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 266, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,aAAa,uOAAA,CAAA,MAAG"}}, + {"offset": {"line": 278, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 283, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 291, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 296, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 312, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 317, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 325, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 330, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-namespace/input/index.js"],"sourcesContent":["import * as lib from './lib'\n\nconsole.log(lib.cat)\n"],"names":[],"mappings":";;;;;;;AAEA,QAAQ,GAAG,CAAC,yOAAA,CAAA,MAAG,CAAC,GAAG"}}, + {"offset": {"line": 338, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 342, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 349, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 354, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 359, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js new file mode 100644 index 0000000000000..cf872380adb2e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js @@ -0,0 +1 @@ +import './lib' diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_cdc49f._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_cdc49f._.js new file mode 100644 index 0000000000000..b7576d6613cb1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_cdc49f._.js @@ -0,0 +1,140 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_cdc49f._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$import$2d$side$2d$effect$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_cdc49f._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_cdc49f._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_cdc49f._.js.map new file mode 100644 index 0000000000000..296bed71af197 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/output/79fb1_turbopack-tests_tests_snapshot_basic-tree-shake_import-side-effect_input_cdc49f._.js.map @@ -0,0 +1,27 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,4OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,4OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,4OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,4OAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,4OAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/import-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,4OAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 112, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 116, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 120, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 125, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 130, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 135, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/index.js new file mode 100644 index 0000000000000..f484400d495cf --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/index.js @@ -0,0 +1 @@ +const {cat} = require('./lib') diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/a587c_tests_snapshot_basic-tree-shake_require-side-effect_input_6b5862._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/a587c_tests_snapshot_basic-tree-shake_require-side-effect_input_6b5862._.js new file mode 100644 index 0000000000000..0907b252734b2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/a587c_tests_snapshot_basic-tree-shake_require-side-effect_input_6b5862._.js @@ -0,0 +1,330 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_basic-tree-shake_require-side-effect_input_6b5862._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": [ + ()=>cat, + (v)=>cat = v + ] +}); +let cat = "cat"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getDog": [ + ()=>getDog, + (v)=>getDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +function getDog() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "setDog": [ + ()=>setDog, + (v)=>setDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +function setDog(newDog) { + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] = newDog; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": [ + ()=>dogRef, + (v)=>dogRef = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +; +; +const dogRef = { + initial: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"], + get: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__["getDog"], + set: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["setDog"] +}; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__["dogRef"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": [ + ()=>getChimera, + (v)=>getChimera = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +function getChimera() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__["getChimera"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": [ + ()=>initialCat, + (v)=>initialCat = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"]; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$require$2d$side$2d$effect$2f$input$2f$lib$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +const { cat } = __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js [test] (ecmascript) "); + +}.call(this) }), +}]); + +//# sourceMappingURL=a587c_tests_snapshot_basic-tree-shake_require-side-effect_input_6b5862._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/a587c_tests_snapshot_basic-tree-shake_require-side-effect_input_6b5862._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/a587c_tests_snapshot_basic-tree-shake_require-side-effect_input_6b5862._.js.map new file mode 100644 index 0000000000000..e4fc85da8365f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/output/a587c_tests_snapshot_basic-tree-shake_require-side-effect_input_6b5862._.js.map @@ -0,0 +1,47 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,6OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,6OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,6OAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,6OAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,6OAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,6OAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 113, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AA4BO,IAAI,MAAM"}}, + {"offset": {"line": 121, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 126, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 134, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 139, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAMA,SAAS;IACP,OAAO,6OAAA,CAAA,MAAG;AACZ"}}, + {"offset": {"line": 155, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 160, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAcA,SAAS,OAAO,MAAM;IACpB,6OAAA,CAAA,MAAG,GAAG;AACR"}}, + {"offset": {"line": 174, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 179, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBO,MAAM,SAAS;IACpB,SAAS,6OAAA,CAAA,MAAG;IACZ,KAAK,8OAAA,CAAA,SAAM;IACX,KAAK,6OAAA,CAAA,SAAM;AACb"}}, + {"offset": {"line": 203, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 208, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 216, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 221, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAgCO,SAAS;IACd,OAAO,6OAAA,CAAA,MAAG,GAAG,6OAAA,CAAA,MAAG;AAClB"}}, + {"offset": {"line": 240, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 245, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 253, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 258, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/lib.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,aAAa,6OAAA,CAAA,MAAG"}}, + {"offset": {"line": 270, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 275, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 283, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 288, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 304, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 309, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 320, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 324, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/require-side-effect/input/index.js"],"sourcesContent":["const {cat} = require('./lib')\n"],"names":[],"mappings":"AAAA,MAAM,EAAC,GAAG,EAAC"}}, + {"offset": {"line": 325, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js new file mode 100644 index 0000000000000..868a25222a78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js @@ -0,0 +1,35 @@ +let dog = "dog"; + +dog += "!"; + +console.log(dog); + +function getDog() { + return dog; +} + +dog += "!"; + +console.log(dog); + +function setDog(newDog) { + dog = newDog; +} + +dog += "!"; + +console.log(dog); + +export const dogRef = { + initial: dog, + get: getDog, + set: setDog, +}; + +export let cat = "cat"; + +export const initialCat = cat; + +export function getChimera() { + return cat + dog; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/options.json new file mode 100644 index 0000000000000..000d78a6b3cbb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/options.json @@ -0,0 +1,3 @@ +{ + "treeShakingMode": "module-fragments" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/a587c_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_87c735.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/a587c_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_87c735.js new file mode 100644 index 0000000000000..9744f84fd5537 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/a587c_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_87c735.js @@ -0,0 +1,325 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_87c735.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dog": [ + ()=>dog, + (v)=>dog = v + ] +}); +let dog = "dog"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] += "!"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__6$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__7$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__16$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__15$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__14$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +"module evaluation"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": [ + ()=>cat, + (v)=>cat = v + ] +}); +let cat = "cat"; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getDog": [ + ()=>getDog, + (v)=>getDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +function getDog() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "setDog": [ + ()=>setDog, + (v)=>setDog = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +function setDog(newDog) { + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"] = newDog; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": [ + ()=>dogRef, + (v)=>dogRef = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +; +; +const dogRef = { + initial: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"], + get: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__11$3e$__["getDog"], + set: __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__5$3e$__["setDog"] +}; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__["dogRef"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__12$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": [ + ()=>getChimera, + (v)=>getChimera = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__8$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +function getChimera() { + return __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"] + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__4$3e$__["dog"]; +} +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__["getChimera"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__9$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": [ + ()=>initialCat, + (v)=>initialCat = v + ] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +const initialCat = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__0$3e$__["cat"]; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$internal__part__2$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__cat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__dogRef$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__getChimera$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$export__initialCat$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) ": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "cat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["cat"], + "dogRef": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["dogRef"], + "getChimera": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["getChimera"], + "initialCat": ()=>__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__["initialCat"] +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$module__evaluation$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2d$tree$2d$shake$2f$tree$2d$shake$2d$test$2d$1$2f$input$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__$3c$exports$3e$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js [test] (ecmascript) "); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; + +})()), +}]); + +//# sourceMappingURL=a587c_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_87c735.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/a587c_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_87c735.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/a587c_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_87c735.js.map new file mode 100644 index 0000000000000..ab349beb6ceb4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/output/a587c_tests_snapshot_basic-tree-shake_tree-shake-test-1_input_index_87c735.js.map @@ -0,0 +1,45 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AAAA,IAAI,MAAM"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;AAEA,gPAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAUA,gPAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 37, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAkBA,gPAAA,CAAA,MAAG,IAAI"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 55, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;AAIA,QAAQ,GAAG,CAAC,gPAAA,CAAA,MAAG"}}, + {"offset": {"line": 63, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 68, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;AAYA,QAAQ,GAAG,CAAC,gPAAA,CAAA,MAAG"}}, + {"offset": {"line": 78, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 83, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA,QAAQ,GAAG,CAAC,gPAAA,CAAA,MAAG"}}, + {"offset": {"line": 95, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 99, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 108, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 113, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;AA4BO,IAAI,MAAM"}}, + {"offset": {"line": 121, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 126, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 134, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 139, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;AAMA,SAAS;IACP,OAAO,gPAAA,CAAA,MAAG;AACZ"}}, + {"offset": {"line": 155, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 160, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AAcA,SAAS,OAAO,MAAM;IACpB,gPAAA,CAAA,MAAG,GAAG;AACR"}}, + {"offset": {"line": 174, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 179, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBO,MAAM,SAAS;IACpB,SAAS,gPAAA,CAAA,MAAG;IACZ,KAAK,iPAAA,CAAA,SAAM;IACX,KAAK,gPAAA,CAAA,SAAM;AACb"}}, + {"offset": {"line": 203, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 208, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 216, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 221, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AAgCO,SAAS;IACd,OAAO,gPAAA,CAAA,MAAG,GAAG,gPAAA,CAAA,MAAG;AAClB"}}, + {"offset": {"line": 240, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 245, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 253, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 258, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic-tree-shake/tree-shake-test-1/input/index.js"],"sourcesContent":["let dog = \"dog\";\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction getDog() {\n return dog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nfunction setDog(newDog) {\n dog = newDog;\n}\n\ndog += \"!\";\n\nconsole.log(dog);\n\nexport const dogRef = {\n initial: dog,\n get: getDog,\n set: setDog,\n};\n\nexport let cat = \"cat\";\n\nexport const initialCat = cat;\n\nexport function getChimera() {\n return cat + dog;\n}\n"],"names":[],"mappings":";;;;;;;;;;AA8BO,MAAM,aAAa,gPAAA,CAAA,MAAG"}}, + {"offset": {"line": 270, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 275, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 283, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 288, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 304, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 309, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 320, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js new file mode 100644 index 0000000000000..1c2b150c634ca --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js @@ -0,0 +1,6 @@ +import { foo } from "foo"; +import { bar } from "bar"; +import "./shared"; + +foo(true); +bar(true); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js new file mode 100644 index 0000000000000..282fdbc134dd3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js @@ -0,0 +1,8 @@ +import { bar } from "bar"; +import "./shared"; + +bar(true); + +import("./import").then(({ foo }) => { + foo(true); +}); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js new file mode 100644 index 0000000000000..6e9a13a68ba32 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js @@ -0,0 +1,3 @@ +export function bar(value) { + console.assert(value); +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/package.json new file mode 100644 index 0000000000000..14ab704d8f639 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js new file mode 100644 index 0000000000000..cb5877b67fcc3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js @@ -0,0 +1,3 @@ +export function foo(value) { + console.assert(value); +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/package.json new file mode 100644 index 0000000000000..14ab704d8f639 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js new file mode 100644 index 0000000000000..645a24a4851fa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js @@ -0,0 +1 @@ +// shared package diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js new file mode 100644 index 0000000000000..6c83a63ecb906 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js @@ -0,0 +1,36 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +// shared package + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$shared$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +(0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["bar"])(true); +__turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js [test] (ecmascript, async loader)")(__turbopack_import__).then(({ foo })=>{ + foo(true); +}); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "bar": ()=>bar +}); +function bar(value) { + console.assert(value); +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js.map new file mode 100644 index 0000000000000..ef464afe3c44a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js"],"sourcesContent":["// shared package\n"],"names":[],"mappings":"AAAA,iBAAiB"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js"],"sourcesContent":["import { bar } from \"bar\";\nimport \"./shared\";\n\nbar(true);\n\nimport(\"./import\").then(({ foo }) => {\n foo(true);\n});\n"],"names":[],"mappings":";;;;;;AAGA,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE;AAEJ,mKAAmB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE;IAC9B,IAAI;AACN"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js"],"sourcesContent":["export function bar(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js new file mode 100644 index 0000000000000..fbd4b11f870cc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js @@ -0,0 +1,31 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/bar/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$shared$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/shared.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +(0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["foo"])(true); +(0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["bar"])(true); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "foo": ()=>foo +}); +function foo(value) { + console.assert(value); +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js.map new file mode 100644 index 0000000000000..b85e2c92babb0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js"],"sourcesContent":["import { foo } from \"foo\";\nimport { bar } from \"bar\";\nimport \"./shared\";\n\nfoo(true);\nbar(true);\n"],"names":[],"mappings":";;;;;;;;AAIA,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE;AACJ,CAAA,GAAA,4MAAA,CAAA,MAAG,AAAD,EAAE"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_import_a037e9.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_import_a037e9.js new file mode 100644 index 0000000000000..d5d91ca08a740 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_import_a037e9.js @@ -0,0 +1,14 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_import_a037e9.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js [test] (ecmascript, async loader)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__((__turbopack_import__) => { + return Promise.all([ + "output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_aea885._.js" +].map((chunk) => __turbopack_load__(chunk))).then(() => { + return __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/import.js [test] (ecmascript)"); + }); +}); + +})()), +}]); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_import_a037e9.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_import_a037e9.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_import_a037e9.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_index_aa8e1e.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_index_aa8e1e.js new file mode 100644 index 0000000000000..501279e272334 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_index_aa8e1e.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_index_aa8e1e.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_4437c1._.js","output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_import_a037e9.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_index_aa8e1e.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_index_aa8e1e.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_input_index_aa8e1e.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js new file mode 100644 index 0000000000000..1c2b150c634ca --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js @@ -0,0 +1,6 @@ +import { foo } from "foo"; +import { bar } from "bar"; +import "./shared"; + +foo(true); +bar(true); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js new file mode 100644 index 0000000000000..282fdbc134dd3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js @@ -0,0 +1,8 @@ +import { bar } from "bar"; +import "./shared"; + +bar(true); + +import("./import").then(({ foo }) => { + foo(true); +}); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js new file mode 100644 index 0000000000000..6e9a13a68ba32 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js @@ -0,0 +1,3 @@ +export function bar(value) { + console.assert(value); +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/package.json new file mode 100644 index 0000000000000..14ab704d8f639 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/index.js new file mode 100644 index 0000000000000..cb5877b67fcc3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/index.js @@ -0,0 +1,3 @@ +export function foo(value) { + console.assert(value); +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/package.json new file mode 100644 index 0000000000000..14ab704d8f639 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js new file mode 100644 index 0000000000000..645a24a4851fa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js @@ -0,0 +1 @@ +// shared package diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/options.json new file mode 100644 index 0000000000000..bb67d5153fce4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/options.json @@ -0,0 +1,4 @@ +{ + "minifyType": "NoMinify", + "runtime": "NodeJs" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/79fb1_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_import_0c7896.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/79fb1_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_import_0c7896.js new file mode 100644 index 0000000000000..3c41c3b1f6d86 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/79fb1_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_import_0c7896.js @@ -0,0 +1,15 @@ +module.exports = { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js [test] (ecmascript, async loader)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__((__turbopack_import__) => { + return Promise.all([ + "output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js" +].map((chunk) => __turbopack_load__(chunk))).then(() => { + return __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js [test] (ecmascript)"); + }); +}); + +})()), + +}; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/79fb1_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_import_0c7896.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/79fb1_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_import_0c7896.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/79fb1_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_import_0c7896.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/[turbopack]_runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/[turbopack]_runtime.js new file mode 100644 index 0000000000000..5ac5725fac479 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/[turbopack]_runtime.js @@ -0,0 +1,4 @@ +const RUNTIME_PUBLIC_PATH = "output/[turbopack]_runtime.js"; +const OUTPUT_ROOT = "crates/turbopack-tests/tests/snapshot/basic/async_chunk_build"; +const ASSET_PREFIX = "/"; +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/[turbopack]_runtime.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/[turbopack]_runtime.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/[turbopack]_runtime.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js new file mode 100644 index 0000000000000..53df69608ff57 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js @@ -0,0 +1,37 @@ +module.exports = { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +// shared package + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk_build$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk_build$2f$input$2f$shared$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +(0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk_build$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["bar"])(true); +__turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js [test] (ecmascript, async loader)")(__turbopack_import__).then(({ foo })=>{ + foo(true); +}); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "bar": ()=>bar +}); +function bar(value) { + console.assert(value); +} + +})()), + +}; + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js.map new file mode 100644 index 0000000000000..ed74a49882995 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js"],"sourcesContent":["// shared package\n"],"names":[],"mappings":"AAAA,iBAAiB"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js"],"sourcesContent":["import { bar } from \"bar\";\nimport \"./shared\";\n\nbar(true);\n\nimport(\"./import\").then(({ foo }) => {\n foo(true);\n});\n"],"names":[],"mappings":";;;;;;AAGA,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE;AAEJ,yKAAmB,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE;IAC9B,IAAI;AACN"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js"],"sourcesContent":["export function bar(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js new file mode 100644 index 0000000000000..45490d7632e89 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js @@ -0,0 +1,32 @@ +module.exports = { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk_build$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk_build$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/bar/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk_build$2f$input$2f$shared$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/shared.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +(0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk_build$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["foo"])(true); +(0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$async_chunk_build$2f$input$2f$node_modules$2f$bar$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["bar"])(true); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "foo": ()=>foo +}); +function foo(value) { + console.assert(value); +} + +})()), + +}; + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js.map new file mode 100644 index 0000000000000..4d585a5aa6a9b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_c494f8._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/import.js"],"sourcesContent":["import { foo } from \"foo\";\nimport { bar } from \"bar\";\nimport \"./shared\";\n\nfoo(true);\nbar(true);\n"],"names":[],"mappings":";;;;;;;;AAIA,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE;AACJ,CAAA,GAAA,kNAAA,CAAA,MAAG,AAAD,EAAE"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/index.entry.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/index.entry.js new file mode 100644 index 0000000000000..7da71aeef1599 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/index.entry.js @@ -0,0 +1,6 @@ +const CHUNK_PUBLIC_PATH = "output/index.entry.js"; +const runtime = require("./[turbopack]_runtime.js"); +runtime.loadChunk("output/crates_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_baff26._.js"); +runtime.loadChunk("output/79fb1_turbopack-tests_tests_snapshot_basic_async_chunk_build_input_import_0c7896.js"); +runtime.getOrInstantiateRuntimeModule("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js [test] (ecmascript)", CHUNK_PUBLIC_PATH); +module.exports = runtime.getOrInstantiateRuntimeModule("[project]/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/input/index.js [test] (ecmascript)", CHUNK_PUBLIC_PATH).exports; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/index.entry.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/index.entry.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/async_chunk_build/output/index.entry.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js new file mode 100644 index 0000000000000..9820516162f14 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js @@ -0,0 +1,3 @@ +import { foo } from "foo"; + +foo(true); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js new file mode 100644 index 0000000000000..cb5877b67fcc3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js @@ -0,0 +1,3 @@ +export function foo(value) { + console.assert(value); +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/package.json new file mode 100644 index 0000000000000..14ab704d8f639 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js new file mode 100644 index 0000000000000..589b94493d7a1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$chunked$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +(0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$chunked$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["foo"])(true); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "foo": ()=>foo +}); +function foo(value) { + console.assert(value); +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js.map new file mode 100644 index 0000000000000..ffb4ceca543ef --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js"],"sourcesContent":["import { foo } from \"foo\";\n\nfoo(true);\n"],"names":[],"mappings":";;;;AAEA,CAAA,GAAA,wMAAA,CAAA,MAAG,AAAD,EAAE"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/node_modules/foo/index.js"],"sourcesContent":["export function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_index_9dc02c.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_index_9dc02c.js new file mode 100644 index 0000000000000..0f61f99f3e107 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_index_9dc02c.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_index_9dc02c.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_09b9a1._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/basic/chunked/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_index_9dc02c.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_index_9dc02c.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/chunked/output/crates_turbopack-tests_tests_snapshot_basic_chunked_input_index_9dc02c.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js new file mode 100644 index 0000000000000..f490af11ac233 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js @@ -0,0 +1,9 @@ +const inlined = 3; +const message = getMessage(); + +console.log("Hello," + " world!", inlined, message); +console.log(message); + +function getMessage() { + return "Hello"; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/options.json new file mode 100644 index 0000000000000..c9b6a3ecaf36a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/options.json @@ -0,0 +1,4 @@ +{ + "runtime": "NodeJs", + "minifyType": "Minify" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/[turbopack]_runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/[turbopack]_runtime.js new file mode 100644 index 0000000000000..70c1228f1da78 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/[turbopack]_runtime.js @@ -0,0 +1,4 @@ +const RUNTIME_PUBLIC_PATH = "output/[turbopack]_runtime.js"; +const OUTPUT_ROOT = "crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify"; +const ASSET_PREFIX = "/"; +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/[turbopack]_runtime.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/[turbopack]_runtime.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/[turbopack]_runtime.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js new file mode 100644 index 0000000000000..79f463d7fbacc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js @@ -0,0 +1,3 @@ +module.exports={"[project]/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js [test] (ecmascript)":function({r:t,f:s,i:e,s:o,v:c,n:l,c:i,M:n,l:r,j:a,P:p,U:m,R:u,g:f,__dirname:d,m:g,e:j,t:b}){(function(){let t="Hello";console.log("Hello, world!",3,t),console.log(t)}).call(this)}}; + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js.map new file mode 100644 index 0000000000000..f5cab8e9ada88 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 0, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js"],"sourcesContent":["const inlined = 3;\nconst message = getMessage();\n\nconsole.log(\"Hello,\" + \" world!\", inlined, message);\nconsole.log(message);\n\nfunction getMessage() {\n return \"Hello\";\n}\n"],"names":[],"mappings":"qOACA,IAAM,EAMG,QAJT,QAAQ,GAAG,CAAC,gBAHI,EAG2B,GAC3C,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 0, "column": 306}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/index.entry.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/index.entry.js new file mode 100644 index 0000000000000..f0cc9f5f935b8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/index.entry.js @@ -0,0 +1,5 @@ +const CHUNK_PUBLIC_PATH = "output/index.entry.js"; +const runtime = require("./[turbopack]_runtime.js"); +runtime.loadChunk("output/crates_turbopack-tests_tests_snapshot_basic_ecmascript_minify_input_index_dc5b16.js"); +runtime.getOrInstantiateRuntimeModule("[project]/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js [test] (ecmascript)", CHUNK_PUBLIC_PATH); +module.exports = runtime.getOrInstantiateRuntimeModule("[project]/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/input/index.js [test] (ecmascript)", CHUNK_PUBLIC_PATH).exports; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/index.entry.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/index.entry.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/ecmascript_minify/output/index.entry.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js new file mode 100644 index 0000000000000..c5d9db6e1c7fc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +import { foo } from "foo"; + +foo(true); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js new file mode 100644 index 0000000000000..db97d18906764 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js @@ -0,0 +1,5 @@ +#!/usr/bin/env node + +export function foo(value) { + console.assert(value); +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/package.json new file mode 100644 index 0000000000000..14ab704d8f639 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/package.json @@ -0,0 +1,3 @@ +{ + "main": "index.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js new file mode 100644 index 0000000000000..09a17c27ac064 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$shebang$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +(0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$shebang$2f$input$2f$node_modules$2f$foo$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["foo"])(true); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "foo": ()=>foo +}); +function foo(value) { + console.assert(value); +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js.map new file mode 100644 index 0000000000000..d2dbe585a12f0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js"],"sourcesContent":["#!/usr/bin/env node\n\nimport { foo } from \"foo\";\n\nfoo(true);\n"],"names":[],"mappings":";;;;AAIA,CAAA,GAAA,wMAAA,CAAA,MAAG,AAAD,EAAE"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/node_modules/foo/index.js"],"sourcesContent":["#!/usr/bin/env node\n\nexport function foo(value) {\n console.assert(value);\n}\n"],"names":[],"mappings":";;;AAEO,SAAS,IAAI,KAAK;IACvB,QAAQ,MAAM,CAAC;AACjB"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_index_b957af.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_index_b957af.js new file mode 100644 index 0000000000000..60ffa00e8e96b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_index_b957af.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_index_b957af.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_a87633._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/basic/shebang/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_index_b957af.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_index_b957af.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/shebang/output/crates_turbopack-tests_tests_snapshot_basic_shebang_input_index_b957af.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js new file mode 100644 index 0000000000000..0f2170c5a2d33 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js @@ -0,0 +1,28 @@ +// import() doesn't care about whether a module is an async module or not +const UserApi = import("./UserAPI.js"); + +export const CreateUserAction = async (name) => { + console.log("Creating user", name); + // These are normal awaits, because they are in an async function + const { createUser } = await UserApi; + await createUser(name); +}; + +// You can place import() where you like +// Placing it at top-level will start loading and evaluating on +// module evaluation. +// see CreateUserAction above +// Here: Connecting to the DB starts when the application starts +// Placing it inside of an (async) function will start loading +// and evaluating when the function is called for the first time +// which basically makes it lazy-loaded. +// see AlternativeCreateUserAction below +// Here: Connecting to the DB starts when AlternativeCreateUserAction +// is called +export const AlternativeCreateUserAction = async (name) => { + const { createUser } = await import("./UserAPI.js"); + await createUser(name); +}; + +// Note: Using await import() at top-level doesn't make much sense +// except in rare cases. It will import modules sequentially. diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/README.md b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/README.md new file mode 100644 index 0000000000000..723f730dc5110 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/README.md @@ -0,0 +1,2 @@ +Adapted from webpack +https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/examples/top-level-await/README.md diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js new file mode 100644 index 0000000000000..810fe24f9aa7f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js @@ -0,0 +1,7 @@ +import { dbCall } from "./db-connection.js"; + +export const createUser = async (name) => { + const command = `CREATE USER ${name}`; + // This is a normal await, because it's in an async function + await dbCall({ command }); +}; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js new file mode 100644 index 0000000000000..412eee71b72cf --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js @@ -0,0 +1,18 @@ +const connectToDB = async (url) => { + console.log("connecting to db", url); + await new Promise((r) => setTimeout(r, 1000)); +}; + +// This is a top-level-await +await connectToDB("my-sql://example.com"); + +export const dbCall = async (data) => { + console.log("dbCall", data); + // This is a normal await, because it's in an async function + await new Promise((r) => setTimeout(r, 100)); + return "fake data"; +}; + +export const close = () => { + console.log("closes the DB connection"); +}; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js new file mode 100644 index 0000000000000..db6ef5c78f9a9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js @@ -0,0 +1,6 @@ +import { CreateUserAction } from "./Actions.js"; + +(async () => { + await CreateUserAction("John"); + console.log("created user John"); +})(); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js new file mode 100644 index 0000000000000..48d673772bf3b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js @@ -0,0 +1,40 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +// import() doesn't care about whether a module is an async module or not +__turbopack_esm__({ + "AlternativeCreateUserAction": ()=>AlternativeCreateUserAction, + "CreateUserAction": ()=>CreateUserAction +}); +const UserApi = __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js [test] (ecmascript, async loader)")(__turbopack_import__); +const CreateUserAction = async (name)=>{ + console.log("Creating user", name); + // These are normal awaits, because they are in an async function + const { createUser } = await UserApi; + await createUser(name); +}; +const AlternativeCreateUserAction = async (name)=>{ + const { createUser } = await __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js [test] (ecmascript, async loader)")(__turbopack_import__); + await createUser(name); +}; // Note: Using await import() at top-level doesn't make much sense + // except in rare cases. It will import modules sequentially. + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$Actions$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +(async ()=>{ + await (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$Actions$2e$js__$5b$test$5d$__$28$ecmascript$29$__["CreateUserAction"])("John"); + console.log("created user John"); +})(); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js.map new file mode 100644 index 0000000000000..f8e6630a057db --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/Actions.js"],"sourcesContent":["// import() doesn't care about whether a module is an async module or not\nconst UserApi = import(\"./UserAPI.js\");\n\nexport const CreateUserAction = async (name) => {\n console.log(\"Creating user\", name);\n // These are normal awaits, because they are in an async function\n const { createUser } = await UserApi;\n await createUser(name);\n};\n\n// You can place import() where you like\n// Placing it at top-level will start loading and evaluating on\n// module evaluation.\n// see CreateUserAction above\n// Here: Connecting to the DB starts when the application starts\n// Placing it inside of an (async) function will start loading\n// and evaluating when the function is called for the first time\n// which basically makes it lazy-loaded.\n// see AlternativeCreateUserAction below\n// Here: Connecting to the DB starts when AlternativeCreateUserAction\n// is called\nexport const AlternativeCreateUserAction = async (name) => {\n const { createUser } = await import(\"./UserAPI.js\");\n await createUser(name);\n};\n\n// Note: Using await import() at top-level doesn't make much sense\n// except in rare cases. It will import modules sequentially.\n"],"names":[],"mappings":"AAAA,yEAAyE;;;;;AACzE,MAAM;AAEC,MAAM,mBAAmB,OAAO;IACrC,QAAQ,GAAG,CAAC,iBAAiB;IAC7B,iEAAiE;IACjE,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM;IAC7B,MAAM,WAAW;AACnB;AAaO,MAAM,8BAA8B,OAAO;IAChD,MAAM,EAAE,UAAU,EAAE,GAAG;IACvB,MAAM,WAAW;AACnB,GAEA,kEAAkE;CAClE,mEAAmE"}}, + {"offset": {"line": 22, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 27, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js"],"sourcesContent":["import { CreateUserAction } from \"./Actions.js\";\n\n(async () => {\n await CreateUserAction(\"John\");\n console.log(\"created user John\");\n})();\n"],"names":[],"mappings":";;;;AAEA,CAAC;IACC,MAAM,CAAA,GAAA,iMAAA,CAAA,mBAAgB,AAAD,EAAE;IACvB,QAAQ,GAAG,CAAC;AACd,CAAC"}}, + {"offset": {"line": 35, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_UserAPI_0d64e4.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_UserAPI_0d64e4.js new file mode 100644 index 0000000000000..150e959a48bf2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_UserAPI_0d64e4.js @@ -0,0 +1,14 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_UserAPI_0d64e4.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js [test] (ecmascript, async loader)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__((__turbopack_import__) => { + return Promise.all([ + "output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js" +].map((chunk) => __turbopack_load__(chunk))).then(() => { + return __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js [test] (ecmascript)"); + }); +}); + +})()), +}]); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_UserAPI_0d64e4.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_UserAPI_0d64e4.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_UserAPI_0d64e4.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js new file mode 100644 index 0000000000000..4f0286e6d36cc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js @@ -0,0 +1,55 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, a: __turbopack_async_module__ }) => (() => { +"use strict"; + +__turbopack_async_module__(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try { +__turbopack_esm__({ + "close": ()=>close, + "dbCall": ()=>dbCall +}); +const connectToDB = async (url)=>{ + console.log("connecting to db", url); + await new Promise((r)=>setTimeout(r, 1000)); +}; +// This is a top-level-await +await connectToDB("my-sql://example.com"); +const dbCall = async (data)=>{ + console.log("dbCall", data); + // This is a normal await, because it's in an async function + await new Promise((r)=>setTimeout(r, 100)); + return "fake data"; +}; +const close = ()=>{ + console.log("closes the DB connection"); +}; +__turbopack_async_result__(); +} catch(e) { __turbopack_async_result__(e); } }, true); +})()), +"[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, a: __turbopack_async_module__ }) => (() => { +"use strict"; + +__turbopack_async_module__(async (__turbopack_handle_async_dependencies__, __turbopack_async_result__) => { try { +__turbopack_esm__({ + "createUser": ()=>createUser +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$db$2d$connection$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js [test] (ecmascript)"); +var __turbopack_async_dependencies__ = __turbopack_handle_async_dependencies__([ + __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$db$2d$connection$2e$js__$5b$test$5d$__$28$ecmascript$29$__ +]); +[__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$db$2d$connection$2e$js__$5b$test$5d$__$28$ecmascript$29$__] = __turbopack_async_dependencies__.then ? (await __turbopack_async_dependencies__)() : __turbopack_async_dependencies__; +"__TURBOPACK__ecmascript__hoisting__location__"; +; +const createUser = async (name)=>{ + const command = `CREATE USER ${name}`; + // This is a normal await, because it's in an async function + await (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$basic$2f$top$2d$level$2d$await$2f$input$2f$db$2d$connection$2e$js__$5b$test$5d$__$28$ecmascript$29$__["dbCall"])({ + command + }); +}; +__turbopack_async_result__(); +} catch(e) { __turbopack_async_result__(e); } }, false); +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js.map diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js.map new file mode 100644 index 0000000000000..eddd729626c3d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_e71653._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/db-connection.js"],"sourcesContent":["const connectToDB = async (url) => {\n console.log(\"connecting to db\", url);\n await new Promise((r) => setTimeout(r, 1000));\n};\n\n// This is a top-level-await\nawait connectToDB(\"my-sql://example.com\");\n\nexport const dbCall = async (data) => {\n console.log(\"dbCall\", data);\n // This is a normal await, because it's in an async function\n await new Promise((r) => setTimeout(r, 100));\n return \"fake data\";\n};\n\nexport const close = () => {\n console.log(\"closes the DB connection\");\n};\n"],"names":[],"mappings":";;;;AAAA,MAAM,cAAc,OAAO;IACzB,QAAQ,GAAG,CAAC,oBAAoB;IAChC,MAAM,IAAI,QAAQ,CAAC,IAAM,WAAW,GAAG;AACzC;AAEA,4BAA4B;AAC5B,MAAM,YAAY;AAEX,MAAM,SAAS,OAAO;IAC3B,QAAQ,GAAG,CAAC,UAAU;IACtB,4DAA4D;IAC5D,MAAM,IAAI,QAAQ,CAAC,IAAM,WAAW,GAAG;IACvC,OAAO;AACT;AAEO,MAAM,QAAQ;IACnB,QAAQ,GAAG,CAAC;AACd"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/UserAPI.js"],"sourcesContent":["import { dbCall } from \"./db-connection.js\";\n\nexport const createUser = async (name) => {\n const command = `CREATE USER ${name}`;\n // This is a normal await, because it's in an async function\n await dbCall({ command });\n};\n"],"names":[],"mappings":";;;;;;;;;;AAEO,MAAM,aAAa,OAAO;IAC/B,MAAM,UAAU,CAAC,YAAY,EAAE,KAAK,CAAC;IACrC,4DAA4D;IAC5D,MAAM,CAAA,GAAA,0MAAA,CAAA,SAAM,AAAD,EAAE;QAAE;IAAQ;AACzB"}}, + {"offset": {"line": 49, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_index_922e09.js b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_index_922e09.js new file mode 100644 index 0000000000000..39276fb233a60 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_index_922e09.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_index_922e09.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_3adb52._.js","output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_UserAPI_0d64e4.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/basic/top-level-await/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_index_922e09.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_index_922e09.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/basic/top-level-await/output/crates_turbopack-tests_tests_snapshot_basic_top-level-await_input_index_922e09.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js new file mode 100644 index 0000000000000..d3bdb3f0bf7f2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js @@ -0,0 +1,35 @@ +if (DEFINED_VALUE) { + console.log('DEFINED_VALUE'); +} + +if (DEFINED_TRUE) { + console.log('DEFINED_VALUE'); +} + +if (A.VERY.LONG.DEFINED.VALUE) { + console.log('A.VERY.LONG.DEFINED.VALUE'); +} + +if (process.env.NODE_ENV) { + console.log('something'); +} + +if (process.env.NODE_ENV === 'production') { + console.log('production'); +} + +var p = process; + +console.log(A.VERY.LONG.DEFINED.VALUE); +console.log(DEFINED_VALUE); +console.log(p.env.NODE_ENV); + +if (p.env.NODE_ENV === 'production') { + console.log('production'); +} + +p.env.NODE_ENV == 'production' ? console.log('production') : console.log('development'); + +// TODO short-circuit is not implemented yet +p.env.NODE_ENV != 'production' && console.log('development'); +p.env.NODE_ENV == 'production' && console.log('production'); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js new file mode 100644 index 0000000000000..5ba3ec6877d0c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js @@ -0,0 +1,35 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +if ("TURBOPACK compile-time truthy", 1) { + console.log('DEFINED_VALUE'); +} +if ("TURBOPACK compile-time truthy", 1) { + console.log('DEFINED_VALUE'); +} +if ("TURBOPACK compile-time value", JSON.parse('{"test":true}')) { + console.log('A.VERY.LONG.DEFINED.VALUE'); +} +if ("TURBOPACK compile-time truthy", 1) { + console.log('something'); +} +if ("TURBOPACK compile-time falsy", 0) { + "TURBOPACK unreachable"; +} +var p = process; +console.log(("TURBOPACK compile-time value", JSON.parse('{"test":true}'))); +console.log(("TURBOPACK compile-time value", "value")); +console.log(("TURBOPACK compile-time value", "development")); +if ("TURBOPACK compile-time falsy", 0) { + "TURBOPACK unreachable"; +} +("TURBOPACK compile-time falsy", 0) ? ("TURBOPACK unreachable", undefined) : console.log('development'); +// TODO short-circuit is not implemented yet +("TURBOPACK compile-time value", "development") != 'production' && console.log('development'); +("TURBOPACK compile-time value", "development") == 'production' && console.log('production'); + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js.map new file mode 100644 index 0000000000000..b469b41139cc4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js"],"sourcesContent":["if (DEFINED_VALUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (DEFINED_TRUE) {\n console.log('DEFINED_VALUE');\n}\n\nif (A.VERY.LONG.DEFINED.VALUE) {\n console.log('A.VERY.LONG.DEFINED.VALUE');\n}\n\nif (process.env.NODE_ENV) {\n console.log('something');\n}\n\nif (process.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\nvar p = process;\n\nconsole.log(A.VERY.LONG.DEFINED.VALUE);\nconsole.log(DEFINED_VALUE);\nconsole.log(p.env.NODE_ENV);\n\nif (p.env.NODE_ENV === 'production') {\n console.log('production');\n}\n\np.env.NODE_ENV == 'production' ? console.log('production') : console.log('development');\n\n// TODO short-circuit is not implemented yet\np.env.NODE_ENV != 'production' && console.log('development');\np.env.NODE_ENV == 'production' && console.log('production');\n"],"names":[],"mappings":"AAAA,wCAAmB;IACjB,QAAQ,GAAG,CAAC;AACd;AAEA,wCAAkB;IAChB,QAAQ,GAAG,CAAC;AACd;AAEA,iEAA+B;IAC7B,QAAQ,GAAG,CAAC;AACd;AAEA,wCAA0B;IACxB,QAAQ,GAAG,CAAC;AACd;AAEA;;;AAIA,IAAI,IAAI;AAER,QAAQ,GAAG;AACX,QAAQ,GAAG;AACX,QAAQ,GAAG;AAEX;;;AAIA,6EAA6D,QAAQ,GAAG,CAAC;AAEzE,4CAA4C;AAC5C,mDAAkB,gBAAgB,QAAQ,GAAG,CAAC;AAC9C,mDAAkB,gBAAgB,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 30, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_5931c6.js b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_5931c6.js new file mode 100644 index 0000000000000..0e47923bbb99f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_5931c6.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_5931c6.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_49857f.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/comptime/define/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_5931c6.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_5931c6.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/comptime/define/output/crates_turbopack-tests_tests_snapshot_comptime_define_input_index_5931c6.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css new file mode 100644 index 0000000000000..4474c22d51998 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css @@ -0,0 +1,9 @@ +@import "https://example.com/stylesheet1.css"; +@import "https://example.com/withquote\".css"; +@import "./other.css"; +@import "./withduplicateurl.css"; +@import url("https://example.com/stylesheet2.css"); + +body { + background-color: blue; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.js new file mode 100644 index 0000000000000..3a29aed15952e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.js @@ -0,0 +1 @@ +import "./index.css"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css new file mode 100644 index 0000000000000..fee6dc0923e7b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css @@ -0,0 +1,3 @@ +.foo { + background-color: red; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css new file mode 100644 index 0000000000000..1fa5bbfd1af30 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css @@ -0,0 +1,6 @@ +/* This should not be duplicated */ +@import "https://example.com/stylesheet1.css"; + +.bar { + background-color:green; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css new file mode 100644 index 0000000000000..49b6d5bb68962 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css [test] (css, ) */ +.bar { + background-color: green; +} + +/*# sourceMappingURL=a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css.map new file mode 100644 index 0000000000000..abfbc2588c793 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css"],"sourcesContent":["/* This should not be duplicated */\n@import \"https://example.com/stylesheet1.css\";\n\n.bar {\n background-color:green;\n}\n"],"names":[],"mappings":"AAGA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css new file mode 100644 index 0000000000000..63b8726a9fd50 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css @@ -0,0 +1,22 @@ +@import "https://example.com/stylesheet1.css"; +@import "https://example.com/withquote\".css"; +@import "https://example.com/stylesheet2.css"; +/* [project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css [test] (css, ) */ +.foo { + background-color: red; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css [test] (css, ) */ +.bar { + background-color: green; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css [test] (css) */ +body { + background-color: #00f; +} + + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css.map new file mode 100644 index 0000000000000..2d9ddce40031b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css"],"sourcesContent":["/* This should not be duplicated */\n@import \"https://example.com/stylesheet1.css\";\n\n.bar {\n background-color:green;\n}\n"],"names":[],"mappings":"AAGA"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css"],"sourcesContent":["@import \"https://example.com/stylesheet1.css\";\n@import \"https://example.com/withquote\\\".css\";\n@import \"./other.css\";\n@import \"./withduplicateurl.css\";\n@import url(\"https://example.com/stylesheet2.css\");\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAMA"}}, + {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js new file mode 100644 index 0000000000000..ba94954aa8b20 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js @@ -0,0 +1,11 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js.map new file mode 100644 index 0000000000000..bf40d9e41cc57 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css new file mode 100644 index 0000000000000..499f01f90c57d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css [test] (css) */ +body { + background-color: #00f; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css.map new file mode 100644 index 0000000000000..ea443b3ac32d8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css"],"sourcesContent":["@import \"https://example.com/stylesheet1.css\";\n@import \"https://example.com/withquote\\\".css\";\n@import \"./other.css\";\n@import \"./withduplicateurl.css\";\n@import url(\"https://example.com/stylesheet2.css\");\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAMA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_9f23d7.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_9f23d7.js new file mode 100644 index 0000000000000..66a6fb550b78e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_9f23d7.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_9f23d7.js", + {}, + {"otherChunks":[{"path":"output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_90d01b._.css","included":["[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css [test] (css, )","[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/withduplicateurl.css [test] (css, )","[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.css [test] (css)"],"moduleChunks":["output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css","output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css","output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_7d7e1c.css","output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css","output/a587c_tests_snapshot_css_absolute-uri-import_input_withduplicateurl_d96429.css"]},"output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_0e8055.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_9f23d7.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_9f23d7.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_index_9f23d7.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css new file mode 100644 index 0000000000000..808248ce5528c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css [test] (css, ) */ +.foo { + background-color: red; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css.map new file mode 100644 index 0000000000000..0bd0381fd9a54 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/output/crates_turbopack-tests_tests_snapshot_css_absolute-uri-import_input_other_d96429.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/absolute-uri-import/input/other.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css new file mode 100644 index 0000000000000..5af5c314984e0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css @@ -0,0 +1,5 @@ +@import url("./b.css") supports(font-format(woff2)); + +.imported { + color: cyan; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css new file mode 100644 index 0000000000000..d0fbf6420012b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css @@ -0,0 +1,6 @@ +@import url("./c.css") layer(foo) (orientation: landscape); +@import url("./c.css") layer(bar) (orientation: portrait); + +.imported { + color: orange; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css new file mode 100644 index 0000000000000..9c9b32924962d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css @@ -0,0 +1,3 @@ +.imported { + color: red; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/index.js new file mode 100644 index 0000000000000..4fe51c72d641f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/index.js @@ -0,0 +1 @@ +import "./style.css"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css new file mode 100644 index 0000000000000..7e7205915f6d1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css @@ -0,0 +1,5 @@ +@import url("./a.css") layer(layer) supports(not(display: inline-grid)) print; + +.style { + color: yellow; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css new file mode 100644 index 0000000000000..a384cb0b47659 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css @@ -0,0 +1,55 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css [test] (css, layer(layer) layer(foo) print and (orientation: landscape) supports(not(display: inline-grid)) supports(font-format(woff2))) */ +@layer layer.foo { +@media print and (orientation: landscape) { +@supports not(display: inline-grid) and font-format(woff2) { +.imported { + color: red; +} + +} +} +} + +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css [test] (css, layer(layer) layer(bar) print and (orientation: portrait) supports(not(display: inline-grid)) supports(font-format(woff2))) */ +@layer layer.bar { +@media print and (orientation: portrait) { +@supports not(display: inline-grid) and font-format(woff2) { +.imported { + color: red; +} + +} +} +} + +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css [test] (css, layer(layer) print supports(not(display: inline-grid)) supports(font-format(woff2))) */ +@layer layer { +@media print { +@supports not(display: inline-grid) and font-format(woff2) { +.imported { + color: orange; +} + +} +} +} + +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css [test] (css, layer(layer) print supports(not(display: inline-grid))) */ +@layer layer { +@media print { +@supports not(display: inline-grid) { +.imported { + color: #0ff; +} + +} +} +} + +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css [test] (css) */ +.style { + color: #ff0; +} + + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css.map new file mode 100644 index 0000000000000..0dc122cbe28b7 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css.map @@ -0,0 +1,15 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 28, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css"],"sourcesContent":["@import url(\"./c.css\") layer(foo) (orientation: landscape);\n@import url(\"./c.css\") layer(bar) (orientation: portrait);\n\n.imported {\n color: orange;\n}\n"],"names":[],"mappings":"AAGA"}}, + {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 40, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css"],"sourcesContent":["@import url(\"./b.css\") supports(font-format(woff2));\n\n.imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 43, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 49, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css"],"sourcesContent":["@import url(\"./a.css\") layer(layer) supports(not(display: inline-grid)) print;\n\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 52, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css new file mode 100644 index 0000000000000..96003109c0291 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css @@ -0,0 +1,12 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css [test] (css, layer(layer) print supports(not(display: inline-grid))) */ +@layer layer { +@media print { +@supports not(display: inline-grid) { +.imported { + color: #0ff; +} + +} +} +} +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css.map new file mode 100644 index 0000000000000..7604512ec73ba --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css"],"sourcesContent":["@import url(\"./b.css\") supports(font-format(woff2));\n\n.imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css new file mode 100644 index 0000000000000..f9142528f040e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css @@ -0,0 +1,12 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css [test] (css, layer(layer) print supports(not(display: inline-grid)) supports(font-format(woff2))) */ +@layer layer { +@media print { +@supports not(display: inline-grid) and font-format(woff2) { +.imported { + color: orange; +} + +} +} +} +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css.map new file mode 100644 index 0000000000000..bce1e5b1034ac --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css"],"sourcesContent":["@import url(\"./c.css\") layer(foo) (orientation: landscape);\n@import url(\"./c.css\") layer(bar) (orientation: portrait);\n\n.imported {\n color: orange;\n}\n"],"names":[],"mappings":"AAGA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css new file mode 100644 index 0000000000000..bf446c395d067 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css @@ -0,0 +1,12 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css [test] (css, layer(layer) layer(bar) print and (orientation: portrait) supports(not(display: inline-grid)) supports(font-format(woff2))) */ +@layer layer.bar { +@media print and (orientation: portrait) { +@supports not(display: inline-grid) and font-format(woff2) { +.imported { + color: red; +} + +} +} +} +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css.map new file mode 100644 index 0000000000000..0dee96844eed0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css new file mode 100644 index 0000000000000..03cb4b9256836 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css @@ -0,0 +1,12 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css [test] (css, layer(layer) layer(foo) print and (orientation: landscape) supports(not(display: inline-grid)) supports(font-format(woff2))) */ +@layer layer.foo { +@media print and (orientation: landscape) { +@supports not(display: inline-grid) and font-format(woff2) { +.imported { + color: red; +} + +} +} +} +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css.map new file mode 100644 index 0000000000000..0dee96844eed0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css"],"sourcesContent":[".imported {\n color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js new file mode 100644 index 0000000000000..663718f36b3f5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js @@ -0,0 +1,11 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js.map new file mode 100644 index 0000000000000..bf40d9e41cc57 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_e6e7e4.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_e6e7e4.js new file mode 100644 index 0000000000000..76360b13e86c2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_e6e7e4.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_e6e7e4.js", + {}, + {"otherChunks":[{"path":"output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_86e399._.css","included":["[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css [test] (css, layer(layer) layer(foo) print and (orientation: landscape) supports(not(display: inline-grid)) supports(font-format(woff2)))","[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/c.css [test] (css, layer(layer) layer(bar) print and (orientation: portrait) supports(not(display: inline-grid)) supports(font-format(woff2)))","[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/b.css [test] (css, layer(layer) print supports(not(display: inline-grid)) supports(font-format(woff2)))","[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/a.css [test] (css, layer(layer) print supports(not(display: inline-grid)))","[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css [test] (css)"],"moduleChunks":["output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css","output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css","output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css","output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css","output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css","output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_823b12.css","output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_c_163c6a.css","output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_b_dc1da6.css","output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_a_bf62fc.css"]},"output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_356166.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_e6e7e4.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_e6e7e4.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_index_e6e7e4.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css new file mode 100644 index 0000000000000..31bea55cfb48a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css [test] (css) */ +.style { + color: #ff0; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css.map new file mode 100644 index 0000000000000..48fe5b49d62fa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/chained-attributes/output/crates_turbopack-tests_tests_snapshot_css_chained-attributes_input_style_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/chained-attributes/input/style.css"],"sourcesContent":["@import url(\"./a.css\") layer(layer) supports(not(display: inline-grid)) print;\n\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js new file mode 100644 index 0000000000000..0378809691424 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js @@ -0,0 +1,3 @@ +import "./style.css"; + +console.log('css-legacy-nesting'); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css new file mode 100644 index 0000000000000..853507cf6de8b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css @@ -0,0 +1,12 @@ +.prose :where(table):not(:where([class~="not-prose"], [class~="not-prose"] *)) { + tr { + td:first-child { + text-wrap: nowrap; + } + } + text-wrap: initial; +} + +.prose :where(code):not(:where([class~="not-prose"], [class~="not-prose"] *)) { + text-wrap: nowrap; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_276773.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_276773.js new file mode 100644 index 0000000000000..b097e5ec977b5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_276773.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_276773.js", + {}, + {"otherChunks":[{"path":"output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css","included":["[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css [test] (css)"],"moduleChunks":["output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css"]},"output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_276773.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_276773.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_276773.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js new file mode 100644 index 0000000000000..b93bcd884ca82 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js @@ -0,0 +1,12 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +; +console.log('css-legacy-nesting'); + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js.map new file mode 100644 index 0000000000000..fae772f721a68 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_index_8e60f2.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/index.js"],"sourcesContent":["import \"./style.css\";\n\nconsole.log('css-legacy-nesting');\n"],"names":[],"mappings":";;AAEA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css new file mode 100644 index 0000000000000..8a1d6f9603aa7 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css @@ -0,0 +1,14 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css [test] (css) */ +.prose :where(table):not(:where([class~="not-prose"], [class~="not-prose"] *)) { + text-wrap: initial; +} + +.prose :where(table):not(:where([class~="not-prose"], [class~="not-prose"] *)) tr td:first-child { + text-wrap: nowrap; +} + +.prose :where(code):not(:where([class~="not-prose"], [class~="not-prose"] *)) { + text-wrap: nowrap; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css.map new file mode 100644 index 0000000000000..f539062ec0af1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css"],"sourcesContent":[".prose :where(table):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n tr {\n td:first-child {\n text-wrap: nowrap;\n }\n }\n text-wrap: initial;\n}\n\n.prose :where(code):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n text-wrap: nowrap;\n}\n"],"names":[],"mappings":"AAAA;;;;AAEI;;;;AAOJ"}}, + {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css new file mode 100644 index 0000000000000..c17f08a2a82d5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css @@ -0,0 +1,15 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css [test] (css) */ +.prose :where(table):not(:where([class~="not-prose"], [class~="not-prose"] *)) { + text-wrap: initial; +} + +.prose :where(table):not(:where([class~="not-prose"], [class~="not-prose"] *)) tr td:first-child { + text-wrap: nowrap; +} + +.prose :where(code):not(:where([class~="not-prose"], [class~="not-prose"] *)) { + text-wrap: nowrap; +} + + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css.map new file mode 100644 index 0000000000000..f539062ec0af1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/output/crates_turbopack-tests_tests_snapshot_css_css-legacy-nesting_input_style_c557a7.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-legacy-nesting/input/style.css"],"sourcesContent":[".prose :where(table):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n tr {\n td:first-child {\n text-wrap: nowrap;\n }\n }\n text-wrap: initial;\n}\n\n.prose :where(code):not(:where([class~=\"not-prose\"], [class~=\"not-prose\"] *)) {\n text-wrap: nowrap;\n}\n"],"names":[],"mappings":"AAAA;;;;AAEI;;;;AAOJ"}}, + {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js new file mode 100644 index 0000000000000..75a49bd8c3fc8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js @@ -0,0 +1,3 @@ +import style from "./style.module.css"; + +console.log(style, import("./style.module.css")); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css new file mode 100644 index 0000000000000..0c7efbbe0aebb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css @@ -0,0 +1,4 @@ +.module-style { + grid-template-areas: 'checkbox avatar content actions menu'; +} + diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/79fb1_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_css_32764e._.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/79fb1_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_css_32764e._.js new file mode 100644 index 0000000000000..fe68b944b37a1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/79fb1_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_css_32764e._.js @@ -0,0 +1,12 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_css_32764e._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css module, async loader)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__((__turbopack_import__) => { + return Promise.resolve().then(() => { + return __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css module)"); + }); +}); + +})()), +}]); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/79fb1_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_css_32764e._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/79fb1_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_css_32764e._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/79fb1_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_css_32764e._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js new file mode 100644 index 0000000000000..ecb8113caf76b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js @@ -0,0 +1,22 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css module)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__({ + "module-style": "style-module__mnEziG__module-style", +}); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$css$2f$css$2d$modules$2f$input$2f$style$2e$module$2e$css__$5b$test$5d$__$28$css__module$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css module)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$css$2f$css$2d$modules$2f$input$2f$style$2e$module$2e$css__$5b$test$5d$__$28$css__module$29$__["default"], __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css module, async loader)")(__turbopack_import__)); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js.map diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js.map new file mode 100644 index 0000000000000..c9a39cf46b0fd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"module-style\": \"style-module__mnEziG__module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js"],"sourcesContent":["import style from \"./style.module.css\";\n\nconsole.log(style, import(\"./style.module.css\"));\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,kMAAA,CAAA,UAAK"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_index_3c81e2.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_index_3c81e2.js new file mode 100644 index 0000000000000..c9f341daa7dd6 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_index_3c81e2.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_index_3c81e2.js", + {}, + {"otherChunks":[{"path":"output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css","included":["[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css)"],"moduleChunks":["output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css"]},"output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_8abc52._.js","output/79fb1_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_css_32764e._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_index_3c81e2.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_index_3c81e2.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_index_3c81e2.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css new file mode 100644 index 0000000000000..c3b83f640b96e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css @@ -0,0 +1,7 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css) */ +.style-module__mnEziG__module-style { + grid-template-areas: "checkbox avatar content actions menu"; +} + + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css.map*/ diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css.map new file mode 100644 index 0000000000000..1d1ae26f1aadb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_71f14f.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css"],"sourcesContent":[".module-style {\n grid-template-areas: 'checkbox avatar content actions menu';\n}\n\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css new file mode 100644 index 0000000000000..bd998c7e0439f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css [test] (css) */ +.style-module__mnEziG__module-style { + grid-template-areas: "checkbox avatar content actions menu"; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css.map*/ diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css.map new file mode 100644 index 0000000000000..1d1ae26f1aadb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css-modules/output/crates_turbopack-tests_tests_snapshot_css_css-modules_input_style_module_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css-modules/input/style.module.css"],"sourcesContent":[".module-style {\n grid-template-areas: 'checkbox avatar content actions menu';\n}\n\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css new file mode 100644 index 0000000000000..efe9ce6085d8b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css @@ -0,0 +1,3 @@ +.imported { + color: cyan; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/index.js new file mode 100644 index 0000000000000..e52a9ac0bb08c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/index.js @@ -0,0 +1,7 @@ +import "foo/style.css"; +import "foo"; +import "./style.css"; +import fooStyle from "foo/style.module.css"; +import style from "./style.module.css"; + +console.log(style, fooStyle, import("foo")); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/index.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/index.css new file mode 100644 index 0000000000000..e1ccfc2c9e88c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/index.css @@ -0,0 +1 @@ +.foo-index { color: red; } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/package.json new file mode 100644 index 0000000000000..41413b6e63efe --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/package.json @@ -0,0 +1,3 @@ +{ + "main": "style.css" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css new file mode 100644 index 0000000000000..719edddbb7aa2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css @@ -0,0 +1 @@ +.foo-style { color: green; } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css new file mode 100644 index 0000000000000..7cccba9626e4f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css @@ -0,0 +1 @@ +.foo-module-style { color: blue; } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/style.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/style.css new file mode 100644 index 0000000000000..38ceb56638d8e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/style.css @@ -0,0 +1,8 @@ +@import url("./imported.css"); +/* De-duplicate similar imports */ +@import url("../input/imported.css"); +/* But not if they have different attributes */ +@import url("./imported.css") layer(layer) print; +.style { + color: yellow; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css new file mode 100644 index 0000000000000..cd9abdebd64a2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css @@ -0,0 +1,17 @@ +.module-style { + color: magenta; + > h1, + + .inner { + background: purple; + } +} + +.composed-module-style { + composes: foo-module-style from "foo/style.module.css"; + color: green; +} + +.another-composed-module-style { + composes: foo-module-style from "foo/style.module.css"; + color: yellow; +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css new file mode 100644 index 0000000000000..3886476782900 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css [test] (css) */ +.foo-style { + color: green; +} + +/*# sourceMappingURL=8697f_foo_style_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css.map new file mode 100644 index 0000000000000..b077bf6e09cbf --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css"],"sourcesContent":[".foo-style { color: green; }\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_css_01e50f._.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_css_01e50f._.js new file mode 100644 index 0000000000000..d808884d3adef --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_css_01e50f._.js @@ -0,0 +1,10 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/8697f_foo_style_css_01e50f._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css [test] (css, async loader)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__((__turbopack_import__) => { + return Promise.resolve(); +}); + +})()), +}]); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_css_01e50f._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_css_01e50f._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_css_01e50f._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css new file mode 100644 index 0000000000000..96dbab3ef0408 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css) */ +.style-module__6THCLW__foo-module-style { + color: #00f; +} + +/*# sourceMappingURL=8697f_foo_style_module_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css.map new file mode 100644 index 0000000000000..ef8b8cd2f4eaa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/8697f_foo_style_module_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css"],"sourcesContent":[".foo-module-style { color: blue; }\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js new file mode 100644 index 0000000000000..f5c0737341f90 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js @@ -0,0 +1,37 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css [test] (css module)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__({ + "another-composed-module-style": "style-module__YW1Vbq__another-composed-module-style" + " " + __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)")["foo-module-style"], + "composed-module-style": "style-module__YW1Vbq__composed-module-style" + " " + __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)")["foo-module-style"], + "inner": "style-module__YW1Vbq__inner", + "module-style": "style-module__YW1Vbq__module-style", +}); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$css$2f$css$2f$input$2f$node_modules$2f$foo$2f$style$2e$module$2e$css__$5b$test$5d$__$28$css__module$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$css$2f$css$2f$input$2f$style$2e$module$2e$css__$5b$test$5d$__$28$css__module$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css [test] (css module)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$css$2f$css$2f$input$2f$style$2e$module$2e$css__$5b$test$5d$__$28$css__module$29$__["default"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$css$2f$css$2f$input$2f$node_modules$2f$foo$2f$style$2e$module$2e$css__$5b$test$5d$__$28$css__module$29$__["default"], __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css [test] (css, async loader)")(__turbopack_import__)); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__({ + "foo-module-style": "style-module__6THCLW__foo-module-style", +}); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js.map new file mode 100644 index 0000000000000..79093448e0f33 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"another-composed-module-style\": \"style-module__YW1Vbq__another-composed-module-style\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)\")[\"foo-module-style\"],\n \"composed-module-style\": \"style-module__YW1Vbq__composed-module-style\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)\")[\"foo-module-style\"],\n \"inner\": \"style-module__YW1Vbq__inner\",\n \"module-style\": \"style-module__YW1Vbq__module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/index.js"],"sourcesContent":["import \"foo/style.css\";\nimport \"foo\";\nimport \"./style.css\";\nimport fooStyle from \"foo/style.module.css\";\nimport style from \"./style.module.css\";\n\nconsole.log(style, fooStyle, import(\"foo\"));\n"],"names":[],"mappings":";;;;;;;;;AAMA,QAAQ,GAAG,CAAC,uLAAA,CAAA,UAAK,EAAE,8MAAA,CAAA,UAAQ"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"foo-module-style\": \"style-module__6THCLW__foo-module-style\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, + {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css new file mode 100644 index 0000000000000..1ff87386b2b2a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css @@ -0,0 +1,53 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css [test] (css, ) */ +.imported { + color: #0ff; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css [test] (css, layer(layer) print) */ +@layer layer { +@media print { +.imported { + color: #0ff; +} + +} +} + +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css [test] (css) */ +.style { + color: #ff0; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css [test] (css) */ +.style-module__YW1Vbq__module-style { + color: #f0f; +} + +.style-module__YW1Vbq__module-style > h1, .style-module__YW1Vbq__module-style + .style-module__YW1Vbq__inner { + background: purple; +} + +.style-module__YW1Vbq__composed-module-style { + color: green; +} + +.style-module__YW1Vbq__another-composed-module-style { + color: #ff0; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css [test] (css) */ +.foo-style { + color: green; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css) */ +.style-module__6THCLW__foo-module-style { + color: #00f; +} + + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css.map new file mode 100644 index 0000000000000..521c93bc84e7e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css.map @@ -0,0 +1,17 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css"],"sourcesContent":["@import url(\"./imported.css\");\n/* De-duplicate similar imports */\n@import url(\"../input/imported.css\");\n/* But not if they have different attributes */\n@import url(\"./imported.css\") layer(layer) print;\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAKA"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css"],"sourcesContent":[".module-style {\n color: magenta;\n > h1,\n + .inner {\n background: purple;\n }\n}\n\n.composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: green;\n}\n\n.another-composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: yellow;\n}"],"names":[],"mappings":"AAAA;;;;AAEE;;;;AAMF;;;;AAKA"}}, + {"offset": {"line": 38, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 41, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css"],"sourcesContent":[".foo-style { color: green; }\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 44, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 47, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css"],"sourcesContent":[".foo-module-style { color: blue; }\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 50, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css new file mode 100644 index 0000000000000..d3c39213b4951 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css @@ -0,0 +1,10 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css [test] (css, layer(layer) print) */ +@layer layer { +@media print { +.imported { + color: #0ff; +} + +} +} +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css.map new file mode 100644 index 0000000000000..b295305bc5aa4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css new file mode 100644 index 0000000000000..a5bb75e575468 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css [test] (css, ) */ +.imported { + color: #0ff; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css.map new file mode 100644 index 0000000000000..e2b22b44eb1de --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css"],"sourcesContent":[".imported {\n color: cyan;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_index_71eb7f.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_index_71eb7f.js new file mode 100644 index 0000000000000..f5e30854a038f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_index_71eb7f.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_css_css_input_index_71eb7f.js", + {}, + {"otherChunks":[{"path":"output/crates_turbopack-tests_tests_snapshot_css_css_input_f3a64b._.css","included":["[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css [test] (css, )","[project]/crates/turbopack-tests/tests/snapshot/css/css/input/imported.css [test] (css, layer(layer) print)","[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css [test] (css)","[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css [test] (css)","[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.css [test] (css)","[project]/crates/turbopack-tests/tests/snapshot/css/css/input/node_modules/foo/style.module.css [test] (css)"],"moduleChunks":["output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css","output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css","output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css","output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css","output/8697f_foo_style_7d7e1c.css","output/8697f_foo_style_module_7d7e1c.css","output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css","output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_d96429.css","output/crates_turbopack-tests_tests_snapshot_css_css_input_imported_9f97d9.css"]},"output/crates_turbopack-tests_tests_snapshot_css_css_input_34944c._.js","output/8697f_foo_style_css_01e50f._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/css/css/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_index_71eb7f.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_index_71eb7f.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_index_71eb7f.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css new file mode 100644 index 0000000000000..b2bde640b6b54 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css [test] (css) */ +.style { + color: #ff0; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css.map new file mode 100644 index 0000000000000..d0dfce55efcfc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.css"],"sourcesContent":["@import url(\"./imported.css\");\n/* De-duplicate similar imports */\n@import url(\"../input/imported.css\");\n/* But not if they have different attributes */\n@import url(\"./imported.css\") layer(layer) print;\n.style {\n color: yellow;\n}\n"],"names":[],"mappings":"AAKA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css new file mode 100644 index 0000000000000..261c6e342d283 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css @@ -0,0 +1,18 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css [test] (css) */ +.style-module__YW1Vbq__module-style { + color: #f0f; +} + +.style-module__YW1Vbq__module-style > h1, .style-module__YW1Vbq__module-style + .style-module__YW1Vbq__inner { + background: purple; +} + +.style-module__YW1Vbq__composed-module-style { + color: green; +} + +.style-module__YW1Vbq__another-composed-module-style { + color: #ff0; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css.map new file mode 100644 index 0000000000000..1fd4f12a986c2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/css/output/crates_turbopack-tests_tests_snapshot_css_css_input_style_module_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/css/input/style.module.css"],"sourcesContent":[".module-style {\n color: magenta;\n > h1,\n + .inner {\n background: purple;\n }\n}\n\n.composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: green;\n}\n\n.another-composed-module-style {\n composes: foo-module-style from \"foo/style.module.css\";\n color: yellow;\n}"],"names":[],"mappings":"AAAA;;;;AAEE;;;;AAMF;;;;AAKA"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css new file mode 100644 index 0000000000000..92b82a36e8934 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css @@ -0,0 +1,3 @@ +.bar { + background-color: green; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css new file mode 100644 index 0000000000000..9019c957741aa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css @@ -0,0 +1,5 @@ +@import "other.css"; + +body { + background-color: blue; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.js new file mode 100644 index 0000000000000..3a29aed15952e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.js @@ -0,0 +1 @@ +import "./index.css"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css new file mode 100644 index 0000000000000..75f117bf26e89 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css @@ -0,0 +1,5 @@ +@import "another.css"; + +.foo { + background-color: red; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css new file mode 100644 index 0000000000000..232595d8bdfdb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css [test] (css, ) */ +.bar { + background-color: green; +} + +/*# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css.map new file mode 100644 index 0000000000000..9e6463624945f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css"],"sourcesContent":[".bar {\n background-color: green;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css new file mode 100644 index 0000000000000..a3648aefb5c93 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css @@ -0,0 +1,19 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css [test] (css, ) */ +.bar { + background-color: green; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css [test] (css, ) */ +.foo { + background-color: red; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css [test] (css) */ +body { + background-color: #00f; +} + + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css.map new file mode 100644 index 0000000000000..cb8a40708749e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css"],"sourcesContent":[".bar {\n background-color: green;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css"],"sourcesContent":["@import \"another.css\";\n\n.foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css"],"sourcesContent":["@import \"other.css\";\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css new file mode 100644 index 0000000000000..74c4e4ed39ba9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css [test] (css) */ +body { + background-color: #00f; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css.map new file mode 100644 index 0000000000000..e937ad402c60b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css"],"sourcesContent":["@import \"other.css\";\n\nbody {\n background-color: blue;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js new file mode 100644 index 0000000000000..8157d0dabdba1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js @@ -0,0 +1,11 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js.map new file mode 100644 index 0000000000000..bf40d9e41cc57 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_f43cc9.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_f43cc9.js new file mode 100644 index 0000000000000..a4715c76e7503 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_f43cc9.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_f43cc9.js", + {}, + {"otherChunks":[{"path":"output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_dc7e6c._.css","included":["[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/another.css [test] (css, )","[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css [test] (css, )","[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.css [test] (css)"],"moduleChunks":["output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css","output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css","output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_7d7e1c.css","output/79fb1_turbopack-tests_tests_snapshot_css_relative-uri-import_input_another_d96429.css","output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css"]},"output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_c2ad30.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_f43cc9.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_f43cc9.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_index_f43cc9.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css new file mode 100644 index 0000000000000..cbb253e47b5cd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css [test] (css, ) */ +.foo { + background-color: red; +} + +/*# sourceMappingURL=crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css.map new file mode 100644 index 0000000000000..fd3d15054a0ec --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/output/crates_turbopack-tests_tests_snapshot_css_relative-uri-import_input_other_d96429.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/relative-uri-import/input/other.css"],"sourcesContent":["@import \"another.css\";\n\n.foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAEA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/index.js new file mode 100644 index 0000000000000..4fe51c72d641f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/index.js @@ -0,0 +1 @@ +import "./style.css"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css new file mode 100644 index 0000000000000..98add921202f9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css @@ -0,0 +1,5 @@ +@supports ((-webkit-mask: url("")) or (mask: url(""))) { + .supports-url-in-query { + color: red; + } +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/options.json new file mode 100644 index 0000000000000..ef4bb46ab0e56 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/options.json @@ -0,0 +1,3 @@ +{ + "useSwcCss": true +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_8263e6.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_8263e6.js new file mode 100644 index 0000000000000..af82544c1ef47 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_8263e6.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_8263e6.js", + {}, + {"otherChunks":[{"path":"output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css","included":["[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css [test] (swc css)"],"moduleChunks":["output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css"]},"output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_8263e6.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_8263e6.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_8263e6.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js new file mode 100644 index 0000000000000..b5829da128ecc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js @@ -0,0 +1,11 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +; + +}.call(this) }), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js.map new file mode 100644 index 0000000000000..bf40d9e41cc57 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_index_c70a2c.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css new file mode 100644 index 0000000000000..9ff935685d88f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css @@ -0,0 +1,7 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css [test] (swc css) */ +@supports ((-webkit-mask: url("")) or (mask: url(""))) { + .supports-url-in-query { + color: red; + } +} +/*# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css.map new file mode 100644 index 0000000000000..6caf936272238 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_4b6496.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css"],"sourcesContent":["@supports ((-webkit-mask: url(\"\")) or (mask: url(\"\"))) {\n .supports-url-in-query {\n color: red;\n }\n}\n"],"names":[],"mappings":"AAAA,CAAC,QAAQ,CAAE,CAAC,CAAC,AAAD,YAAY,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,IAAM,CAAC,AAAD,IAAI,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,CAAC,CAAE,CAAC;EACtD,CAAC,qBAAqB,CAAC,CAAC;IACtB,KAAK,EAAE,GAAG;EACZ,CAAC;AACH,CAAC"}}, + {"offset": {"line": 5, "column": 1}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css new file mode 100644 index 0000000000000..945b18d49eb9d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css @@ -0,0 +1,8 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css [test] (swc css) */ +@supports ((-webkit-mask: url("")) or (mask: url(""))) { + .supports-url-in-query { + color: red; + } +} + +/*# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css.map new file mode 100644 index 0000000000000..6caf936272238 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/output/79fb1_turbopack-tests_tests_snapshot_css_url-in-supports-query_input_style_a5a67a.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/css/url-in-supports-query/input/style.css"],"sourcesContent":["@supports ((-webkit-mask: url(\"\")) or (mask: url(\"\"))) {\n .supports-url-in-query {\n color: red;\n }\n}\n"],"names":[],"mappings":"AAAA,CAAC,QAAQ,CAAE,CAAC,CAAC,AAAD,YAAY,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,IAAM,CAAC,AAAD,IAAI,EAAE,GAAG,CAAC,EAAE,CAAA,CAAC,CAAC,CAAE,CAAC;EACtD,CAAC,qBAAqB,CAAC,CAAC;IACtB,KAAK,EAAE,GAAG;EACZ,CAAC;AACH,CAAC"}}, + {"offset": {"line": 5, "column": 1}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.js new file mode 100644 index 0000000000000..852edce117b26 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.js @@ -0,0 +1 @@ +import { subClass } from './index.module.css' diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css new file mode 100644 index 0000000000000..0999b553172d8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css @@ -0,0 +1,9 @@ +.className { + background: red; + color: yellow; +} + +.subClass { + composes: className; + background: blue; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css new file mode 100644 index 0000000000000..4e9348cff7d2a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css @@ -0,0 +1,11 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css [test] (css) */ +.index-module__Tw9iRq__className { + background: red; + color: #ff0; +} + +.index-module__Tw9iRq__subClass { + background: #00f; +} + +/*# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css.map new file mode 100644 index 0000000000000..e8880255cede2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css"],"sourcesContent":[".className {\n background: red;\n color: yellow;\n}\n\n.subClass {\n composes: className;\n background: blue;\n}\n"],"names":[],"mappings":"AAAA;;;;;AAKA"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css new file mode 100644 index 0000000000000..ef135f6bbb79a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css @@ -0,0 +1,12 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css [test] (css) */ +.index-module__Tw9iRq__className { + background: red; + color: #ff0; +} + +.index-module__Tw9iRq__subClass { + background: #00f; +} + + +/*# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css.map new file mode 100644 index 0000000000000..e8880255cede2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css"],"sourcesContent":[".className {\n background: red;\n color: yellow;\n}\n\n.subClass {\n composes: className;\n background: blue;\n}\n"],"names":[],"mappings":"AAAA;;;;;AAKA"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js new file mode 100644 index 0000000000000..b6bf94049acaa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js @@ -0,0 +1,22 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css [test] (css module)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__({ + "className": "index-module__Tw9iRq__className", + "subClass": "index-module__Tw9iRq__subClass" + " " + "index-module__Tw9iRq__className", +}); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$cssmodules$2f$composes$2f$input$2f$index$2e$module$2e$css__$5b$test$5d$__$28$css__module$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css [test] (css module)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js.map new file mode 100644 index 0000000000000..50ddd5eb83ec0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"className\": \"index-module__Tw9iRq__className\",\n \"subClass\": \"index-module__Tw9iRq__subClass\" + \" \" + \"index-module__Tw9iRq__className\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA"}}, + {"offset": {"line": 8, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_607308.js b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_607308.js new file mode 100644 index 0000000000000..e8acd60e1ab89 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_607308.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_607308.js", + {}, + {"otherChunks":[{"path":"output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_cb674a.css","included":["[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.module.css [test] (css)"],"moduleChunks":["output/79fb1_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_module_7d7e1c.css"]},"output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_2ba052._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/cssmodules/composes/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_607308.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_607308.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/composes/output/crates_turbopack-tests_tests_snapshot_cssmodules_composes_input_index_607308.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.js new file mode 100644 index 0000000000000..73c72922b98e8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.js @@ -0,0 +1 @@ +import {foo} from "./index.module.css"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css new file mode 100644 index 0000000000000..8ca55aa2eceac --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css @@ -0,0 +1,3 @@ +.bar { + composes: foo from 'other.module.css'; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css new file mode 100644 index 0000000000000..fee6dc0923e7b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css @@ -0,0 +1,3 @@ +.foo { + background-color: red; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css new file mode 100644 index 0000000000000..fa2e0ee2fdab2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css @@ -0,0 +1,12 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css) */ +.other-module__O4Xnbq__foo { + background-color: red; +} + + +/* [project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css [test] (css) */ +.index-module__kgTkkG__bar { +} + + +/*# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css.map new file mode 100644 index 0000000000000..ea017a744395b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css"],"sourcesContent":[".bar {\n composes: foo from 'other.module.css';\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js new file mode 100644 index 0000000000000..c111dc96f6d1a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js @@ -0,0 +1,28 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css module)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__({ + "foo": "other-module__O4Xnbq__foo", +}); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css [test] (css module)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__({ + "bar": "index-module__kgTkkG__bar" + " " + __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css module)")["foo"], +}); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$cssmodules$2f$relative$2d$uri$2d$import$2f$input$2f$index$2e$module$2e$css__$5b$test$5d$__$28$css__module$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css [test] (css module)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js.map new file mode 100644 index 0000000000000..51a37e55719d2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"foo\": \"other-module__O4Xnbq__foo\",\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, + {"offset": {"line": 7, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css [test] (css module)"],"sourcesContent":["__turbopack_export_value__({\n \"bar\": \"index-module__kgTkkG__bar\" + \" \" + __turbopack_import__(\"[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css module)\")[\"foo\"],\n});\n"],"names":[],"mappings":"AAAA;AACA;AACA"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_659e9a.js b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_659e9a.js new file mode 100644 index 0000000000000..814fb09ba57ba --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_659e9a.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_659e9a.js", + {}, + {"otherChunks":[{"path":"output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_6d6278._.css","included":["[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css)","[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css [test] (css)"],"moduleChunks":["output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css","output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css"]},"output/79fb1_turbopack-tests_tests_snapshot_cssmodules_relative-uri-import_input_f065a6._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_659e9a.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_659e9a.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_659e9a.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css new file mode 100644 index 0000000000000..4a3f770dfc812 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css @@ -0,0 +1,5 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css [test] (css) */ +.index-module__kgTkkG__bar { +} + +/*# sourceMappingURL=a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css.map new file mode 100644 index 0000000000000..4023ac1465cb0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_index_module_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/index.module.css"],"sourcesContent":[".bar {\n composes: foo from 'other.module.css';\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css new file mode 100644 index 0000000000000..7a0e2d482fb62 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css @@ -0,0 +1,6 @@ +/* [project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css [test] (css) */ +.other-module__O4Xnbq__foo { + background-color: red; +} + +/*# sourceMappingURL=a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css.map*/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css.map b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css.map new file mode 100644 index 0000000000000..b436945bf266f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/output/a587c_tests_snapshot_cssmodules_relative-uri-import_input_other_module_7d7e1c.css.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 1, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/cssmodules/relative-uri-import/input/other.module.css"],"sourcesContent":[".foo {\n background-color: red;\n}\n"],"names":[],"mappings":"AAAA"}}, + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js new file mode 100644 index 0000000000000..c1174f9211a50 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js @@ -0,0 +1,17 @@ +import child_process from "node:child_process"; +import fs, { readFileSync } from "node:fs"; + +const unknown = Math.random(); + +child_process.spawnSync(unknown); +child_process.spawnSync("node", unknown); +child_process.spawnSync("node", [unknown, unknown]); + +require(unknown); + +import(unknown); + +fs.readFileSync(unknown); +readFileSync(unknown); + +new URL(unknown, import.meta.url); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1001__ import(FreeVar(Math)[__quo__ra-fcce98.txt b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1001__ import(FreeVar(Math)[__quo__ra-fcce98.txt new file mode 100644 index 0000000000000..ef6e8298a5d80 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1001__ import(FreeVar(Math)[__quo__ra-fcce98.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:12:0 lint TP1001 import(FreeVar(Math)["random"]()) is very dynamic + + 8 | child_process.spawnSync("node", [unknown, unknown]); + 9 | + 10 | require(unknown); + 11 | + + v-------------v + 12 + import(unknown); + + ^-------------^ + 13 | + 14 | fs.readFileSync(unknown); + 15 | readFileSync(unknown); + 16 | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1002__ require(FreeVar(Math)[__quo__r-fa7bb4.txt b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1002__ require(FreeVar(Math)[__quo__r-fa7bb4.txt new file mode 100644 index 0000000000000..3a5080fea30e1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1002__ require(FreeVar(Math)[__quo__r-fa7bb4.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:10:0 lint TP1002 require(FreeVar(Math)["random"]()) is very dynamic + + 6 | child_process.spawnSync(unknown); + 7 | child_process.spawnSync("node", unknown); + 8 | child_process.spawnSync("node", [unknown, unknown]); + 9 | + + v--------------v + 10 + require(unknown); + + ^--------------^ + 11 | + 12 | import(unknown); + 13 | + 14 | fs.readFileSync(unknown); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-45dc7a.txt b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-45dc7a.txt new file mode 100644 index 0000000000000..6a31c28da0d86 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-45dc7a.txt @@ -0,0 +1,12 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:15:0 lint TP1004 fs.readFileSync(FreeVar(Math)["random"]()) is very dynamic + + 11 | + 12 | import(unknown); + 13 | + 14 | fs.readFileSync(unknown); + + v-------------------v + 15 + readFileSync(unknown); + + ^-------------------^ + 16 | + 17 | new URL(unknown, import.meta.url); + 18 | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-d5af53.txt b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-d5af53.txt new file mode 100644 index 0000000000000..3c5e2740bce66 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1004__ fs.readFileSync(FreeVar(Math)[-d5af53.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:14:0 lint TP1004 fs.readFileSync(FreeVar(Math)["random"]()) is very dynamic + + 10 | require(unknown); + 11 | + 12 | import(unknown); + 13 | + + v----------------------v + 14 + fs.readFileSync(unknown); + + ^----------------------^ + 15 | readFileSync(unknown); + 16 | + 17 | new URL(unknown, import.meta.url); + 18 | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(FreeVa-fa7b47.txt b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(FreeVa-fa7b47.txt new file mode 100644 index 0000000000000..bbb5163b08b7f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(FreeVa-fa7b47.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:6:0 lint TP1005 child_process.spawnSync(FreeVar(Math)["random"]()) is very dynamic + + 2 | import fs, { readFileSync } from "node:fs"; + 3 | + 4 | const unknown = Math.random(); + 5 | + + v------------------------------v + 6 + child_process.spawnSync(unknown); + + ^------------------------------^ + 7 | child_process.spawnSync("node", unknown); + 8 | child_process.spawnSync("node", [unknown, unknown]); + 9 | + 10 | require(unknown); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__-a30479.txt b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__-a30479.txt new file mode 100644 index 0000000000000..adab944608ee8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__-a30479.txt @@ -0,0 +1,17 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:8:0 lint TP1005 child_process.spawnSync( + + 4 | const unknown = Math.random(); + 5 | + 6 | child_process.spawnSync(unknown); + 7 | child_process.spawnSync("node", unknown); + + v-------------------------------------------------v + 8 + child_process.spawnSync("node", [unknown, unknown]); + + ^-------------------------------------------------^ + 9 | + 10 | require(unknown); + 11 | + 12 | import(unknown); + + "node", + [FreeVar(Math)["random"](), FreeVar(Math)["random"]()] + ) is very dynamic \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__quo_-a93044.txt b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__quo_-a93044.txt new file mode 100644 index 0000000000000..abac239782e5c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1005__ child_process.spawnSync(__quo_-a93044.txt @@ -0,0 +1,13 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:7:0 lint TP1005 child_process.spawnSync("node", FreeVar(Math)["random"]()) is very dynamic + + 3 | + 4 | const unknown = Math.random(); + 5 | + 6 | child_process.spawnSync(unknown); + + v--------------------------------------v + 7 + child_process.spawnSync("node", unknown); + + ^--------------------------------------^ + 8 | child_process.spawnSync("node", [unknown, unknown]); + 9 | + 10 | require(unknown); + 11 | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1201__ new URL(Variable(unknown##2), -f5ba3f.txt b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1201__ new URL(Variable(unknown##2), -f5ba3f.txt new file mode 100644 index 0000000000000..e96bb52573d90 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/issues/__l___lint TP1201__ new URL(Variable(unknown##2), -f5ba3f.txt @@ -0,0 +1,10 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js /crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js:17:0 lint TP1201 new URL(Variable(unknown##2), import.meta.url) is very dynamic + + 13 | + 14 | fs.readFileSync(unknown); + 15 | readFileSync(unknown); + 16 | + + v-------------------------------v + 17 + new URL(unknown, import.meta.url); + + ^-------------------------------^ + 18 | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/options.json new file mode 100644 index 0000000000000..f530cd0f0bd7b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/options.json @@ -0,0 +1,3 @@ +{ + "environment": "NodeJs" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js new file mode 100644 index 0000000000000..fd67efa012ecd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js @@ -0,0 +1,41 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__url__external__node$3a$child_process__ = __turbopack_external_require__("node:child_process", true); +var __TURBOPACK__url__external__node$3a$fs__ = __turbopack_external_require__("node:fs", true); +const __TURBOPACK__import$2e$meta__ = { + get url () { + return `file://${__turbopack_resolve_absolute_path__("crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js")}`; + } +}; +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +const unknown = Math.random(); +__TURBOPACK__url__external__node$3a$child_process__["default"].spawnSync(unknown); +__TURBOPACK__url__external__node$3a$child_process__["default"].spawnSync("node", unknown); +__TURBOPACK__url__external__node$3a$child_process__["default"].spawnSync("node", [ + unknown, + unknown +]); +(()=>{ + const e = new Error("Cannot find module as expression is too dynamic"); + e.code = 'MODULE_NOT_FOUND'; + throw e; +})(); +Promise.resolve().then(()=>{ + const e = new Error("Cannot find module as expression is too dynamic"); + e.code = 'MODULE_NOT_FOUND'; + throw e; +}); +__TURBOPACK__url__external__node$3a$fs__["default"].readFileSync(unknown); +(0, __TURBOPACK__url__external__node$3a$fs__["readFileSync"])(unknown); +new URL(unknown, __TURBOPACK__import$2e$meta__.url); + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map new file mode 100644 index 0000000000000..833d6af6987a4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js"],"sourcesContent":["import child_process from \"node:child_process\";\nimport fs, { readFileSync } from \"node:fs\";\n\nconst unknown = Math.random();\n\nchild_process.spawnSync(unknown);\nchild_process.spawnSync(\"node\", unknown);\nchild_process.spawnSync(\"node\", [unknown, unknown]);\n\nrequire(unknown);\n\nimport(unknown);\n\nfs.readFileSync(unknown);\nreadFileSync(unknown);\n\nnew URL(unknown, import.meta.url);\n"],"names":[],"mappings":";;;;;;;;;;;AAGA,MAAM,UAAU,KAAK,MAAM;AAE3B,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC;AACxB,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC,QAAQ;AAChC,mDAAA,CAAA,UAAa,CAAC,SAAS,CAAC,QAAQ;IAAC;IAAS;CAAQ;;;;;;;;;;;AAMlD,wCAAA,CAAA,UAAE,CAAC,YAAY,CAAC;AAChB,CAAA,GAAA,wCAAA,CAAA,eAAY,AAAD,EAAE;AAEb,IAAI,IAAI,SAAS,8BAAY,GAAG"}}, + {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js new file mode 100644 index 0000000000000..70b53abe38062 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js", + {}, + {"otherChunks":["output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_0d92c3.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/dynamic-request/very-dynamic/output/79fb1_turbopack-tests_tests_snapshot_dynamic-request_very-dynamic_input_index_c551c8.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js new file mode 100644 index 0000000000000..03b3df2d150e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js @@ -0,0 +1,22 @@ +/** @jsxImportSource @emotion/react */ + +import { jsx } from "@emotion/react"; +import styled from "@emotion/styled"; + +const StyledButton = styled.button` + background: blue; +`; + +function ClassNameButton({ children }) { + return ( + + ); +} + +console.log(StyledButton, ClassNameButton); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js new file mode 100644 index 0000000000000..22bb0e475b339 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js @@ -0,0 +1,52 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_b36339._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +/** @jsxImportSource @emotion/react */ __turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f40$emotion$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f40$emotion$2f$react$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f40$emotion$2f$styled$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +const StyledButton = /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f40$emotion$2f$styled$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"])("button", { + target: "e9t88h50" +})("background:blue;"); +function ClassNameButton({ children }) { + return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f40$emotion$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$test$5d$__$28$ecmascript$29$__["jsxDEV"])("button", { + className: css` + background: blue; + `, + children: children + }, void 0, false, { + fileName: "[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js", + lineNumber: 12, + columnNumber: 5 + }, this); +} +console.log(StyledButton, ClassNameButton); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +"purposefully empty stub"; +"@emtion/react/jsx-dev-runtime.js"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +"purposefully empty stub"; +"@emtion/react/index.js"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +"purposefully empty stub"; +"@emtion/styled/index.js"; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_b36339._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js.map new file mode 100644 index 0000000000000..5646d6f04b95b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_b36339._.js.map @@ -0,0 +1,13 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js"],"sourcesContent":["/** @jsxImportSource @emotion/react */\n\nimport { jsx } from \"@emotion/react\";\nimport styled from \"@emotion/styled\";\n\nconst StyledButton = styled.button`\n background: blue;\n`;\n\nfunction ClassNameButton({ children }) {\n return (\n \n {children}\n \n );\n}\n\nconsole.log(StyledButton, ClassNameButton);\n"],"names":[],"mappings":"AAAA,oCAAoC;;;;;;;;AAKpC,MAAM,6BAAe,CAAA,GAAA,2LAAA,CAAA,UAAM,AAAD;;;AAI1B,SAAS,gBAAgB,EAAE,QAAQ,EAAE;IACnC,qBACE,0NAAC;QACC,WAAW,GAAG,CAAC;;MAEf,CAAC;kBAEA;;;;;;AAGP;AAEA,QAAQ,GAAG,CAAC,cAAc"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 33, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/react/jsx-dev-runtime.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 35, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 39, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/react/index.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 41, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 45, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@emtion/styled/index.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 47, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b67a84.js b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b67a84.js new file mode 100644 index 0000000000000..2908c33a460b8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b67a84.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b67a84.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_b36339._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/emotion/emotion/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b67a84.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b67a84.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/emotion/emotion/output/crates_turbopack-tests_tests_snapshot_emotion_emotion_input_index_b67a84.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/env/env/input/.env b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/input/.env new file mode 100644 index 0000000000000..daf3eff9e0bbc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/input/.env @@ -0,0 +1,4 @@ +FOO=foo +FOOBAR=${FOO}bar +BARFOO=${BAR:-bar}foo +ALLFOOBAR=foo${BAR:-bar}${FOO}bar diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/env/env/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/input/index.js new file mode 100644 index 0000000000000..a8bd6472cb8cc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/input/index.js @@ -0,0 +1,3 @@ +console.log(process.env.FOOBAR); +console.log(process.env.BARFOO); +console.log(process.env.ALLFOOBAR); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js new file mode 100644 index 0000000000000..cc481128b117c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js @@ -0,0 +1,23 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/env/env/input/.env/.env.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +const env = process.env = { + ...process.env +}; +env["ALLFOOBAR"] = foobarfoobar; +env["BARFOO"] = barfoo; +env["FOO"] = foo; +env["FOOBAR"] = foobar; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/env/env/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +console.log(process.env.FOOBAR); +console.log(process.env.BARFOO); +console.log(process.env.ALLFOOBAR); + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js.map new file mode 100644 index 0000000000000..910ba0f6169f9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/env/env/input/.env/.env.js"],"sourcesContent":["const env = process.env = {...process.env};\n\nenv[\"ALLFOOBAR\"] = foobarfoobar;\nenv[\"BARFOO\"] = barfoo;\nenv[\"FOO\"] = foo;\nenv[\"FOOBAR\"] = foobar;\n"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,GAAG;IAAC,GAAG,QAAQ,GAAG;AAAA;AAEzC,GAAG,CAAC,YAAY,GAAG;AACnB,GAAG,CAAC,SAAS,GAAG;AAChB,GAAG,CAAC,MAAM,GAAG;AACb,GAAG,CAAC,SAAS,GAAG"}}, + {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/env/env/input/index.js"],"sourcesContent":["console.log(process.env.FOOBAR);\nconsole.log(process.env.BARFOO);\nconsole.log(process.env.ALLFOOBAR);\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,MAAM;AAC9B,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,MAAM;AAC9B,QAAQ,GAAG,CAAC,QAAQ,GAAG,CAAC,SAAS"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_index_6512b1.js b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_index_6512b1.js new file mode 100644 index 0000000000000..addfa89512fa3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_index_6512b1.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_env_env_input_index_6512b1.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_env_env_input_673035._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/env/env/input/.env/.env.js [test] (ecmascript)","[project]/crates/turbopack-tests/tests/snapshot/env/env/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_index_6512b1.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_index_6512b1.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/env/env/output/crates_turbopack-tests_tests_snapshot_env_env_input_index_6512b1.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js new file mode 100644 index 0000000000000..6b2b3db0f6520 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js @@ -0,0 +1 @@ +console.log("hello world"); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/runtime.js new file mode 100644 index 0000000000000..5a18d42cb8f2d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/runtime.js @@ -0,0 +1 @@ +console.log("runtime"); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_1ec742.js b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_1ec742.js new file mode 100644 index 0000000000000..e1709edb3416a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_1ec742.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_1ec742.js", + {}, + {"otherChunks":["output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_1ec742.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_1ec742.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_1ec742.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js new file mode 100644 index 0000000000000..3ee4945ac8c12 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js @@ -0,0 +1,10 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +console.log("hello world"); + +}.call(this) }), +}]); + +//# sourceMappingURL=a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js.map new file mode 100644 index 0000000000000..2e7a45d8f0ba9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/output/a587c_tests_snapshot_evaluated_entrry_runtime_entry_input_index_97d560.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/evaluated_entrry/runtime_entry/input/index.js"],"sourcesContent":["console.log(\"hello world\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/example/example/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/input/index.js new file mode 100644 index 0000000000000..6b2b3db0f6520 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/input/index.js @@ -0,0 +1 @@ +console.log("hello world"); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js new file mode 100644 index 0000000000000..cd3d30bb2a80d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js @@ -0,0 +1,10 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/example/example/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +console.log("hello world"); + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js.map new file mode 100644 index 0000000000000..feb2b5c3ed7e1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/example/example/input/index.js"],"sourcesContent":["console.log(\"hello world\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_86f5c3.js b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_86f5c3.js new file mode 100644 index 0000000000000..f017434780176 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_86f5c3.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_example_example_input_index_86f5c3.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_example_example_input_index_838420.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/example/example/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_86f5c3.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_86f5c3.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/example/example/output/crates_turbopack-tests_tests_snapshot_example_example_input_index_86f5c3.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js new file mode 100644 index 0000000000000..55591793dce25 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js @@ -0,0 +1,4 @@ +// b.js +export * from "./c"; +// This would not be handled, but still need __turbopack__cjs__ +// as there are properties dynamically added by __turbopack__cjs__ in c.js diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js new file mode 100644 index 0000000000000..9d4bfd782ed88 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js @@ -0,0 +1,3 @@ +// c.js +export * from "./commonjs.js"; +// This would be handled by existing logic diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js new file mode 100644 index 0000000000000..70410e762b19a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js @@ -0,0 +1,3 @@ +// commonjs.js +exports.hello = "World"; + diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js new file mode 100644 index 0000000000000..7079fea2e886e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js @@ -0,0 +1,3 @@ +// a.js +import * as B from "./b"; +console.log(B); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/issues/unexpected export __star__-544d33.txt b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/issues/unexpected export __star__-544d33.txt new file mode 100644 index 0000000000000..17b30c834747f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/issues/unexpected export __star__-544d33.txt @@ -0,0 +1,3 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js unexpected export * + export * used with module [project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js [test] (ecmascript) which is a CommonJS module with exports only available at runtime + List all export names manually (`export { a, b, c } from "...") or rewrite the module to ESM, to avoid the additional runtime code.` \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js new file mode 100644 index 0000000000000..f41bd8ed97528 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js @@ -0,0 +1,47 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +// commonjs.js +exports.hello = "World"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +// c.js +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$2$2f$input$2f$commonjs$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js [test] (ecmascript)"); +__turbopack_dynamic__(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$2$2f$input$2f$commonjs$2e$js__$5b$test$5d$__$28$ecmascript$29$__); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + // This would be handled by existing logic + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +// b.js +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$2$2f$input$2f$c$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js [test] (ecmascript)"); +__turbopack_dynamic__(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$2$2f$input$2f$c$2e$js__$5b$test$5d$__$28$ecmascript$29$__); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + // This would not be handled, but still need __turbopack__cjs__ + // as there are properties dynamically added by __turbopack__cjs__ in c.js + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +// a.js +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$2$2f$input$2f$b$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$2$2f$input$2f$b$2e$js__$5b$test$5d$__$28$ecmascript$29$__); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js.map new file mode 100644 index 0000000000000..e61d7499aae71 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js.map @@ -0,0 +1,13 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/commonjs.js"],"sourcesContent":["// commonjs.js\nexports.hello = \"World\";\n\n"],"names":[],"mappings":"AAAA,cAAc;AACd,QAAQ,KAAK,GAAG"}}, + {"offset": {"line": 6, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/c.js"],"sourcesContent":["// c.js\nexport * from \"./commonjs.js\";\n// This would be handled by existing logic\n"],"names":[],"mappings":"AAAA,OAAO;;;;;;CAEP,0CAA0C"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/b.js"],"sourcesContent":["// b.js\nexport * from \"./c\";\n// This would not be handled, but still need __turbopack__cjs__\n// as there are properties dynamically added by __turbopack__cjs__ in c.js\n"],"names":[],"mappings":"AAAA,OAAO;;;;;;CAEP,+DAA+D;CAC/D,0EAA0E"}}, + {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js"],"sourcesContent":["// a.js\nimport * as B from \"./b\";\nconsole.log(B);"],"names":[],"mappings":"AAAA,OAAO;;;;;AAEP,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 42, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_index_d8a134.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_index_d8a134.js new file mode 100644 index 0000000000000..2ac4b001945c3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_index_d8a134.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_index_d8a134.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_2c57a6._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_index_d8a134.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_index_d8a134.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-2/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-2_input_index_d8a134.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs new file mode 100644 index 0000000000000..bd3b8ed298729 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs @@ -0,0 +1 @@ +module.exports = { foo: 1, bar: 2 } \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js new file mode 100644 index 0000000000000..1f075aa1599cc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js @@ -0,0 +1,3 @@ +import * as foo from './mod.js'; + +console.log(foo) \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js new file mode 100644 index 0000000000000..78e69d953770e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js @@ -0,0 +1,4 @@ + +export * from './exported.cjs' + +console.log('Hoist test') \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/issues/unexpected export __star__-b3e41e.txt b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/issues/unexpected export __star__-b3e41e.txt new file mode 100644 index 0000000000000..bc1db77e582ad --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/issues/unexpected export __star__-b3e41e.txt @@ -0,0 +1,3 @@ +warning - [analysis] [project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs unexpected export * + export * used with module [project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs [test] (ecmascript) which is a CommonJS module with exports only available at runtime + List all export names manually (`export { a, b, c } from "...") or rewrite the module to ESM, to avoid the additional runtime code.` \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js new file mode 100644 index 0000000000000..5d84368b21c58 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js @@ -0,0 +1,34 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +module.exports = { + foo: 1, + bar: 2 +}; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$script$2f$input$2f$exported$2e$cjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs [test] (ecmascript)"); +__turbopack_dynamic__(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$script$2f$input$2f$exported$2e$cjs__$5b$test$5d$__$28$ecmascript$29$__); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log('Hoist test'); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$script$2f$input$2f$mod$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$export$2d$alls$2f$cjs$2d$script$2f$input$2f$mod$2e$js__$5b$test$5d$__$28$ecmascript$29$__); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js.map new file mode 100644 index 0000000000000..ad0db65390b37 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/exported.cjs"],"sourcesContent":["module.exports = { foo: 1, bar: 2 }"],"names":[],"mappings":"AAAA,OAAO,OAAO,GAAG;IAAE,KAAK;IAAG,KAAK;AAAE"}}, + {"offset": {"line": 8, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/mod.js"],"sourcesContent":["\nexport * from './exported.cjs'\n\nconsole.log('Hoist test')"],"names":[],"mappings":";;;;;AAGA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js"],"sourcesContent":["import * as foo from './mod.js';\n\nconsole.log(foo)"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 29, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_index_fae267.js b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_index_fae267.js new file mode 100644 index 0000000000000..ab5a175a34544 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_index_fae267.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_index_fae267.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_ffd38d._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_index_fae267.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_index_fae267.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/export-alls/cjs-script/output/crates_turbopack-tests_tests_snapshot_export-alls_cjs-script_input_index_fae267.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/index.js new file mode 100644 index 0000000000000..4562cbf62b4dd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/index.js @@ -0,0 +1 @@ +import './mod.cjs'; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs new file mode 100644 index 0000000000000..d9536a69b3f87 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs @@ -0,0 +1 @@ +console.log(import.meta.url); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js new file mode 100644 index 0000000000000..518bc5119cadd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js @@ -0,0 +1,24 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +const __TURBOPACK__import$2e$meta__ = { + get url () { + return `file://${__turbopack_resolve_absolute_path__("crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs")}`; + } +}; +"__TURBOPACK__ecmascript__hoisting__location__"; +console.log(__TURBOPACK__import$2e$meta__.url); + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$cjs$2f$input$2f$mod$2e$cjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js.map new file mode 100644 index 0000000000000..bab01750ebd87 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/mod.cjs"],"sourcesContent":["console.log(import.meta.url);\n"],"names":[],"mappings":";;;;;;AAAA,QAAQ,GAAG,CAAC,8BAAY,GAAG"}}, + {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_index_cbf1c5.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_index_cbf1c5.js new file mode 100644 index 0000000000000..012aa60fda5a0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_index_cbf1c5.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_index_cbf1c5.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_44576c._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/import-meta/cjs/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_index_cbf1c5.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_index_cbf1c5.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/cjs/output/crates_turbopack-tests_tests_snapshot_import-meta_cjs_input_index_cbf1c5.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/index.js new file mode 100644 index 0000000000000..b489875206e46 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/index.js @@ -0,0 +1 @@ +import './mod.mjs'; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs new file mode 100644 index 0000000000000..702f022f7acbc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs @@ -0,0 +1,9 @@ +function foo() { + console.log(import.meta.url); +} +function bar() { + console.log(import.meta.url); +} + +foo(); +bar(); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/79fb1_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_index_bf1234.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/79fb1_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_index_bf1234.js new file mode 100644 index 0000000000000..8674184f0dc30 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/79fb1_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_index_bf1234.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_index_bf1234.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/79fb1_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_index_bf1234.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/79fb1_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_index_bf1234.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/79fb1_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_index_bf1234.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js new file mode 100644 index 0000000000000..ff8af0da07be5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js @@ -0,0 +1,33 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +const __TURBOPACK__import$2e$meta__ = { + get url () { + return `file://${__turbopack_resolve_absolute_path__("crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs")}`; + } +}; +"__TURBOPACK__ecmascript__hoisting__location__"; +function foo() { + console.log(__TURBOPACK__import$2e$meta__.url); +} +function bar() { + console.log(__TURBOPACK__import$2e$meta__.url); +} +foo(); +bar(); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$esm$2d$multiple$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js.map new file mode 100644 index 0000000000000..011ff7e3ee16a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-multiple_input_b94ed5._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-multiple/input/mod.mjs"],"sourcesContent":["function foo() {\n console.log(import.meta.url);\n}\nfunction bar() {\n console.log(import.meta.url);\n}\n\nfoo();\nbar();\n"],"names":[],"mappings":";;;;;;;AAAA,SAAS;IACP,QAAQ,GAAG,CAAC,8BAAY,GAAG;AAC7B;AACA,SAAS;IACP,QAAQ,GAAG,CAAC,8BAAY,GAAG;AAC7B;AAEA;AACA"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 28, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/index.js new file mode 100644 index 0000000000000..b489875206e46 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/index.js @@ -0,0 +1 @@ +import './mod.mjs'; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs new file mode 100644 index 0000000000000..7760b3acc792c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs @@ -0,0 +1 @@ +import.meta.foo = 1; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js new file mode 100644 index 0000000000000..0d1bccb16cd07 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +const __TURBOPACK__import$2e$meta__ = { + get url () { + return `file://${__turbopack_resolve_absolute_path__("crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs")}`; + } +}; +"__TURBOPACK__ecmascript__hoisting__location__"; +__TURBOPACK__import$2e$meta__.foo = 1; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$esm$2d$mutable$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js.map new file mode 100644 index 0000000000000..a5ea31f14260c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/mod.mjs"],"sourcesContent":["import.meta.foo = 1;\n"],"names":[],"mappings":";;;;;;;AAAA,8BAAY,GAAG,GAAG"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_index_156a15.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_index_156a15.js new file mode 100644 index 0000000000000..3506d1a7e23da --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_index_156a15.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_index_156a15.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_f730df._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_index_156a15.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_index_156a15.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-mutable/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-mutable_input_index_156a15.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/index.js new file mode 100644 index 0000000000000..b489875206e46 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/index.js @@ -0,0 +1 @@ +import './mod.mjs'; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs new file mode 100644 index 0000000000000..e7313a090ffe5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs @@ -0,0 +1 @@ +console.log(import.meta); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js new file mode 100644 index 0000000000000..f88f6b8b174a9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +const __TURBOPACK__import$2e$meta__ = { + get url () { + return `file://${__turbopack_resolve_absolute_path__("crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs")}`; + } +}; +"__TURBOPACK__ecmascript__hoisting__location__"; +console.log(__TURBOPACK__import$2e$meta__); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$esm$2d$object$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js.map new file mode 100644 index 0000000000000..712b8657fe4c8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/mod.mjs"],"sourcesContent":["console.log(import.meta);\n"],"names":[],"mappings":";;;;;;;AAAA,QAAQ,GAAG"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_index_a40b5c.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_index_a40b5c.js new file mode 100644 index 0000000000000..c97ccfed89457 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_index_a40b5c.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_index_a40b5c.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_51cbdd._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_index_a40b5c.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_index_a40b5c.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm-object/output/crates_turbopack-tests_tests_snapshot_import-meta_esm-object_input_index_a40b5c.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/index.js new file mode 100644 index 0000000000000..b489875206e46 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/index.js @@ -0,0 +1 @@ +import './mod.mjs'; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs new file mode 100644 index 0000000000000..d9536a69b3f87 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs @@ -0,0 +1 @@ +console.log(import.meta.url); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js new file mode 100644 index 0000000000000..4efa689fcd239 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +const __TURBOPACK__import$2e$meta__ = { + get url () { + return `file://${__turbopack_resolve_absolute_path__("crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs")}`; + } +}; +"__TURBOPACK__ecmascript__hoisting__location__"; +console.log(__TURBOPACK__import$2e$meta__.url); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$esm$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js.map new file mode 100644 index 0000000000000..b308c4de546ba --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/mod.mjs"],"sourcesContent":["console.log(import.meta.url);\n"],"names":[],"mappings":";;;;;;;AAAA,QAAQ,GAAG,CAAC,8BAAY,GAAG"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_index_f9fbd8.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_index_f9fbd8.js new file mode 100644 index 0000000000000..31a195b2b6acf --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_index_f9fbd8.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_index_f9fbd8.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_5f2592._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/import-meta/esm/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_index_f9fbd8.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_index_f9fbd8.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/esm/output/crates_turbopack-tests_tests_snapshot_import-meta_esm_input_index_f9fbd8.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/asset.txt b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/asset.txt new file mode 100644 index 0000000000000..a042389697364 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/asset.txt @@ -0,0 +1 @@ +hello world! diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/index.js new file mode 100644 index 0000000000000..b489875206e46 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/index.js @@ -0,0 +1 @@ +import './mod.mjs'; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs new file mode 100644 index 0000000000000..ef8b841422841 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs @@ -0,0 +1,6 @@ +const assetUrl = new URL('./asset.txt', import.meta.url); + +console.log(assetUrl); +fetch(assetUrl) + .then(res => res.text()) + .then(console.log); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js new file mode 100644 index 0000000000000..ba6d48e54ae3a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js @@ -0,0 +1,32 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/asset.txt [test] (static)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__("/static/asset.05254cf2.txt"); +})()), +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +const __TURBOPACK__import$2e$meta__ = { + get url () { + return `file://${__turbopack_resolve_absolute_path__("crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs")}`; + } +}; +"__TURBOPACK__ecmascript__hoisting__location__"; +const assetUrl = new __turbopack_relative_url__(__turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/asset.txt [test] (static)")); +console.log(assetUrl); +fetch(assetUrl).then((res)=>res.text()).then(console.log); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$import$2d$meta$2f$url$2f$input$2f$mod$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js.map new file mode 100644 index 0000000000000..20641d5b665cd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/mod.mjs"],"sourcesContent":["const assetUrl = new URL('./asset.txt', import.meta.url);\n\nconsole.log(assetUrl);\nfetch(assetUrl)\n .then(res => res.text())\n .then(console.log);\n"],"names":[],"mappings":";;;;;;;AAAA,MAAM;AAEN,QAAQ,GAAG,CAAC;AACZ,MAAM,UACH,IAAI,CAAC,CAAA,MAAO,IAAI,IAAI,IACpB,IAAI,CAAC,QAAQ,GAAG"}}, + {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 27, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_index_d1e531.js b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_index_d1e531.js new file mode 100644 index 0000000000000..a7d92731b4ee3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_index_d1e531.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_index_d1e531.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_9b6f5c._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/import-meta/url/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_index_d1e531.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_index_d1e531.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/output/crates_turbopack-tests_tests_snapshot_import-meta_url_input_index_d1e531.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/static/asset.05254cf2.txt b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/static/asset.05254cf2.txt new file mode 100644 index 0000000000000..bc7774a7b18de --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/import-meta/url/static/asset.05254cf2.txt @@ -0,0 +1 @@ +hello world! \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js new file mode 100644 index 0000000000000..bf83c2cf3f510 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js @@ -0,0 +1,6 @@ + +import { Table } from "./table" + +export function Table() { + console.log(Table) +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js new file mode 100644 index 0000000000000..07b73c6749c8d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js @@ -0,0 +1,3 @@ +export const Table = ()=>{ + return 'table' +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/issues/Ecmascript file had an error-bb54cd.txt b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/issues/Ecmascript file had an error-bb54cd.txt new file mode 100644 index 0000000000000..6ee6e419889ee --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/issues/Ecmascript file had an error-bb54cd.txt @@ -0,0 +1,12 @@ +error - [analysis] [project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js /crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js:4:16 Ecmascript file had an error + 1 | + 2 | import { Table } from "./table" + 3 | + + v---v + 4 + export function Table() { + + ^---^ + 5 | console.log(Table) + 6 | } + 7 | + + the name `Table` is defined multiple times \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/79fb1_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_index_be113b.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/79fb1_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_index_be113b.js new file mode 100644 index 0000000000000..4e64ec215b57b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/79fb1_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_index_be113b.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_index_be113b.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/79fb1_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_index_be113b.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/79fb1_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_index_be113b.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/79fb1_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_index_be113b.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js new file mode 100644 index 0000000000000..efa5e92b6d837 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js @@ -0,0 +1,30 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "Table": ()=>Table +}); +const Table = ()=>{ + return 'table'; +}; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "Table": ()=>Table +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$duplicate$2d$binding$2f$input$2f$table$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +function Table() { + console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$duplicate$2d$binding$2f$input$2f$table$2e$js__$5b$test$5d$__$28$ecmascript$29$__["Table"]); +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js.map new file mode 100644 index 0000000000000..8eb4573580dd6 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/output/crates_turbopack-tests_tests_snapshot_imports_duplicate-binding_input_9ca1ac._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/table.js"],"sourcesContent":["export const Table = ()=>{\n return 'table'\n}\n"],"names":[],"mappings":";;;AAAO,MAAM,QAAQ;IACnB,OAAO;AACT"}}, + {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/duplicate-binding/input/index.js"],"sourcesContent":["\nimport { Table } from \"./table\"\n\nexport function Table() {\n console.log(Table)\n}\n"],"names":[],"mappings":";;;;;;AAGO,SAAS;IACZ,QAAQ,GAAG,CAAC,gMAAA,CAAA,QAAK;AACrB"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js new file mode 100644 index 0000000000000..bec99fde07e55 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js @@ -0,0 +1 @@ +import("./vercel.mjs").then(console.log); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs new file mode 100644 index 0000000000000..900be17c9ca13 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs @@ -0,0 +1 @@ +export default "turbopack"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js new file mode 100644 index 0000000000000..38f0c13f2007b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js @@ -0,0 +1,10 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +__turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs [test] (ecmascript, async loader)")(__turbopack_import__).then(console.log); + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js.map new file mode 100644 index 0000000000000..6afa602b1df84 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js"],"sourcesContent":["import(\"./vercel.mjs\").then(console.log);\n"],"names":[],"mappings":"AAAA,kKAAuB,IAAI,CAAC,QAAQ,GAAG"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_e773b5.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_e773b5.js new file mode 100644 index 0000000000000..fee463a520cf9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_e773b5.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_e773b5.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_5ee1a4.js","output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_b7663b._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_e773b5.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_e773b5.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_index_e773b5.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js new file mode 100644 index 0000000000000..3dc2389de4d87 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js @@ -0,0 +1,14 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +const __TURBOPACK__default__export__ = "turbopack"; + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js.map new file mode 100644 index 0000000000000..794f5d5dae28e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs"],"sourcesContent":["export default \"turbopack\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_b7663b._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_b7663b._.js new file mode 100644 index 0000000000000..479449f704832 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_b7663b._.js @@ -0,0 +1,14 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_b7663b._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs [test] (ecmascript, async loader)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__((__turbopack_import__) => { + return Promise.all([ + "output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_18521c._.js" +].map((chunk) => __turbopack_load__(chunk))).then(() => { + return __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/dynamic/input/vercel.mjs [test] (ecmascript)"); + }); +}); + +})()), +}]); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_b7663b._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_b7663b._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/dynamic/output/crates_turbopack-tests_tests_snapshot_imports_dynamic_input_vercel_mjs_b7663b._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js new file mode 100644 index 0000000000000..68833b1fe60d9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js @@ -0,0 +1,4 @@ +import pkg from "./package.json"; +console.log(pkg.name); +import invalid from "./invalid.json"; +console.log(invalid["this-is"]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json new file mode 100644 index 0000000000000..1a09514f79ec1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json @@ -0,0 +1,5 @@ +{ + "nested": { + "this-is": "invalid" // lint-staged will remove trailing commas, so here's a comment + } +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/package.json new file mode 100644 index 0000000000000..ff4f0a69addb8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/input/package.json @@ -0,0 +1,3 @@ +{ + "name": "json-snapshot" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/issues/Code generation for chunk item errored-54164f.txt b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/issues/Code generation for chunk item errored-54164f.txt new file mode 100644 index 0000000000000..77512fa6323fa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/issues/Code generation for chunk item errored-54164f.txt @@ -0,0 +1,19 @@ +error - [code gen] [project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json Code generation for chunk item errored + An error occurred while generating the chunk item [project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json (json) + + Caused by: + - Unable to make a module from invalid JSON: expected `,` or `}` at line 3 column 26 + + Debug info: + - An error occurred while generating the chunk item [project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json (json) + - Execution of EcmascriptChunkItemContent::module_factory failed + - Execution of ::content failed + - Unable to make a module from invalid JSON: expected `,` or `}` at line 3 column 26 + at nested.? + 1 | { + 2 | "nested": { + | v + 3 + "this-is": "invalid" // lint-staged will remove trailing commas, so here's a comment + | ^ + 4 | } + 5 | } \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js new file mode 100644 index 0000000000000..81aaeb6bb53ca --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js @@ -0,0 +1,27 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/package.json (json)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__(JSON.parse("{\"name\":\"json-snapshot\"}")); +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json (json)": (() => {{ + +throw new Error("An error occurred while generating the chunk item [project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json (json)\n\nCaused by:\n- Unable to make a module from invalid JSON: expected `,` or `}` at line 3 column 26\n\nDebug info:\n- An error occurred while generating the chunk item [project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json (json)\n- Execution of EcmascriptChunkItemContent::module_factory failed\n- Execution of ::content failed\n- Unable to make a module from invalid JSON: expected `,` or `}` at line 3 column 26\n at nested.?\n 1 | {\n 2 | \"nested\": {\n | v\n 3 + \"this-is\": \"invalid\" // lint-staged will remove trailing commas, so here's a comment\n | ^\n 4 | }\n 5 | }"); + +}}), +"[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$json$2f$input$2f$package$2e$json__$28$json$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/package.json (json)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$json$2f$input$2f$invalid$2e$json__$28$json$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/invalid.json (json)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$json$2f$input$2f$package$2e$json__$28$json$29$__["default"].name); +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$json$2f$input$2f$invalid$2e$json__$28$json$29$__["default"]["this-is"]); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js.map new file mode 100644 index 0000000000000..8affe11a79ec9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js"],"sourcesContent":["import pkg from \"./package.json\";\nconsole.log(pkg.name);\nimport invalid from \"./invalid.json\";\nconsole.log(invalid[\"this-is\"]);\n"],"names":[],"mappings":";;;;;AACA,QAAQ,GAAG,CAAC,gKAAA,CAAA,UAAG,CAAC,IAAI;;AAEpB,QAAQ,GAAG,CAAC,gKAAA,CAAA,UAAO,CAAC,UAAU"}}, + {"offset": {"line": 22, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_index_d98c3c.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_index_d98c3c.js new file mode 100644 index 0000000000000..020e56900b0ae --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_index_d98c3c.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_imports_json_input_index_d98c3c.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_imports_json_input_22bb62._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/json/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_index_d98c3c.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_index_d98c3c.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/json/output/crates_turbopack-tests_tests_snapshot_imports_json_input_index_d98c3c.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js new file mode 100644 index 0000000000000..c0dc83d3308ac --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js @@ -0,0 +1,6 @@ +import posts from "./posts"; + +console.log(posts.js); +if (!posts.js) { + process.exit(1); +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.json b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.json new file mode 100644 index 0000000000000..d8351c5dda596 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.json @@ -0,0 +1,3 @@ +{ + "js": false +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts new file mode 100644 index 0000000000000..5ec2a6d7e517d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts @@ -0,0 +1,3 @@ +export default { + js: true, +}; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js new file mode 100644 index 0000000000000..e615a1e30e205 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js @@ -0,0 +1,29 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +const __TURBOPACK__default__export__ = { + js: true +}; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$order$2f$input$2f$posts$2e$ts__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$order$2f$input$2f$posts$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["default"].js); +if (!__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$order$2f$input$2f$posts$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["default"].js) { + process.exit(1); +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js.map new file mode 100644 index 0000000000000..08eb3b36a73b8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/posts.ts"],"sourcesContent":["export default {\n js: true,\n};\n"],"names":[],"mappings":";;;uCAAe;IACb,IAAI;AACN"}}, + {"offset": {"line": 11, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js"],"sourcesContent":["import posts from \"./posts\";\n\nconsole.log(posts.js);\nif (!posts.js) {\n process.exit(1);\n}\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,iLAAA,CAAA,UAAK,CAAC,EAAE;AACpB,IAAI,CAAC,iLAAA,CAAA,UAAK,CAAC,EAAE,EAAE;IACb,QAAQ,IAAI,CAAC;AACf"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_index_ffb1b9.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_index_ffb1b9.js new file mode 100644 index 0000000000000..df318cd1aef88 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_index_ffb1b9.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_imports_order_input_index_ffb1b9.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_imports_order_input_c5b1db._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/order/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_index_ffb1b9.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_index_ffb1b9.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/order/output/crates_turbopack-tests_tests_snapshot_imports_order_input_index_ffb1b9.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js new file mode 100644 index 0000000000000..8dc65313a558a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js @@ -0,0 +1,3 @@ +const dne = require("does-not-exist/path"); + +console.log(dne); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/__l___Module not found____c__ Can't resolve '__c_d-10ac1f.txt b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/__l___Module not found____c__ Can't resolve '__c_d-10ac1f.txt new file mode 100644 index 0000000000000..f2afc4e66c64c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/issues/__l___Module not found____c__ Can't resolve '__c_d-10ac1f.txt @@ -0,0 +1,16 @@ +error - [resolve] [project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js /crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js:1:12 Module not found: Can't resolve 'does-not-exist/path' + + + v----------------------------v + 1 + const dne = require("does-not-exist/path"); + + ^----------------------------^ + 2 | + 3 | console.log(dne); + 4 | + + + + | It was not possible to find the requested file. + | Parsed request as written in source code: module "does-not-exist" with subpath "/path" + | Path where resolving has started: [project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js + | Type of request: commonjs request + | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_6a5153.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_6a5153.js new file mode 100644 index 0000000000000..d482dfe94a338 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_6a5153.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_6a5153.js", + {}, + {"otherChunks":["output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_6a5153.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_6a5153.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_6a5153.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js new file mode 100644 index 0000000000000..c69036142b68f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js @@ -0,0 +1,15 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +const dne = (()=>{ + const e = new Error("Cannot find module 'does-not-exist/path'"); + e.code = 'MODULE_NOT_FOUND'; + throw e; +})(); +console.log(dne); + +}.call(this) }), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js.map new file mode 100644 index 0000000000000..e4e9373c6763e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_cjs_input_index_86e786.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_cjs/input/index.js"],"sourcesContent":["const dne = require(\"does-not-exist/path\");\n\nconsole.log(dne);\n"],"names":[],"mappings":"AAAA,MAAM;;;;;AAEN,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 10, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js new file mode 100644 index 0000000000000..4fe5624cd762b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js @@ -0,0 +1,4 @@ +import dne from "does-not-exist/path"; + +console.log(dne); +console.log({}[dne]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve '__c_d-b78915.txt b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve '__c_d-b78915.txt new file mode 100644 index 0000000000000..a4c6fb578a6f7 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/issues/__l___Module not found____c__ Can't resolve '__c_d-b78915.txt @@ -0,0 +1,17 @@ +error - [resolve] [project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js /crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js:1:0 Module not found: Can't resolve 'does-not-exist/path' + + + v------------------------------------v + 1 + import dne from "does-not-exist/path"; + + ^------------------------------------^ + 2 | + 3 | console.log(dne); + 4 | console.log({}[dne]); + 5 | + + + + | It was not possible to find the requested file. + | Parsed request as written in source code: module "does-not-exist" with subpath "/path" + | Path where resolving has started: [project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js + | Type of request: EcmaScript Modules request + | \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_91d712.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_91d712.js new file mode 100644 index 0000000000000..e68bff4ab5f1b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_91d712.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_91d712.js", + {}, + {"otherChunks":["output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_91d712.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_91d712.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_91d712.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js new file mode 100644 index 0000000000000..2004a41c60091 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js @@ -0,0 +1,20 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +(()=>{ + const e = new Error("Cannot find module 'does-not-exist/path'"); + e.code = 'MODULE_NOT_FOUND'; + throw e; +})(); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(dne); +console.log({}[dne]); + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js.map new file mode 100644 index 0000000000000..c4850dcda61ae --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/output/79fb1_turbopack-tests_tests_snapshot_imports_resolve_error_esm_input_index_c7ccd7.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/resolve_error_esm/input/index.js"],"sourcesContent":["import dne from \"does-not-exist/path\";\n\nconsole.log(dne);\nconsole.log({}[dne]);\n"],"names":[],"mappings":";;;;;;;;AAEA,QAAQ,GAAG,CAAC;AACZ,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js new file mode 100644 index 0000000000000..f1fd12c270627 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js @@ -0,0 +1,4 @@ +import img from "./vercel.mjs"; +console.log(img); + +import("./vercel.mjs").then(console.log); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs new file mode 100644 index 0000000000000..900be17c9ca13 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs @@ -0,0 +1 @@ +export default "turbopack"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/79fb1_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_index_09e9a5.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/79fb1_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_index_09e9a5.js new file mode 100644 index 0000000000000..da2b03dbb87ab --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/79fb1_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_index_09e9a5.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_index_09e9a5.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js","output/a587c_tests_snapshot_imports_static-and-dynamic_input_vercel_mjs_aa3704._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/79fb1_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_index_09e9a5.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/79fb1_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_index_09e9a5.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/79fb1_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_index_09e9a5.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/a587c_tests_snapshot_imports_static-and-dynamic_input_vercel_mjs_aa3704._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/a587c_tests_snapshot_imports_static-and-dynamic_input_vercel_mjs_aa3704._.js new file mode 100644 index 0000000000000..f89abd0062bbe --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/a587c_tests_snapshot_imports_static-and-dynamic_input_vercel_mjs_aa3704._.js @@ -0,0 +1,12 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_imports_static-and-dynamic_input_vercel_mjs_aa3704._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs [test] (ecmascript, async loader)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__((__turbopack_import__) => { + return Promise.resolve().then(() => { + return __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs [test] (ecmascript)"); + }); +}); + +})()), +}]); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/a587c_tests_snapshot_imports_static-and-dynamic_input_vercel_mjs_aa3704._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/a587c_tests_snapshot_imports_static-and-dynamic_input_vercel_mjs_aa3704._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/a587c_tests_snapshot_imports_static-and-dynamic_input_vercel_mjs_aa3704._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js new file mode 100644 index 0000000000000..dbb3bbfd770fc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js @@ -0,0 +1,25 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +const __TURBOPACK__default__export__ = "turbopack"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$static$2d$and$2d$dynamic$2f$input$2f$vercel$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$static$2d$and$2d$dynamic$2f$input$2f$vercel$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__["default"]); +__turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs [test] (ecmascript, async loader)")(__turbopack_import__).then(console.log); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js.map new file mode 100644 index 0000000000000..4c606d3b86870 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/output/crates_turbopack-tests_tests_snapshot_imports_static-and-dynamic_input_cbb273._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/vercel.mjs"],"sourcesContent":["export default \"turbopack\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/static-and-dynamic/input/index.js"],"sourcesContent":["import img from \"./vercel.mjs\";\nconsole.log(img);\n\nimport(\"./vercel.mjs\").then(console.log);\n"],"names":[],"mappings":";;;;AACA,QAAQ,GAAG,CAAC,sMAAA,CAAA,UAAG;AAEf,6KAAuB,IAAI,CAAC,QAAQ,GAAG"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js new file mode 100644 index 0000000000000..f259874a52539 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js @@ -0,0 +1,2 @@ +import img from "./vercel.svg"; +console.log(img); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/input/vercel.svg b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/input/vercel.svg new file mode 100644 index 0000000000000..76bea97e3e9a8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/input/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js new file mode 100644 index 0000000000000..59fba5f79929e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js @@ -0,0 +1,19 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/vercel.svg [test] (static)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { + +__turbopack_export_value__("/static/vercel.957b9b16.svg"); +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$static$2f$input$2f$vercel$2e$svg__$5b$test$5d$__$28$static$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/vercel.svg [test] (static)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$static$2f$input$2f$vercel$2e$svg__$5b$test$5d$__$28$static$29$__["default"]); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js.map new file mode 100644 index 0000000000000..5e64d30ea2871 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js"],"sourcesContent":["import img from \"./vercel.svg\";\nconsole.log(img);\n"],"names":[],"mappings":";;;;AACA,QAAQ,GAAG,CAAC,gLAAA,CAAA,UAAG"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_index_300143.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_index_300143.js new file mode 100644 index 0000000000000..3ab2deac003e3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_index_300143.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_imports_static_input_index_300143.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_imports_static_input_4175d9._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/static/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_index_300143.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_index_300143.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/output/crates_turbopack-tests_tests_snapshot_imports_static_input_index_300143.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/static/vercel.957b9b16.svg b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/static/vercel.957b9b16.svg new file mode 100644 index 0000000000000..76bea97e3e9a8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/static/static/vercel.957b9b16.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js new file mode 100644 index 0000000000000..60c6c8d8b04f9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js @@ -0,0 +1 @@ +export default "foo"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js new file mode 100644 index 0000000000000..b13c2e5d95f3a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js @@ -0,0 +1,3 @@ +import foo from "./nested"; + +console.log(foo); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js new file mode 100644 index 0000000000000..50d8edbc2b170 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js @@ -0,0 +1,2 @@ +import foo from "#foo"; +export default foo; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/package.json new file mode 100644 index 0000000000000..3ce936c482a58 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/package.json @@ -0,0 +1,6 @@ +{ + "name": "subpath-imports", + "imports": { + "#foo": "./foo.js" + } +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js new file mode 100644 index 0000000000000..b3249debfc235 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js @@ -0,0 +1,36 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +const __TURBOPACK__default__export__ = "foo"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2d$nested$2f$input$2f$foo$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +const __TURBOPACK__default__export__ = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2d$nested$2f$input$2f$foo$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"]; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2d$nested$2f$input$2f$nested$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2d$nested$2f$input$2f$nested$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"]); + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js.map new file mode 100644 index 0000000000000..f7a30062f0362 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js.map @@ -0,0 +1,11 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/foo.js"],"sourcesContent":["export default \"foo\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/nested/index.js"],"sourcesContent":["import foo from \"#foo\";\nexport default foo;\n"],"names":[],"mappings":";;;;;;uCACe,sMAAA,CAAA,UAAG"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js"],"sourcesContent":["import foo from \"./nested\";\n\nconsole.log(foo);\n"],"names":[],"mappings":";;;;AAEA,QAAQ,GAAG,CAAC,kNAAA,CAAA,UAAG"}}, + {"offset": {"line": 31, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/a587c_tests_snapshot_imports_subpath-imports-nested_input_index_b710e1.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/a587c_tests_snapshot_imports_subpath-imports-nested_input_index_b710e1.js new file mode 100644 index 0000000000000..82c5076df8d84 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/a587c_tests_snapshot_imports_subpath-imports-nested_input_index_b710e1.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_imports_subpath-imports-nested_input_index_b710e1.js", + {}, + {"otherChunks":["output/79fb1_turbopack-tests_tests_snapshot_imports_subpath-imports-nested_input_83c7e7._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/a587c_tests_snapshot_imports_subpath-imports-nested_input_index_b710e1.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/a587c_tests_snapshot_imports_subpath-imports-nested_input_index_b710e1.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports-nested/output/a587c_tests_snapshot_imports_subpath-imports-nested_input_index_b710e1.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js new file mode 100644 index 0000000000000..f1e020421cbfe --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js @@ -0,0 +1 @@ +export default "dep"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/package.json new file mode 100644 index 0000000000000..d814501e55981 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/package.json @@ -0,0 +1,3 @@ +{ + "name": "dep" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js new file mode 100644 index 0000000000000..60c6c8d8b04f9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js @@ -0,0 +1 @@ +export default "foo"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs new file mode 100644 index 0000000000000..7d3341883b8e4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs @@ -0,0 +1 @@ +export default "import"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js new file mode 100644 index 0000000000000..accb6aeaa8182 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js @@ -0,0 +1,7 @@ +import foo from "#foo"; +import dep from "#dep"; +import pattern from "#pattern/pat.js"; +import conditionalImport from "#conditional"; +const conditionalRequire = require("#conditional"); + +console.log(foo, dep, pattern, conditionalImport, conditionalRequire); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/package.json new file mode 100644 index 0000000000000..2790b239a509c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/package.json @@ -0,0 +1,15 @@ +{ + "name": "subpath-imports", + "imports": { + "#foo": "./foo.js", + "#dep": "dep", + "#conditional": { + "import": "./import.mjs", + "require": "./require.cjs" + }, + "#pattern/*.js": "./*.js" + }, + "dependencies": { + "dep": "./dep" + } +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js new file mode 100644 index 0000000000000..6ffed9800b7b9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js @@ -0,0 +1 @@ +export default "pat"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs new file mode 100644 index 0000000000000..e7da5bd67c152 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs @@ -0,0 +1 @@ +module.exports = "require"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js new file mode 100644 index 0000000000000..288e8056b1cfa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js @@ -0,0 +1,63 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +const __TURBOPACK__default__export__ = "foo"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +const __TURBOPACK__default__export__ = "dep"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +const __TURBOPACK__default__export__ = "pat"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>__TURBOPACK__default__export__ +}); +const __TURBOPACK__default__export__ = "import"; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +module.exports = "require"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2f$input$2f$foo$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2f$input$2f$dep$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2f$input$2f$pat$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2f$input$2f$import$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +; +const conditionalRequire = __turbopack_require__("[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs [test] (ecmascript)"); +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2f$input$2f$foo$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2f$input$2f$dep$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2f$input$2f$pat$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$imports$2f$subpath$2d$imports$2f$input$2f$import$2e$mjs__$5b$test$5d$__$28$ecmascript$29$__["default"], conditionalRequire); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js.map new file mode 100644 index 0000000000000..ce53d823e7c64 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js.map @@ -0,0 +1,17 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/foo.js"],"sourcesContent":["export default \"foo\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/dep/index.js"],"sourcesContent":["export default \"dep\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 23, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/pat.js"],"sourcesContent":["export default \"pat\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 27, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/import.mjs"],"sourcesContent":["export default \"import\";\n"],"names":[],"mappings":";;;uCAAe"}}, + {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 40, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/require.cjs"],"sourcesContent":["module.exports = \"require\";\n"],"names":[],"mappings":"AAAA,OAAO,OAAO,GAAG"}}, + {"offset": {"line": 41, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 46, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js"],"sourcesContent":["import foo from \"#foo\";\nimport dep from \"#dep\";\nimport pattern from \"#pattern/pat.js\";\nimport conditionalImport from \"#conditional\";\nconst conditionalRequire = require(\"#conditional\");\n\nconsole.log(foo, dep, pattern, conditionalImport, conditionalRequire);\n"],"names":[],"mappings":";;;;;;;;;;AAIA,MAAM;AAEN,QAAQ,GAAG,CAAC,4LAAA,CAAA,UAAG,EAAE,qMAAA,CAAA,UAAG,EAAE,4LAAA,CAAA,UAAO,EAAE,gMAAA,CAAA,UAAiB,EAAE"}}, + {"offset": {"line": 58, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_index_f436bb.js b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_index_f436bb.js new file mode 100644 index 0000000000000..25182ae1de703 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_index_f436bb.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_index_f436bb.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_f5873d._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_index_f436bb.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_index_f436bb.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/imports/subpath-imports/output/crates_turbopack-tests_tests_snapshot_imports_subpath-imports_input_index_f436bb.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_743c8b.js b/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_743c8b.js new file mode 100644 index 0000000000000..f5c9fc12f7cc9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_743c8b.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_743c8b.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_a3c4fd.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/mdx/error/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_743c8b.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_743c8b.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_743c8b.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_a3c4fd.js b/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_a3c4fd.js new file mode 100644 index 0000000000000..54b9be29e22f1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_a3c4fd.js @@ -0,0 +1,9 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_a3c4fd.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/mdx/error/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +const e = new Error("Could not parse module '[project]/crates/turbopack-tests/tests/snapshot/mdx/error/input/index.js'"); +e.code = 'MODULE_UNPARSEABLE'; +throw e; +}.call(this) }), +}]); \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_a3c4fd.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_a3c4fd.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/mdx/error/output/crates_turbopack-tests_tests_snapshot_mdx_error_input_index_a3c4fd.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/input/index.js new file mode 100644 index 0000000000000..44575a4e4a4e0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/input/index.js @@ -0,0 +1,30 @@ +function toFixed(value, maxDecimals, roundingFunction, optionals) { + var splitValue = value.toString().split('.'), + minDecimals = maxDecimals - (optionals || 0), + + optionalsRegExp, + power, + output; + var boundedPrecisions; + // var unused = 'xxxx'; + + // Use the smallest precision value possible to avoid errors from floating point representation + if (splitValue.length === 2) { + boundedPrecisions = Math.min(Math.max(splitValue[1].length, minDecimals), maxDecimals); + } else { + boundedPrecisions = minDecimals; + } + + power = Math.pow(10, boundedPrecisions); + + // Multiply up by precision, round accurately, then divide and use native toFixed(): + output = (roundingFunction(value + 'e+' + boundedPrecisions) / power).toFixed(boundedPrecisions); + + if (optionals > maxDecimals - boundedPrecisions) { + optionalsRegExp = new RegExp('\\.?0{1,' + (optionals - (maxDecimals - boundedPrecisions)) + '}$'); + output = output.replace(optionalsRegExp, ''); + } + + return output; +} +toFixed(1.2345, 2, Math.round, 1); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/options.json new file mode 100644 index 0000000000000..06c4926889d64 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/options.json @@ -0,0 +1,3 @@ +{ + "minifyType": "Minify" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js new file mode 100644 index 0000000000000..e329353957897 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js @@ -0,0 +1,29 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/minification/paren-remover/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +function toFixed(value, maxDecimals, roundingFunction, optionals) { + var splitValue = value.toString().split('.'), minDecimals = maxDecimals - (optionals || 0), optionalsRegExp, power, output; + var boundedPrecisions; + // var unused = 'xxxx'; + // Use the smallest precision value possible to avoid errors from floating point representation + if (splitValue.length === 2) { + boundedPrecisions = Math.min(Math.max(splitValue[1].length, minDecimals), maxDecimals); + } else { + boundedPrecisions = minDecimals; + } + power = Math.pow(10, boundedPrecisions); + // Multiply up by precision, round accurately, then divide and use native toFixed(): + output = (roundingFunction(value + 'e+' + boundedPrecisions) / power).toFixed(boundedPrecisions); + if (optionals > maxDecimals - boundedPrecisions) { + optionalsRegExp = new RegExp('\\.?0{1,' + (optionals - (maxDecimals - boundedPrecisions)) + '}$'); + output = output.replace(optionalsRegExp, ''); + } + return output; +} +toFixed(1.2345, 2, Math.round, 1); + +}.call(this) }), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js.map new file mode 100644 index 0000000000000..00428656abab1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/minification/paren-remover/input/index.js"],"sourcesContent":["function toFixed(value, maxDecimals, roundingFunction, optionals) {\n var splitValue = value.toString().split('.'),\n minDecimals = maxDecimals - (optionals || 0),\n\n optionalsRegExp,\n power,\n output;\n var boundedPrecisions;\n // var unused = 'xxxx';\n\n // Use the smallest precision value possible to avoid errors from floating point representation\n if (splitValue.length === 2) {\n boundedPrecisions = Math.min(Math.max(splitValue[1].length, minDecimals), maxDecimals);\n } else {\n boundedPrecisions = minDecimals;\n }\n\n power = Math.pow(10, boundedPrecisions);\n\n // Multiply up by precision, round accurately, then divide and use native toFixed():\n output = (roundingFunction(value + 'e+' + boundedPrecisions) / power).toFixed(boundedPrecisions);\n\n if (optionals > maxDecimals - boundedPrecisions) {\n optionalsRegExp = new RegExp('\\\\.?0{1,' + (optionals - (maxDecimals - boundedPrecisions)) + '}$');\n output = output.replace(optionalsRegExp, '');\n }\n\n return output;\n}\ntoFixed(1.2345, 2, Math.round, 1);\n"],"names":[],"mappings":"AAAA,SAAS,QAAQ,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,SAAS;IAC9D,IAAI,aAAa,MAAM,QAAQ,GAAG,KAAK,CAAC,MACpC,cAAc,cAAc,CAAC,aAAa,CAAC,GAE3C,iBACA,OACA;IACJ,IAAI;IACJ,uBAAuB;IAEvB,+FAA+F;IAC/F,IAAI,WAAW,MAAM,KAAK,GAAG;QAC3B,oBAAoB,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc;IAC5E,OAAO;QACL,oBAAoB;IACtB;IAEA,QAAQ,KAAK,GAAG,CAAC,IAAI;IAErB,oFAAoF;IACpF,SAAS,CAAC,iBAAiB,QAAQ,OAAO,qBAAqB,KAAK,EAAE,OAAO,CAAC;IAE9E,IAAI,YAAY,cAAc,mBAAmB;QAC7C,kBAAkB,IAAI,OAAO,aAAa,CAAC,YAAY,CAAC,cAAc,iBAAiB,CAAC,IAAI;QAC5F,SAAS,OAAO,OAAO,CAAC,iBAAiB;IAC7C;IAEA,OAAO;AACT;AACA,QAAQ,QAAQ,GAAG,KAAK,KAAK,EAAE"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_eab450.js b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_eab450.js new file mode 100644 index 0000000000000..a80290164545e --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_eab450.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_eab450.js", + {}, + {"otherChunks":["output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_80e2cf.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/minification/paren-remover/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_eab450.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_eab450.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/minification/paren-remover/output/79fb1_turbopack-tests_tests_snapshot_minification_paren-remover_input_index_eab450.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/input/index.js new file mode 100644 index 0000000000000..efb36e6149bf9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/input/index.js @@ -0,0 +1 @@ +import fs from "node:fs"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/options.json new file mode 100644 index 0000000000000..d56676da5aa7f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/options.json @@ -0,0 +1,3 @@ +{ + "environment": "NodeJs" +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_0fca49.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_0fca49.js new file mode 100644 index 0000000000000..5182df517fca8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_0fca49.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_0fca49.js", + {}, + {"otherChunks":["output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_0fca49.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_0fca49.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_0fca49.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js new file mode 100644 index 0000000000000..bbae53d76a1f2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js @@ -0,0 +1,14 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__url__external__node$3a$fs__ = __turbopack_external_require__("node:fs", true); +"__TURBOPACK__ecmascript__hoisting__location__"; +; + +})()), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js.map new file mode 100644 index 0000000000000..9cdb7b480b138 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/node_protocol_external/output/79fb1_turbopack-tests_tests_snapshot_node_node_protocol_external_input_index_8770aa.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":""}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js new file mode 100644 index 0000000000000..82589227ff2bb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js @@ -0,0 +1,4 @@ +import { spawn } from "child_process"; + +const program = ['ls']; +const proc = spawn(program[0], ['-la']); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js new file mode 100644 index 0000000000000..96c72b27fcdd2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js @@ -0,0 +1,3 @@ +export function spawn(cmd, args) { + // +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/options.json new file mode 100644 index 0000000000000..d56676da5aa7f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/options.json @@ -0,0 +1,3 @@ +{ + "environment": "NodeJs" +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js new file mode 100644 index 0000000000000..1e8e487649901 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js @@ -0,0 +1,31 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node$2f$spawn_dynamic$2f$input$2f$node_modules$2f$child_process$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +const program = [ + 'ls' +]; +const proc = (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node$2f$spawn_dynamic$2f$input$2f$node_modules$2f$child_process$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["spawn"])(program[0], [ + '-la' +]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { +"use strict"; + +__turbopack_esm__({ + "spawn": ()=>spawn +}); +function spawn(cmd, args) { +// +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js.map new file mode 100644 index 0000000000000..2cf2e680f6035 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js"],"sourcesContent":["import { spawn } from \"child_process\";\n\nconst program = ['ls'];\nconst proc = spawn(program[0], ['-la']);\n"],"names":[],"mappings":";;;;AAEA,MAAM,UAAU;IAAC;CAAK;AACtB,MAAM,OAAO,CAAA,GAAA,uNAAA,CAAA,QAAK,AAAD,EAAE,OAAO,CAAC,EAAE,EAAE;IAAC;CAAM"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/node_modules/child_process/index.js"],"sourcesContent":["export function spawn(cmd, args) {\n //\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,MAAM,GAAG,EAAE,IAAI;AAC7B,EAAE;AACJ"}}, + {"offset": {"line": 26, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_index_2d1475.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_index_2d1475.js new file mode 100644 index 0000000000000..402daff5a5204 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_index_2d1475.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_index_2d1475.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_e65664._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_index_2d1475.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_index_2d1475.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_dynamic/output/crates_turbopack-tests_tests_snapshot_node_spawn_dynamic_input_index_2d1475.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js new file mode 100644 index 0000000000000..59b2403d0823b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js @@ -0,0 +1,3 @@ +import { spawn } from "child_process"; + +let x = spawn(process.argv[0], ["-e", "console.log('foo');"]); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js new file mode 100644 index 0000000000000..96c72b27fcdd2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js @@ -0,0 +1,3 @@ +export function spawn(cmd, args) { + // +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/options.json new file mode 100644 index 0000000000000..d56676da5aa7f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/options.json @@ -0,0 +1,3 @@ +{ + "environment": "NodeJs" +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js new file mode 100644 index 0000000000000..b7908aae10751 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js @@ -0,0 +1,29 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node$2f$spawn_node_eval$2f$input$2f$node_modules$2f$child_process$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +let x = (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node$2f$spawn_node_eval$2f$input$2f$node_modules$2f$child_process$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["spawn"])(process.argv[0], [ + "-e", + "console.log('foo');" +]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, x: __turbopack_external_require__, y: __turbopack_external_import__ }) => (() => { +"use strict"; + +__turbopack_esm__({ + "spawn": ()=>spawn +}); +function spawn(cmd, args) { +// +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js.map new file mode 100644 index 0000000000000..473760c1138a0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js"],"sourcesContent":["import { spawn } from \"child_process\";\n\nlet x = spawn(process.argv[0], [\"-e\", \"console.log('foo');\"]);\n"],"names":[],"mappings":";;;;AAEA,IAAI,IAAI,CAAA,GAAA,yNAAA,CAAA,QAAK,AAAD,EAAE,QAAQ,IAAI,CAAC,EAAE,EAAE;IAAC;IAAM;CAAsB"}}, + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 18, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/node_modules/child_process/index.js"],"sourcesContent":["export function spawn(cmd, args) {\n //\n}\n"],"names":[],"mappings":";;;AAAO,SAAS,MAAM,GAAG,EAAE,IAAI;AAC7B,EAAE;AACJ"}}, + {"offset": {"line": 24, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_index_123ad9.js b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_index_123ad9.js new file mode 100644 index 0000000000000..a6039b4cd0966 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_index_123ad9.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_index_123ad9.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_d0030e._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_index_123ad9.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_index_123ad9.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node/spawn_node_eval/output/crates_turbopack-tests_tests_snapshot_node_spawn_node_eval_input_index_123ad9.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js new file mode 100644 index 0000000000000..9d2737fd0b1b5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/index.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"@emtion/react/index.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js new file mode 100644 index 0000000000000..eee7c33dd5e39 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-dev-runtime.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"@emtion/react/jsx-dev-runtime.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-runtime.js new file mode 100644 index 0000000000000..885532e7a31df --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/react/jsx-runtime.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"@emtion/react/jsx-runtime.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js new file mode 100644 index 0000000000000..84d649be392cf --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@emotion/styled/index.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"@emtion/styled/index.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@next/font/google/target.css b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@next/font/google/target.css new file mode 100644 index 0000000000000..7bc527f2def74 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@next/font/google/target.css @@ -0,0 +1,2 @@ +/* "purposefully empty stub"; +"@next/font/google/target.css"; */ diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@next/font/local/target.css b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@next/font/local/target.css new file mode 100644 index 0000000000000..590d8bd19490b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@next/font/local/target.css @@ -0,0 +1,2 @@ +/* "purposefully empty stub"; +"@next/font/local/target.css"; */ diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js new file mode 100644 index 0000000000000..e66813ad2bca4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"@swc/helpers/_/_class_call_check.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/index.js new file mode 100644 index 0000000000000..4a62f07619929 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/index.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"@swc/helpers/index.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/index.js new file mode 100644 index 0000000000000..f115b2d8e1395 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/index.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"react/index.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js new file mode 100644 index 0000000000000..f561dbe24f620 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"react/jsx-dev-runtime.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-runtime.js new file mode 100644 index 0000000000000..ee1da08297184 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-runtime.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"react/jsx-runtime.js"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js new file mode 100644 index 0000000000000..c14944409b889 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js @@ -0,0 +1,2 @@ +"purposefully empty stub"; +"styled-components/index.js" diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/foo.ts b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/foo.ts new file mode 100644 index 0000000000000..7765b67ff7e72 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/foo.ts @@ -0,0 +1 @@ +export const prop = "prop"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts new file mode 100644 index 0000000000000..2592244d35ea0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts @@ -0,0 +1 @@ +export const prop = 1; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/tsconfig.json new file mode 100644 index 0000000000000..6be0dc1c681c0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "foo": ["./prop"], + "./foo": ["./prop"], + "@/*": ["./*"], + } + }, + "include": ["./*.ts"] + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/package.json b/turbopack/crates/turbopack-tests/tests/snapshot/package.json new file mode 100644 index 0000000000000..4c700bf788905 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/package.json @@ -0,0 +1,12 @@ +{ + "description": "DO NOT NPM INSTALL ANYTHING. This is not a real package.JSON, it's a stub for tests. The node_modules dir are stubs.", + "private": true, + "devDependencies": { + "@swc/helpers": "100000000000", + "styled-components": "^100000", + "react": "1000000000000000000", + "@emotion/react": "1000000000", + "@emotion/styled": "100000000", + "tsconfig-mod": "100000000000" + } +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js new file mode 100644 index 0000000000000..a8141d3b18d34 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js @@ -0,0 +1 @@ +console.log("Hello, world!"); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/options.json new file mode 100644 index 0000000000000..001f0f2624608 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/options.json @@ -0,0 +1,5 @@ +{ + "minifyType": "NoMinify", + "runtime": "NodeJs", + "runtimeType": "Production" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js new file mode 100644 index 0000000000000..2cda85eb3fbf2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js @@ -0,0 +1,11 @@ +module.exports = { + +"[project]/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +console.log("Hello, world!"); + +}.call(this) }), + +}; + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js.map new file mode 100644 index 0000000000000..b712177004c01 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js"],"sourcesContent":["console.log(\"Hello, world!\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js new file mode 100644 index 0000000000000..d1ea5ab0f4fdf --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js @@ -0,0 +1,641 @@ +const RUNTIME_PUBLIC_PATH = "output/[turbopack]_runtime.js"; +const OUTPUT_ROOT = "crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime"; +const ASSET_PREFIX = "/"; +/** + * This file contains runtime types and functions that are shared between all + * TurboPack ECMAScript runtimes. + * + * It will be prepended to the runtime code of each runtime. + */ /* eslint-disable @next/next/no-assign-module-variable */ /// +const REEXPORTED_OBJECTS = Symbol("reexported objects"); +const hasOwnProperty = Object.prototype.hasOwnProperty; +const toStringTag = typeof Symbol !== "undefined" && Symbol.toStringTag; +function defineProp(obj, name1, options) { + if (!hasOwnProperty.call(obj, name1)) Object.defineProperty(obj, name1, options); +} +/** + * Adds the getters to the exports object. + */ function esm(exports, getters) { + defineProp(exports, "__esModule", { + value: true + }); + if (toStringTag) defineProp(exports, toStringTag, { + value: "Module" + }); + for(const key in getters){ + const item = getters[key]; + if (Array.isArray(item)) { + defineProp(exports, key, { + get: item[0], + set: item[1], + enumerable: true + }); + } else { + defineProp(exports, key, { + get: item, + enumerable: true + }); + } + } + Object.seal(exports); +} +/** + * Makes the module an ESM with exports + */ function esmExport(module, exports, getters) { + module.namespaceObject = module.exports; + esm(exports, getters); +} +function ensureDynamicExports(module, exports) { + let reexportedObjects = module[REEXPORTED_OBJECTS]; + if (!reexportedObjects) { + reexportedObjects = module[REEXPORTED_OBJECTS] = []; + module.exports = module.namespaceObject = new Proxy(exports, { + get (target, prop) { + if (hasOwnProperty.call(target, prop) || prop === "default" || prop === "__esModule") { + return Reflect.get(target, prop); + } + for (const obj of reexportedObjects){ + const value = Reflect.get(obj, prop); + if (value !== undefined) return value; + } + return undefined; + }, + ownKeys (target) { + const keys = Reflect.ownKeys(target); + for (const obj of reexportedObjects){ + for (const key of Reflect.ownKeys(obj)){ + if (key !== "default" && !keys.includes(key)) keys.push(key); + } + } + return keys; + } + }); + } +} +/** + * Dynamically exports properties from an object + */ function dynamicExport(module, exports, object) { + ensureDynamicExports(module, exports); + if (typeof object === "object" && object !== null) { + module[REEXPORTED_OBJECTS].push(object); + } +} +function exportValue(module, value) { + module.exports = value; +} +function exportNamespace(module, namespace) { + module.exports = module.namespaceObject = namespace; +} +function createGetter(obj, key) { + return ()=>obj[key]; +} +/** + * @returns prototype of the object + */ const getProto = Object.getPrototypeOf ? (obj)=>Object.getPrototypeOf(obj) : (obj)=>obj.__proto__; +/** Prototypes that are not expanded for exports */ const LEAF_PROTOTYPES = [ + null, + getProto({}), + getProto([]), + getProto(getProto) +]; +/** + * @param raw + * @param ns + * @param allowExportDefault + * * `false`: will have the raw module as default export + * * `true`: will have the default property as default export + */ function interopEsm(raw, ns, allowExportDefault) { + const getters = Object.create(null); + for(let current = raw; (typeof current === "object" || typeof current === "function") && !LEAF_PROTOTYPES.includes(current); current = getProto(current)){ + for (const key of Object.getOwnPropertyNames(current)){ + getters[key] = createGetter(raw, key); + } + } + // this is not really correct + // we should set the `default` getter if the imported module is a `.cjs file` + if (!(allowExportDefault && "default" in getters)) { + getters["default"] = ()=>raw; + } + esm(ns, getters); + return ns; +} +function createNS(raw) { + if (typeof raw === "function") { + return function(...args) { + return raw.apply(this, args); + }; + } else { + return Object.create(null); + } +} +function esmImport(sourceModule, id) { + const module = getOrInstantiateModuleFromParent(id, sourceModule); + if (module.error) throw module.error; + // any ES module has to have `module.namespaceObject` defined. + if (module.namespaceObject) return module.namespaceObject; + // only ESM can be an async module, so we don't need to worry about exports being a promise here. + const raw = module.exports; + return module.namespaceObject = interopEsm(raw, createNS(raw), raw && raw.__esModule); +} +// Add a simple runtime require so that environments without one can still pass +// `typeof require` CommonJS checks so that exports are correctly registered. +const runtimeRequire = typeof require === "function" ? require : function require1() { + throw new Error("Unexpected use of runtime require"); +}; +function commonJsRequire(sourceModule, id) { + const module = getOrInstantiateModuleFromParent(id, sourceModule); + if (module.error) throw module.error; + return module.exports; +} +/** + * `require.context` and require/import expression runtime. + */ function moduleContext(map) { + function moduleContext(id) { + if (hasOwnProperty.call(map, id)) { + return map[id].module(); + } + const e = new Error(`Cannot find module '${name}'`); + e.code = "MODULE_NOT_FOUND"; + throw e; + } + moduleContext.keys = ()=>{ + return Object.keys(map); + }; + moduleContext.resolve = (id)=>{ + if (hasOwnProperty.call(map, id)) { + return map[id].id(); + } + const e = new Error(`Cannot find module '${name}'`); + e.code = "MODULE_NOT_FOUND"; + throw e; + }; + moduleContext.import = async (id)=>{ + return await moduleContext(id); + }; + return moduleContext; +} +/** + * Returns the path of a chunk defined by its data. + */ function getChunkPath(chunkData) { + return typeof chunkData === "string" ? chunkData : chunkData.path; +} +function isPromise(maybePromise) { + return maybePromise != null && typeof maybePromise === "object" && "then" in maybePromise && typeof maybePromise.then === "function"; +} +function isAsyncModuleExt(obj) { + return turbopackQueues in obj; +} +function createPromise() { + let resolve; + let reject; + const promise = new Promise((res, rej)=>{ + reject = rej; + resolve = res; + }); + return { + promise, + resolve: resolve, + reject: reject + }; +} +// everything below is adapted from webpack +// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13 +const turbopackQueues = Symbol("turbopack queues"); +const turbopackExports = Symbol("turbopack exports"); +const turbopackError = Symbol("turbopack error"); +let QueueStatus; +function resolveQueue(queue) { + if (queue && queue.status !== 1) { + queue.status = 1; + queue.forEach((fn)=>fn.queueCount--); + queue.forEach((fn)=>fn.queueCount-- ? fn.queueCount++ : fn()); + } +} +function wrapDeps(deps) { + return deps.map((dep)=>{ + if (dep !== null && typeof dep === "object") { + if (isAsyncModuleExt(dep)) return dep; + if (isPromise(dep)) { + const queue = Object.assign([], { + status: 0 + }); + const obj = { + [turbopackExports]: {}, + [turbopackQueues]: (fn)=>fn(queue) + }; + dep.then((res)=>{ + obj[turbopackExports] = res; + resolveQueue(queue); + }, (err)=>{ + obj[turbopackError] = err; + resolveQueue(queue); + }); + return obj; + } + } + return { + [turbopackExports]: dep, + [turbopackQueues]: ()=>{} + }; + }); +} +function asyncModule(module, body, hasAwait) { + const queue = hasAwait ? Object.assign([], { + status: -1 + }) : undefined; + const depQueues = new Set(); + const { resolve, reject, promise: rawPromise } = createPromise(); + const promise = Object.assign(rawPromise, { + [turbopackExports]: module.exports, + [turbopackQueues]: (fn)=>{ + queue && fn(queue); + depQueues.forEach(fn); + promise["catch"](()=>{}); + } + }); + const attributes = { + get () { + return promise; + }, + set (v) { + // Calling `esmExport` leads to this. + if (v !== promise) { + promise[turbopackExports] = v; + } + } + }; + Object.defineProperty(module, "exports", attributes); + Object.defineProperty(module, "namespaceObject", attributes); + function handleAsyncDependencies(deps) { + const currentDeps = wrapDeps(deps); + const getResult = ()=>currentDeps.map((d)=>{ + if (d[turbopackError]) throw d[turbopackError]; + return d[turbopackExports]; + }); + const { promise, resolve } = createPromise(); + const fn = Object.assign(()=>resolve(getResult), { + queueCount: 0 + }); + function fnQueue(q) { + if (q !== queue && !depQueues.has(q)) { + depQueues.add(q); + if (q && q.status === 0) { + fn.queueCount++; + q.push(fn); + } + } + } + currentDeps.map((dep)=>dep[turbopackQueues](fnQueue)); + return fn.queueCount ? promise : getResult(); + } + function asyncResult(err) { + if (err) { + reject(promise[turbopackError] = err); + } else { + resolve(promise[turbopackExports]); + } + resolveQueue(queue); + } + body(handleAsyncDependencies, asyncResult); + if (queue && queue.status === -1) { + queue.status = 0; + } +} +/** + * A pseudo "fake" URL object to resolve to its relative path. + * + * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this + * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid + * hydration mismatch. + * + * This is based on webpack's existing implementation: + * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js + */ const relativeURL = function relativeURL(inputUrl) { + const realUrl = new URL(inputUrl, "x:/"); + const values = {}; + for(const key in realUrl)values[key] = realUrl[key]; + values.href = inputUrl; + values.pathname = inputUrl.replace(/[?#].*/, ""); + values.origin = values.protocol = ""; + values.toString = values.toJSON = (..._args)=>inputUrl; + for(const key in values)Object.defineProperty(this, key, { + enumerable: true, + configurable: true, + value: values[key] + }); +}; +relativeURL.prototype = URL.prototype; +/// +/// A 'base' utilities to support runtime can have externals. +/// Currently this is for node.js / edge runtime both. +/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead. +async function externalImport(id) { + let raw; + try { + raw = await import(id); + } catch (err) { + // TODO(alexkirsz) This can happen when a client-side module tries to load + // an external module we don't provide a shim for (e.g. querystring, url). + // For now, we fail semi-silently, but in the future this should be a + // compilation error. + throw new Error(`Failed to load external module ${id}: ${err}`); + } + if (raw && raw.__esModule && raw.default && "default" in raw.default) { + return interopEsm(raw.default, createNS(raw), true); + } + return raw; +} +function externalRequire(id, esm = false) { + let raw; + try { + raw = require(id); + } catch (err) { + // TODO(alexkirsz) This can happen when a client-side module tries to load + // an external module we don't provide a shim for (e.g. querystring, url). + // For now, we fail semi-silently, but in the future this should be a + // compilation error. + throw new Error(`Failed to load external module ${id}: ${err}`); + } + if (!esm || raw.__esModule) { + return raw; + } + return interopEsm(raw, createNS(raw), true); +} +externalRequire.resolve = (id, options)=>{ + return require.resolve(id, options); +}; +const path = require("path"); +const relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, "."); +// Compute the relative path to the `distDir`. +const relativePathToDistRoot = path.relative(path.join(OUTPUT_ROOT, RUNTIME_PUBLIC_PATH), "."); +const RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot); +// Compute the absolute path to the root, by stripping distDir from the absolute path to this file. +const ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot); +/** + * Returns an absolute path to the given module path. + * Module path should be relative, either path to a file or a directory. + * + * This fn allows to calculate an absolute path for some global static values, such as + * `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time. + * See ImportMetaBinding::code_generation for the usage. + */ function resolveAbsolutePath(modulePath) { + if (modulePath) { + return path.join(ABSOLUTE_ROOT, modulePath); + } + return ABSOLUTE_ROOT; +} +/// +function readWebAssemblyAsResponse(path) { + const { createReadStream } = require("fs"); + const { Readable } = require("stream"); + const stream = createReadStream(path); + // @ts-ignore unfortunately there's a slight type mismatch with the stream. + return new Response(Readable.toWeb(stream), { + headers: { + "content-type": "application/wasm" + } + }); +} +async function compileWebAssemblyFromPath(path) { + const response = readWebAssemblyAsResponse(path); + return await WebAssembly.compileStreaming(response); +} +async function instantiateWebAssemblyFromPath(path, importsObj) { + const response = readWebAssemblyAsResponse(path); + const { instance } = await WebAssembly.instantiateStreaming(response, importsObj); + return instance.exports; +} +/// +/// +/// +/// +let SourceType; +(function(SourceType) { + /** + * The module was instantiated because it was included in an evaluated chunk's + * runtime. + */ SourceType[SourceType["Runtime"] = 0] = "Runtime"; + /** + * The module was instantiated because a parent module imported it. + */ SourceType[SourceType["Parent"] = 1] = "Parent"; +})(SourceType || (SourceType = {})); +function stringifySourceInfo(source) { + switch(source.type){ + case 0: + return `runtime for chunk ${source.chunkPath}`; + case 1: + return `parent module ${source.parentId}`; + } +} +const url = require("url"); +const fs = require("fs/promises"); +const vm = require("vm"); +const moduleFactories = Object.create(null); +const moduleCache = Object.create(null); +/** + * Returns an absolute path to the given module's id. + */ function createResolvePathFromModule(resolver) { + return function resolvePathFromModule(moduleId) { + const exported = resolver(moduleId); + const exportedPath = exported?.default ?? exported; + if (typeof exportedPath !== "string") { + return exported; + } + const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length); + const resolved = path.resolve(ABSOLUTE_ROOT, OUTPUT_ROOT, strippedAssetPrefix); + return url.pathToFileURL(resolved); + }; +} +function loadChunk(chunkData, source) { + if (typeof chunkData === "string") { + return loadChunkPath(chunkData, source); + } else { + return loadChunkPath(chunkData.path, source); + } +} +function loadChunkPath(chunkPath, source) { + if (!chunkPath.endsWith(".js")) { + // We only support loading JS chunks in Node.js. + // This branch can be hit when trying to load a CSS chunk. + return; + } + try { + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + const chunkModules = require(resolved); + for (const [moduleId, moduleFactory] of Object.entries(chunkModules)){ + if (!moduleFactories[moduleId]) { + moduleFactories[moduleId] = moduleFactory; + } + } + } catch (e) { + let errorMessage = `Failed to load chunk ${chunkPath}`; + if (source) { + errorMessage += ` from ${stringifySourceInfo(source)}`; + } + throw new Error(errorMessage, { + cause: e + }); + } +} +async function loadChunkAsync(source, chunkData) { + const chunkPath = typeof chunkData === "string" ? chunkData : chunkData.path; + if (!chunkPath.endsWith(".js")) { + // We only support loading JS chunks in Node.js. + // This branch can be hit when trying to load a CSS chunk. + return; + } + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + try { + const contents = await fs.readFile(resolved, "utf-8"); + const module1 = { + exports: {} + }; + vm.runInThisContext("(function(module, exports, require, __dirname, __filename) {" + contents + "\n})", resolved)(module1, module1.exports, require, path.dirname(resolved), resolved); + const chunkModules = module1.exports; + for (const [moduleId, moduleFactory] of Object.entries(chunkModules)){ + if (!moduleFactories[moduleId]) { + moduleFactories[moduleId] = moduleFactory; + } + } + } catch (e) { + let errorMessage = `Failed to load chunk ${chunkPath}`; + if (source) { + errorMessage += ` from ${stringifySourceInfo(source)}`; + } + throw new Error(errorMessage, { + cause: e + }); + } +} +function loadWebAssembly(chunkPath, imports) { + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + return instantiateWebAssemblyFromPath(resolved, imports); +} +function loadWebAssemblyModule(chunkPath) { + const resolved = path.resolve(RUNTIME_ROOT, chunkPath); + return compileWebAssemblyFromPath(resolved); +} +function instantiateModule(id, source) { + const moduleFactory = moduleFactories[id]; + if (typeof moduleFactory !== "function") { + // This can happen if modules incorrectly handle HMR disposes/updates, + // e.g. when they keep a `setTimeout` around which still executes old code + // and contains e.g. a `require("something")` call. + let instantiationReason; + switch(source.type){ + case 0: + instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`; + break; + case 1: + instantiationReason = `because it was required from module ${source.parentId}`; + break; + } + throw new Error(`Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`); + } + let parents; + switch(source.type){ + case 0: + parents = []; + break; + case 1: + // No need to add this module as a child of the parent module here, this + // has already been taken care of in `getOrInstantiateModuleFromParent`. + parents = [ + source.parentId + ]; + break; + } + const module1 = { + exports: {}, + error: undefined, + loaded: false, + id, + parents, + children: [], + namespaceObject: undefined + }; + moduleCache[id] = module1; + // NOTE(alexkirsz) This can fail when the module encounters a runtime error. + try { + const r = commonJsRequire.bind(null, module1); + moduleFactory.call(module1.exports, { + a: asyncModule.bind(null, module1), + e: module1.exports, + r, + t: runtimeRequire, + x: externalRequire, + y: externalImport, + f: moduleContext, + i: esmImport.bind(null, module1), + s: esmExport.bind(null, module1, module1.exports), + j: dynamicExport.bind(null, module1, module1.exports), + v: exportValue.bind(null, module1), + n: exportNamespace.bind(null, module1), + m: module1, + c: moduleCache, + M: moduleFactories, + l: loadChunkAsync.bind(null, { + type: 1, + parentId: id + }), + w: loadWebAssembly, + u: loadWebAssemblyModule, + g: globalThis, + P: resolveAbsolutePath, + U: relativeURL, + R: createResolvePathFromModule(r), + __dirname: module1.id.replace(/(^|\/)[\/]+$/, "") + }); + } catch (error) { + module1.error = error; + throw error; + } + module1.loaded = true; + if (module1.namespaceObject && module1.exports !== module1.namespaceObject) { + // in case of a circular dependency: cjs1 -> esm2 -> cjs1 + interopEsm(module1.exports, module1.namespaceObject); + } + return module1; +} +/** + * Retrieves a module from the cache, or instantiate it if it is not cached. + */ function getOrInstantiateModuleFromParent(id, sourceModule) { + const module1 = moduleCache[id]; + if (sourceModule.children.indexOf(id) === -1) { + sourceModule.children.push(id); + } + if (module1) { + if (module1.parents.indexOf(sourceModule.id) === -1) { + module1.parents.push(sourceModule.id); + } + return module1; + } + return instantiateModule(id, { + type: 1, + parentId: sourceModule.id + }); +} +/** + * Instantiates a runtime module. + */ function instantiateRuntimeModule(moduleId, chunkPath) { + return instantiateModule(moduleId, { + type: 0, + chunkPath + }); +} +/** + * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached. + */ function getOrInstantiateRuntimeModule(moduleId, chunkPath) { + const module1 = moduleCache[moduleId]; + if (module1) { + if (module1.error) { + throw module1.error; + } + return module1; + } + return instantiateRuntimeModule(moduleId, chunkPath); +} +module.exports = { + getOrInstantiateRuntimeModule, + loadChunk +}; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map new file mode 100644 index 0000000000000..bf446d5d55b18 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/[turbopack]_runtime.js.map @@ -0,0 +1,10 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 3, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n\ninterface Exports {\n __esModule?: boolean;\n\n [key: string]: any;\n}\n\ntype EsmNamespaceObject = Record;\n\nconst REEXPORTED_OBJECTS = Symbol(\"reexported objects\");\n\ninterface BaseModule {\n exports: Function | Exports | Promise | AsyncModulePromise;\n error: Error | undefined;\n loaded: boolean;\n id: ModuleId;\n children: ModuleId[];\n parents: ModuleId[];\n namespaceObject?:\n | EsmNamespaceObject\n | Promise\n | AsyncModulePromise;\n [REEXPORTED_OBJECTS]?: any[];\n}\n\ninterface Module extends BaseModule {}\n\ntype ModuleContextMap = Record;\n\ninterface ModuleContextEntry {\n id: () => ModuleId;\n module: () => any;\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject;\n\n // async import call\n import(moduleId: ModuleId): Promise;\n\n keys(): ModuleId[];\n\n resolve(moduleId: ModuleId): ModuleId;\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: Module\n) => Module;\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst toStringTag = typeof Symbol !== \"undefined\" && Symbol.toStringTag;\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name))\n Object.defineProperty(obj, name, options);\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(\n exports: Exports,\n getters: Record any) | [() => any, (v: any) => void]>\n) {\n defineProp(exports, \"__esModule\", { value: true });\n if (toStringTag) defineProp(exports, toStringTag, { value: \"Module\" });\n for (const key in getters) {\n const item = getters[key];\n if (Array.isArray(item)) {\n defineProp(exports, key, {\n get: item[0],\n set: item[1],\n enumerable: true,\n });\n } else {\n defineProp(exports, key, { get: item, enumerable: true });\n }\n }\n Object.seal(exports);\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n getters: Record any>\n) {\n module.namespaceObject = module.exports;\n esm(exports, getters);\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS];\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = [];\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === \"default\" ||\n prop === \"__esModule\"\n ) {\n return Reflect.get(target, prop);\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop);\n if (value !== undefined) return value;\n }\n return undefined;\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target);\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== \"default\" && !keys.includes(key)) keys.push(key);\n }\n }\n return keys;\n },\n });\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n object: Record\n) {\n ensureDynamicExports(module, exports);\n\n if (typeof object === \"object\" && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object);\n }\n}\n\nfunction exportValue(module: Module, value: any) {\n module.exports = value;\n}\n\nfunction exportNamespace(module: Module, namespace: any) {\n module.exports = module.namespaceObject = namespace;\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key];\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__;\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)];\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null);\n for (\n let current = raw;\n (typeof current === \"object\" || typeof current === \"function\") &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key);\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && \"default\" in getters)) {\n getters[\"default\"] = () => raw;\n }\n\n esm(ns, getters);\n return ns;\n}\n\nfunction createNS(raw: BaseModule[\"exports\"]): EsmNamespaceObject {\n if (typeof raw === \"function\") {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args);\n };\n } else {\n return Object.create(null);\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject;\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports;\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ));\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n typeof require === \"function\"\n ? require\n : function require() {\n throw new Error(\"Unexpected use of runtime require\");\n };\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n return module.exports;\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map);\n };\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n };\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise);\n };\n\n return moduleContext;\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === \"string\" ? chunkData : chunkData.path;\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === \"object\" &&\n \"then\" in maybePromise &&\n typeof maybePromise.then === \"function\"\n );\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj;\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void;\n let reject: (reason?: any) => void;\n\n const promise = new Promise((res, rej) => {\n reject = rej;\n resolve = res;\n });\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n };\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol(\"turbopack queues\");\nconst turbopackExports = Symbol(\"turbopack exports\");\nconst turbopackError = Symbol(\"turbopack error\");\n\nconst enum QueueStatus {\n Unknown = -1,\n Unresolved = 0,\n Resolved = 1,\n}\n\ntype AsyncQueueFn = (() => void) & { queueCount: number };\ntype AsyncQueue = AsyncQueueFn[] & {\n status: QueueStatus;\n};\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && queue.status !== QueueStatus.Resolved) {\n queue.status = QueueStatus.Resolved;\n queue.forEach((fn) => fn.queueCount--);\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()));\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise;\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void;\n [turbopackExports]: Exports;\n [turbopackError]?: any;\n};\n\ntype AsyncModulePromise = Promise & AsyncModuleExt;\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep): AsyncModuleExt => {\n if (dep !== null && typeof dep === \"object\") {\n if (isAsyncModuleExt(dep)) return dep;\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], {\n status: QueueStatus.Unresolved,\n });\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n };\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res;\n resolveQueue(queue);\n },\n (err) => {\n obj[turbopackError] = err;\n resolveQueue(queue);\n }\n );\n\n return obj;\n }\n }\n\n return {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n };\n });\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { status: QueueStatus.Unknown })\n : undefined;\n\n const depQueues: Set = new Set();\n\n const { resolve, reject, promise: rawPromise } = createPromise();\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: module.exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue);\n depQueues.forEach(fn);\n promise[\"catch\"](() => {});\n },\n } satisfies AsyncModuleExt);\n\n const attributes: PropertyDescriptor = {\n get(): any {\n return promise;\n },\n set(v: any) {\n // Calling `esmExport` leads to this.\n if (v !== promise) {\n promise[turbopackExports] = v;\n }\n },\n };\n\n Object.defineProperty(module, \"exports\", attributes);\n Object.defineProperty(module, \"namespaceObject\", attributes);\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps);\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError];\n return d[turbopackExports];\n });\n\n const { promise, resolve } = createPromise<() => Exports[]>();\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n });\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q);\n if (q && q.status === QueueStatus.Unresolved) {\n fn.queueCount++;\n q.push(fn);\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue));\n\n return fn.queueCount ? promise : getResult();\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err));\n } else {\n resolve(promise[turbopackExports]);\n }\n\n resolveQueue(queue);\n }\n\n body(handleAsyncDependencies, asyncResult);\n\n if (queue && queue.status === QueueStatus.Unknown) {\n queue.status = QueueStatus.Unresolved;\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, \"x:/\");\n const values: Record = {};\n for (const key in realUrl) values[key] = (realUrl as any)[key];\n values.href = inputUrl;\n values.pathname = inputUrl.replace(/[?#].*/, \"\");\n values.origin = values.protocol = \"\";\n values.toString = values.toJSON = (..._args: Array) => inputUrl;\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n });\n};\n\nrelativeURL.prototype = URL.prototype;\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAED,uDAAuD,GAEvD,6CAA6C;AAU7C,MAAM,qBAAqB,OAAO;AA0ClC,MAAM,iBAAiB,OAAO,SAAS,CAAC,cAAc;AACtD,MAAM,cAAc,OAAO,WAAW,eAAe,OAAO,WAAW;AAEvE,SAAS,WACP,GAAQ,EACR,KAAiB,EACjB,OAA2C;IAE3C,IAAI,CAAC,eAAe,IAAI,CAAC,KAAK,QAC5B,OAAO,cAAc,CAAC,KAAK,OAAM;AACrC;AAEA;;CAEC,GACD,SAAS,IACP,OAAgB,EAChB,OAAoE;IAEpE,WAAW,SAAS,cAAc;QAAE,OAAO;IAAK;IAChD,IAAI,aAAa,WAAW,SAAS,aAAa;QAAE,OAAO;IAAS;IACpE,IAAK,MAAM,OAAO,QAAS;QACzB,MAAM,OAAO,OAAO,CAAC,IAAI;QACzB,IAAI,MAAM,OAAO,CAAC,OAAO;YACvB,WAAW,SAAS,KAAK;gBACvB,KAAK,IAAI,CAAC,EAAE;gBACZ,KAAK,IAAI,CAAC,EAAE;gBACZ,YAAY;YACd;QACF,OAAO;YACL,WAAW,SAAS,KAAK;gBAAE,KAAK;gBAAM,YAAY;YAAK;QACzD;IACF;IACA,OAAO,IAAI,CAAC;AACd;AAEA;;CAEC,GACD,SAAS,UACP,MAAc,EACd,OAAgB,EAChB,OAAkC;IAElC,OAAO,eAAe,GAAG,OAAO,OAAO;IACvC,IAAI,SAAS;AACf;AAEA,SAAS,qBAAqB,MAAc,EAAE,OAAgB;IAC5D,IAAI,oBAAoB,MAAM,CAAC,mBAAmB;IAElD,IAAI,CAAC,mBAAmB;QACtB,oBAAoB,MAAM,CAAC,mBAAmB,GAAG,EAAE;QACnD,OAAO,OAAO,GAAG,OAAO,eAAe,GAAG,IAAI,MAAM,SAAS;YAC3D,KAAI,MAAM,EAAE,IAAI;gBACd,IACE,eAAe,IAAI,CAAC,QAAQ,SAC5B,SAAS,aACT,SAAS,cACT;oBACA,OAAO,QAAQ,GAAG,CAAC,QAAQ;gBAC7B;gBACA,KAAK,MAAM,OAAO,kBAAoB;oBACpC,MAAM,QAAQ,QAAQ,GAAG,CAAC,KAAK;oBAC/B,IAAI,UAAU,WAAW,OAAO;gBAClC;gBACA,OAAO;YACT;YACA,SAAQ,MAAM;gBACZ,MAAM,OAAO,QAAQ,OAAO,CAAC;gBAC7B,KAAK,MAAM,OAAO,kBAAoB;oBACpC,KAAK,MAAM,OAAO,QAAQ,OAAO,CAAC,KAAM;wBACtC,IAAI,QAAQ,aAAa,CAAC,KAAK,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC;oBAC1D;gBACF;gBACA,OAAO;YACT;QACF;IACF;AACF;AAEA;;CAEC,GACD,SAAS,cACP,MAAc,EACd,OAAgB,EAChB,MAA2B;IAE3B,qBAAqB,QAAQ;IAE7B,IAAI,OAAO,WAAW,YAAY,WAAW,MAAM;QACjD,MAAM,CAAC,mBAAmB,CAAE,IAAI,CAAC;IACnC;AACF;AAEA,SAAS,YAAY,MAAc,EAAE,KAAU;IAC7C,OAAO,OAAO,GAAG;AACnB;AAEA,SAAS,gBAAgB,MAAc,EAAE,SAAc;IACrD,OAAO,OAAO,GAAG,OAAO,eAAe,GAAG;AAC5C;AAEA,SAAS,aAAa,GAAiC,EAAE,GAAoB;IAC3E,OAAO,IAAM,GAAG,CAAC,IAAI;AACvB;AAEA;;CAEC,GACD,MAAM,WAA8B,OAAO,cAAc,GACrD,CAAC,MAAQ,OAAO,cAAc,CAAC,OAC/B,CAAC,MAAQ,IAAI,SAAS;AAE1B,iDAAiD,GACjD,MAAM,kBAAkB;IAAC;IAAM,SAAS,CAAC;IAAI,SAAS,EAAE;IAAG,SAAS;CAAU;AAE9E;;;;;;CAMC,GACD,SAAS,WACP,GAAY,EACZ,EAAsB,EACtB,kBAA4B;IAE5B,MAAM,UAAsC,OAAO,MAAM,CAAC;IAC1D,IACE,IAAI,UAAU,KACd,CAAC,OAAO,YAAY,YAAY,OAAO,YAAY,UAAU,KAC7D,CAAC,gBAAgB,QAAQ,CAAC,UAC1B,UAAU,SAAS,SACnB;QACA,KAAK,MAAM,OAAO,OAAO,mBAAmB,CAAC,SAAU;YACrD,OAAO,CAAC,IAAI,GAAG,aAAa,KAAK;QACnC;IACF;IAEA,6BAA6B;IAC7B,6EAA6E;IAC7E,IAAI,CAAC,CAAC,sBAAsB,aAAa,OAAO,GAAG;QACjD,OAAO,CAAC,UAAU,GAAG,IAAM;IAC7B;IAEA,IAAI,IAAI;IACR,OAAO;AACT;AAEA,SAAS,SAAS,GAA0B;IAC1C,IAAI,OAAO,QAAQ,YAAY;QAC7B,OAAO,SAAqB,GAAG,IAAW;YACxC,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;QACzB;IACF,OAAO;QACL,OAAO,OAAO,MAAM,CAAC;IACvB;AACF;AAEA,SAAS,UACP,YAAoB,EACpB,EAAY;IAEZ,MAAM,SAAS,iCAAiC,IAAI;IACpD,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,KAAK;IAEpC,8DAA8D;IAC9D,IAAI,OAAO,eAAe,EAAE,OAAO,OAAO,eAAe;IAEzD,iGAAiG;IACjG,MAAM,MAAM,OAAO,OAAO;IAC1B,OAAQ,OAAO,eAAe,GAAG,WAC/B,KACA,SAAS,MACT,OAAO,AAAC,IAAY,UAAU;AAElC;AAEA,+EAA+E;AAC/E,6EAA6E;AAC7E,MAAM,iBACJ,OAAO,YAAY,aACf,UACA,SAAS;IACP,MAAM,IAAI,MAAM;AAClB;AAEN,SAAS,gBAAgB,YAAoB,EAAE,EAAY;IACzD,MAAM,SAAS,iCAAiC,IAAI;IACpD,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,KAAK;IACpC,OAAO,OAAO,OAAO;AACvB;AAEA;;CAEC,GACD,SAAS,cAAc,GAAqB;IAC1C,SAAS,cAAc,EAAY;QACjC,IAAI,eAAe,IAAI,CAAC,KAAK,KAAK;YAChC,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM;QACvB;QAEA,MAAM,IAAI,IAAI,MAAM,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QACjD,EAAU,IAAI,GAAG;QAClB,MAAM;IACR;IAEA,cAAc,IAAI,GAAG;QACnB,OAAO,OAAO,IAAI,CAAC;IACrB;IAEA,cAAc,OAAO,GAAG,CAAC;QACvB,IAAI,eAAe,IAAI,CAAC,KAAK,KAAK;YAChC,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE;QACnB;QAEA,MAAM,IAAI,IAAI,MAAM,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QACjD,EAAU,IAAI,GAAG;QAClB,MAAM;IACR;IAEA,cAAc,MAAM,GAAG,OAAO;QAC5B,OAAO,MAAO,cAAc;IAC9B;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,aAAa,SAAoB;IACxC,OAAO,OAAO,cAAc,WAAW,YAAY,UAAU,IAAI;AACnE;AAEA,SAAS,UAAmB,YAAiB;IAC3C,OACE,gBAAgB,QAChB,OAAO,iBAAiB,YACxB,UAAU,gBACV,OAAO,aAAa,IAAI,KAAK;AAEjC;AAEA,SAAS,iBAA+B,GAAM;IAC5C,OAAO,mBAAmB;AAC5B;AAEA,SAAS;IACP,IAAI;IACJ,IAAI;IAEJ,MAAM,UAAU,IAAI,QAAW,CAAC,KAAK;QACnC,SAAS;QACT,UAAU;IACZ;IAEA,OAAO;QACL;QACA,SAAS;QACT,QAAQ;IACV;AACF;AAEA,2CAA2C;AAC3C,+HAA+H;AAE/H,MAAM,kBAAkB,OAAO;AAC/B,MAAM,mBAAmB,OAAO;AAChC,MAAM,iBAAiB,OAAO;;AAa9B,SAAS,aAAa,KAAkB;IACtC,IAAI,SAAS,MAAM,MAAM,QAA2B;QAClD,MAAM,MAAM;QACZ,MAAM,OAAO,CAAC,CAAC,KAAO,GAAG,UAAU;QACnC,MAAM,OAAO,CAAC,CAAC,KAAQ,GAAG,UAAU,KAAK,GAAG,UAAU,KAAK;IAC7D;AACF;AAYA,SAAS,SAAS,IAAW;IAC3B,OAAO,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;YAC3C,IAAI,iBAAiB,MAAM,OAAO;YAClC,IAAI,UAAU,MAAM;gBAClB,MAAM,QAAoB,OAAO,MAAM,CAAC,EAAE,EAAE;oBAC1C,MAAM;gBACR;gBAEA,MAAM,MAAsB;oBAC1B,CAAC,iBAAiB,EAAE,CAAC;oBACrB,CAAC,gBAAgB,EAAE,CAAC,KAAoC,GAAG;gBAC7D;gBAEA,IAAI,IAAI,CACN,CAAC;oBACC,GAAG,CAAC,iBAAiB,GAAG;oBACxB,aAAa;gBACf,GACA,CAAC;oBACC,GAAG,CAAC,eAAe,GAAG;oBACtB,aAAa;gBACf;gBAGF,OAAO;YACT;QACF;QAEA,OAAO;YACL,CAAC,iBAAiB,EAAE;YACpB,CAAC,gBAAgB,EAAE,KAAO;QAC5B;IACF;AACF;AAEA,SAAS,YACP,MAAc,EACd,IAKS,EACT,QAAiB;IAEjB,MAAM,QAAgC,WAClC,OAAO,MAAM,CAAC,EAAE,EAAE;QAAE,MAAM;IAAsB,KAChD;IAEJ,MAAM,YAA6B,IAAI;IAEvC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG;IAEjD,MAAM,UAA8B,OAAO,MAAM,CAAC,YAAY;QAC5D,CAAC,iBAAiB,EAAE,OAAO,OAAO;QAClC,CAAC,gBAAgB,EAAE,CAAC;YAClB,SAAS,GAAG;YACZ,UAAU,OAAO,CAAC;YAClB,OAAO,CAAC,QAAQ,CAAC,KAAO;QAC1B;IACF;IAEA,MAAM,aAAiC;QACrC;YACE,OAAO;QACT;QACA,KAAI,CAAM;YACR,qCAAqC;YACrC,IAAI,MAAM,SAAS;gBACjB,OAAO,CAAC,iBAAiB,GAAG;YAC9B;QACF;IACF;IAEA,OAAO,cAAc,CAAC,QAAQ,WAAW;IACzC,OAAO,cAAc,CAAC,QAAQ,mBAAmB;IAEjD,SAAS,wBAAwB,IAAW;QAC1C,MAAM,cAAc,SAAS;QAE7B,MAAM,YAAY,IAChB,YAAY,GAAG,CAAC,CAAC;gBACf,IAAI,CAAC,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,eAAe;gBAC9C,OAAO,CAAC,CAAC,iBAAiB;YAC5B;QAEF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG;QAE7B,MAAM,KAAmB,OAAO,MAAM,CAAC,IAAM,QAAQ,YAAY;YAC/D,YAAY;QACd;QAEA,SAAS,QAAQ,CAAa;YAC5B,IAAI,MAAM,SAAS,CAAC,UAAU,GAAG,CAAC,IAAI;gBACpC,UAAU,GAAG,CAAC;gBACd,IAAI,KAAK,EAAE,MAAM,QAA6B;oBAC5C,GAAG,UAAU;oBACb,EAAE,IAAI,CAAC;gBACT;YACF;QACF;QAEA,YAAY,GAAG,CAAC,CAAC,MAAQ,GAAG,CAAC,gBAAgB,CAAC;QAE9C,OAAO,GAAG,UAAU,GAAG,UAAU;IACnC;IAEA,SAAS,YAAY,GAAS;QAC5B,IAAI,KAAK;YACP,OAAQ,OAAO,CAAC,eAAe,GAAG;QACpC,OAAO;YACL,QAAQ,OAAO,CAAC,iBAAiB;QACnC;QAEA,aAAa;IACf;IAEA,KAAK,yBAAyB;IAE9B,IAAI,SAAS,MAAM,MAAM,SAA0B;QACjD,MAAM,MAAM;IACd;AACF;AAEA;;;;;;;;;CASC,GACD,MAAM,cAAc,SAAS,YAAuB,QAAgB;IAClE,MAAM,UAAU,IAAI,IAAI,UAAU;IAClC,MAAM,SAA8B,CAAC;IACrC,IAAK,MAAM,OAAO,QAAS,MAAM,CAAC,IAAI,GAAG,AAAC,OAAe,CAAC,IAAI;IAC9D,OAAO,IAAI,GAAG;IACd,OAAO,QAAQ,GAAG,SAAS,OAAO,CAAC,UAAU;IAC7C,OAAO,MAAM,GAAG,OAAO,QAAQ,GAAG;IAClC,OAAO,QAAQ,GAAG,OAAO,MAAM,GAAG,CAAC,GAAG,QAAsB;IAC5D,IAAK,MAAM,OAAO,OAChB,OAAO,cAAc,CAAC,IAAI,EAAE,KAAK;QAC/B,YAAY;QACZ,cAAc;QACd,OAAO,MAAM,CAAC,IAAI;IACpB;AACJ;AAEA,YAAY,SAAS,GAAG,IAAI,SAAS"}}, + {"offset": {"line": 327, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/base-externals-utils.ts"],"sourcesContent":["/// \n\n/// A 'base' utilities to support runtime can have externals.\n/// Currently this is for node.js / edge runtime both.\n/// If a fn requires node.js specific behavior, it should be placed in `node-external-utils` instead.\n\nasync function externalImport(id: ModuleId) {\n let raw;\n try {\n raw = await import(id);\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`);\n }\n\n if (raw && raw.__esModule && raw.default && \"default\" in raw.default) {\n return interopEsm(raw.default, createNS(raw), true);\n }\n\n return raw;\n}\n\nfunction externalRequire(\n id: ModuleId,\n esm: boolean = false\n): Exports | EsmNamespaceObject {\n let raw;\n try {\n raw = require(id);\n } catch (err) {\n // TODO(alexkirsz) This can happen when a client-side module tries to load\n // an external module we don't provide a shim for (e.g. querystring, url).\n // For now, we fail semi-silently, but in the future this should be a\n // compilation error.\n throw new Error(`Failed to load external module ${id}: ${err}`);\n }\n\n if (!esm || raw.__esModule) {\n return raw;\n }\n\n return interopEsm(raw, createNS(raw), true);\n}\n\nexternalRequire.resolve = (\n id: string,\n options?: {\n paths?: string[];\n }\n) => {\n return require.resolve(id, options);\n};\n"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,6DAA6D;AAC7D,sDAAsD;AACtD,qGAAqG;AAErG,eAAe,eAAe,EAAY;IACxC,IAAI;IACJ,IAAI;QACF,MAAM,MAAM,MAAM,CAAC;IACrB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;IAChE;IAEA,IAAI,OAAO,IAAI,UAAU,IAAI,IAAI,OAAO,IAAI,aAAa,IAAI,OAAO,EAAE;QACpE,OAAO,WAAW,IAAI,OAAO,EAAE,SAAS,MAAM;IAChD;IAEA,OAAO;AACT;AAEA,SAAS,gBACP,EAAY,EACZ,MAAe,KAAK;IAEpB,IAAI;IACJ,IAAI;QACF,MAAM,QAAQ;IAChB,EAAE,OAAO,KAAK;QACZ,0EAA0E;QAC1E,0EAA0E;QAC1E,qEAAqE;QACrE,qBAAqB;QACrB,MAAM,IAAI,MAAM,CAAC,+BAA+B,EAAE,GAAG,EAAE,EAAE,IAAI,CAAC;IAChE;IAEA,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE;QAC1B,OAAO;IACT;IAEA,OAAO,WAAW,KAAK,SAAS,MAAM;AACxC;AAEA,gBAAgB,OAAO,GAAG,CACxB,IACA;IAIA,OAAO,QAAQ,OAAO,CAAC,IAAI;AAC7B"}}, + {"offset": {"line": 366, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/node-externals-utils.ts"],"sourcesContent":["declare var RUNTIME_PUBLIC_PATH: string;\ndeclare var OUTPUT_ROOT: string;\ndeclare var ASSET_PREFIX: string;\n\nconst path = require(\"path\");\n\nconst relativePathToRuntimeRoot = path.relative(RUNTIME_PUBLIC_PATH, \".\");\n// Compute the relative path to the `distDir`.\nconst relativePathToDistRoot = path.relative(\n path.join(OUTPUT_ROOT, RUNTIME_PUBLIC_PATH),\n \".\"\n);\nconst RUNTIME_ROOT = path.resolve(__filename, relativePathToRuntimeRoot);\n// Compute the absolute path to the root, by stripping distDir from the absolute path to this file.\nconst ABSOLUTE_ROOT = path.resolve(__filename, relativePathToDistRoot);\n\n/**\n * Returns an absolute path to the given module path.\n * Module path should be relative, either path to a file or a directory.\n *\n * This fn allows to calculate an absolute path for some global static values, such as\n * `__dirname` or `import.meta.url` that Turbopack will not embeds in compile time.\n * See ImportMetaBinding::code_generation for the usage.\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n if (modulePath) {\n return path.join(ABSOLUTE_ROOT, modulePath);\n }\n return ABSOLUTE_ROOT;\n}\n"],"names":[],"mappings":"AAIA,MAAM,OAAO,QAAQ;AAErB,MAAM,4BAA4B,KAAK,QAAQ,CAAC,qBAAqB;AACrE,8CAA8C;AAC9C,MAAM,yBAAyB,KAAK,QAAQ,CAC1C,KAAK,IAAI,CAAC,aAAa,sBACvB;AAEF,MAAM,eAAe,KAAK,OAAO,CAAC,YAAY;AAC9C,mGAAmG;AACnG,MAAM,gBAAgB,KAAK,OAAO,CAAC,YAAY;AAE/C;;;;;;;CAOC,GACD,SAAS,oBAAoB,UAAmB;IAC9C,IAAI,YAAY;QACd,OAAO,KAAK,IAAI,CAAC,eAAe;IAClC;IACA,OAAO;AACT"}}, + {"offset": {"line": 386, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared-node/node-wasm-utils.ts"],"sourcesContent":["/// \n\nfunction readWebAssemblyAsResponse(path: string) {\n const { createReadStream } = require(\"fs\") as typeof import(\"fs\");\n const { Readable } = require(\"stream\") as typeof import(\"stream\");\n\n const stream = createReadStream(path);\n\n // @ts-ignore unfortunately there's a slight type mismatch with the stream.\n return new Response(Readable.toWeb(stream), {\n headers: {\n \"content-type\": \"application/wasm\",\n },\n });\n}\n\nasync function compileWebAssemblyFromPath(\n path: string\n): Promise {\n const response = readWebAssemblyAsResponse(path);\n\n return await WebAssembly.compileStreaming(response);\n}\n\nasync function instantiateWebAssemblyFromPath(\n path: string,\n importsObj: WebAssembly.Imports\n): Promise {\n const response = readWebAssemblyAsResponse(path);\n\n const { instance } = await WebAssembly.instantiateStreaming(\n response,\n importsObj\n );\n\n return instance.exports;\n}\n"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,SAAS,0BAA0B,IAAY;IAC7C,MAAM,EAAE,gBAAgB,EAAE,GAAG,QAAQ;IACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ;IAE7B,MAAM,SAAS,iBAAiB;IAEhC,2EAA2E;IAC3E,OAAO,IAAI,SAAS,SAAS,KAAK,CAAC,SAAS;QAC1C,SAAS;YACP,gBAAgB;QAClB;IACF;AACF;AAEA,eAAe,2BACb,IAAY;IAEZ,MAAM,WAAW,0BAA0B;IAE3C,OAAO,MAAM,YAAY,gBAAgB,CAAC;AAC5C;AAEA,eAAe,+BACb,IAAY,EACZ,UAA+B;IAE/B,MAAM,WAAW,0BAA0B;IAE3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,oBAAoB,CACzD,UACA;IAGF,OAAO,SAAS,OAAO;AACzB"}}, + {"offset": {"line": 407, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/nodejs/runtime.ts"],"sourcesContent":["/// \n/// \n/// \n/// \n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime;\n chunkPath: ChunkPath;\n }\n | {\n type: SourceType.Parent;\n parentId: ModuleId;\n };\n\nfunction stringifySourceInfo(source: SourceInfo): string {\n switch (source.type) {\n case SourceType.Runtime:\n return `runtime for chunk ${source.chunkPath}`;\n case SourceType.Parent:\n return `parent module ${source.parentId}`;\n }\n}\n\ntype ExternalRequire = (id: ModuleId) => Exports | EsmNamespaceObject;\ntype ExternalImport = (id: ModuleId) => Promise;\n\ninterface TurbopackNodeBuildContext extends TurbopackBaseContext {\n R: ResolvePathFromModule;\n x: ExternalRequire;\n y: ExternalImport;\n}\n\ntype ModuleFactory = (\n this: Module[\"exports\"],\n context: TurbopackNodeBuildContext\n) => undefined;\n\nconst url = require(\"url\");\nconst fs = require(\"fs/promises\");\nconst vm = require(\"vm\");\n\nconst moduleFactories: ModuleFactories = Object.create(null);\nconst moduleCache: ModuleCache = Object.create(null);\n\n/**\n * Returns an absolute path to the given module's id.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId);\n const exportedPath = exported?.default ?? exported;\n if (typeof exportedPath !== \"string\") {\n return exported as any;\n }\n\n const strippedAssetPrefix = exportedPath.slice(ASSET_PREFIX.length);\n const resolved = path.resolve(\n ABSOLUTE_ROOT,\n OUTPUT_ROOT,\n strippedAssetPrefix\n );\n\n return url.pathToFileURL(resolved);\n };\n}\n\nfunction loadChunk(chunkData: ChunkData, source?: SourceInfo): void {\n if (typeof chunkData === \"string\") {\n return loadChunkPath(chunkData, source);\n } else {\n return loadChunkPath(chunkData.path, source);\n }\n}\n\nfunction loadChunkPath(chunkPath: ChunkPath, source?: SourceInfo): void {\n if (!chunkPath.endsWith(\".js\")) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return;\n }\n\n try {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n const chunkModules: ModuleFactories = require(resolved);\n\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n }\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`;\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`;\n }\n\n throw new Error(errorMessage, {\n cause: e,\n });\n }\n}\n\nasync function loadChunkAsync(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n const chunkPath = typeof chunkData === \"string\" ? chunkData : chunkData.path;\n if (!chunkPath.endsWith(\".js\")) {\n // We only support loading JS chunks in Node.js.\n // This branch can be hit when trying to load a CSS chunk.\n return;\n }\n\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n try {\n const contents = await fs.readFile(resolved, \"utf-8\");\n\n const module = {\n exports: {},\n };\n vm.runInThisContext(\n \"(function(module, exports, require, __dirname, __filename) {\" +\n contents +\n \"\\n})\",\n resolved\n )(module, module.exports, require, path.dirname(resolved), resolved);\n\n const chunkModules: ModuleFactories = module.exports;\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n }\n } catch (e) {\n let errorMessage = `Failed to load chunk ${chunkPath}`;\n\n if (source) {\n errorMessage += ` from ${stringifySourceInfo(source)}`;\n }\n\n throw new Error(errorMessage, {\n cause: e,\n });\n }\n}\n\nfunction loadWebAssembly(chunkPath: ChunkPath, imports: WebAssembly.Imports) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return instantiateWebAssemblyFromPath(resolved, imports);\n}\n\nfunction loadWebAssemblyModule(chunkPath: ChunkPath) {\n const resolved = path.resolve(RUNTIME_ROOT, chunkPath);\n\n return compileWebAssemblyFromPath(resolved);\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id];\n if (typeof moduleFactory !== \"function\") {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason;\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`;\n break;\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n );\n }\n\n let parents: ModuleId[];\n switch (source.type) {\n case SourceType.Runtime:\n parents = [];\n break;\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId];\n break;\n }\n\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n };\n moduleCache[id] = module;\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const r = commonJsRequire.bind(null, module);\n moduleFactory.call(module.exports, {\n a: asyncModule.bind(null, module),\n e: module.exports,\n r,\n t: runtimeRequire,\n x: externalRequire,\n y: externalImport,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunkAsync.bind(null, { type: SourceType.Parent, parentId: id }),\n w: loadWebAssembly,\n u: loadWebAssemblyModule,\n g: globalThis,\n P: resolveAbsolutePath,\n U: relativeURL,\n R: createResolvePathFromModule(r),\n __dirname: module.id.replace(/(^|\\/)[\\/]+$/, \"\"),\n });\n } catch (error) {\n module.error = error as any;\n throw error;\n }\n\n module.loaded = true;\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject);\n }\n\n return module;\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\nfunction getOrInstantiateModuleFromParent(\n id: ModuleId,\n sourceModule: Module\n): Module {\n const module = moduleCache[id];\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id);\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id);\n }\n\n return module;\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n });\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it as a runtime module if it is not cached.\n */\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId];\n if (module) {\n if (module.error) {\n throw module.error;\n }\n return module;\n }\n\n return instantiateRuntimeModule(moduleId, chunkPath);\n}\n\nmodule.exports = {\n getOrInstantiateRuntimeModule,\n loadChunk,\n};\n"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,+DAA+D;AAC/D,+DAA+D;AAC/D,0DAA0D;;UAErD;IACH;;;GAGC;IAED;;GAEC;GARE,eAAA;AAsBL,SAAS,oBAAoB,MAAkB;IAC7C,OAAQ,OAAO,IAAI;QACjB;YACE,OAAO,CAAC,kBAAkB,EAAE,OAAO,SAAS,CAAC,CAAC;QAChD;YACE,OAAO,CAAC,cAAc,EAAE,OAAO,QAAQ,CAAC,CAAC;IAC7C;AACF;AAgBA,MAAM,MAAM,QAAQ;AACpB,MAAM,KAAK,QAAQ;AACnB,MAAM,KAAK,QAAQ;AAEnB,MAAM,kBAAmC,OAAO,MAAM,CAAC;AACvD,MAAM,cAA2B,OAAO,MAAM,CAAC;AAE/C;;CAEC,GACD,SAAS,4BACP,QAAuC;IAEvC,OAAO,SAAS,sBAAsB,QAAgB;QACpD,MAAM,WAAW,SAAS;QAC1B,MAAM,eAAe,UAAU,WAAW;QAC1C,IAAI,OAAO,iBAAiB,UAAU;YACpC,OAAO;QACT;QAEA,MAAM,sBAAsB,aAAa,KAAK,CAAC,aAAa,MAAM;QAClE,MAAM,WAAW,KAAK,OAAO,CAC3B,eACA,aACA;QAGF,OAAO,IAAI,aAAa,CAAC;IAC3B;AACF;AAEA,SAAS,UAAU,SAAoB,EAAE,MAAmB;IAC1D,IAAI,OAAO,cAAc,UAAU;QACjC,OAAO,cAAc,WAAW;IAClC,OAAO;QACL,OAAO,cAAc,UAAU,IAAI,EAAE;IACvC;AACF;AAEA,SAAS,cAAc,SAAoB,EAAE,MAAmB;IAC9D,IAAI,CAAC,UAAU,QAAQ,CAAC,QAAQ;QAC9B,gDAAgD;QAChD,0DAA0D;QAC1D;IACF;IAEA,IAAI;QACF,MAAM,WAAW,KAAK,OAAO,CAAC,cAAc;QAC5C,MAAM,eAAgC,QAAQ;QAE9C,KAAK,MAAM,CAAC,UAAU,cAAc,IAAI,OAAO,OAAO,CAAC,cAAe;YACpE,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE;gBAC9B,eAAe,CAAC,SAAS,GAAG;YAC9B;QACF;IACF,EAAE,OAAO,GAAG;QACV,IAAI,eAAe,CAAC,qBAAqB,EAAE,UAAU,CAAC;QAEtD,IAAI,QAAQ;YACV,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,QAAQ,CAAC;QACxD;QAEA,MAAM,IAAI,MAAM,cAAc;YAC5B,OAAO;QACT;IACF;AACF;AAEA,eAAe,eACb,MAAkB,EAClB,SAAoB;IAEpB,MAAM,YAAY,OAAO,cAAc,WAAW,YAAY,UAAU,IAAI;IAC5E,IAAI,CAAC,UAAU,QAAQ,CAAC,QAAQ;QAC9B,gDAAgD;QAChD,0DAA0D;QAC1D;IACF;IAEA,MAAM,WAAW,KAAK,OAAO,CAAC,cAAc;IAE5C,IAAI;QACF,MAAM,WAAW,MAAM,GAAG,QAAQ,CAAC,UAAU;QAE7C,MAAM,UAAS;YACb,SAAS,CAAC;QACZ;QACA,GAAG,gBAAgB,CACjB,iEACE,WACA,QACF,UACA,SAAQ,QAAO,OAAO,EAAE,SAAS,KAAK,OAAO,CAAC,WAAW;QAE3D,MAAM,eAAgC,QAAO,OAAO;QACpD,KAAK,MAAM,CAAC,UAAU,cAAc,IAAI,OAAO,OAAO,CAAC,cAAe;YACpE,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE;gBAC9B,eAAe,CAAC,SAAS,GAAG;YAC9B;QACF;IACF,EAAE,OAAO,GAAG;QACV,IAAI,eAAe,CAAC,qBAAqB,EAAE,UAAU,CAAC;QAEtD,IAAI,QAAQ;YACV,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,QAAQ,CAAC;QACxD;QAEA,MAAM,IAAI,MAAM,cAAc;YAC5B,OAAO;QACT;IACF;AACF;AAEA,SAAS,gBAAgB,SAAoB,EAAE,OAA4B;IACzE,MAAM,WAAW,KAAK,OAAO,CAAC,cAAc;IAE5C,OAAO,+BAA+B,UAAU;AAClD;AAEA,SAAS,sBAAsB,SAAoB;IACjD,MAAM,WAAW,KAAK,OAAO,CAAC,cAAc;IAE5C,OAAO,2BAA2B;AACpC;AAEA,SAAS,kBAAkB,EAAY,EAAE,MAAkB;IACzD,MAAM,gBAAgB,eAAe,CAAC,GAAG;IACzC,IAAI,OAAO,kBAAkB,YAAY;QACvC,sEAAsE;QACtE,0EAA0E;QAC1E,mDAAmD;QACnD,IAAI;QACJ,OAAQ,OAAO,IAAI;YACjB;gBACE,sBAAsB,CAAC,4BAA4B,EAAE,OAAO,SAAS,CAAC,CAAC;gBACvE;YACF;gBACE,sBAAsB,CAAC,oCAAoC,EAAE,OAAO,QAAQ,CAAC,CAAC;gBAC9E;QACJ;QACA,MAAM,IAAI,MACR,CAAC,OAAO,EAAE,GAAG,kBAAkB,EAAE,oBAAoB,uFAAuF,CAAC;IAEjJ;IAEA,IAAI;IACJ,OAAQ,OAAO,IAAI;QACjB;YACE,UAAU,EAAE;YACZ;QACF;YACE,wEAAwE;YACxE,wEAAwE;YACxE,UAAU;gBAAC,OAAO,QAAQ;aAAC;YAC3B;IACJ;IAEA,MAAM,UAAiB;QACrB,SAAS,CAAC;QACV,OAAO;QACP,QAAQ;QACR;QACA;QACA,UAAU,EAAE;QACZ,iBAAiB;IACnB;IACA,WAAW,CAAC,GAAG,GAAG;IAElB,4EAA4E;IAC5E,IAAI;QACF,MAAM,IAAI,gBAAgB,IAAI,CAAC,MAAM;QACrC,cAAc,IAAI,CAAC,QAAO,OAAO,EAAE;YACjC,GAAG,YAAY,IAAI,CAAC,MAAM;YAC1B,GAAG,QAAO,OAAO;YACjB;YACA,GAAG;YACH,GAAG;YACH,GAAG;YACH,GAAG;YACH,GAAG,UAAU,IAAI,CAAC,MAAM;YACxB,GAAG,UAAU,IAAI,CAAC,MAAM,SAAQ,QAAO,OAAO;YAC9C,GAAG,cAAc,IAAI,CAAC,MAAM,SAAQ,QAAO,OAAO;YAClD,GAAG,YAAY,IAAI,CAAC,MAAM;YAC1B,GAAG,gBAAgB,IAAI,CAAC,MAAM;YAC9B,GAAG;YACH,GAAG;YACH,GAAG;YACH,GAAG,eAAe,IAAI,CAAC,MAAM;gBAAE,IAAI;gBAAqB,UAAU;YAAG;YACrE,GAAG;YACH,GAAG;YACH,GAAG;YACH,GAAG;YACH,GAAG;YACH,GAAG,4BAA4B;YAC/B,WAAW,QAAO,EAAE,CAAC,OAAO,CAAC,gBAAgB;QAC/C;IACF,EAAE,OAAO,OAAO;QACd,QAAO,KAAK,GAAG;QACf,MAAM;IACR;IAEA,QAAO,MAAM,GAAG;IAChB,IAAI,QAAO,eAAe,IAAI,QAAO,OAAO,KAAK,QAAO,eAAe,EAAE;QACvE,yDAAyD;QACzD,WAAW,QAAO,OAAO,EAAE,QAAO,eAAe;IACnD;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,iCACP,EAAY,EACZ,YAAoB;IAEpB,MAAM,UAAS,WAAW,CAAC,GAAG;IAE9B,IAAI,aAAa,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG;QAC5C,aAAa,QAAQ,CAAC,IAAI,CAAC;IAC7B;IAEA,IAAI,SAAQ;QACV,IAAI,QAAO,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAClD,QAAO,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE;QACrC;QAEA,OAAO;IACT;IAEA,OAAO,kBAAkB,IAAI;QAC3B,IAAI;QACJ,UAAU,aAAa,EAAE;IAC3B;AACF;AAEA;;CAEC,GACD,SAAS,yBACP,QAAkB,EAClB,SAAoB;IAEpB,OAAO,kBAAkB,UAAU;QAAE,IAAI;QAAsB;IAAU;AAC3E;AAEA;;CAEC,GACD,SAAS,8BACP,QAAkB,EAClB,SAAoB;IAEpB,MAAM,UAAS,WAAW,CAAC,SAAS;IACpC,IAAI,SAAQ;QACV,IAAI,QAAO,KAAK,EAAE;YAChB,MAAM,QAAO,KAAK;QACpB;QACA,OAAO;IACT;IAEA,OAAO,yBAAyB,UAAU;AAC5C;AAEA,OAAO,OAAO,GAAG;IACf;IACA;AACF"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/index.entry.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/index.entry.js new file mode 100644 index 0000000000000..e56e1fdb259c2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/index.entry.js @@ -0,0 +1,5 @@ +const CHUNK_PUBLIC_PATH = "output/index.entry.js"; +const runtime = require("./[turbopack]_runtime.js"); +runtime.loadChunk("output/79fb1_turbopack-tests_tests_snapshot_runtime_default_build_runtime_input_index_e22b2e.js"); +runtime.getOrInstantiateRuntimeModule("[project]/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js [test] (ecmascript)", CHUNK_PUBLIC_PATH); +module.exports = runtime.getOrInstantiateRuntimeModule("[project]/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/input/index.js [test] (ecmascript)", CHUNK_PUBLIC_PATH).exports; \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/index.entry.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/index.entry.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_build_runtime/output/index.entry.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js new file mode 100644 index 0000000000000..a8141d3b18d34 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js @@ -0,0 +1 @@ +console.log("Hello, world!"); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/options.json new file mode 100644 index 0000000000000..ce91cf6a6c596 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/options.json @@ -0,0 +1,3 @@ +{ + "runtimeType": "Development" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js new file mode 100644 index 0000000000000..98e59c467e79b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js @@ -0,0 +1,1590 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js", + {}, + {"otherChunks":["output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js [test] (ecmascript)"]} +]); +(() => { +if (!Array.isArray(globalThis.TURBOPACK)) { + return; +} + +const CHUNK_BASE_PATH = ""; +const RUNTIME_PUBLIC_PATH = ""; +const OUTPUT_ROOT = "crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime"; +/** + * This file contains runtime types and functions that are shared between all + * TurboPack ECMAScript runtimes. + * + * It will be prepended to the runtime code of each runtime. + */ /* eslint-disable @next/next/no-assign-module-variable */ /// +const REEXPORTED_OBJECTS = Symbol("reexported objects"); +const hasOwnProperty = Object.prototype.hasOwnProperty; +const toStringTag = typeof Symbol !== "undefined" && Symbol.toStringTag; +function defineProp(obj, name1, options) { + if (!hasOwnProperty.call(obj, name1)) Object.defineProperty(obj, name1, options); +} +/** + * Adds the getters to the exports object. + */ function esm(exports, getters) { + defineProp(exports, "__esModule", { + value: true + }); + if (toStringTag) defineProp(exports, toStringTag, { + value: "Module" + }); + for(const key in getters){ + const item = getters[key]; + if (Array.isArray(item)) { + defineProp(exports, key, { + get: item[0], + set: item[1], + enumerable: true + }); + } else { + defineProp(exports, key, { + get: item, + enumerable: true + }); + } + } + Object.seal(exports); +} +/** + * Makes the module an ESM with exports + */ function esmExport(module, exports, getters) { + module.namespaceObject = module.exports; + esm(exports, getters); +} +function ensureDynamicExports(module, exports) { + let reexportedObjects = module[REEXPORTED_OBJECTS]; + if (!reexportedObjects) { + reexportedObjects = module[REEXPORTED_OBJECTS] = []; + module.exports = module.namespaceObject = new Proxy(exports, { + get (target, prop) { + if (hasOwnProperty.call(target, prop) || prop === "default" || prop === "__esModule") { + return Reflect.get(target, prop); + } + for (const obj of reexportedObjects){ + const value = Reflect.get(obj, prop); + if (value !== undefined) return value; + } + return undefined; + }, + ownKeys (target) { + const keys = Reflect.ownKeys(target); + for (const obj of reexportedObjects){ + for (const key of Reflect.ownKeys(obj)){ + if (key !== "default" && !keys.includes(key)) keys.push(key); + } + } + return keys; + } + }); + } +} +/** + * Dynamically exports properties from an object + */ function dynamicExport(module, exports, object) { + ensureDynamicExports(module, exports); + if (typeof object === "object" && object !== null) { + module[REEXPORTED_OBJECTS].push(object); + } +} +function exportValue(module, value) { + module.exports = value; +} +function exportNamespace(module, namespace) { + module.exports = module.namespaceObject = namespace; +} +function createGetter(obj, key) { + return ()=>obj[key]; +} +/** + * @returns prototype of the object + */ const getProto = Object.getPrototypeOf ? (obj)=>Object.getPrototypeOf(obj) : (obj)=>obj.__proto__; +/** Prototypes that are not expanded for exports */ const LEAF_PROTOTYPES = [ + null, + getProto({}), + getProto([]), + getProto(getProto) +]; +/** + * @param raw + * @param ns + * @param allowExportDefault + * * `false`: will have the raw module as default export + * * `true`: will have the default property as default export + */ function interopEsm(raw, ns, allowExportDefault) { + const getters = Object.create(null); + for(let current = raw; (typeof current === "object" || typeof current === "function") && !LEAF_PROTOTYPES.includes(current); current = getProto(current)){ + for (const key of Object.getOwnPropertyNames(current)){ + getters[key] = createGetter(raw, key); + } + } + // this is not really correct + // we should set the `default` getter if the imported module is a `.cjs file` + if (!(allowExportDefault && "default" in getters)) { + getters["default"] = ()=>raw; + } + esm(ns, getters); + return ns; +} +function createNS(raw) { + if (typeof raw === "function") { + return function(...args) { + return raw.apply(this, args); + }; + } else { + return Object.create(null); + } +} +function esmImport(sourceModule, id) { + const module = getOrInstantiateModuleFromParent(id, sourceModule); + if (module.error) throw module.error; + // any ES module has to have `module.namespaceObject` defined. + if (module.namespaceObject) return module.namespaceObject; + // only ESM can be an async module, so we don't need to worry about exports being a promise here. + const raw = module.exports; + return module.namespaceObject = interopEsm(raw, createNS(raw), raw && raw.__esModule); +} +// Add a simple runtime require so that environments without one can still pass +// `typeof require` CommonJS checks so that exports are correctly registered. +const runtimeRequire = typeof require === "function" ? require : function require1() { + throw new Error("Unexpected use of runtime require"); +}; +function commonJsRequire(sourceModule, id) { + const module = getOrInstantiateModuleFromParent(id, sourceModule); + if (module.error) throw module.error; + return module.exports; +} +/** + * `require.context` and require/import expression runtime. + */ function moduleContext(map) { + function moduleContext(id) { + if (hasOwnProperty.call(map, id)) { + return map[id].module(); + } + const e = new Error(`Cannot find module '${name}'`); + e.code = "MODULE_NOT_FOUND"; + throw e; + } + moduleContext.keys = ()=>{ + return Object.keys(map); + }; + moduleContext.resolve = (id)=>{ + if (hasOwnProperty.call(map, id)) { + return map[id].id(); + } + const e = new Error(`Cannot find module '${name}'`); + e.code = "MODULE_NOT_FOUND"; + throw e; + }; + moduleContext.import = async (id)=>{ + return await moduleContext(id); + }; + return moduleContext; +} +/** + * Returns the path of a chunk defined by its data. + */ function getChunkPath(chunkData) { + return typeof chunkData === "string" ? chunkData : chunkData.path; +} +function isPromise(maybePromise) { + return maybePromise != null && typeof maybePromise === "object" && "then" in maybePromise && typeof maybePromise.then === "function"; +} +function isAsyncModuleExt(obj) { + return turbopackQueues in obj; +} +function createPromise() { + let resolve; + let reject; + const promise = new Promise((res, rej)=>{ + reject = rej; + resolve = res; + }); + return { + promise, + resolve: resolve, + reject: reject + }; +} +// everything below is adapted from webpack +// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13 +const turbopackQueues = Symbol("turbopack queues"); +const turbopackExports = Symbol("turbopack exports"); +const turbopackError = Symbol("turbopack error"); +let QueueStatus; +function resolveQueue(queue) { + if (queue && queue.status !== 1) { + queue.status = 1; + queue.forEach((fn)=>fn.queueCount--); + queue.forEach((fn)=>fn.queueCount-- ? fn.queueCount++ : fn()); + } +} +function wrapDeps(deps) { + return deps.map((dep)=>{ + if (dep !== null && typeof dep === "object") { + if (isAsyncModuleExt(dep)) return dep; + if (isPromise(dep)) { + const queue = Object.assign([], { + status: 0 + }); + const obj = { + [turbopackExports]: {}, + [turbopackQueues]: (fn)=>fn(queue) + }; + dep.then((res)=>{ + obj[turbopackExports] = res; + resolveQueue(queue); + }, (err)=>{ + obj[turbopackError] = err; + resolveQueue(queue); + }); + return obj; + } + } + return { + [turbopackExports]: dep, + [turbopackQueues]: ()=>{} + }; + }); +} +function asyncModule(module, body, hasAwait) { + const queue = hasAwait ? Object.assign([], { + status: -1 + }) : undefined; + const depQueues = new Set(); + const { resolve, reject, promise: rawPromise } = createPromise(); + const promise = Object.assign(rawPromise, { + [turbopackExports]: module.exports, + [turbopackQueues]: (fn)=>{ + queue && fn(queue); + depQueues.forEach(fn); + promise["catch"](()=>{}); + } + }); + const attributes = { + get () { + return promise; + }, + set (v) { + // Calling `esmExport` leads to this. + if (v !== promise) { + promise[turbopackExports] = v; + } + } + }; + Object.defineProperty(module, "exports", attributes); + Object.defineProperty(module, "namespaceObject", attributes); + function handleAsyncDependencies(deps) { + const currentDeps = wrapDeps(deps); + const getResult = ()=>currentDeps.map((d)=>{ + if (d[turbopackError]) throw d[turbopackError]; + return d[turbopackExports]; + }); + const { promise, resolve } = createPromise(); + const fn = Object.assign(()=>resolve(getResult), { + queueCount: 0 + }); + function fnQueue(q) { + if (q !== queue && !depQueues.has(q)) { + depQueues.add(q); + if (q && q.status === 0) { + fn.queueCount++; + q.push(fn); + } + } + } + currentDeps.map((dep)=>dep[turbopackQueues](fnQueue)); + return fn.queueCount ? promise : getResult(); + } + function asyncResult(err) { + if (err) { + reject(promise[turbopackError] = err); + } else { + resolve(promise[turbopackExports]); + } + resolveQueue(queue); + } + body(handleAsyncDependencies, asyncResult); + if (queue && queue.status === -1) { + queue.status = 0; + } +} +/** + * A pseudo "fake" URL object to resolve to its relative path. + * + * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this + * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid + * hydration mismatch. + * + * This is based on webpack's existing implementation: + * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js + */ const relativeURL = function relativeURL(inputUrl) { + const realUrl = new URL(inputUrl, "x:/"); + const values = {}; + for(const key in realUrl)values[key] = realUrl[key]; + values.href = inputUrl; + values.pathname = inputUrl.replace(/[?#].*/, ""); + values.origin = values.protocol = ""; + values.toString = values.toJSON = (..._args)=>inputUrl; + for(const key in values)Object.defineProperty(this, key, { + enumerable: true, + configurable: true, + value: values[key] + }); +}; +relativeURL.prototype = URL.prototype; +/** + * This file contains runtime types and functions that are shared between all + * Turbopack *development* ECMAScript runtimes. + * + * It will be appended to the runtime code of each runtime right after the + * shared runtime utils. + */ /* eslint-disable @next/next/no-assign-module-variable */ /// +/// +/// +/// +// This file must not use `import` and `export` statements. Otherwise, it +// becomes impossible to augment interfaces declared in ``d files +// (e.g. `Module`). Hence, the need for `import()` here. +let SourceType; +(function(SourceType) { + /** + * The module was instantiated because it was included in an evaluated chunk's + * runtime. + */ SourceType[SourceType["Runtime"] = 0] = "Runtime"; + /** + * The module was instantiated because a parent module imported it. + */ SourceType[SourceType["Parent"] = 1] = "Parent"; + /** + * The module was instantiated because it was included in a chunk's hot module + * update. + */ SourceType[SourceType["Update"] = 2] = "Update"; +})(SourceType || (SourceType = {})); +class UpdateApplyError extends Error { + name = "UpdateApplyError"; + dependencyChain; + constructor(message, dependencyChain){ + super(message); + this.dependencyChain = dependencyChain; + } +} +const moduleFactories = Object.create(null); +const moduleCache = Object.create(null); +/** + * Maps module IDs to persisted data between executions of their hot module + * implementation (`hot.data`). + */ const moduleHotData = new Map(); +/** + * Maps module instances to their hot module state. + */ const moduleHotState = new Map(); +/** + * Modules that call `module.hot.invalidate()` (while being updated). + */ const queuedInvalidatedModules = new Set(); +/** + * Module IDs that are instantiated as part of the runtime of a chunk. + */ const runtimeModules = new Set(); +/** + * Map from module ID to the chunks that contain this module. + * + * In HMR, we need to keep track of which modules are contained in which so + * chunks. This is so we don't eagerly dispose of a module when it is removed + * from chunk A, but still exists in chunk B. + */ const moduleChunksMap = new Map(); +/** + * Map from a chunk path to all modules it contains. + */ const chunkModulesMap = new Map(); +/** + * Chunk lists that contain a runtime. When these chunk lists receive an update + * that can't be reconciled with the current state of the page, we need to + * reload the runtime entirely. + */ const runtimeChunkLists = new Set(); +/** + * Map from a chunk list to the chunk paths it contains. + */ const chunkListChunksMap = new Map(); +/** + * Map from a chunk path to the chunk lists it belongs to. + */ const chunkChunkListsMap = new Map(); +const availableModules = new Map(); +const availableModuleChunks = new Map(); +async function loadChunk(source, chunkData) { + if (typeof chunkData === "string") { + return loadChunkPath(source, chunkData); + } + const includedList = chunkData.included || []; + const modulesPromises = includedList.map((included)=>{ + if (moduleFactories[included]) return true; + return availableModules.get(included); + }); + if (modulesPromises.length > 0 && modulesPromises.every((p)=>p)) { + // When all included items are already loaded or loading, we can skip loading ourselves + return Promise.all(modulesPromises); + } + const includedModuleChunksList = chunkData.moduleChunks || []; + const moduleChunksPromises = includedModuleChunksList.map((included)=>{ + // TODO(alexkirsz) Do we need this check? + // if (moduleFactories[included]) return true; + return availableModuleChunks.get(included); + }).filter((p)=>p); + let promise; + if (moduleChunksPromises.length > 0) { + // Some module chunks are already loaded or loading. + if (moduleChunksPromises.length == includedModuleChunksList.length) { + // When all included module chunks are already loaded or loading, we can skip loading ourselves + return Promise.all(moduleChunksPromises); + } + const moduleChunksToLoad = new Set(); + for (const moduleChunk of includedModuleChunksList){ + if (!availableModuleChunks.has(moduleChunk)) { + moduleChunksToLoad.add(moduleChunk); + } + } + for (const moduleChunkToLoad of moduleChunksToLoad){ + const promise = loadChunkPath(source, moduleChunkToLoad); + availableModuleChunks.set(moduleChunkToLoad, promise); + moduleChunksPromises.push(promise); + } + promise = Promise.all(moduleChunksPromises); + } else { + promise = loadChunkPath(source, chunkData.path); + // Mark all included module chunks as loading if they are not already loaded or loading. + for (const includedModuleChunk of includedModuleChunksList){ + if (!availableModuleChunks.has(includedModuleChunk)) { + availableModuleChunks.set(includedModuleChunk, promise); + } + } + } + for (const included of includedList){ + if (!availableModules.has(included)) { + // It might be better to race old and new promises, but it's rare that the new promise will be faster than a request started earlier. + // In production it's even more rare, because the chunk optimization tries to deduplicate modules anyway. + availableModules.set(included, promise); + } + } + return promise; +} +async function loadChunkPath(source, chunkPath) { + try { + await BACKEND.loadChunk(chunkPath, source); + } catch (error) { + let loadReason; + switch(source.type){ + case 0: + loadReason = `as a runtime dependency of chunk ${source.chunkPath}`; + break; + case 1: + loadReason = `from module ${source.parentId}`; + break; + case 2: + loadReason = "from an HMR update"; + break; + } + throw new Error(`Failed to load chunk ${chunkPath} ${loadReason}${error ? `: ${error}` : ""}`, error ? { + cause: error + } : undefined); + } +} +/** + * Returns an absolute url to an asset. + */ function createResolvePathFromModule(resolver) { + return function resolvePathFromModule(moduleId) { + const exported = resolver(moduleId); + return exported?.default ?? exported; + }; +} +function instantiateModule(id, source) { + const moduleFactory = moduleFactories[id]; + if (typeof moduleFactory !== "function") { + // This can happen if modules incorrectly handle HMR disposes/updates, + // e.g. when they keep a `setTimeout` around which still executes old code + // and contains e.g. a `require("something")` call. + let instantiationReason; + switch(source.type){ + case 0: + instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`; + break; + case 1: + instantiationReason = `because it was required from module ${source.parentId}`; + break; + case 2: + instantiationReason = "because of an HMR update"; + break; + } + throw new Error(`Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`); + } + const hotData = moduleHotData.get(id); + const { hot, hotState } = createModuleHot(id, hotData); + let parents; + switch(source.type){ + case 0: + runtimeModules.add(id); + parents = []; + break; + case 1: + // No need to add this module as a child of the parent module here, this + // has already been taken care of in `getOrInstantiateModuleFromParent`. + parents = [ + source.parentId + ]; + break; + case 2: + parents = source.parents || []; + break; + } + const module = { + exports: {}, + error: undefined, + loaded: false, + id, + parents, + children: [], + namespaceObject: undefined, + hot + }; + moduleCache[id] = module; + moduleHotState.set(module, hotState); + // NOTE(alexkirsz) This can fail when the module encounters a runtime error. + try { + const sourceInfo = { + type: 1, + parentId: id + }; + runModuleExecutionHooks(module, (refresh)=>{ + const r = commonJsRequire.bind(null, module); + moduleFactory.call(module.exports, augmentContext({ + a: asyncModule.bind(null, module), + e: module.exports, + r: commonJsRequire.bind(null, module), + t: runtimeRequire, + f: moduleContext, + i: esmImport.bind(null, module), + s: esmExport.bind(null, module, module.exports), + j: dynamicExport.bind(null, module, module.exports), + v: exportValue.bind(null, module), + n: exportNamespace.bind(null, module), + m: module, + c: moduleCache, + M: moduleFactories, + l: loadChunk.bind(null, sourceInfo), + w: loadWebAssembly.bind(null, sourceInfo), + u: loadWebAssemblyModule.bind(null, sourceInfo), + g: globalThis, + P: resolveAbsolutePath, + U: relativeURL, + k: refresh, + R: createResolvePathFromModule(r), + __dirname: module.id.replace(/(^|\/)\/+$/, "") + })); + }); + } catch (error) { + module.error = error; + throw error; + } + module.loaded = true; + if (module.namespaceObject && module.exports !== module.namespaceObject) { + // in case of a circular dependency: cjs1 -> esm2 -> cjs1 + interopEsm(module.exports, module.namespaceObject); + } + return module; +} +/** + * no-op for browser + * @param modulePath + */ function resolveAbsolutePath(modulePath) { + return `/ROOT/${modulePath ?? ""}`; +} +/** + * NOTE(alexkirsz) Webpack has a "module execution" interception hook that + * Next.js' React Refresh runtime hooks into to add module context to the + * refresh registry. + */ function runModuleExecutionHooks(module, executeModule) { + const cleanupReactRefreshIntercept = typeof globalThis.$RefreshInterceptModuleExecution$ === "function" ? globalThis.$RefreshInterceptModuleExecution$(module.id) : ()=>{}; + try { + executeModule({ + register: globalThis.$RefreshReg$, + signature: globalThis.$RefreshSig$, + registerExports: registerExportsAndSetupBoundaryForReactRefresh + }); + } catch (e) { + throw e; + } finally{ + // Always cleanup the intercept, even if module execution failed. + cleanupReactRefreshIntercept(); + } +} +/** + * Retrieves a module from the cache, or instantiate it if it is not cached. + */ const getOrInstantiateModuleFromParent = (id, sourceModule)=>{ + if (!sourceModule.hot.active) { + console.warn(`Unexpected import of module ${id} from module ${sourceModule.id}, which was deleted by an HMR update`); + } + const module = moduleCache[id]; + if (sourceModule.children.indexOf(id) === -1) { + sourceModule.children.push(id); + } + if (module) { + if (module.parents.indexOf(sourceModule.id) === -1) { + module.parents.push(sourceModule.id); + } + return module; + } + return instantiateModule(id, { + type: 1, + parentId: sourceModule.id + }); +}; +/** + * This is adapted from https://github.com/vercel/next.js/blob/3466862d9dc9c8bb3131712134d38757b918d1c0/packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts + */ function registerExportsAndSetupBoundaryForReactRefresh(module, helpers) { + const currentExports = module.exports; + const prevExports = module.hot.data.prevExports ?? null; + helpers.registerExportsForReactRefresh(currentExports, module.id); + // A module can be accepted automatically based on its exports, e.g. when + // it is a Refresh Boundary. + if (helpers.isReactRefreshBoundary(currentExports)) { + // Save the previous exports on update, so we can compare the boundary + // signatures. + module.hot.dispose((data)=>{ + data.prevExports = currentExports; + }); + // Unconditionally accept an update to this module, we'll check if it's + // still a Refresh Boundary later. + module.hot.accept(); + // This field is set when the previous version of this module was a + // Refresh Boundary, letting us know we need to check for invalidation or + // enqueue an update. + if (prevExports !== null) { + // A boundary can become ineligible if its exports are incompatible + // with the previous exports. + // + // For example, if you add/remove/change exports, we'll want to + // re-execute the importing modules, and force those components to + // re-render. Similarly, if you convert a class component to a + // function, we want to invalidate the boundary. + if (helpers.shouldInvalidateReactRefreshBoundary(helpers.getRefreshBoundarySignature(prevExports), helpers.getRefreshBoundarySignature(currentExports))) { + module.hot.invalidate(); + } else { + helpers.scheduleUpdate(); + } + } + } else { + // Since we just executed the code for the module, it's possible that the + // new exports made it ineligible for being a boundary. + // We only care about the case when we were _previously_ a boundary, + // because we already accepted this update (accidental side effect). + const isNoLongerABoundary = prevExports !== null; + if (isNoLongerABoundary) { + module.hot.invalidate(); + } + } +} +function formatDependencyChain(dependencyChain) { + return `Dependency chain: ${dependencyChain.join(" -> ")}`; +} +function computeOutdatedModules(added, modified) { + const newModuleFactories = new Map(); + for (const [moduleId, entry] of added){ + if (entry != null) { + newModuleFactories.set(moduleId, _eval(entry)); + } + } + const outdatedModules = computedInvalidatedModules(modified.keys()); + for (const [moduleId, entry] of modified){ + newModuleFactories.set(moduleId, _eval(entry)); + } + return { + outdatedModules, + newModuleFactories + }; +} +function computedInvalidatedModules(invalidated) { + const outdatedModules = new Set(); + for (const moduleId of invalidated){ + const effect = getAffectedModuleEffects(moduleId); + switch(effect.type){ + case "unaccepted": + throw new UpdateApplyError(`cannot apply update: unaccepted module. ${formatDependencyChain(effect.dependencyChain)}.`, effect.dependencyChain); + case "self-declined": + throw new UpdateApplyError(`cannot apply update: self-declined module. ${formatDependencyChain(effect.dependencyChain)}.`, effect.dependencyChain); + case "accepted": + for (const outdatedModuleId of effect.outdatedModules){ + outdatedModules.add(outdatedModuleId); + } + break; + } + } + return outdatedModules; +} +function computeOutdatedSelfAcceptedModules(outdatedModules) { + const outdatedSelfAcceptedModules = []; + for (const moduleId of outdatedModules){ + const module = moduleCache[moduleId]; + const hotState = moduleHotState.get(module); + if (module && hotState.selfAccepted && !hotState.selfInvalidated) { + outdatedSelfAcceptedModules.push({ + moduleId, + errorHandler: hotState.selfAccepted + }); + } + } + return outdatedSelfAcceptedModules; +} +/** + * Adds, deletes, and moves modules between chunks. This must happen before the + * dispose phase as it needs to know which modules were removed from all chunks, + * which we can only compute *after* taking care of added and moved modules. + */ function updateChunksPhase(chunksAddedModules, chunksDeletedModules) { + for (const [chunkPath, addedModuleIds] of chunksAddedModules){ + for (const moduleId of addedModuleIds){ + addModuleToChunk(moduleId, chunkPath); + } + } + const disposedModules = new Set(); + for (const [chunkPath, addedModuleIds] of chunksDeletedModules){ + for (const moduleId of addedModuleIds){ + if (removeModuleFromChunk(moduleId, chunkPath)) { + disposedModules.add(moduleId); + } + } + } + return { + disposedModules + }; +} +function disposePhase(outdatedModules, disposedModules) { + for (const moduleId of outdatedModules){ + disposeModule(moduleId, "replace"); + } + for (const moduleId of disposedModules){ + disposeModule(moduleId, "clear"); + } + // Removing modules from the module cache is a separate step. + // We also want to keep track of previous parents of the outdated modules. + const outdatedModuleParents = new Map(); + for (const moduleId of outdatedModules){ + const oldModule = moduleCache[moduleId]; + outdatedModuleParents.set(moduleId, oldModule?.parents); + delete moduleCache[moduleId]; + } + // TODO(alexkirsz) Dependencies: remove outdated dependency from module + // children. + return { + outdatedModuleParents + }; +} +/** + * Disposes of an instance of a module. + * + * Returns the persistent hot data that should be kept for the next module + * instance. + * + * NOTE: mode = "replace" will not remove modules from the moduleCache. + * This must be done in a separate step afterwards. + * This is important because all modules need to be disposed to update the + * parent/child relationships before they are actually removed from the moduleCache. + * If this was done in this method, the following disposeModule calls won't find + * the module from the module id in the cache. + */ function disposeModule(moduleId, mode) { + const module = moduleCache[moduleId]; + if (!module) { + return; + } + const hotState = moduleHotState.get(module); + const data = {}; + // Run the `hot.dispose` handler, if any, passing in the persistent + // `hot.data` object. + for (const disposeHandler of hotState.disposeHandlers){ + disposeHandler(data); + } + // This used to warn in `getOrInstantiateModuleFromParent` when a disposed + // module is still importing other modules. + module.hot.active = false; + moduleHotState.delete(module); + // TODO(alexkirsz) Dependencies: delete the module from outdated deps. + // Remove the disposed module from its children's parent list. + // It will be added back once the module re-instantiates and imports its + // children again. + for (const childId of module.children){ + const child = moduleCache[childId]; + if (!child) { + continue; + } + const idx = child.parents.indexOf(module.id); + if (idx >= 0) { + child.parents.splice(idx, 1); + } + } + switch(mode){ + case "clear": + delete moduleCache[module.id]; + moduleHotData.delete(module.id); + break; + case "replace": + moduleHotData.set(module.id, data); + break; + default: + invariant(mode, (mode)=>`invalid mode: ${mode}`); + } +} +function applyPhase(outdatedSelfAcceptedModules, newModuleFactories, outdatedModuleParents, reportError) { + // Update module factories. + for (const [moduleId, factory] of newModuleFactories.entries()){ + moduleFactories[moduleId] = factory; + } + // TODO(alexkirsz) Run new runtime entries here. + // TODO(alexkirsz) Dependencies: call accept handlers for outdated deps. + // Re-instantiate all outdated self-accepted modules. + for (const { moduleId, errorHandler } of outdatedSelfAcceptedModules){ + try { + instantiateModule(moduleId, { + type: 2, + parents: outdatedModuleParents.get(moduleId) + }); + } catch (err) { + if (typeof errorHandler === "function") { + try { + errorHandler(err, { + moduleId, + module: moduleCache[moduleId] + }); + } catch (err2) { + reportError(err2); + reportError(err); + } + } else { + reportError(err); + } + } + } +} +/** + * Utility function to ensure all variants of an enum are handled. + */ function invariant(never, computeMessage) { + throw new Error(`Invariant: ${computeMessage(never)}`); +} +function applyUpdate(update) { + switch(update.type){ + case "ChunkListUpdate": + applyChunkListUpdate(update); + break; + default: + invariant(update, (update)=>`Unknown update type: ${update.type}`); + } +} +function applyChunkListUpdate(update) { + if (update.merged != null) { + for (const merged of update.merged){ + switch(merged.type){ + case "EcmascriptMergedUpdate": + applyEcmascriptMergedUpdate(merged); + break; + default: + invariant(merged, (merged)=>`Unknown merged type: ${merged.type}`); + } + } + } + if (update.chunks != null) { + for (const [chunkPath, chunkUpdate] of Object.entries(update.chunks)){ + switch(chunkUpdate.type){ + case "added": + BACKEND.loadChunk(chunkPath, { + type: 2 + }); + break; + case "total": + BACKEND.reloadChunk?.(chunkPath); + break; + case "deleted": + BACKEND.unloadChunk?.(chunkPath); + break; + case "partial": + invariant(chunkUpdate.instruction, (instruction)=>`Unknown partial instruction: ${JSON.stringify(instruction)}.`); + default: + invariant(chunkUpdate, (chunkUpdate)=>`Unknown chunk update type: ${chunkUpdate.type}`); + } + } + } +} +function applyEcmascriptMergedUpdate(update) { + const { entries = {}, chunks = {} } = update; + const { added, modified, chunksAdded, chunksDeleted } = computeChangedModules(entries, chunks); + const { outdatedModules, newModuleFactories } = computeOutdatedModules(added, modified); + const { disposedModules } = updateChunksPhase(chunksAdded, chunksDeleted); + applyInternal(outdatedModules, disposedModules, newModuleFactories); +} +function applyInvalidatedModules(outdatedModules) { + if (queuedInvalidatedModules.size > 0) { + computedInvalidatedModules(queuedInvalidatedModules).forEach((moduleId)=>{ + outdatedModules.add(moduleId); + }); + queuedInvalidatedModules.clear(); + } + return outdatedModules; +} +function applyInternal(outdatedModules, disposedModules, newModuleFactories) { + outdatedModules = applyInvalidatedModules(outdatedModules); + const outdatedSelfAcceptedModules = computeOutdatedSelfAcceptedModules(outdatedModules); + const { outdatedModuleParents } = disposePhase(outdatedModules, disposedModules); + // we want to continue on error and only throw the error after we tried applying all updates + let error; + function reportError(err) { + if (!error) error = err; + } + applyPhase(outdatedSelfAcceptedModules, newModuleFactories, outdatedModuleParents, reportError); + if (error) { + throw error; + } + if (queuedInvalidatedModules.size > 0) { + applyInternal(new Set(), [], new Map()); + } +} +function computeChangedModules(entries, updates) { + const chunksAdded = new Map(); + const chunksDeleted = new Map(); + const added = new Map(); + const modified = new Map(); + const deleted = new Set(); + for (const [chunkPath, mergedChunkUpdate] of Object.entries(updates)){ + switch(mergedChunkUpdate.type){ + case "added": + { + const updateAdded = new Set(mergedChunkUpdate.modules); + for (const moduleId of updateAdded){ + added.set(moduleId, entries[moduleId]); + } + chunksAdded.set(chunkPath, updateAdded); + break; + } + case "deleted": + { + // We could also use `mergedChunkUpdate.modules` here. + const updateDeleted = new Set(chunkModulesMap.get(chunkPath)); + for (const moduleId of updateDeleted){ + deleted.add(moduleId); + } + chunksDeleted.set(chunkPath, updateDeleted); + break; + } + case "partial": + { + const updateAdded = new Set(mergedChunkUpdate.added); + const updateDeleted = new Set(mergedChunkUpdate.deleted); + for (const moduleId of updateAdded){ + added.set(moduleId, entries[moduleId]); + } + for (const moduleId of updateDeleted){ + deleted.add(moduleId); + } + chunksAdded.set(chunkPath, updateAdded); + chunksDeleted.set(chunkPath, updateDeleted); + break; + } + default: + invariant(mergedChunkUpdate, (mergedChunkUpdate)=>`Unknown merged chunk update type: ${mergedChunkUpdate.type}`); + } + } + // If a module was added from one chunk and deleted from another in the same update, + // consider it to be modified, as it means the module was moved from one chunk to another + // AND has new code in a single update. + for (const moduleId of added.keys()){ + if (deleted.has(moduleId)) { + added.delete(moduleId); + deleted.delete(moduleId); + } + } + for (const [moduleId, entry] of Object.entries(entries)){ + // Modules that haven't been added to any chunk but have new code are considered + // to be modified. + // This needs to be under the previous loop, as we need it to get rid of modules + // that were added and deleted in the same update. + if (!added.has(moduleId)) { + modified.set(moduleId, entry); + } + } + return { + added, + deleted, + modified, + chunksAdded, + chunksDeleted + }; +} +function getAffectedModuleEffects(moduleId) { + const outdatedModules = new Set(); + const queue = [ + { + moduleId, + dependencyChain: [] + } + ]; + let nextItem; + while(nextItem = queue.shift()){ + const { moduleId, dependencyChain } = nextItem; + if (moduleId != null) { + if (outdatedModules.has(moduleId)) { + continue; + } + outdatedModules.add(moduleId); + } + // We've arrived at the runtime of the chunk, which means that nothing + // else above can accept this update. + if (moduleId === undefined) { + return { + type: "unaccepted", + dependencyChain + }; + } + const module = moduleCache[moduleId]; + const hotState = moduleHotState.get(module); + if (// The module is not in the cache. Since this is a "modified" update, + // it means that the module was never instantiated before. + !module || hotState.selfAccepted && !hotState.selfInvalidated) { + continue; + } + if (hotState.selfDeclined) { + return { + type: "self-declined", + dependencyChain, + moduleId + }; + } + if (runtimeModules.has(moduleId)) { + queue.push({ + moduleId: undefined, + dependencyChain: [ + ...dependencyChain, + moduleId + ] + }); + continue; + } + for (const parentId of module.parents){ + const parent = moduleCache[parentId]; + if (!parent) { + continue; + } + // TODO(alexkirsz) Dependencies: check accepted and declined + // dependencies here. + queue.push({ + moduleId: parentId, + dependencyChain: [ + ...dependencyChain, + moduleId + ] + }); + } + } + return { + type: "accepted", + moduleId, + outdatedModules + }; +} +function handleApply(chunkListPath, update) { + switch(update.type){ + case "partial": + { + // This indicates that the update is can be applied to the current state of the application. + applyUpdate(update.instruction); + break; + } + case "restart": + { + // This indicates that there is no way to apply the update to the + // current state of the application, and that the application must be + // restarted. + BACKEND.restart(); + break; + } + case "notFound": + { + // This indicates that the chunk list no longer exists: either the dynamic import which created it was removed, + // or the page itself was deleted. + // If it is a dynamic import, we simply discard all modules that the chunk has exclusive access to. + // If it is a runtime chunk list, we restart the application. + if (runtimeChunkLists.has(chunkListPath)) { + BACKEND.restart(); + } else { + disposeChunkList(chunkListPath); + } + break; + } + default: + throw new Error(`Unknown update type: ${update.type}`); + } +} +function createModuleHot(moduleId, hotData) { + const hotState = { + selfAccepted: false, + selfDeclined: false, + selfInvalidated: false, + disposeHandlers: [] + }; + const hot = { + // TODO(alexkirsz) This is not defined in the HMR API. It was used to + // decide whether to warn whenever an HMR-disposed module required other + // modules. We might want to remove it. + active: true, + data: hotData ?? {}, + // TODO(alexkirsz) Support full (dep, callback, errorHandler) form. + accept: (modules, _callback, _errorHandler)=>{ + if (modules === undefined) { + hotState.selfAccepted = true; + } else if (typeof modules === "function") { + hotState.selfAccepted = modules; + } else { + throw new Error("unsupported `accept` signature"); + } + }, + decline: (dep)=>{ + if (dep === undefined) { + hotState.selfDeclined = true; + } else { + throw new Error("unsupported `decline` signature"); + } + }, + dispose: (callback)=>{ + hotState.disposeHandlers.push(callback); + }, + addDisposeHandler: (callback)=>{ + hotState.disposeHandlers.push(callback); + }, + removeDisposeHandler: (callback)=>{ + const idx = hotState.disposeHandlers.indexOf(callback); + if (idx >= 0) { + hotState.disposeHandlers.splice(idx, 1); + } + }, + invalidate: ()=>{ + hotState.selfInvalidated = true; + queuedInvalidatedModules.add(moduleId); + }, + // NOTE(alexkirsz) This is part of the management API, which we don't + // implement, but the Next.js React Refresh runtime uses this to decide + // whether to schedule an update. + status: ()=>"idle", + // NOTE(alexkirsz) Since we always return "idle" for now, these are no-ops. + addStatusHandler: (_handler)=>{}, + removeStatusHandler: (_handler)=>{}, + // NOTE(jridgewell) Check returns the list of updated modules, but we don't + // want the webpack code paths to ever update (the turbopack paths handle + // this already). + check: ()=>Promise.resolve(null) + }; + return { + hot, + hotState + }; +} +/** + * Adds a module to a chunk. + */ function addModuleToChunk(moduleId, chunkPath) { + let moduleChunks = moduleChunksMap.get(moduleId); + if (!moduleChunks) { + moduleChunks = new Set([ + chunkPath + ]); + moduleChunksMap.set(moduleId, moduleChunks); + } else { + moduleChunks.add(chunkPath); + } + let chunkModules = chunkModulesMap.get(chunkPath); + if (!chunkModules) { + chunkModules = new Set([ + moduleId + ]); + chunkModulesMap.set(chunkPath, chunkModules); + } else { + chunkModules.add(moduleId); + } +} +/** + * Returns the first chunk that included a module. + * This is used by the Node.js backend, hence why it's marked as unused in this + * file. + */ function getFirstModuleChunk(moduleId) { + const moduleChunkPaths = moduleChunksMap.get(moduleId); + if (moduleChunkPaths == null) { + return null; + } + return moduleChunkPaths.values().next().value; +} +/** + * Removes a module from a chunk. + * Returns `true` if there are no remaining chunks including this module. + */ function removeModuleFromChunk(moduleId, chunkPath) { + const moduleChunks = moduleChunksMap.get(moduleId); + moduleChunks.delete(chunkPath); + const chunkModules = chunkModulesMap.get(chunkPath); + chunkModules.delete(moduleId); + const noRemainingModules = chunkModules.size === 0; + if (noRemainingModules) { + chunkModulesMap.delete(chunkPath); + } + const noRemainingChunks = moduleChunks.size === 0; + if (noRemainingChunks) { + moduleChunksMap.delete(moduleId); + } + return noRemainingChunks; +} +/** + * Disposes of a chunk list and its corresponding exclusive chunks. + */ function disposeChunkList(chunkListPath) { + const chunkPaths = chunkListChunksMap.get(chunkListPath); + if (chunkPaths == null) { + return false; + } + chunkListChunksMap.delete(chunkListPath); + for (const chunkPath of chunkPaths){ + const chunkChunkLists = chunkChunkListsMap.get(chunkPath); + chunkChunkLists.delete(chunkListPath); + if (chunkChunkLists.size === 0) { + chunkChunkListsMap.delete(chunkPath); + disposeChunk(chunkPath); + } + } + // We must also dispose of the chunk list's chunk itself to ensure it may + // be reloaded properly in the future. + BACKEND.unloadChunk?.(chunkListPath); + return true; +} +/** + * Disposes of a chunk and its corresponding exclusive modules. + * + * @returns Whether the chunk was disposed of. + */ function disposeChunk(chunkPath) { + // This should happen whether the chunk has any modules in it or not. + // For instance, CSS chunks have no modules in them, but they still need to be unloaded. + BACKEND.unloadChunk?.(chunkPath); + const chunkModules = chunkModulesMap.get(chunkPath); + if (chunkModules == null) { + return false; + } + chunkModules.delete(chunkPath); + for (const moduleId of chunkModules){ + const moduleChunks = moduleChunksMap.get(moduleId); + moduleChunks.delete(chunkPath); + const noRemainingChunks = moduleChunks.size === 0; + if (noRemainingChunks) { + moduleChunksMap.delete(moduleId); + disposeModule(moduleId, "clear"); + availableModules.delete(moduleId); + } + } + return true; +} +/** + * Instantiates a runtime module. + */ function instantiateRuntimeModule(moduleId, chunkPath) { + return instantiateModule(moduleId, { + type: 0, + chunkPath + }); +} +/** + * Gets or instantiates a runtime module. + */ function getOrInstantiateRuntimeModule(moduleId, chunkPath) { + const module = moduleCache[moduleId]; + if (module) { + if (module.error) { + throw module.error; + } + return module; + } + return instantiateModule(moduleId, { + type: 0, + chunkPath + }); +} +/** + * Returns the URL relative to the origin where a chunk can be fetched from. + */ function getChunkRelativeUrl(chunkPath) { + return `${CHUNK_BASE_PATH}${chunkPath.split("/").map((p)=>encodeURIComponent(p)).join("/")}`; +} +/** + * Subscribes to chunk list updates from the update server and applies them. + */ function registerChunkList(chunkUpdateProvider, chunkList) { + chunkUpdateProvider.push([ + chunkList.path, + handleApply.bind(null, chunkList.path) + ]); + // Adding chunks to chunk lists and vice versa. + const chunks = new Set(chunkList.chunks.map(getChunkPath)); + chunkListChunksMap.set(chunkList.path, chunks); + for (const chunkPath of chunks){ + let chunkChunkLists = chunkChunkListsMap.get(chunkPath); + if (!chunkChunkLists) { + chunkChunkLists = new Set([ + chunkList.path + ]); + chunkChunkListsMap.set(chunkPath, chunkChunkLists); + } else { + chunkChunkLists.add(chunkList.path); + } + } + if (chunkList.source === "entry") { + markChunkListAsRuntime(chunkList.path); + } +} +/** + * Marks a chunk list as a runtime chunk list. There can be more than one + * runtime chunk list. For instance, integration tests can have multiple chunk + * groups loaded at runtime, each with its own chunk list. + */ function markChunkListAsRuntime(chunkListPath) { + runtimeChunkLists.add(chunkListPath); +} +function registerChunk([chunkPath, chunkModules, runtimeParams]) { + for (const [moduleId, moduleFactory] of Object.entries(chunkModules)){ + if (!moduleFactories[moduleId]) { + moduleFactories[moduleId] = moduleFactory; + } + addModuleToChunk(moduleId, chunkPath); + } + return BACKEND.registerChunk(chunkPath, runtimeParams); +} +globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS ??= []; +const chunkListsToRegister = globalThis.TURBOPACK_CHUNK_LISTS; +if (Array.isArray(chunkListsToRegister)) { + for (const chunkList of chunkListsToRegister){ + registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS, chunkList); + } +} +globalThis.TURBOPACK_CHUNK_LISTS = { + push: (chunkList)=>{ + registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS, chunkList); + } +}; +/** + * This file contains the runtime code specific to the Turbopack development + * ECMAScript DOM runtime. + * + * It will be appended to the base development runtime code. + */ /// +/// +let BACKEND; +function augmentContext(context) { + return context; +} +function fetchWebAssembly(wasmChunkPath) { + return fetch(getChunkRelativeUrl(wasmChunkPath)); +} +async function loadWebAssembly(_source, wasmChunkPath, importsObj) { + const req = fetchWebAssembly(wasmChunkPath); + const { instance } = await WebAssembly.instantiateStreaming(req, importsObj); + return instance.exports; +} +async function loadWebAssemblyModule(_source, wasmChunkPath) { + const req = fetchWebAssembly(wasmChunkPath); + return await WebAssembly.compileStreaming(req); +} +(()=>{ + BACKEND = { + async registerChunk (chunkPath, params) { + const resolver = getOrCreateResolver(chunkPath); + resolver.resolve(); + if (params == null) { + return; + } + for (const otherChunkData of params.otherChunks){ + const otherChunkPath = getChunkPath(otherChunkData); + // Chunk might have started loading, so we want to avoid triggering another load. + getOrCreateResolver(otherChunkPath); + } + // This waits for chunks to be loaded, but also marks included items as available. + await Promise.all(params.otherChunks.map((otherChunkData)=>loadChunk({ + type: SourceType.Runtime, + chunkPath + }, otherChunkData))); + if (params.runtimeModuleIds.length > 0) { + for (const moduleId of params.runtimeModuleIds){ + getOrInstantiateRuntimeModule(moduleId, chunkPath); + } + } + }, + loadChunk (chunkPath, source) { + return doLoadChunk(chunkPath, source); + }, + unloadChunk (chunkPath) { + deleteResolver(chunkPath); + const chunkUrl = getChunkRelativeUrl(chunkPath); + // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped. + const decodedChunkUrl = decodeURI(chunkUrl); + if (chunkPath.endsWith(".css")) { + const links = document.querySelectorAll(`link[href="${chunkUrl}"],link[href^="${chunkUrl}?"],link[href="${decodedChunkUrl}"],link[href^="${decodedChunkUrl}?"]`); + for (const link of Array.from(links)){ + link.remove(); + } + } else if (chunkPath.endsWith(".js")) { + // Unloading a JS chunk would have no effect, as it lives in the JS + // runtime once evaluated. + // However, we still want to remove the script tag from the DOM to keep + // the HTML somewhat consistent from the user's perspective. + const scripts = document.querySelectorAll(`script[src="${chunkUrl}"],script[src^="${chunkUrl}?"],script[src="${decodedChunkUrl}"],script[src^="${decodedChunkUrl}?"]`); + for (const script of Array.from(scripts)){ + script.remove(); + } + } else { + throw new Error(`can't infer type of chunk from path ${chunkPath}`); + } + }, + reloadChunk (chunkPath) { + return new Promise((resolve, reject)=>{ + if (!chunkPath.endsWith(".css")) { + reject(new Error("The DOM backend can only reload CSS chunks")); + return; + } + const chunkUrl = getChunkRelativeUrl(chunkPath); + const decodedChunkUrl = decodeURI(chunkUrl); + const previousLinks = document.querySelectorAll(`link[rel=stylesheet][href="${chunkUrl}"],link[rel=stylesheet][href^="${chunkUrl}?"],link[rel=stylesheet][href="${decodedChunkUrl}"],link[rel=stylesheet][href^="${decodedChunkUrl}?"]`); + if (previousLinks.length == 0) { + reject(new Error(`No link element found for chunk ${chunkPath}`)); + return; + } + const link = document.createElement("link"); + link.rel = "stylesheet"; + if (navigator.userAgent.includes("Firefox")) { + // Firefox won't reload CSS files that were previously loaded on the current page, + // we need to add a query param to make sure CSS is actually reloaded from the server. + // + // I believe this is this issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1037506 + // + // Safari has a similar issue, but only if you have a `` tag + // pointing to the same URL as the stylesheet: https://bugs.webkit.org/show_bug.cgi?id=187726 + link.href = `${chunkUrl}?ts=${Date.now()}`; + } else { + link.href = chunkUrl; + } + link.onerror = ()=>{ + reject(); + }; + link.onload = ()=>{ + // First load the new CSS, then remove the old ones. This prevents visible + // flickering that would happen in-between removing the previous CSS and + // loading the new one. + for (const previousLink of Array.from(previousLinks))previousLink.remove(); + // CSS chunks do not register themselves, and as such must be marked as + // loaded instantly. + resolve(); + }; + // Make sure to insert the new CSS right after the previous one, so that + // its precedence is higher. + previousLinks[0].parentElement.insertBefore(link, previousLinks[0].nextSibling); + }); + }, + restart: ()=>self.location.reload() + }; + /** + * Maps chunk paths to the corresponding resolver. + */ const chunkResolvers = new Map(); + function getOrCreateResolver(chunkPath) { + let resolver = chunkResolvers.get(chunkPath); + if (!resolver) { + let resolve; + let reject; + const promise = new Promise((innerResolve, innerReject)=>{ + resolve = innerResolve; + reject = innerReject; + }); + resolver = { + resolved: false, + promise, + resolve: ()=>{ + resolver.resolved = true; + resolve(); + }, + reject: reject + }; + chunkResolvers.set(chunkPath, resolver); + } + return resolver; + } + function deleteResolver(chunkPath) { + chunkResolvers.delete(chunkPath); + } + /** + * Loads the given chunk, and returns a promise that resolves once the chunk + * has been loaded. + */ async function doLoadChunk(chunkPath, source) { + const resolver = getOrCreateResolver(chunkPath); + if (resolver.resolved) { + return resolver.promise; + } + if (source.type === SourceType.Runtime) { + // We don't need to load chunks references from runtime code, as they're already + // present in the DOM. + if (chunkPath.endsWith(".css")) { + // CSS chunks do not register themselves, and as such must be marked as + // loaded instantly. + resolver.resolve(); + } + // We need to wait for JS chunks to register themselves within `registerChunk` + // before we can start instantiating runtime modules, hence the absence of + // `resolver.resolve()` in this branch. + return resolver.promise; + } + const chunkUrl = getChunkRelativeUrl(chunkPath); + const decodedChunkUrl = decodeURI(chunkUrl); + if (chunkPath.endsWith(".css")) { + const previousLinks = document.querySelectorAll(`link[rel=stylesheet][href="${chunkUrl}"],link[rel=stylesheet][href^="${chunkUrl}?"],link[rel=stylesheet][href="${decodedChunkUrl}"],link[rel=stylesheet][href^="${decodedChunkUrl}?"]`); + if (previousLinks.length > 0) { + // CSS chunks do not register themselves, and as such must be marked as + // loaded instantly. + resolver.resolve(); + } else { + const link = document.createElement("link"); + link.rel = "stylesheet"; + link.href = chunkUrl; + link.onerror = ()=>{ + resolver.reject(); + }; + link.onload = ()=>{ + // CSS chunks do not register themselves, and as such must be marked as + // loaded instantly. + resolver.resolve(); + }; + document.body.appendChild(link); + } + } else if (chunkPath.endsWith(".js")) { + const previousScripts = document.querySelectorAll(`script[src="${chunkUrl}"],script[src^="${chunkUrl}?"],script[src="${decodedChunkUrl}"],script[src^="${decodedChunkUrl}?"]`); + if (previousScripts.length > 0) { + // There is this edge where the script already failed loading, but we + // can't detect that. The Promise will never resolve in this case. + for (const script of Array.from(previousScripts)){ + script.addEventListener("error", ()=>{ + resolver.reject(); + }); + } + } else { + const script = document.createElement("script"); + script.src = chunkUrl; + // We'll only mark the chunk as loaded once the script has been executed, + // which happens in `registerChunk`. Hence the absence of `resolve()` in + // this branch. + script.onerror = ()=>{ + resolver.reject(); + }; + document.body.appendChild(script); + } + } else { + throw new Error(`can't infer type of chunk from path ${chunkPath}`); + } + return resolver.promise; + } +})(); +function _eval({ code, url, map }) { + code += `\n\n//# sourceURL=${encodeURI(location.origin + CHUNK_BASE_PATH + url)}`; + if (map) { + code += `\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa(// btoa doesn't handle nonlatin characters, so escape them as \x sequences + // See https://stackoverflow.com/a/26603875 + unescape(encodeURIComponent(map)))}`; + } + return eval(code); +} +const chunksToRegister = globalThis.TURBOPACK; +globalThis.TURBOPACK = { push: registerChunk }; +chunksToRegister.forEach(registerChunk); +})(); + + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js.map new file mode 100644 index 0000000000000..cfe18e65bc397 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_40d141.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 13, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/shared/runtime-utils.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * TurboPack ECMAScript runtimes.\n *\n * It will be prepended to the runtime code of each runtime.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n\ninterface Exports {\n __esModule?: boolean;\n\n [key: string]: any;\n}\n\ntype EsmNamespaceObject = Record;\n\nconst REEXPORTED_OBJECTS = Symbol(\"reexported objects\");\n\ninterface BaseModule {\n exports: Function | Exports | Promise | AsyncModulePromise;\n error: Error | undefined;\n loaded: boolean;\n id: ModuleId;\n children: ModuleId[];\n parents: ModuleId[];\n namespaceObject?:\n | EsmNamespaceObject\n | Promise\n | AsyncModulePromise;\n [REEXPORTED_OBJECTS]?: any[];\n}\n\ninterface Module extends BaseModule {}\n\ntype ModuleContextMap = Record;\n\ninterface ModuleContextEntry {\n id: () => ModuleId;\n module: () => any;\n}\n\ninterface ModuleContext {\n // require call\n (moduleId: ModuleId): Exports | EsmNamespaceObject;\n\n // async import call\n import(moduleId: ModuleId): Promise;\n\n keys(): ModuleId[];\n\n resolve(moduleId: ModuleId): ModuleId;\n}\n\ntype GetOrInstantiateModuleFromParent = (\n moduleId: ModuleId,\n parentModule: Module\n) => Module;\n\nconst hasOwnProperty = Object.prototype.hasOwnProperty;\nconst toStringTag = typeof Symbol !== \"undefined\" && Symbol.toStringTag;\n\nfunction defineProp(\n obj: any,\n name: PropertyKey,\n options: PropertyDescriptor & ThisType\n) {\n if (!hasOwnProperty.call(obj, name))\n Object.defineProperty(obj, name, options);\n}\n\n/**\n * Adds the getters to the exports object.\n */\nfunction esm(\n exports: Exports,\n getters: Record any) | [() => any, (v: any) => void]>\n) {\n defineProp(exports, \"__esModule\", { value: true });\n if (toStringTag) defineProp(exports, toStringTag, { value: \"Module\" });\n for (const key in getters) {\n const item = getters[key];\n if (Array.isArray(item)) {\n defineProp(exports, key, {\n get: item[0],\n set: item[1],\n enumerable: true,\n });\n } else {\n defineProp(exports, key, { get: item, enumerable: true });\n }\n }\n Object.seal(exports);\n}\n\n/**\n * Makes the module an ESM with exports\n */\nfunction esmExport(\n module: Module,\n exports: Exports,\n getters: Record any>\n) {\n module.namespaceObject = module.exports;\n esm(exports, getters);\n}\n\nfunction ensureDynamicExports(module: Module, exports: Exports) {\n let reexportedObjects = module[REEXPORTED_OBJECTS];\n\n if (!reexportedObjects) {\n reexportedObjects = module[REEXPORTED_OBJECTS] = [];\n module.exports = module.namespaceObject = new Proxy(exports, {\n get(target, prop) {\n if (\n hasOwnProperty.call(target, prop) ||\n prop === \"default\" ||\n prop === \"__esModule\"\n ) {\n return Reflect.get(target, prop);\n }\n for (const obj of reexportedObjects!) {\n const value = Reflect.get(obj, prop);\n if (value !== undefined) return value;\n }\n return undefined;\n },\n ownKeys(target) {\n const keys = Reflect.ownKeys(target);\n for (const obj of reexportedObjects!) {\n for (const key of Reflect.ownKeys(obj)) {\n if (key !== \"default\" && !keys.includes(key)) keys.push(key);\n }\n }\n return keys;\n },\n });\n }\n}\n\n/**\n * Dynamically exports properties from an object\n */\nfunction dynamicExport(\n module: Module,\n exports: Exports,\n object: Record\n) {\n ensureDynamicExports(module, exports);\n\n if (typeof object === \"object\" && object !== null) {\n module[REEXPORTED_OBJECTS]!.push(object);\n }\n}\n\nfunction exportValue(module: Module, value: any) {\n module.exports = value;\n}\n\nfunction exportNamespace(module: Module, namespace: any) {\n module.exports = module.namespaceObject = namespace;\n}\n\nfunction createGetter(obj: Record, key: string | symbol) {\n return () => obj[key];\n}\n\n/**\n * @returns prototype of the object\n */\nconst getProto: (obj: any) => any = Object.getPrototypeOf\n ? (obj) => Object.getPrototypeOf(obj)\n : (obj) => obj.__proto__;\n\n/** Prototypes that are not expanded for exports */\nconst LEAF_PROTOTYPES = [null, getProto({}), getProto([]), getProto(getProto)];\n\n/**\n * @param raw\n * @param ns\n * @param allowExportDefault\n * * `false`: will have the raw module as default export\n * * `true`: will have the default property as default export\n */\nfunction interopEsm(\n raw: Exports,\n ns: EsmNamespaceObject,\n allowExportDefault?: boolean\n) {\n const getters: { [s: string]: () => any } = Object.create(null);\n for (\n let current = raw;\n (typeof current === \"object\" || typeof current === \"function\") &&\n !LEAF_PROTOTYPES.includes(current);\n current = getProto(current)\n ) {\n for (const key of Object.getOwnPropertyNames(current)) {\n getters[key] = createGetter(raw, key);\n }\n }\n\n // this is not really correct\n // we should set the `default` getter if the imported module is a `.cjs file`\n if (!(allowExportDefault && \"default\" in getters)) {\n getters[\"default\"] = () => raw;\n }\n\n esm(ns, getters);\n return ns;\n}\n\nfunction createNS(raw: BaseModule[\"exports\"]): EsmNamespaceObject {\n if (typeof raw === \"function\") {\n return function (this: any, ...args: any[]) {\n return raw.apply(this, args);\n };\n } else {\n return Object.create(null);\n }\n}\n\nfunction esmImport(\n sourceModule: Module,\n id: ModuleId\n): Exclude {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n\n // any ES module has to have `module.namespaceObject` defined.\n if (module.namespaceObject) return module.namespaceObject;\n\n // only ESM can be an async module, so we don't need to worry about exports being a promise here.\n const raw = module.exports;\n return (module.namespaceObject = interopEsm(\n raw,\n createNS(raw),\n raw && (raw as any).__esModule\n ));\n}\n\n// Add a simple runtime require so that environments without one can still pass\n// `typeof require` CommonJS checks so that exports are correctly registered.\nconst runtimeRequire =\n typeof require === \"function\"\n ? require\n : function require() {\n throw new Error(\"Unexpected use of runtime require\");\n };\n\nfunction commonJsRequire(sourceModule: Module, id: ModuleId): Exports {\n const module = getOrInstantiateModuleFromParent(id, sourceModule);\n if (module.error) throw module.error;\n return module.exports;\n}\n\n/**\n * `require.context` and require/import expression runtime.\n */\nfunction moduleContext(map: ModuleContextMap): ModuleContext {\n function moduleContext(id: ModuleId): Exports {\n if (hasOwnProperty.call(map, id)) {\n return map[id].module();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n }\n\n moduleContext.keys = (): ModuleId[] => {\n return Object.keys(map);\n };\n\n moduleContext.resolve = (id: ModuleId): ModuleId => {\n if (hasOwnProperty.call(map, id)) {\n return map[id].id();\n }\n\n const e = new Error(`Cannot find module '${name}'`);\n (e as any).code = \"MODULE_NOT_FOUND\";\n throw e;\n };\n\n moduleContext.import = async (id: ModuleId) => {\n return await (moduleContext(id) as Promise);\n };\n\n return moduleContext;\n}\n\n/**\n * Returns the path of a chunk defined by its data.\n */\nfunction getChunkPath(chunkData: ChunkData): ChunkPath {\n return typeof chunkData === \"string\" ? chunkData : chunkData.path;\n}\n\nfunction isPromise(maybePromise: any): maybePromise is Promise {\n return (\n maybePromise != null &&\n typeof maybePromise === \"object\" &&\n \"then\" in maybePromise &&\n typeof maybePromise.then === \"function\"\n );\n}\n\nfunction isAsyncModuleExt(obj: T): obj is AsyncModuleExt & T {\n return turbopackQueues in obj;\n}\n\nfunction createPromise() {\n let resolve: (value: T | PromiseLike) => void;\n let reject: (reason?: any) => void;\n\n const promise = new Promise((res, rej) => {\n reject = rej;\n resolve = res;\n });\n\n return {\n promise,\n resolve: resolve!,\n reject: reject!,\n };\n}\n\n// everything below is adapted from webpack\n// https://github.com/webpack/webpack/blob/6be4065ade1e252c1d8dcba4af0f43e32af1bdc1/lib/runtime/AsyncModuleRuntimeModule.js#L13\n\nconst turbopackQueues = Symbol(\"turbopack queues\");\nconst turbopackExports = Symbol(\"turbopack exports\");\nconst turbopackError = Symbol(\"turbopack error\");\n\nconst enum QueueStatus {\n Unknown = -1,\n Unresolved = 0,\n Resolved = 1,\n}\n\ntype AsyncQueueFn = (() => void) & { queueCount: number };\ntype AsyncQueue = AsyncQueueFn[] & {\n status: QueueStatus;\n};\n\nfunction resolveQueue(queue?: AsyncQueue) {\n if (queue && queue.status !== QueueStatus.Resolved) {\n queue.status = QueueStatus.Resolved;\n queue.forEach((fn) => fn.queueCount--);\n queue.forEach((fn) => (fn.queueCount-- ? fn.queueCount++ : fn()));\n }\n}\n\ntype Dep = Exports | AsyncModulePromise | Promise;\n\ntype AsyncModuleExt = {\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => void;\n [turbopackExports]: Exports;\n [turbopackError]?: any;\n};\n\ntype AsyncModulePromise = Promise & AsyncModuleExt;\n\nfunction wrapDeps(deps: Dep[]): AsyncModuleExt[] {\n return deps.map((dep): AsyncModuleExt => {\n if (dep !== null && typeof dep === \"object\") {\n if (isAsyncModuleExt(dep)) return dep;\n if (isPromise(dep)) {\n const queue: AsyncQueue = Object.assign([], {\n status: QueueStatus.Unresolved,\n });\n\n const obj: AsyncModuleExt = {\n [turbopackExports]: {},\n [turbopackQueues]: (fn: (queue: AsyncQueue) => void) => fn(queue),\n };\n\n dep.then(\n (res) => {\n obj[turbopackExports] = res;\n resolveQueue(queue);\n },\n (err) => {\n obj[turbopackError] = err;\n resolveQueue(queue);\n }\n );\n\n return obj;\n }\n }\n\n return {\n [turbopackExports]: dep,\n [turbopackQueues]: () => {},\n };\n });\n}\n\nfunction asyncModule(\n module: Module,\n body: (\n handleAsyncDependencies: (\n deps: Dep[]\n ) => Exports[] | Promise<() => Exports[]>,\n asyncResult: (err?: any) => void\n ) => void,\n hasAwait: boolean\n) {\n const queue: AsyncQueue | undefined = hasAwait\n ? Object.assign([], { status: QueueStatus.Unknown })\n : undefined;\n\n const depQueues: Set = new Set();\n\n const { resolve, reject, promise: rawPromise } = createPromise();\n\n const promise: AsyncModulePromise = Object.assign(rawPromise, {\n [turbopackExports]: module.exports,\n [turbopackQueues]: (fn) => {\n queue && fn(queue);\n depQueues.forEach(fn);\n promise[\"catch\"](() => {});\n },\n } satisfies AsyncModuleExt);\n\n const attributes: PropertyDescriptor = {\n get(): any {\n return promise;\n },\n set(v: any) {\n // Calling `esmExport` leads to this.\n if (v !== promise) {\n promise[turbopackExports] = v;\n }\n },\n };\n\n Object.defineProperty(module, \"exports\", attributes);\n Object.defineProperty(module, \"namespaceObject\", attributes);\n\n function handleAsyncDependencies(deps: Dep[]) {\n const currentDeps = wrapDeps(deps);\n\n const getResult = () =>\n currentDeps.map((d) => {\n if (d[turbopackError]) throw d[turbopackError];\n return d[turbopackExports];\n });\n\n const { promise, resolve } = createPromise<() => Exports[]>();\n\n const fn: AsyncQueueFn = Object.assign(() => resolve(getResult), {\n queueCount: 0,\n });\n\n function fnQueue(q: AsyncQueue) {\n if (q !== queue && !depQueues.has(q)) {\n depQueues.add(q);\n if (q && q.status === QueueStatus.Unresolved) {\n fn.queueCount++;\n q.push(fn);\n }\n }\n }\n\n currentDeps.map((dep) => dep[turbopackQueues](fnQueue));\n\n return fn.queueCount ? promise : getResult();\n }\n\n function asyncResult(err?: any) {\n if (err) {\n reject((promise[turbopackError] = err));\n } else {\n resolve(promise[turbopackExports]);\n }\n\n resolveQueue(queue);\n }\n\n body(handleAsyncDependencies, asyncResult);\n\n if (queue && queue.status === QueueStatus.Unknown) {\n queue.status = QueueStatus.Unresolved;\n }\n}\n\n/**\n * A pseudo \"fake\" URL object to resolve to its relative path.\n *\n * When UrlRewriteBehavior is set to relative, calls to the `new URL()` will construct url without base using this\n * runtime function to generate context-agnostic urls between different rendering context, i.e ssr / client to avoid\n * hydration mismatch.\n *\n * This is based on webpack's existing implementation:\n * https://github.com/webpack/webpack/blob/87660921808566ef3b8796f8df61bd79fc026108/lib/runtime/RelativeUrlRuntimeModule.js\n */\nconst relativeURL = function relativeURL(this: any, inputUrl: string) {\n const realUrl = new URL(inputUrl, \"x:/\");\n const values: Record = {};\n for (const key in realUrl) values[key] = (realUrl as any)[key];\n values.href = inputUrl;\n values.pathname = inputUrl.replace(/[?#].*/, \"\");\n values.origin = values.protocol = \"\";\n values.toString = values.toJSON = (..._args: Array) => inputUrl;\n for (const key in values)\n Object.defineProperty(this, key, {\n enumerable: true,\n configurable: true,\n value: values[key],\n });\n};\n\nrelativeURL.prototype = URL.prototype;\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAED,uDAAuD,GAEvD,6CAA6C;AAU7C,MAAM,qBAAqB,OAAO;AA0ClC,MAAM,iBAAiB,OAAO,SAAS,CAAC,cAAc;AACtD,MAAM,cAAc,OAAO,WAAW,eAAe,OAAO,WAAW;AAEvE,SAAS,WACP,GAAQ,EACR,KAAiB,EACjB,OAA2C;IAE3C,IAAI,CAAC,eAAe,IAAI,CAAC,KAAK,QAC5B,OAAO,cAAc,CAAC,KAAK,OAAM;AACrC;AAEA;;CAEC,GACD,SAAS,IACP,OAAgB,EAChB,OAAoE;IAEpE,WAAW,SAAS,cAAc;QAAE,OAAO;IAAK;IAChD,IAAI,aAAa,WAAW,SAAS,aAAa;QAAE,OAAO;IAAS;IACpE,IAAK,MAAM,OAAO,QAAS;QACzB,MAAM,OAAO,OAAO,CAAC,IAAI;QACzB,IAAI,MAAM,OAAO,CAAC,OAAO;YACvB,WAAW,SAAS,KAAK;gBACvB,KAAK,IAAI,CAAC,EAAE;gBACZ,KAAK,IAAI,CAAC,EAAE;gBACZ,YAAY;YACd;QACF,OAAO;YACL,WAAW,SAAS,KAAK;gBAAE,KAAK;gBAAM,YAAY;YAAK;QACzD;IACF;IACA,OAAO,IAAI,CAAC;AACd;AAEA;;CAEC,GACD,SAAS,UACP,MAAc,EACd,OAAgB,EAChB,OAAkC;IAElC,OAAO,eAAe,GAAG,OAAO,OAAO;IACvC,IAAI,SAAS;AACf;AAEA,SAAS,qBAAqB,MAAc,EAAE,OAAgB;IAC5D,IAAI,oBAAoB,MAAM,CAAC,mBAAmB;IAElD,IAAI,CAAC,mBAAmB;QACtB,oBAAoB,MAAM,CAAC,mBAAmB,GAAG,EAAE;QACnD,OAAO,OAAO,GAAG,OAAO,eAAe,GAAG,IAAI,MAAM,SAAS;YAC3D,KAAI,MAAM,EAAE,IAAI;gBACd,IACE,eAAe,IAAI,CAAC,QAAQ,SAC5B,SAAS,aACT,SAAS,cACT;oBACA,OAAO,QAAQ,GAAG,CAAC,QAAQ;gBAC7B;gBACA,KAAK,MAAM,OAAO,kBAAoB;oBACpC,MAAM,QAAQ,QAAQ,GAAG,CAAC,KAAK;oBAC/B,IAAI,UAAU,WAAW,OAAO;gBAClC;gBACA,OAAO;YACT;YACA,SAAQ,MAAM;gBACZ,MAAM,OAAO,QAAQ,OAAO,CAAC;gBAC7B,KAAK,MAAM,OAAO,kBAAoB;oBACpC,KAAK,MAAM,OAAO,QAAQ,OAAO,CAAC,KAAM;wBACtC,IAAI,QAAQ,aAAa,CAAC,KAAK,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC;oBAC1D;gBACF;gBACA,OAAO;YACT;QACF;IACF;AACF;AAEA;;CAEC,GACD,SAAS,cACP,MAAc,EACd,OAAgB,EAChB,MAA2B;IAE3B,qBAAqB,QAAQ;IAE7B,IAAI,OAAO,WAAW,YAAY,WAAW,MAAM;QACjD,MAAM,CAAC,mBAAmB,CAAE,IAAI,CAAC;IACnC;AACF;AAEA,SAAS,YAAY,MAAc,EAAE,KAAU;IAC7C,OAAO,OAAO,GAAG;AACnB;AAEA,SAAS,gBAAgB,MAAc,EAAE,SAAc;IACrD,OAAO,OAAO,GAAG,OAAO,eAAe,GAAG;AAC5C;AAEA,SAAS,aAAa,GAAiC,EAAE,GAAoB;IAC3E,OAAO,IAAM,GAAG,CAAC,IAAI;AACvB;AAEA;;CAEC,GACD,MAAM,WAA8B,OAAO,cAAc,GACrD,CAAC,MAAQ,OAAO,cAAc,CAAC,OAC/B,CAAC,MAAQ,IAAI,SAAS;AAE1B,iDAAiD,GACjD,MAAM,kBAAkB;IAAC;IAAM,SAAS,CAAC;IAAI,SAAS,EAAE;IAAG,SAAS;CAAU;AAE9E;;;;;;CAMC,GACD,SAAS,WACP,GAAY,EACZ,EAAsB,EACtB,kBAA4B;IAE5B,MAAM,UAAsC,OAAO,MAAM,CAAC;IAC1D,IACE,IAAI,UAAU,KACd,CAAC,OAAO,YAAY,YAAY,OAAO,YAAY,UAAU,KAC7D,CAAC,gBAAgB,QAAQ,CAAC,UAC1B,UAAU,SAAS,SACnB;QACA,KAAK,MAAM,OAAO,OAAO,mBAAmB,CAAC,SAAU;YACrD,OAAO,CAAC,IAAI,GAAG,aAAa,KAAK;QACnC;IACF;IAEA,6BAA6B;IAC7B,6EAA6E;IAC7E,IAAI,CAAC,CAAC,sBAAsB,aAAa,OAAO,GAAG;QACjD,OAAO,CAAC,UAAU,GAAG,IAAM;IAC7B;IAEA,IAAI,IAAI;IACR,OAAO;AACT;AAEA,SAAS,SAAS,GAA0B;IAC1C,IAAI,OAAO,QAAQ,YAAY;QAC7B,OAAO,SAAqB,GAAG,IAAW;YACxC,OAAO,IAAI,KAAK,CAAC,IAAI,EAAE;QACzB;IACF,OAAO;QACL,OAAO,OAAO,MAAM,CAAC;IACvB;AACF;AAEA,SAAS,UACP,YAAoB,EACpB,EAAY;IAEZ,MAAM,SAAS,iCAAiC,IAAI;IACpD,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,KAAK;IAEpC,8DAA8D;IAC9D,IAAI,OAAO,eAAe,EAAE,OAAO,OAAO,eAAe;IAEzD,iGAAiG;IACjG,MAAM,MAAM,OAAO,OAAO;IAC1B,OAAQ,OAAO,eAAe,GAAG,WAC/B,KACA,SAAS,MACT,OAAO,AAAC,IAAY,UAAU;AAElC;AAEA,+EAA+E;AAC/E,6EAA6E;AAC7E,MAAM,iBACJ,OAAO,YAAY,aACf,UACA,SAAS;IACP,MAAM,IAAI,MAAM;AAClB;AAEN,SAAS,gBAAgB,YAAoB,EAAE,EAAY;IACzD,MAAM,SAAS,iCAAiC,IAAI;IACpD,IAAI,OAAO,KAAK,EAAE,MAAM,OAAO,KAAK;IACpC,OAAO,OAAO,OAAO;AACvB;AAEA;;CAEC,GACD,SAAS,cAAc,GAAqB;IAC1C,SAAS,cAAc,EAAY;QACjC,IAAI,eAAe,IAAI,CAAC,KAAK,KAAK;YAChC,OAAO,GAAG,CAAC,GAAG,CAAC,MAAM;QACvB;QAEA,MAAM,IAAI,IAAI,MAAM,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QACjD,EAAU,IAAI,GAAG;QAClB,MAAM;IACR;IAEA,cAAc,IAAI,GAAG;QACnB,OAAO,OAAO,IAAI,CAAC;IACrB;IAEA,cAAc,OAAO,GAAG,CAAC;QACvB,IAAI,eAAe,IAAI,CAAC,KAAK,KAAK;YAChC,OAAO,GAAG,CAAC,GAAG,CAAC,EAAE;QACnB;QAEA,MAAM,IAAI,IAAI,MAAM,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QACjD,EAAU,IAAI,GAAG;QAClB,MAAM;IACR;IAEA,cAAc,MAAM,GAAG,OAAO;QAC5B,OAAO,MAAO,cAAc;IAC9B;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,aAAa,SAAoB;IACxC,OAAO,OAAO,cAAc,WAAW,YAAY,UAAU,IAAI;AACnE;AAEA,SAAS,UAAmB,YAAiB;IAC3C,OACE,gBAAgB,QAChB,OAAO,iBAAiB,YACxB,UAAU,gBACV,OAAO,aAAa,IAAI,KAAK;AAEjC;AAEA,SAAS,iBAA+B,GAAM;IAC5C,OAAO,mBAAmB;AAC5B;AAEA,SAAS;IACP,IAAI;IACJ,IAAI;IAEJ,MAAM,UAAU,IAAI,QAAW,CAAC,KAAK;QACnC,SAAS;QACT,UAAU;IACZ;IAEA,OAAO;QACL;QACA,SAAS;QACT,QAAQ;IACV;AACF;AAEA,2CAA2C;AAC3C,+HAA+H;AAE/H,MAAM,kBAAkB,OAAO;AAC/B,MAAM,mBAAmB,OAAO;AAChC,MAAM,iBAAiB,OAAO;;AAa9B,SAAS,aAAa,KAAkB;IACtC,IAAI,SAAS,MAAM,MAAM,QAA2B;QAClD,MAAM,MAAM;QACZ,MAAM,OAAO,CAAC,CAAC,KAAO,GAAG,UAAU;QACnC,MAAM,OAAO,CAAC,CAAC,KAAQ,GAAG,UAAU,KAAK,GAAG,UAAU,KAAK;IAC7D;AACF;AAYA,SAAS,SAAS,IAAW;IAC3B,OAAO,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;YAC3C,IAAI,iBAAiB,MAAM,OAAO;YAClC,IAAI,UAAU,MAAM;gBAClB,MAAM,QAAoB,OAAO,MAAM,CAAC,EAAE,EAAE;oBAC1C,MAAM;gBACR;gBAEA,MAAM,MAAsB;oBAC1B,CAAC,iBAAiB,EAAE,CAAC;oBACrB,CAAC,gBAAgB,EAAE,CAAC,KAAoC,GAAG;gBAC7D;gBAEA,IAAI,IAAI,CACN,CAAC;oBACC,GAAG,CAAC,iBAAiB,GAAG;oBACxB,aAAa;gBACf,GACA,CAAC;oBACC,GAAG,CAAC,eAAe,GAAG;oBACtB,aAAa;gBACf;gBAGF,OAAO;YACT;QACF;QAEA,OAAO;YACL,CAAC,iBAAiB,EAAE;YACpB,CAAC,gBAAgB,EAAE,KAAO;QAC5B;IACF;AACF;AAEA,SAAS,YACP,MAAc,EACd,IAKS,EACT,QAAiB;IAEjB,MAAM,QAAgC,WAClC,OAAO,MAAM,CAAC,EAAE,EAAE;QAAE,MAAM;IAAsB,KAChD;IAEJ,MAAM,YAA6B,IAAI;IAEvC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG;IAEjD,MAAM,UAA8B,OAAO,MAAM,CAAC,YAAY;QAC5D,CAAC,iBAAiB,EAAE,OAAO,OAAO;QAClC,CAAC,gBAAgB,EAAE,CAAC;YAClB,SAAS,GAAG;YACZ,UAAU,OAAO,CAAC;YAClB,OAAO,CAAC,QAAQ,CAAC,KAAO;QAC1B;IACF;IAEA,MAAM,aAAiC;QACrC;YACE,OAAO;QACT;QACA,KAAI,CAAM;YACR,qCAAqC;YACrC,IAAI,MAAM,SAAS;gBACjB,OAAO,CAAC,iBAAiB,GAAG;YAC9B;QACF;IACF;IAEA,OAAO,cAAc,CAAC,QAAQ,WAAW;IACzC,OAAO,cAAc,CAAC,QAAQ,mBAAmB;IAEjD,SAAS,wBAAwB,IAAW;QAC1C,MAAM,cAAc,SAAS;QAE7B,MAAM,YAAY,IAChB,YAAY,GAAG,CAAC,CAAC;gBACf,IAAI,CAAC,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC,eAAe;gBAC9C,OAAO,CAAC,CAAC,iBAAiB;YAC5B;QAEF,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG;QAE7B,MAAM,KAAmB,OAAO,MAAM,CAAC,IAAM,QAAQ,YAAY;YAC/D,YAAY;QACd;QAEA,SAAS,QAAQ,CAAa;YAC5B,IAAI,MAAM,SAAS,CAAC,UAAU,GAAG,CAAC,IAAI;gBACpC,UAAU,GAAG,CAAC;gBACd,IAAI,KAAK,EAAE,MAAM,QAA6B;oBAC5C,GAAG,UAAU;oBACb,EAAE,IAAI,CAAC;gBACT;YACF;QACF;QAEA,YAAY,GAAG,CAAC,CAAC,MAAQ,GAAG,CAAC,gBAAgB,CAAC;QAE9C,OAAO,GAAG,UAAU,GAAG,UAAU;IACnC;IAEA,SAAS,YAAY,GAAS;QAC5B,IAAI,KAAK;YACP,OAAQ,OAAO,CAAC,eAAe,GAAG;QACpC,OAAO;YACL,QAAQ,OAAO,CAAC,iBAAiB;QACnC;QAEA,aAAa;IACf;IAEA,KAAK,yBAAyB;IAE9B,IAAI,SAAS,MAAM,MAAM,SAA0B;QACjD,MAAM,MAAM;IACd;AACF;AAEA;;;;;;;;;CASC,GACD,MAAM,cAAc,SAAS,YAAuB,QAAgB;IAClE,MAAM,UAAU,IAAI,IAAI,UAAU;IAClC,MAAM,SAA8B,CAAC;IACrC,IAAK,MAAM,OAAO,QAAS,MAAM,CAAC,IAAI,GAAG,AAAC,OAAe,CAAC,IAAI;IAC9D,OAAO,IAAI,GAAG;IACd,OAAO,QAAQ,GAAG,SAAS,OAAO,CAAC,UAAU;IAC7C,OAAO,MAAM,GAAG,OAAO,QAAQ,GAAG;IAClC,OAAO,QAAQ,GAAG,OAAO,MAAM,GAAG,CAAC,GAAG,QAAsB;IAC5D,IAAK,MAAM,OAAO,OAChB,OAAO,cAAc,CAAC,IAAI,EAAE,KAAK;QAC/B,YAAY;QACZ,cAAc;QACd,OAAO,MAAM,CAAC,IAAI;IACpB;AACJ;AAEA,YAAY,SAAS,GAAG,IAAI,SAAS"}}, + {"offset": {"line": 337, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/browser/dev/runtime/base/runtime-base.ts"],"sourcesContent":["/**\n * This file contains runtime types and functions that are shared between all\n * Turbopack *development* ECMAScript runtimes.\n *\n * It will be appended to the runtime code of each runtime right after the\n * shared runtime utils.\n */\n\n/* eslint-disable @next/next/no-assign-module-variable */\n\n/// \n/// \n/// \n/// \n\n// This file must not use `import` and `export` statements. Otherwise, it\n// becomes impossible to augment interfaces declared in ``d files\n// (e.g. `Module`). Hence, the need for `import()` here.\ntype RefreshRuntimeGlobals =\n import(\"@next/react-refresh-utils/dist/runtime\").RefreshRuntimeGlobals;\n\ndeclare var CHUNK_BASE_PATH: string;\ndeclare var $RefreshHelpers$: RefreshRuntimeGlobals[\"$RefreshHelpers$\"];\ndeclare var $RefreshReg$: RefreshRuntimeGlobals[\"$RefreshReg$\"];\ndeclare var $RefreshSig$: RefreshRuntimeGlobals[\"$RefreshSig$\"];\ndeclare var $RefreshInterceptModuleExecution$:\n | RefreshRuntimeGlobals[\"$RefreshInterceptModuleExecution$\"];\n\ntype RefreshContext = {\n register: RefreshRuntimeGlobals[\"$RefreshReg$\"];\n signature: RefreshRuntimeGlobals[\"$RefreshSig$\"];\n registerExports: typeof registerExportsAndSetupBoundaryForReactRefresh;\n};\n\ntype RefreshHelpers = RefreshRuntimeGlobals[\"$RefreshHelpers$\"];\n\ninterface TurbopackDevBaseContext extends TurbopackBaseContext {\n k: RefreshContext;\n R: ResolvePathFromModule;\n}\n\ninterface TurbopackDevContext extends TurbopackDevBaseContext {}\n\n// string encoding of a module factory (used in hmr updates)\ntype ModuleFactoryString = string;\n\ntype ModuleFactory = (\n this: Module[\"exports\"],\n context: TurbopackDevContext\n) => undefined;\n\ntype DevRuntimeParams = {\n otherChunks: ChunkData[];\n runtimeModuleIds: ModuleId[];\n};\n\ntype ChunkRegistration = [\n chunkPath: ChunkPath,\n chunkModules: ModuleFactories,\n params: DevRuntimeParams | undefined\n];\ntype ChunkList = {\n path: ChunkPath;\n chunks: ChunkData[];\n source: \"entry\" | \"dynamic\";\n};\n\nenum SourceType {\n /**\n * The module was instantiated because it was included in an evaluated chunk's\n * runtime.\n */\n Runtime = 0,\n /**\n * The module was instantiated because a parent module imported it.\n */\n Parent = 1,\n /**\n * The module was instantiated because it was included in a chunk's hot module\n * update.\n */\n Update = 2,\n}\n\ntype SourceInfo =\n | {\n type: SourceType.Runtime;\n chunkPath: ChunkPath;\n }\n | {\n type: SourceType.Parent;\n parentId: ModuleId;\n }\n | {\n type: SourceType.Update;\n parents?: ModuleId[];\n };\n\ninterface RuntimeBackend {\n registerChunk: (chunkPath: ChunkPath, params?: DevRuntimeParams) => void;\n loadChunk: (chunkPath: ChunkPath, source: SourceInfo) => Promise;\n reloadChunk?: (chunkPath: ChunkPath) => Promise;\n unloadChunk?: (chunkPath: ChunkPath) => void;\n\n restart: () => void;\n}\n\nclass UpdateApplyError extends Error {\n name = \"UpdateApplyError\";\n\n dependencyChain: string[];\n\n constructor(message: string, dependencyChain: string[]) {\n super(message);\n this.dependencyChain = dependencyChain;\n }\n}\n\nconst moduleFactories: ModuleFactories = Object.create(null);\nconst moduleCache: ModuleCache = Object.create(null);\n/**\n * Maps module IDs to persisted data between executions of their hot module\n * implementation (`hot.data`).\n */\nconst moduleHotData: Map = new Map();\n/**\n * Maps module instances to their hot module state.\n */\nconst moduleHotState: Map = new Map();\n/**\n * Modules that call `module.hot.invalidate()` (while being updated).\n */\nconst queuedInvalidatedModules: Set = new Set();\n/**\n * Module IDs that are instantiated as part of the runtime of a chunk.\n */\nconst runtimeModules: Set = new Set();\n/**\n * Map from module ID to the chunks that contain this module.\n *\n * In HMR, we need to keep track of which modules are contained in which so\n * chunks. This is so we don't eagerly dispose of a module when it is removed\n * from chunk A, but still exists in chunk B.\n */\nconst moduleChunksMap: Map> = new Map();\n/**\n * Map from a chunk path to all modules it contains.\n */\nconst chunkModulesMap: Map> = new Map();\n/**\n * Chunk lists that contain a runtime. When these chunk lists receive an update\n * that can't be reconciled with the current state of the page, we need to\n * reload the runtime entirely.\n */\nconst runtimeChunkLists: Set = new Set();\n/**\n * Map from a chunk list to the chunk paths it contains.\n */\nconst chunkListChunksMap: Map> = new Map();\n/**\n * Map from a chunk path to the chunk lists it belongs to.\n */\nconst chunkChunkListsMap: Map> = new Map();\n\nconst availableModules: Map | true> = new Map();\n\nconst availableModuleChunks: Map | true> = new Map();\n\nasync function loadChunk(\n source: SourceInfo,\n chunkData: ChunkData\n): Promise {\n if (typeof chunkData === \"string\") {\n return loadChunkPath(source, chunkData);\n }\n\n const includedList = chunkData.included || [];\n const modulesPromises = includedList.map((included) => {\n if (moduleFactories[included]) return true;\n return availableModules.get(included);\n });\n if (modulesPromises.length > 0 && modulesPromises.every((p) => p)) {\n // When all included items are already loaded or loading, we can skip loading ourselves\n return Promise.all(modulesPromises);\n }\n\n const includedModuleChunksList = chunkData.moduleChunks || [];\n const moduleChunksPromises = includedModuleChunksList\n .map((included) => {\n // TODO(alexkirsz) Do we need this check?\n // if (moduleFactories[included]) return true;\n return availableModuleChunks.get(included);\n })\n .filter((p) => p);\n\n let promise;\n if (moduleChunksPromises.length > 0) {\n // Some module chunks are already loaded or loading.\n\n if (moduleChunksPromises.length == includedModuleChunksList.length) {\n // When all included module chunks are already loaded or loading, we can skip loading ourselves\n return Promise.all(moduleChunksPromises);\n }\n\n const moduleChunksToLoad: Set = new Set();\n for (const moduleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(moduleChunk)) {\n moduleChunksToLoad.add(moduleChunk);\n }\n }\n\n for (const moduleChunkToLoad of moduleChunksToLoad) {\n const promise = loadChunkPath(source, moduleChunkToLoad);\n\n availableModuleChunks.set(moduleChunkToLoad, promise);\n\n moduleChunksPromises.push(promise);\n }\n\n promise = Promise.all(moduleChunksPromises);\n } else {\n promise = loadChunkPath(source, chunkData.path);\n\n // Mark all included module chunks as loading if they are not already loaded or loading.\n for (const includedModuleChunk of includedModuleChunksList) {\n if (!availableModuleChunks.has(includedModuleChunk)) {\n availableModuleChunks.set(includedModuleChunk, promise);\n }\n }\n }\n\n for (const included of includedList) {\n if (!availableModules.has(included)) {\n // It might be better to race old and new promises, but it's rare that the new promise will be faster than a request started earlier.\n // In production it's even more rare, because the chunk optimization tries to deduplicate modules anyway.\n availableModules.set(included, promise);\n }\n }\n\n return promise;\n}\n\nasync function loadChunkPath(\n source: SourceInfo,\n chunkPath: ChunkPath\n): Promise {\n try {\n await BACKEND.loadChunk(chunkPath, source);\n } catch (error) {\n let loadReason;\n switch (source.type) {\n case SourceType.Runtime:\n loadReason = `as a runtime dependency of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n loadReason = `from module ${source.parentId}`;\n break;\n case SourceType.Update:\n loadReason = \"from an HMR update\";\n break;\n }\n throw new Error(\n `Failed to load chunk ${chunkPath} ${loadReason}${\n error ? `: ${error}` : \"\"\n }`,\n error\n ? {\n cause: error,\n }\n : undefined\n );\n }\n}\n\n/**\n * Returns an absolute url to an asset.\n */\nfunction createResolvePathFromModule(\n resolver: (moduleId: string) => Exports\n): (moduleId: string) => string {\n return function resolvePathFromModule(moduleId: string): string {\n const exported = resolver(moduleId);\n return exported?.default ?? exported;\n };\n}\n\nfunction instantiateModule(id: ModuleId, source: SourceInfo): Module {\n const moduleFactory = moduleFactories[id];\n if (typeof moduleFactory !== \"function\") {\n // This can happen if modules incorrectly handle HMR disposes/updates,\n // e.g. when they keep a `setTimeout` around which still executes old code\n // and contains e.g. a `require(\"something\")` call.\n let instantiationReason;\n switch (source.type) {\n case SourceType.Runtime:\n instantiationReason = `as a runtime entry of chunk ${source.chunkPath}`;\n break;\n case SourceType.Parent:\n instantiationReason = `because it was required from module ${source.parentId}`;\n break;\n case SourceType.Update:\n instantiationReason = \"because of an HMR update\";\n break;\n }\n throw new Error(\n `Module ${id} was instantiated ${instantiationReason}, but the module factory is not available. It might have been deleted in an HMR update.`\n );\n }\n\n const hotData = moduleHotData.get(id)!;\n const { hot, hotState } = createModuleHot(id, hotData);\n\n let parents: ModuleId[];\n switch (source.type) {\n case SourceType.Runtime:\n runtimeModules.add(id);\n parents = [];\n break;\n case SourceType.Parent:\n // No need to add this module as a child of the parent module here, this\n // has already been taken care of in `getOrInstantiateModuleFromParent`.\n parents = [source.parentId];\n break;\n case SourceType.Update:\n parents = source.parents || [];\n break;\n }\n const module: Module = {\n exports: {},\n error: undefined,\n loaded: false,\n id,\n parents,\n children: [],\n namespaceObject: undefined,\n hot,\n };\n\n moduleCache[id] = module;\n moduleHotState.set(module, hotState);\n\n // NOTE(alexkirsz) This can fail when the module encounters a runtime error.\n try {\n const sourceInfo: SourceInfo = { type: SourceType.Parent, parentId: id };\n\n runModuleExecutionHooks(module, (refresh) => {\n const r = commonJsRequire.bind(null, module);\n moduleFactory.call(\n module.exports,\n augmentContext({\n a: asyncModule.bind(null, module),\n e: module.exports,\n r: commonJsRequire.bind(null, module),\n t: runtimeRequire,\n f: moduleContext,\n i: esmImport.bind(null, module),\n s: esmExport.bind(null, module, module.exports),\n j: dynamicExport.bind(null, module, module.exports),\n v: exportValue.bind(null, module),\n n: exportNamespace.bind(null, module),\n m: module,\n c: moduleCache,\n M: moduleFactories,\n l: loadChunk.bind(null, sourceInfo),\n w: loadWebAssembly.bind(null, sourceInfo),\n u: loadWebAssemblyModule.bind(null, sourceInfo),\n g: globalThis,\n P: resolveAbsolutePath,\n U: relativeURL,\n k: refresh,\n R: createResolvePathFromModule(r),\n __dirname: module.id.replace(/(^|\\/)\\/+$/, \"\"),\n })\n );\n });\n } catch (error) {\n module.error = error as any;\n throw error;\n }\n\n module.loaded = true;\n if (module.namespaceObject && module.exports !== module.namespaceObject) {\n // in case of a circular dependency: cjs1 -> esm2 -> cjs1\n interopEsm(module.exports, module.namespaceObject);\n }\n\n return module;\n}\n\n/**\n * no-op for browser\n * @param modulePath\n */\nfunction resolveAbsolutePath(modulePath?: string): string {\n return `/ROOT/${modulePath ?? \"\"}`;\n}\n\n/**\n * NOTE(alexkirsz) Webpack has a \"module execution\" interception hook that\n * Next.js' React Refresh runtime hooks into to add module context to the\n * refresh registry.\n */\nfunction runModuleExecutionHooks(\n module: Module,\n executeModule: (ctx: RefreshContext) => void\n) {\n const cleanupReactRefreshIntercept =\n typeof globalThis.$RefreshInterceptModuleExecution$ === \"function\"\n ? globalThis.$RefreshInterceptModuleExecution$(module.id)\n : () => {};\n\n try {\n executeModule({\n register: globalThis.$RefreshReg$,\n signature: globalThis.$RefreshSig$,\n registerExports: registerExportsAndSetupBoundaryForReactRefresh,\n });\n } catch (e) {\n throw e;\n } finally {\n // Always cleanup the intercept, even if module execution failed.\n cleanupReactRefreshIntercept();\n }\n}\n\n/**\n * Retrieves a module from the cache, or instantiate it if it is not cached.\n */\nconst getOrInstantiateModuleFromParent: GetOrInstantiateModuleFromParent = (\n id,\n sourceModule\n) => {\n if (!sourceModule.hot.active) {\n console.warn(\n `Unexpected import of module ${id} from module ${sourceModule.id}, which was deleted by an HMR update`\n );\n }\n\n const module = moduleCache[id];\n\n if (sourceModule.children.indexOf(id) === -1) {\n sourceModule.children.push(id);\n }\n\n if (module) {\n if (module.parents.indexOf(sourceModule.id) === -1) {\n module.parents.push(sourceModule.id);\n }\n\n return module;\n }\n\n return instantiateModule(id, {\n type: SourceType.Parent,\n parentId: sourceModule.id,\n });\n};\n\n/**\n * This is adapted from https://github.com/vercel/next.js/blob/3466862d9dc9c8bb3131712134d38757b918d1c0/packages/react-refresh-utils/internal/ReactRefreshModule.runtime.ts\n */\nfunction registerExportsAndSetupBoundaryForReactRefresh(\n module: Module,\n helpers: RefreshHelpers\n) {\n const currentExports = module.exports;\n const prevExports = module.hot.data.prevExports ?? null;\n\n helpers.registerExportsForReactRefresh(currentExports, module.id);\n\n // A module can be accepted automatically based on its exports, e.g. when\n // it is a Refresh Boundary.\n if (helpers.isReactRefreshBoundary(currentExports)) {\n // Save the previous exports on update, so we can compare the boundary\n // signatures.\n module.hot.dispose((data) => {\n data.prevExports = currentExports;\n });\n // Unconditionally accept an update to this module, we'll check if it's\n // still a Refresh Boundary later.\n module.hot.accept();\n\n // This field is set when the previous version of this module was a\n // Refresh Boundary, letting us know we need to check for invalidation or\n // enqueue an update.\n if (prevExports !== null) {\n // A boundary can become ineligible if its exports are incompatible\n // with the previous exports.\n //\n // For example, if you add/remove/change exports, we'll want to\n // re-execute the importing modules, and force those components to\n // re-render. Similarly, if you convert a class component to a\n // function, we want to invalidate the boundary.\n if (\n helpers.shouldInvalidateReactRefreshBoundary(\n helpers.getRefreshBoundarySignature(prevExports),\n helpers.getRefreshBoundarySignature(currentExports)\n )\n ) {\n module.hot.invalidate();\n } else {\n helpers.scheduleUpdate();\n }\n }\n } else {\n // Since we just executed the code for the module, it's possible that the\n // new exports made it ineligible for being a boundary.\n // We only care about the case when we were _previously_ a boundary,\n // because we already accepted this update (accidental side effect).\n const isNoLongerABoundary = prevExports !== null;\n if (isNoLongerABoundary) {\n module.hot.invalidate();\n }\n }\n}\n\nfunction formatDependencyChain(dependencyChain: ModuleId[]): string {\n return `Dependency chain: ${dependencyChain.join(\" -> \")}`;\n}\n\nfunction computeOutdatedModules(\n added: Map,\n modified: Map\n): {\n outdatedModules: Set;\n newModuleFactories: Map;\n} {\n const newModuleFactories = new Map();\n\n for (const [moduleId, entry] of added) {\n if (entry != null) {\n newModuleFactories.set(moduleId, _eval(entry));\n }\n }\n\n const outdatedModules = computedInvalidatedModules(modified.keys());\n\n for (const [moduleId, entry] of modified) {\n newModuleFactories.set(moduleId, _eval(entry));\n }\n\n return { outdatedModules, newModuleFactories };\n}\n\nfunction computedInvalidatedModules(\n invalidated: Iterable\n): Set {\n const outdatedModules = new Set();\n\n for (const moduleId of invalidated) {\n const effect = getAffectedModuleEffects(moduleId);\n\n switch (effect.type) {\n case \"unaccepted\":\n throw new UpdateApplyError(\n `cannot apply update: unaccepted module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n );\n case \"self-declined\":\n throw new UpdateApplyError(\n `cannot apply update: self-declined module. ${formatDependencyChain(\n effect.dependencyChain\n )}.`,\n effect.dependencyChain\n );\n case \"accepted\":\n for (const outdatedModuleId of effect.outdatedModules) {\n outdatedModules.add(outdatedModuleId);\n }\n break;\n // TODO(alexkirsz) Dependencies: handle dependencies effects.\n }\n }\n\n return outdatedModules;\n}\n\nfunction computeOutdatedSelfAcceptedModules(\n outdatedModules: Iterable\n): { moduleId: ModuleId; errorHandler: true | Function }[] {\n const outdatedSelfAcceptedModules = [];\n for (const moduleId of outdatedModules) {\n const module = moduleCache[moduleId];\n const hotState = moduleHotState.get(module)!;\n if (module && hotState.selfAccepted && !hotState.selfInvalidated) {\n outdatedSelfAcceptedModules.push({\n moduleId,\n errorHandler: hotState.selfAccepted,\n });\n }\n }\n return outdatedSelfAcceptedModules;\n}\n\n/**\n * Adds, deletes, and moves modules between chunks. This must happen before the\n * dispose phase as it needs to know which modules were removed from all chunks,\n * which we can only compute *after* taking care of added and moved modules.\n */\nfunction updateChunksPhase(\n chunksAddedModules: Map>,\n chunksDeletedModules: Map>\n): { disposedModules: Set } {\n for (const [chunkPath, addedModuleIds] of chunksAddedModules) {\n for (const moduleId of addedModuleIds) {\n addModuleToChunk(moduleId, chunkPath);\n }\n }\n\n const disposedModules: Set = new Set();\n for (const [chunkPath, addedModuleIds] of chunksDeletedModules) {\n for (const moduleId of addedModuleIds) {\n if (removeModuleFromChunk(moduleId, chunkPath)) {\n disposedModules.add(moduleId);\n }\n }\n }\n\n return { disposedModules };\n}\n\nfunction disposePhase(\n outdatedModules: Iterable,\n disposedModules: Iterable\n): { outdatedModuleParents: Map> } {\n for (const moduleId of outdatedModules) {\n disposeModule(moduleId, \"replace\");\n }\n\n for (const moduleId of disposedModules) {\n disposeModule(moduleId, \"clear\");\n }\n\n // Removing modules from the module cache is a separate step.\n // We also want to keep track of previous parents of the outdated modules.\n const outdatedModuleParents = new Map();\n for (const moduleId of outdatedModules) {\n const oldModule = moduleCache[moduleId];\n outdatedModuleParents.set(moduleId, oldModule?.parents);\n delete moduleCache[moduleId];\n }\n\n // TODO(alexkirsz) Dependencies: remove outdated dependency from module\n // children.\n\n return { outdatedModuleParents };\n}\n\n/**\n * Disposes of an instance of a module.\n *\n * Returns the persistent hot data that should be kept for the next module\n * instance.\n *\n * NOTE: mode = \"replace\" will not remove modules from the moduleCache.\n * This must be done in a separate step afterwards.\n * This is important because all modules need to be disposed to update the\n * parent/child relationships before they are actually removed from the moduleCache.\n * If this was done in this method, the following disposeModule calls won't find\n * the module from the module id in the cache.\n */\nfunction disposeModule(moduleId: ModuleId, mode: \"clear\" | \"replace\") {\n const module = moduleCache[moduleId];\n if (!module) {\n return;\n }\n\n const hotState = moduleHotState.get(module)!;\n const data = {};\n\n // Run the `hot.dispose` handler, if any, passing in the persistent\n // `hot.data` object.\n for (const disposeHandler of hotState.disposeHandlers) {\n disposeHandler(data);\n }\n\n // This used to warn in `getOrInstantiateModuleFromParent` when a disposed\n // module is still importing other modules.\n module.hot.active = false;\n\n moduleHotState.delete(module);\n\n // TODO(alexkirsz) Dependencies: delete the module from outdated deps.\n\n // Remove the disposed module from its children's parent list.\n // It will be added back once the module re-instantiates and imports its\n // children again.\n for (const childId of module.children) {\n const child = moduleCache[childId];\n if (!child) {\n continue;\n }\n\n const idx = child.parents.indexOf(module.id);\n if (idx >= 0) {\n child.parents.splice(idx, 1);\n }\n }\n\n switch (mode) {\n case \"clear\":\n delete moduleCache[module.id];\n moduleHotData.delete(module.id);\n break;\n case \"replace\":\n moduleHotData.set(module.id, data);\n break;\n default:\n invariant(mode, (mode) => `invalid mode: ${mode}`);\n }\n}\n\nfunction applyPhase(\n outdatedSelfAcceptedModules: {\n moduleId: ModuleId;\n errorHandler: true | Function;\n }[],\n newModuleFactories: Map,\n outdatedModuleParents: Map>,\n reportError: (err: any) => void\n) {\n // Update module factories.\n for (const [moduleId, factory] of newModuleFactories.entries()) {\n moduleFactories[moduleId] = factory;\n }\n\n // TODO(alexkirsz) Run new runtime entries here.\n\n // TODO(alexkirsz) Dependencies: call accept handlers for outdated deps.\n\n // Re-instantiate all outdated self-accepted modules.\n for (const { moduleId, errorHandler } of outdatedSelfAcceptedModules) {\n try {\n instantiateModule(moduleId, {\n type: SourceType.Update,\n parents: outdatedModuleParents.get(moduleId),\n });\n } catch (err) {\n if (typeof errorHandler === \"function\") {\n try {\n errorHandler(err, { moduleId, module: moduleCache[moduleId] });\n } catch (err2) {\n reportError(err2);\n reportError(err);\n }\n } else {\n reportError(err);\n }\n }\n }\n}\n\n/**\n * Utility function to ensure all variants of an enum are handled.\n */\nfunction invariant(never: never, computeMessage: (arg: any) => string): never {\n throw new Error(`Invariant: ${computeMessage(never)}`);\n}\n\nfunction applyUpdate(update: PartialUpdate) {\n switch (update.type) {\n case \"ChunkListUpdate\":\n applyChunkListUpdate(update);\n break;\n default:\n invariant(update, (update) => `Unknown update type: ${update.type}`);\n }\n}\n\nfunction applyChunkListUpdate(update: ChunkListUpdate) {\n if (update.merged != null) {\n for (const merged of update.merged) {\n switch (merged.type) {\n case \"EcmascriptMergedUpdate\":\n applyEcmascriptMergedUpdate(merged);\n break;\n default:\n invariant(merged, (merged) => `Unknown merged type: ${merged.type}`);\n }\n }\n }\n\n if (update.chunks != null) {\n for (const [chunkPath, chunkUpdate] of Object.entries(update.chunks)) {\n switch (chunkUpdate.type) {\n case \"added\":\n BACKEND.loadChunk(chunkPath, { type: SourceType.Update });\n break;\n case \"total\":\n BACKEND.reloadChunk?.(chunkPath);\n break;\n case \"deleted\":\n BACKEND.unloadChunk?.(chunkPath);\n break;\n case \"partial\":\n invariant(\n chunkUpdate.instruction,\n (instruction) =>\n `Unknown partial instruction: ${JSON.stringify(instruction)}.`\n );\n default:\n invariant(\n chunkUpdate,\n (chunkUpdate) => `Unknown chunk update type: ${chunkUpdate.type}`\n );\n }\n }\n }\n}\n\nfunction applyEcmascriptMergedUpdate(update: EcmascriptMergedUpdate) {\n const { entries = {}, chunks = {} } = update;\n const { added, modified, chunksAdded, chunksDeleted } = computeChangedModules(\n entries,\n chunks\n );\n const { outdatedModules, newModuleFactories } = computeOutdatedModules(\n added,\n modified\n );\n const { disposedModules } = updateChunksPhase(chunksAdded, chunksDeleted);\n\n applyInternal(outdatedModules, disposedModules, newModuleFactories);\n}\n\nfunction applyInvalidatedModules(outdatedModules: Set) {\n if (queuedInvalidatedModules.size > 0) {\n computedInvalidatedModules(queuedInvalidatedModules).forEach((moduleId) => {\n outdatedModules.add(moduleId);\n });\n\n queuedInvalidatedModules.clear();\n }\n\n return outdatedModules;\n}\n\nfunction applyInternal(\n outdatedModules: Set,\n disposedModules: Iterable,\n newModuleFactories: Map\n) {\n outdatedModules = applyInvalidatedModules(outdatedModules);\n\n const outdatedSelfAcceptedModules =\n computeOutdatedSelfAcceptedModules(outdatedModules);\n\n const { outdatedModuleParents } = disposePhase(\n outdatedModules,\n disposedModules\n );\n\n // we want to continue on error and only throw the error after we tried applying all updates\n let error: any;\n\n function reportError(err: any) {\n if (!error) error = err;\n }\n\n applyPhase(\n outdatedSelfAcceptedModules,\n newModuleFactories,\n outdatedModuleParents,\n reportError\n );\n\n if (error) {\n throw error;\n }\n\n if (queuedInvalidatedModules.size > 0) {\n applyInternal(new Set(), [], new Map());\n }\n}\n\nfunction computeChangedModules(\n entries: Record,\n updates: Record\n): {\n added: Map;\n modified: Map;\n deleted: Set;\n chunksAdded: Map>;\n chunksDeleted: Map>;\n} {\n const chunksAdded = new Map();\n const chunksDeleted = new Map();\n const added: Map = new Map();\n const modified = new Map();\n const deleted: Set = new Set();\n\n for (const [chunkPath, mergedChunkUpdate] of Object.entries(updates)) {\n switch (mergedChunkUpdate.type) {\n case \"added\": {\n const updateAdded = new Set(mergedChunkUpdate.modules);\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId]);\n }\n chunksAdded.set(chunkPath, updateAdded);\n break;\n }\n case \"deleted\": {\n // We could also use `mergedChunkUpdate.modules` here.\n const updateDeleted = new Set(chunkModulesMap.get(chunkPath));\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId);\n }\n chunksDeleted.set(chunkPath, updateDeleted);\n break;\n }\n case \"partial\": {\n const updateAdded = new Set(mergedChunkUpdate.added);\n const updateDeleted = new Set(mergedChunkUpdate.deleted);\n for (const moduleId of updateAdded) {\n added.set(moduleId, entries[moduleId]);\n }\n for (const moduleId of updateDeleted) {\n deleted.add(moduleId);\n }\n chunksAdded.set(chunkPath, updateAdded);\n chunksDeleted.set(chunkPath, updateDeleted);\n break;\n }\n default:\n invariant(\n mergedChunkUpdate,\n (mergedChunkUpdate) =>\n `Unknown merged chunk update type: ${mergedChunkUpdate.type}`\n );\n }\n }\n\n // If a module was added from one chunk and deleted from another in the same update,\n // consider it to be modified, as it means the module was moved from one chunk to another\n // AND has new code in a single update.\n for (const moduleId of added.keys()) {\n if (deleted.has(moduleId)) {\n added.delete(moduleId);\n deleted.delete(moduleId);\n }\n }\n\n for (const [moduleId, entry] of Object.entries(entries)) {\n // Modules that haven't been added to any chunk but have new code are considered\n // to be modified.\n // This needs to be under the previous loop, as we need it to get rid of modules\n // that were added and deleted in the same update.\n if (!added.has(moduleId)) {\n modified.set(moduleId, entry);\n }\n }\n\n return { added, deleted, modified, chunksAdded, chunksDeleted };\n}\n\ntype ModuleEffect =\n | {\n type: \"unaccepted\";\n dependencyChain: ModuleId[];\n }\n | {\n type: \"self-declined\";\n dependencyChain: ModuleId[];\n moduleId: ModuleId;\n }\n | {\n type: \"accepted\";\n moduleId: ModuleId;\n outdatedModules: Set;\n };\n\nfunction getAffectedModuleEffects(moduleId: ModuleId): ModuleEffect {\n const outdatedModules: Set = new Set();\n\n type QueueItem = { moduleId?: ModuleId; dependencyChain: ModuleId[] };\n\n const queue: QueueItem[] = [\n {\n moduleId,\n dependencyChain: [],\n },\n ];\n\n let nextItem;\n while ((nextItem = queue.shift())) {\n const { moduleId, dependencyChain } = nextItem;\n\n if (moduleId != null) {\n if (outdatedModules.has(moduleId)) {\n // Avoid infinite loops caused by cycles between modules in the dependency chain.\n continue;\n }\n\n outdatedModules.add(moduleId);\n }\n\n // We've arrived at the runtime of the chunk, which means that nothing\n // else above can accept this update.\n if (moduleId === undefined) {\n return {\n type: \"unaccepted\",\n dependencyChain,\n };\n }\n\n const module = moduleCache[moduleId];\n const hotState = moduleHotState.get(module)!;\n\n if (\n // The module is not in the cache. Since this is a \"modified\" update,\n // it means that the module was never instantiated before.\n !module || // The module accepted itself without invalidating globalThis.\n // TODO is that right?\n (hotState.selfAccepted && !hotState.selfInvalidated)\n ) {\n continue;\n }\n\n if (hotState.selfDeclined) {\n return {\n type: \"self-declined\",\n dependencyChain,\n moduleId,\n };\n }\n\n if (runtimeModules.has(moduleId)) {\n queue.push({\n moduleId: undefined,\n dependencyChain: [...dependencyChain, moduleId],\n });\n continue;\n }\n\n for (const parentId of module.parents) {\n const parent = moduleCache[parentId];\n\n if (!parent) {\n // TODO(alexkirsz) Is this even possible?\n continue;\n }\n\n // TODO(alexkirsz) Dependencies: check accepted and declined\n // dependencies here.\n\n queue.push({\n moduleId: parentId,\n dependencyChain: [...dependencyChain, moduleId],\n });\n }\n }\n\n return {\n type: \"accepted\",\n moduleId,\n outdatedModules,\n };\n}\n\nfunction handleApply(chunkListPath: ChunkPath, update: ServerMessage) {\n switch (update.type) {\n case \"partial\": {\n // This indicates that the update is can be applied to the current state of the application.\n applyUpdate(update.instruction);\n break;\n }\n case \"restart\": {\n // This indicates that there is no way to apply the update to the\n // current state of the application, and that the application must be\n // restarted.\n BACKEND.restart();\n break;\n }\n case \"notFound\": {\n // This indicates that the chunk list no longer exists: either the dynamic import which created it was removed,\n // or the page itself was deleted.\n // If it is a dynamic import, we simply discard all modules that the chunk has exclusive access to.\n // If it is a runtime chunk list, we restart the application.\n if (runtimeChunkLists.has(chunkListPath)) {\n BACKEND.restart();\n } else {\n disposeChunkList(chunkListPath);\n }\n break;\n }\n default:\n throw new Error(`Unknown update type: ${update.type}`);\n }\n}\n\nfunction createModuleHot(\n moduleId: ModuleId,\n hotData: HotData\n): { hot: Hot; hotState: HotState } {\n const hotState: HotState = {\n selfAccepted: false,\n selfDeclined: false,\n selfInvalidated: false,\n disposeHandlers: [],\n };\n\n const hot: Hot = {\n // TODO(alexkirsz) This is not defined in the HMR API. It was used to\n // decide whether to warn whenever an HMR-disposed module required other\n // modules. We might want to remove it.\n active: true,\n\n data: hotData ?? {},\n\n // TODO(alexkirsz) Support full (dep, callback, errorHandler) form.\n accept: (\n modules?: string | string[] | AcceptErrorHandler,\n _callback?: AcceptCallback,\n _errorHandler?: AcceptErrorHandler\n ) => {\n if (modules === undefined) {\n hotState.selfAccepted = true;\n } else if (typeof modules === \"function\") {\n hotState.selfAccepted = modules;\n } else {\n throw new Error(\"unsupported `accept` signature\");\n }\n },\n\n decline: (dep) => {\n if (dep === undefined) {\n hotState.selfDeclined = true;\n } else {\n throw new Error(\"unsupported `decline` signature\");\n }\n },\n\n dispose: (callback) => {\n hotState.disposeHandlers.push(callback);\n },\n\n addDisposeHandler: (callback) => {\n hotState.disposeHandlers.push(callback);\n },\n\n removeDisposeHandler: (callback) => {\n const idx = hotState.disposeHandlers.indexOf(callback);\n if (idx >= 0) {\n hotState.disposeHandlers.splice(idx, 1);\n }\n },\n\n invalidate: () => {\n hotState.selfInvalidated = true;\n queuedInvalidatedModules.add(moduleId);\n },\n\n // NOTE(alexkirsz) This is part of the management API, which we don't\n // implement, but the Next.js React Refresh runtime uses this to decide\n // whether to schedule an update.\n status: () => \"idle\",\n\n // NOTE(alexkirsz) Since we always return \"idle\" for now, these are no-ops.\n addStatusHandler: (_handler) => {},\n removeStatusHandler: (_handler) => {},\n\n // NOTE(jridgewell) Check returns the list of updated modules, but we don't\n // want the webpack code paths to ever update (the turbopack paths handle\n // this already).\n check: () => Promise.resolve(null),\n };\n\n return { hot, hotState };\n}\n\n/**\n * Adds a module to a chunk.\n */\nfunction addModuleToChunk(moduleId: ModuleId, chunkPath: ChunkPath) {\n let moduleChunks = moduleChunksMap.get(moduleId);\n if (!moduleChunks) {\n moduleChunks = new Set([chunkPath]);\n moduleChunksMap.set(moduleId, moduleChunks);\n } else {\n moduleChunks.add(chunkPath);\n }\n\n let chunkModules = chunkModulesMap.get(chunkPath);\n if (!chunkModules) {\n chunkModules = new Set([moduleId]);\n chunkModulesMap.set(chunkPath, chunkModules);\n } else {\n chunkModules.add(moduleId);\n }\n}\n\n/**\n * Returns the first chunk that included a module.\n * This is used by the Node.js backend, hence why it's marked as unused in this\n * file.\n */\nfunction getFirstModuleChunk(moduleId: ModuleId) {\n const moduleChunkPaths = moduleChunksMap.get(moduleId);\n if (moduleChunkPaths == null) {\n return null;\n }\n\n return moduleChunkPaths.values().next().value;\n}\n\n/**\n * Removes a module from a chunk.\n * Returns `true` if there are no remaining chunks including this module.\n */\nfunction removeModuleFromChunk(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): boolean {\n const moduleChunks = moduleChunksMap.get(moduleId)!;\n moduleChunks.delete(chunkPath);\n\n const chunkModules = chunkModulesMap.get(chunkPath)!;\n chunkModules.delete(moduleId);\n\n const noRemainingModules = chunkModules.size === 0;\n if (noRemainingModules) {\n chunkModulesMap.delete(chunkPath);\n }\n\n const noRemainingChunks = moduleChunks.size === 0;\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId);\n }\n\n return noRemainingChunks;\n}\n\n/**\n * Disposes of a chunk list and its corresponding exclusive chunks.\n */\nfunction disposeChunkList(chunkListPath: ChunkPath): boolean {\n const chunkPaths = chunkListChunksMap.get(chunkListPath);\n if (chunkPaths == null) {\n return false;\n }\n chunkListChunksMap.delete(chunkListPath);\n\n for (const chunkPath of chunkPaths) {\n const chunkChunkLists = chunkChunkListsMap.get(chunkPath)!;\n chunkChunkLists.delete(chunkListPath);\n\n if (chunkChunkLists.size === 0) {\n chunkChunkListsMap.delete(chunkPath);\n disposeChunk(chunkPath);\n }\n }\n\n // We must also dispose of the chunk list's chunk itself to ensure it may\n // be reloaded properly in the future.\n BACKEND.unloadChunk?.(chunkListPath);\n\n return true;\n}\n\n/**\n * Disposes of a chunk and its corresponding exclusive modules.\n *\n * @returns Whether the chunk was disposed of.\n */\nfunction disposeChunk(chunkPath: ChunkPath): boolean {\n // This should happen whether the chunk has any modules in it or not.\n // For instance, CSS chunks have no modules in them, but they still need to be unloaded.\n BACKEND.unloadChunk?.(chunkPath);\n\n const chunkModules = chunkModulesMap.get(chunkPath);\n if (chunkModules == null) {\n return false;\n }\n chunkModules.delete(chunkPath);\n\n for (const moduleId of chunkModules) {\n const moduleChunks = moduleChunksMap.get(moduleId)!;\n moduleChunks.delete(chunkPath);\n\n const noRemainingChunks = moduleChunks.size === 0;\n if (noRemainingChunks) {\n moduleChunksMap.delete(moduleId);\n disposeModule(moduleId, \"clear\");\n availableModules.delete(moduleId);\n }\n }\n\n return true;\n}\n\n/**\n * Instantiates a runtime module.\n */\nfunction instantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Gets or instantiates a runtime module.\n */\nfunction getOrInstantiateRuntimeModule(\n moduleId: ModuleId,\n chunkPath: ChunkPath\n): Module {\n const module = moduleCache[moduleId];\n if (module) {\n if (module.error) {\n throw module.error;\n }\n return module;\n }\n\n return instantiateModule(moduleId, { type: SourceType.Runtime, chunkPath });\n}\n\n/**\n * Returns the URL relative to the origin where a chunk can be fetched from.\n */\nfunction getChunkRelativeUrl(chunkPath: ChunkPath): string {\n return `${CHUNK_BASE_PATH}${chunkPath\n .split(\"/\")\n .map((p) => encodeURIComponent(p))\n .join(\"/\")}`;\n}\n\n/**\n * Subscribes to chunk list updates from the update server and applies them.\n */\nfunction registerChunkList(\n chunkUpdateProvider: ChunkUpdateProvider,\n chunkList: ChunkList\n) {\n chunkUpdateProvider.push([\n chunkList.path,\n handleApply.bind(null, chunkList.path),\n ]);\n\n // Adding chunks to chunk lists and vice versa.\n const chunks = new Set(chunkList.chunks.map(getChunkPath));\n chunkListChunksMap.set(chunkList.path, chunks);\n for (const chunkPath of chunks) {\n let chunkChunkLists = chunkChunkListsMap.get(chunkPath);\n if (!chunkChunkLists) {\n chunkChunkLists = new Set([chunkList.path]);\n chunkChunkListsMap.set(chunkPath, chunkChunkLists);\n } else {\n chunkChunkLists.add(chunkList.path);\n }\n }\n\n if (chunkList.source === \"entry\") {\n markChunkListAsRuntime(chunkList.path);\n }\n}\n\n/**\n * Marks a chunk list as a runtime chunk list. There can be more than one\n * runtime chunk list. For instance, integration tests can have multiple chunk\n * groups loaded at runtime, each with its own chunk list.\n */\nfunction markChunkListAsRuntime(chunkListPath: ChunkPath) {\n runtimeChunkLists.add(chunkListPath);\n}\n\nfunction registerChunk([\n chunkPath,\n chunkModules,\n runtimeParams,\n]: ChunkRegistration) {\n for (const [moduleId, moduleFactory] of Object.entries(chunkModules)) {\n if (!moduleFactories[moduleId]) {\n moduleFactories[moduleId] = moduleFactory;\n }\n addModuleToChunk(moduleId, chunkPath);\n }\n\n return BACKEND.registerChunk(chunkPath, runtimeParams);\n}\n\nglobalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS ??= [];\n\nconst chunkListsToRegister = globalThis.TURBOPACK_CHUNK_LISTS;\nif (Array.isArray(chunkListsToRegister)) {\n for (const chunkList of chunkListsToRegister) {\n registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS, chunkList);\n }\n}\n\nglobalThis.TURBOPACK_CHUNK_LISTS = {\n push: (chunkList) => {\n registerChunkList(globalThis.TURBOPACK_CHUNK_UPDATE_LISTENERS!, chunkList);\n },\n} satisfies ChunkListProvider;\n"],"names":[],"mappings":"AAAA;;;;;;CAMC,GAED,uDAAuD,GAEvD,4DAA4D;AAC5D,uCAAuC;AACvC,wCAAwC;AACxC,0CAA0C;AAE1C,yEAAyE;AACzE,4EAA4E;AAC5E,wDAAwD;;UAkDnD;IACH;;;GAGC;IAED;;GAEC;IAED;;;GAGC;GAbE,eAAA;AAwCL,MAAM,yBAAyB;IAC7B,OAAO,mBAAmB;IAE1B,gBAA0B;IAE1B,YAAY,OAAe,EAAE,eAAyB,CAAE;QACtD,KAAK,CAAC;QACN,IAAI,CAAC,eAAe,GAAG;IACzB;AACF;AAEA,MAAM,kBAAmC,OAAO,MAAM,CAAC;AACvD,MAAM,cAA2B,OAAO,MAAM,CAAC;AAC/C;;;CAGC,GACD,MAAM,gBAAwC,IAAI;AAClD;;CAEC,GACD,MAAM,iBAAwC,IAAI;AAClD;;CAEC,GACD,MAAM,2BAA0C,IAAI;AACpD;;CAEC,GACD,MAAM,iBAAgC,IAAI;AAC1C;;;;;;CAMC,GACD,MAAM,kBAAiD,IAAI;AAC3D;;CAEC,GACD,MAAM,kBAAiD,IAAI;AAC3D;;;;CAIC,GACD,MAAM,oBAAoC,IAAI;AAC9C;;CAEC,GACD,MAAM,qBAAqD,IAAI;AAC/D;;CAEC,GACD,MAAM,qBAAqD,IAAI;AAE/D,MAAM,mBAAuD,IAAI;AAEjE,MAAM,wBAA6D,IAAI;AAEvE,eAAe,UACb,MAAkB,EAClB,SAAoB;IAEpB,IAAI,OAAO,cAAc,UAAU;QACjC,OAAO,cAAc,QAAQ;IAC/B;IAEA,MAAM,eAAe,UAAU,QAAQ,IAAI,EAAE;IAC7C,MAAM,kBAAkB,aAAa,GAAG,CAAC,CAAC;QACxC,IAAI,eAAe,CAAC,SAAS,EAAE,OAAO;QACtC,OAAO,iBAAiB,GAAG,CAAC;IAC9B;IACA,IAAI,gBAAgB,MAAM,GAAG,KAAK,gBAAgB,KAAK,CAAC,CAAC,IAAM,IAAI;QACjE,uFAAuF;QACvF,OAAO,QAAQ,GAAG,CAAC;IACrB;IAEA,MAAM,2BAA2B,UAAU,YAAY,IAAI,EAAE;IAC7D,MAAM,uBAAuB,yBAC1B,GAAG,CAAC,CAAC;QACJ,yCAAyC;QACzC,8CAA8C;QAC9C,OAAO,sBAAsB,GAAG,CAAC;IACnC,GACC,MAAM,CAAC,CAAC,IAAM;IAEjB,IAAI;IACJ,IAAI,qBAAqB,MAAM,GAAG,GAAG;QACnC,oDAAoD;QAEpD,IAAI,qBAAqB,MAAM,IAAI,yBAAyB,MAAM,EAAE;YAClE,+FAA+F;YAC/F,OAAO,QAAQ,GAAG,CAAC;QACrB;QAEA,MAAM,qBAAqC,IAAI;QAC/C,KAAK,MAAM,eAAe,yBAA0B;YAClD,IAAI,CAAC,sBAAsB,GAAG,CAAC,cAAc;gBAC3C,mBAAmB,GAAG,CAAC;YACzB;QACF;QAEA,KAAK,MAAM,qBAAqB,mBAAoB;YAClD,MAAM,UAAU,cAAc,QAAQ;YAEtC,sBAAsB,GAAG,CAAC,mBAAmB;YAE7C,qBAAqB,IAAI,CAAC;QAC5B;QAEA,UAAU,QAAQ,GAAG,CAAC;IACxB,OAAO;QACL,UAAU,cAAc,QAAQ,UAAU,IAAI;QAE9C,wFAAwF;QACxF,KAAK,MAAM,uBAAuB,yBAA0B;YAC1D,IAAI,CAAC,sBAAsB,GAAG,CAAC,sBAAsB;gBACnD,sBAAsB,GAAG,CAAC,qBAAqB;YACjD;QACF;IACF;IAEA,KAAK,MAAM,YAAY,aAAc;QACnC,IAAI,CAAC,iBAAiB,GAAG,CAAC,WAAW;YACnC,qIAAqI;YACrI,yGAAyG;YACzG,iBAAiB,GAAG,CAAC,UAAU;QACjC;IACF;IAEA,OAAO;AACT;AAEA,eAAe,cACb,MAAkB,EAClB,SAAoB;IAEpB,IAAI;QACF,MAAM,QAAQ,SAAS,CAAC,WAAW;IACrC,EAAE,OAAO,OAAO;QACd,IAAI;QACJ,OAAQ,OAAO,IAAI;YACjB;gBACE,aAAa,CAAC,iCAAiC,EAAE,OAAO,SAAS,CAAC,CAAC;gBACnE;YACF;gBACE,aAAa,CAAC,YAAY,EAAE,OAAO,QAAQ,CAAC,CAAC;gBAC7C;YACF;gBACE,aAAa;gBACb;QACJ;QACA,MAAM,IAAI,MACR,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAAE,WAAW,EAC9C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,GACxB,CAAC,EACF,QACI;YACE,OAAO;QACT,IACA;IAER;AACF;AAEA;;CAEC,GACD,SAAS,4BACP,QAAuC;IAEvC,OAAO,SAAS,sBAAsB,QAAgB;QACpD,MAAM,WAAW,SAAS;QAC1B,OAAO,UAAU,WAAW;IAC9B;AACF;AAEA,SAAS,kBAAkB,EAAY,EAAE,MAAkB;IACzD,MAAM,gBAAgB,eAAe,CAAC,GAAG;IACzC,IAAI,OAAO,kBAAkB,YAAY;QACvC,sEAAsE;QACtE,0EAA0E;QAC1E,mDAAmD;QACnD,IAAI;QACJ,OAAQ,OAAO,IAAI;YACjB;gBACE,sBAAsB,CAAC,4BAA4B,EAAE,OAAO,SAAS,CAAC,CAAC;gBACvE;YACF;gBACE,sBAAsB,CAAC,oCAAoC,EAAE,OAAO,QAAQ,CAAC,CAAC;gBAC9E;YACF;gBACE,sBAAsB;gBACtB;QACJ;QACA,MAAM,IAAI,MACR,CAAC,OAAO,EAAE,GAAG,kBAAkB,EAAE,oBAAoB,uFAAuF,CAAC;IAEjJ;IAEA,MAAM,UAAU,cAAc,GAAG,CAAC;IAClC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,gBAAgB,IAAI;IAE9C,IAAI;IACJ,OAAQ,OAAO,IAAI;QACjB;YACE,eAAe,GAAG,CAAC;YACnB,UAAU,EAAE;YACZ;QACF;YACE,wEAAwE;YACxE,wEAAwE;YACxE,UAAU;gBAAC,OAAO,QAAQ;aAAC;YAC3B;QACF;YACE,UAAU,OAAO,OAAO,IAAI,EAAE;YAC9B;IACJ;IACA,MAAM,SAAiB;QACrB,SAAS,CAAC;QACV,OAAO;QACP,QAAQ;QACR;QACA;QACA,UAAU,EAAE;QACZ,iBAAiB;QACjB;IACF;IAEA,WAAW,CAAC,GAAG,GAAG;IAClB,eAAe,GAAG,CAAC,QAAQ;IAE3B,4EAA4E;IAC5E,IAAI;QACF,MAAM,aAAyB;YAAE,IAAI;YAAqB,UAAU;QAAG;QAEvE,wBAAwB,QAAQ,CAAC;YAC/B,MAAM,IAAI,gBAAgB,IAAI,CAAC,MAAM;YACrC,cAAc,IAAI,CAChB,OAAO,OAAO,EACd,eAAe;gBACb,GAAG,YAAY,IAAI,CAAC,MAAM;gBAC1B,GAAG,OAAO,OAAO;gBACjB,GAAG,gBAAgB,IAAI,CAAC,MAAM;gBAC9B,GAAG;gBACH,GAAG;gBACH,GAAG,UAAU,IAAI,CAAC,MAAM;gBACxB,GAAG,UAAU,IAAI,CAAC,MAAM,QAAQ,OAAO,OAAO;gBAC9C,GAAG,cAAc,IAAI,CAAC,MAAM,QAAQ,OAAO,OAAO;gBAClD,GAAG,YAAY,IAAI,CAAC,MAAM;gBAC1B,GAAG,gBAAgB,IAAI,CAAC,MAAM;gBAC9B,GAAG;gBACH,GAAG;gBACH,GAAG;gBACH,GAAG,UAAU,IAAI,CAAC,MAAM;gBACxB,GAAG,gBAAgB,IAAI,CAAC,MAAM;gBAC9B,GAAG,sBAAsB,IAAI,CAAC,MAAM;gBACpC,GAAG;gBACH,GAAG;gBACH,GAAG;gBACH,GAAG;gBACH,GAAG,4BAA4B;gBAC/B,WAAW,OAAO,EAAE,CAAC,OAAO,CAAC,cAAc;YAC7C;QAEJ;IACF,EAAE,OAAO,OAAO;QACd,OAAO,KAAK,GAAG;QACf,MAAM;IACR;IAEA,OAAO,MAAM,GAAG;IAChB,IAAI,OAAO,eAAe,IAAI,OAAO,OAAO,KAAK,OAAO,eAAe,EAAE;QACvE,yDAAyD;QACzD,WAAW,OAAO,OAAO,EAAE,OAAO,eAAe;IACnD;IAEA,OAAO;AACT;AAEA;;;CAGC,GACD,SAAS,oBAAoB,UAAmB;IAC9C,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,CAAC;AACpC;AAEA;;;;CAIC,GACD,SAAS,wBACP,MAAc,EACd,aAA4C;IAE5C,MAAM,+BACJ,OAAO,WAAW,iCAAiC,KAAK,aACpD,WAAW,iCAAiC,CAAC,OAAO,EAAE,IACtD,KAAO;IAEb,IAAI;QACF,cAAc;YACZ,UAAU,WAAW,YAAY;YACjC,WAAW,WAAW,YAAY;YAClC,iBAAiB;QACnB;IACF,EAAE,OAAO,GAAG;QACV,MAAM;IACR,SAAU;QACR,iEAAiE;QACjE;IACF;AACF;AAEA;;CAEC,GACD,MAAM,mCAAqE,CACzE,IACA;IAEA,IAAI,CAAC,aAAa,GAAG,CAAC,MAAM,EAAE;QAC5B,QAAQ,IAAI,CACV,CAAC,4BAA4B,EAAE,GAAG,aAAa,EAAE,aAAa,EAAE,CAAC,oCAAoC,CAAC;IAE1G;IAEA,MAAM,SAAS,WAAW,CAAC,GAAG;IAE9B,IAAI,aAAa,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG;QAC5C,aAAa,QAAQ,CAAC,IAAI,CAAC;IAC7B;IAEA,IAAI,QAAQ;QACV,IAAI,OAAO,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG;YAClD,OAAO,OAAO,CAAC,IAAI,CAAC,aAAa,EAAE;QACrC;QAEA,OAAO;IACT;IAEA,OAAO,kBAAkB,IAAI;QAC3B,IAAI;QACJ,UAAU,aAAa,EAAE;IAC3B;AACF;AAEA;;CAEC,GACD,SAAS,+CACP,MAAc,EACd,OAAuB;IAEvB,MAAM,iBAAiB,OAAO,OAAO;IACrC,MAAM,cAAc,OAAO,GAAG,CAAC,IAAI,CAAC,WAAW,IAAI;IAEnD,QAAQ,8BAA8B,CAAC,gBAAgB,OAAO,EAAE;IAEhE,yEAAyE;IACzE,4BAA4B;IAC5B,IAAI,QAAQ,sBAAsB,CAAC,iBAAiB;QAClD,sEAAsE;QACtE,cAAc;QACd,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;YAClB,KAAK,WAAW,GAAG;QACrB;QACA,uEAAuE;QACvE,kCAAkC;QAClC,OAAO,GAAG,CAAC,MAAM;QAEjB,mEAAmE;QACnE,yEAAyE;QACzE,qBAAqB;QACrB,IAAI,gBAAgB,MAAM;YACxB,mEAAmE;YACnE,6BAA6B;YAC7B,EAAE;YACF,+DAA+D;YAC/D,kEAAkE;YAClE,8DAA8D;YAC9D,gDAAgD;YAChD,IACE,QAAQ,oCAAoC,CAC1C,QAAQ,2BAA2B,CAAC,cACpC,QAAQ,2BAA2B,CAAC,kBAEtC;gBACA,OAAO,GAAG,CAAC,UAAU;YACvB,OAAO;gBACL,QAAQ,cAAc;YACxB;QACF;IACF,OAAO;QACL,yEAAyE;QACzE,uDAAuD;QACvD,oEAAoE;QACpE,oEAAoE;QACpE,MAAM,sBAAsB,gBAAgB;QAC5C,IAAI,qBAAqB;YACvB,OAAO,GAAG,CAAC,UAAU;QACvB;IACF;AACF;AAEA,SAAS,sBAAsB,eAA2B;IACxD,OAAO,CAAC,kBAAkB,EAAE,gBAAgB,IAAI,CAAC,QAAQ,CAAC;AAC5D;AAEA,SAAS,uBACP,KAAuD,EACvD,QAA8C;IAK9C,MAAM,qBAAqB,IAAI;IAE/B,KAAK,MAAM,CAAC,UAAU,MAAM,IAAI,MAAO;QACrC,IAAI,SAAS,MAAM;YACjB,mBAAmB,GAAG,CAAC,UAAU,MAAM;QACzC;IACF;IAEA,MAAM,kBAAkB,2BAA2B,SAAS,IAAI;IAEhE,KAAK,MAAM,CAAC,UAAU,MAAM,IAAI,SAAU;QACxC,mBAAmB,GAAG,CAAC,UAAU,MAAM;IACzC;IAEA,OAAO;QAAE;QAAiB;IAAmB;AAC/C;AAEA,SAAS,2BACP,WAA+B;IAE/B,MAAM,kBAAkB,IAAI;IAE5B,KAAK,MAAM,YAAY,YAAa;QAClC,MAAM,SAAS,yBAAyB;QAExC,OAAQ,OAAO,IAAI;YACjB,KAAK;gBACH,MAAM,IAAI,iBACR,CAAC,wCAAwC,EAAE,sBACzC,OAAO,eAAe,EACtB,CAAC,CAAC,EACJ,OAAO,eAAe;YAE1B,KAAK;gBACH,MAAM,IAAI,iBACR,CAAC,2CAA2C,EAAE,sBAC5C,OAAO,eAAe,EACtB,CAAC,CAAC,EACJ,OAAO,eAAe;YAE1B,KAAK;gBACH,KAAK,MAAM,oBAAoB,OAAO,eAAe,CAAE;oBACrD,gBAAgB,GAAG,CAAC;gBACtB;gBACA;QAEJ;IACF;IAEA,OAAO;AACT;AAEA,SAAS,mCACP,eAAmC;IAEnC,MAAM,8BAA8B,EAAE;IACtC,KAAK,MAAM,YAAY,gBAAiB;QACtC,MAAM,SAAS,WAAW,CAAC,SAAS;QACpC,MAAM,WAAW,eAAe,GAAG,CAAC;QACpC,IAAI,UAAU,SAAS,YAAY,IAAI,CAAC,SAAS,eAAe,EAAE;YAChE,4BAA4B,IAAI,CAAC;gBAC/B;gBACA,cAAc,SAAS,YAAY;YACrC;QACF;IACF;IACA,OAAO;AACT;AAEA;;;;CAIC,GACD,SAAS,kBACP,kBAAiD,EACjD,oBAAmD;IAEnD,KAAK,MAAM,CAAC,WAAW,eAAe,IAAI,mBAAoB;QAC5D,KAAK,MAAM,YAAY,eAAgB;YACrC,iBAAiB,UAAU;QAC7B;IACF;IAEA,MAAM,kBAAiC,IAAI;IAC3C,KAAK,MAAM,CAAC,WAAW,eAAe,IAAI,qBAAsB;QAC9D,KAAK,MAAM,YAAY,eAAgB;YACrC,IAAI,sBAAsB,UAAU,YAAY;gBAC9C,gBAAgB,GAAG,CAAC;YACtB;QACF;IACF;IAEA,OAAO;QAAE;IAAgB;AAC3B;AAEA,SAAS,aACP,eAAmC,EACnC,eAAmC;IAEnC,KAAK,MAAM,YAAY,gBAAiB;QACtC,cAAc,UAAU;IAC1B;IAEA,KAAK,MAAM,YAAY,gBAAiB;QACtC,cAAc,UAAU;IAC1B;IAEA,6DAA6D;IAC7D,0EAA0E;IAC1E,MAAM,wBAAwB,IAAI;IAClC,KAAK,MAAM,YAAY,gBAAiB;QACtC,MAAM,YAAY,WAAW,CAAC,SAAS;QACvC,sBAAsB,GAAG,CAAC,UAAU,WAAW;QAC/C,OAAO,WAAW,CAAC,SAAS;IAC9B;IAEA,uEAAuE;IACvE,YAAY;IAEZ,OAAO;QAAE;IAAsB;AACjC;AAEA;;;;;;;;;;;;CAYC,GACD,SAAS,cAAc,QAAkB,EAAE,IAAyB;IAClE,MAAM,SAAS,WAAW,CAAC,SAAS;IACpC,IAAI,CAAC,QAAQ;QACX;IACF;IAEA,MAAM,WAAW,eAAe,GAAG,CAAC;IACpC,MAAM,OAAO,CAAC;IAEd,mEAAmE;IACnE,qBAAqB;IACrB,KAAK,MAAM,kBAAkB,SAAS,eAAe,CAAE;QACrD,eAAe;IACjB;IAEA,0EAA0E;IAC1E,2CAA2C;IAC3C,OAAO,GAAG,CAAC,MAAM,GAAG;IAEpB,eAAe,MAAM,CAAC;IAEtB,sEAAsE;IAEtE,8DAA8D;IAC9D,wEAAwE;IACxE,kBAAkB;IAClB,KAAK,MAAM,WAAW,OAAO,QAAQ,CAAE;QACrC,MAAM,QAAQ,WAAW,CAAC,QAAQ;QAClC,IAAI,CAAC,OAAO;YACV;QACF;QAEA,MAAM,MAAM,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE;QAC3C,IAAI,OAAO,GAAG;YACZ,MAAM,OAAO,CAAC,MAAM,CAAC,KAAK;QAC5B;IACF;IAEA,OAAQ;QACN,KAAK;YACH,OAAO,WAAW,CAAC,OAAO,EAAE,CAAC;YAC7B,cAAc,MAAM,CAAC,OAAO,EAAE;YAC9B;QACF,KAAK;YACH,cAAc,GAAG,CAAC,OAAO,EAAE,EAAE;YAC7B;QACF;YACE,UAAU,MAAM,CAAC,OAAS,CAAC,cAAc,EAAE,KAAK,CAAC;IACrD;AACF;AAEA,SAAS,WACP,2BAGG,EACH,kBAAgD,EAChD,qBAAqD,EACrD,WAA+B;IAE/B,2BAA2B;IAC3B,KAAK,MAAM,CAAC,UAAU,QAAQ,IAAI,mBAAmB,OAAO,GAAI;QAC9D,eAAe,CAAC,SAAS,GAAG;IAC9B;IAEA,gDAAgD;IAEhD,wEAAwE;IAExE,qDAAqD;IACrD,KAAK,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,4BAA6B;QACpE,IAAI;YACF,kBAAkB,UAAU;gBAC1B,IAAI;gBACJ,SAAS,sBAAsB,GAAG,CAAC;YACrC;QACF,EAAE,OAAO,KAAK;YACZ,IAAI,OAAO,iBAAiB,YAAY;gBACtC,IAAI;oBACF,aAAa,KAAK;wBAAE;wBAAU,QAAQ,WAAW,CAAC,SAAS;oBAAC;gBAC9D,EAAE,OAAO,MAAM;oBACb,YAAY;oBACZ,YAAY;gBACd;YACF,OAAO;gBACL,YAAY;YACd;QACF;IACF;AACF;AAEA;;CAEC,GACD,SAAS,UAAU,KAAY,EAAE,cAAoC;IACnE,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,eAAe,OAAO,CAAC;AACvD;AAEA,SAAS,YAAY,MAAqB;IACxC,OAAQ,OAAO,IAAI;QACjB,KAAK;YACH,qBAAqB;YACrB;QACF;YACE,UAAU,QAAQ,CAAC,SAAW,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,CAAC;IACvE;AACF;AAEA,SAAS,qBAAqB,MAAuB;IACnD,IAAI,OAAO,MAAM,IAAI,MAAM;QACzB,KAAK,MAAM,UAAU,OAAO,MAAM,CAAE;YAClC,OAAQ,OAAO,IAAI;gBACjB,KAAK;oBACH,4BAA4B;oBAC5B;gBACF;oBACE,UAAU,QAAQ,CAAC,SAAW,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,CAAC;YACvE;QACF;IACF;IAEA,IAAI,OAAO,MAAM,IAAI,MAAM;QACzB,KAAK,MAAM,CAAC,WAAW,YAAY,IAAI,OAAO,OAAO,CAAC,OAAO,MAAM,EAAG;YACpE,OAAQ,YAAY,IAAI;gBACtB,KAAK;oBACH,QAAQ,SAAS,CAAC,WAAW;wBAAE,IAAI;oBAAoB;oBACvD;gBACF,KAAK;oBACH,QAAQ,WAAW,GAAG;oBACtB;gBACF,KAAK;oBACH,QAAQ,WAAW,GAAG;oBACtB;gBACF,KAAK;oBACH,UACE,YAAY,WAAW,EACvB,CAAC,cACC,CAAC,6BAA6B,EAAE,KAAK,SAAS,CAAC,aAAa,CAAC,CAAC;gBAEpE;oBACE,UACE,aACA,CAAC,cAAgB,CAAC,2BAA2B,EAAE,YAAY,IAAI,CAAC,CAAC;YAEvE;QACF;IACF;AACF;AAEA,SAAS,4BAA4B,MAA8B;IACjE,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG;IACtC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,sBACtD,SACA;IAEF,MAAM,EAAE,eAAe,EAAE,kBAAkB,EAAE,GAAG,uBAC9C,OACA;IAEF,MAAM,EAAE,eAAe,EAAE,GAAG,kBAAkB,aAAa;IAE3D,cAAc,iBAAiB,iBAAiB;AAClD;AAEA,SAAS,wBAAwB,eAA8B;IAC7D,IAAI,yBAAyB,IAAI,GAAG,GAAG;QACrC,2BAA2B,0BAA0B,OAAO,CAAC,CAAC;YAC5D,gBAAgB,GAAG,CAAC;QACtB;QAEA,yBAAyB,KAAK;IAChC;IAEA,OAAO;AACT;AAEA,SAAS,cACP,eAA8B,EAC9B,eAAmC,EACnC,kBAAgD;IAEhD,kBAAkB,wBAAwB;IAE1C,MAAM,8BACJ,mCAAmC;IAErC,MAAM,EAAE,qBAAqB,EAAE,GAAG,aAChC,iBACA;IAGF,4FAA4F;IAC5F,IAAI;IAEJ,SAAS,YAAY,GAAQ;QAC3B,IAAI,CAAC,OAAO,QAAQ;IACtB;IAEA,WACE,6BACA,oBACA,uBACA;IAGF,IAAI,OAAO;QACT,MAAM;IACR;IAEA,IAAI,yBAAyB,IAAI,GAAG,GAAG;QACrC,cAAc,IAAI,OAAO,EAAE,EAAE,IAAI;IACnC;AACF;AAEA,SAAS,sBACP,OAAgD,EAChD,OAAuD;IAQvD,MAAM,cAAc,IAAI;IACxB,MAAM,gBAAgB,IAAI;IAC1B,MAAM,QAA8C,IAAI;IACxD,MAAM,WAAW,IAAI;IACrB,MAAM,UAAyB,IAAI;IAEnC,KAAK,MAAM,CAAC,WAAW,kBAAkB,IAAI,OAAO,OAAO,CAAC,SAAU;QACpE,OAAQ,kBAAkB,IAAI;YAC5B,KAAK;gBAAS;oBACZ,MAAM,cAAc,IAAI,IAAI,kBAAkB,OAAO;oBACrD,KAAK,MAAM,YAAY,YAAa;wBAClC,MAAM,GAAG,CAAC,UAAU,OAAO,CAAC,SAAS;oBACvC;oBACA,YAAY,GAAG,CAAC,WAAW;oBAC3B;gBACF;YACA,KAAK;gBAAW;oBACd,sDAAsD;oBACtD,MAAM,gBAAgB,IAAI,IAAI,gBAAgB,GAAG,CAAC;oBAClD,KAAK,MAAM,YAAY,cAAe;wBACpC,QAAQ,GAAG,CAAC;oBACd;oBACA,cAAc,GAAG,CAAC,WAAW;oBAC7B;gBACF;YACA,KAAK;gBAAW;oBACd,MAAM,cAAc,IAAI,IAAI,kBAAkB,KAAK;oBACnD,MAAM,gBAAgB,IAAI,IAAI,kBAAkB,OAAO;oBACvD,KAAK,MAAM,YAAY,YAAa;wBAClC,MAAM,GAAG,CAAC,UAAU,OAAO,CAAC,SAAS;oBACvC;oBACA,KAAK,MAAM,YAAY,cAAe;wBACpC,QAAQ,GAAG,CAAC;oBACd;oBACA,YAAY,GAAG,CAAC,WAAW;oBAC3B,cAAc,GAAG,CAAC,WAAW;oBAC7B;gBACF;YACA;gBACE,UACE,mBACA,CAAC,oBACC,CAAC,kCAAkC,EAAE,kBAAkB,IAAI,CAAC,CAAC;QAErE;IACF;IAEA,oFAAoF;IACpF,yFAAyF;IACzF,uCAAuC;IACvC,KAAK,MAAM,YAAY,MAAM,IAAI,GAAI;QACnC,IAAI,QAAQ,GAAG,CAAC,WAAW;YACzB,MAAM,MAAM,CAAC;YACb,QAAQ,MAAM,CAAC;QACjB;IACF;IAEA,KAAK,MAAM,CAAC,UAAU,MAAM,IAAI,OAAO,OAAO,CAAC,SAAU;QACvD,gFAAgF;QAChF,kBAAkB;QAClB,gFAAgF;QAChF,kDAAkD;QAClD,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW;YACxB,SAAS,GAAG,CAAC,UAAU;QACzB;IACF;IAEA,OAAO;QAAE;QAAO;QAAS;QAAU;QAAa;IAAc;AAChE;AAkBA,SAAS,yBAAyB,QAAkB;IAClD,MAAM,kBAAiC,IAAI;IAI3C,MAAM,QAAqB;QACzB;YACE;YACA,iBAAiB,EAAE;QACrB;KACD;IAED,IAAI;IACJ,MAAQ,WAAW,MAAM,KAAK,GAAK;QACjC,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG;QAEtC,IAAI,YAAY,MAAM;YACpB,IAAI,gBAAgB,GAAG,CAAC,WAAW;gBAEjC;YACF;YAEA,gBAAgB,GAAG,CAAC;QACtB;QAEA,sEAAsE;QACtE,qCAAqC;QACrC,IAAI,aAAa,WAAW;YAC1B,OAAO;gBACL,MAAM;gBACN;YACF;QACF;QAEA,MAAM,SAAS,WAAW,CAAC,SAAS;QACpC,MAAM,WAAW,eAAe,GAAG,CAAC;QAEpC,IACE,qEAAqE;QACrE,0DAA0D;QAC1D,CAAC,UAEA,SAAS,YAAY,IAAI,CAAC,SAAS,eAAe,EACnD;YACA;QACF;QAEA,IAAI,SAAS,YAAY,EAAE;YACzB,OAAO;gBACL,MAAM;gBACN;gBACA;YACF;QACF;QAEA,IAAI,eAAe,GAAG,CAAC,WAAW;YAChC,MAAM,IAAI,CAAC;gBACT,UAAU;gBACV,iBAAiB;uBAAI;oBAAiB;iBAAS;YACjD;YACA;QACF;QAEA,KAAK,MAAM,YAAY,OAAO,OAAO,CAAE;YACrC,MAAM,SAAS,WAAW,CAAC,SAAS;YAEpC,IAAI,CAAC,QAAQ;gBAEX;YACF;YAEA,4DAA4D;YAC5D,qBAAqB;YAErB,MAAM,IAAI,CAAC;gBACT,UAAU;gBACV,iBAAiB;uBAAI;oBAAiB;iBAAS;YACjD;QACF;IACF;IAEA,OAAO;QACL,MAAM;QACN;QACA;IACF;AACF;AAEA,SAAS,YAAY,aAAwB,EAAE,MAAqB;IAClE,OAAQ,OAAO,IAAI;QACjB,KAAK;YAAW;gBACd,4FAA4F;gBAC5F,YAAY,OAAO,WAAW;gBAC9B;YACF;QACA,KAAK;YAAW;gBACd,iEAAiE;gBACjE,qEAAqE;gBACrE,aAAa;gBACb,QAAQ,OAAO;gBACf;YACF;QACA,KAAK;YAAY;gBACf,+GAA+G;gBAC/G,kCAAkC;gBAClC,mGAAmG;gBACnG,6DAA6D;gBAC7D,IAAI,kBAAkB,GAAG,CAAC,gBAAgB;oBACxC,QAAQ,OAAO;gBACjB,OAAO;oBACL,iBAAiB;gBACnB;gBACA;YACF;QACA;YACE,MAAM,IAAI,MAAM,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,CAAC;IACzD;AACF;AAEA,SAAS,gBACP,QAAkB,EAClB,OAAgB;IAEhB,MAAM,WAAqB;QACzB,cAAc;QACd,cAAc;QACd,iBAAiB;QACjB,iBAAiB,EAAE;IACrB;IAEA,MAAM,MAAW;QACf,qEAAqE;QACrE,wEAAwE;QACxE,uCAAuC;QACvC,QAAQ;QAER,MAAM,WAAW,CAAC;QAElB,mEAAmE;QACnE,QAAQ,CACN,SACA,WACA;YAEA,IAAI,YAAY,WAAW;gBACzB,SAAS,YAAY,GAAG;YAC1B,OAAO,IAAI,OAAO,YAAY,YAAY;gBACxC,SAAS,YAAY,GAAG;YAC1B,OAAO;gBACL,MAAM,IAAI,MAAM;YAClB;QACF;QAEA,SAAS,CAAC;YACR,IAAI,QAAQ,WAAW;gBACrB,SAAS,YAAY,GAAG;YAC1B,OAAO;gBACL,MAAM,IAAI,MAAM;YAClB;QACF;QAEA,SAAS,CAAC;YACR,SAAS,eAAe,CAAC,IAAI,CAAC;QAChC;QAEA,mBAAmB,CAAC;YAClB,SAAS,eAAe,CAAC,IAAI,CAAC;QAChC;QAEA,sBAAsB,CAAC;YACrB,MAAM,MAAM,SAAS,eAAe,CAAC,OAAO,CAAC;YAC7C,IAAI,OAAO,GAAG;gBACZ,SAAS,eAAe,CAAC,MAAM,CAAC,KAAK;YACvC;QACF;QAEA,YAAY;YACV,SAAS,eAAe,GAAG;YAC3B,yBAAyB,GAAG,CAAC;QAC/B;QAEA,qEAAqE;QACrE,uEAAuE;QACvE,iCAAiC;QACjC,QAAQ,IAAM;QAEd,2EAA2E;QAC3E,kBAAkB,CAAC,YAAc;QACjC,qBAAqB,CAAC,YAAc;QAEpC,2EAA2E;QAC3E,yEAAyE;QACzE,iBAAiB;QACjB,OAAO,IAAM,QAAQ,OAAO,CAAC;IAC/B;IAEA,OAAO;QAAE;QAAK;IAAS;AACzB;AAEA;;CAEC,GACD,SAAS,iBAAiB,QAAkB,EAAE,SAAoB;IAChE,IAAI,eAAe,gBAAgB,GAAG,CAAC;IACvC,IAAI,CAAC,cAAc;QACjB,eAAe,IAAI,IAAI;YAAC;SAAU;QAClC,gBAAgB,GAAG,CAAC,UAAU;IAChC,OAAO;QACL,aAAa,GAAG,CAAC;IACnB;IAEA,IAAI,eAAe,gBAAgB,GAAG,CAAC;IACvC,IAAI,CAAC,cAAc;QACjB,eAAe,IAAI,IAAI;YAAC;SAAS;QACjC,gBAAgB,GAAG,CAAC,WAAW;IACjC,OAAO;QACL,aAAa,GAAG,CAAC;IACnB;AACF;AAEA;;;;CAIC,GACD,SAAS,oBAAoB,QAAkB;IAC7C,MAAM,mBAAmB,gBAAgB,GAAG,CAAC;IAC7C,IAAI,oBAAoB,MAAM;QAC5B,OAAO;IACT;IAEA,OAAO,iBAAiB,MAAM,GAAG,IAAI,GAAG,KAAK;AAC/C;AAEA;;;CAGC,GACD,SAAS,sBACP,QAAkB,EAClB,SAAoB;IAEpB,MAAM,eAAe,gBAAgB,GAAG,CAAC;IACzC,aAAa,MAAM,CAAC;IAEpB,MAAM,eAAe,gBAAgB,GAAG,CAAC;IACzC,aAAa,MAAM,CAAC;IAEpB,MAAM,qBAAqB,aAAa,IAAI,KAAK;IACjD,IAAI,oBAAoB;QACtB,gBAAgB,MAAM,CAAC;IACzB;IAEA,MAAM,oBAAoB,aAAa,IAAI,KAAK;IAChD,IAAI,mBAAmB;QACrB,gBAAgB,MAAM,CAAC;IACzB;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,iBAAiB,aAAwB;IAChD,MAAM,aAAa,mBAAmB,GAAG,CAAC;IAC1C,IAAI,cAAc,MAAM;QACtB,OAAO;IACT;IACA,mBAAmB,MAAM,CAAC;IAE1B,KAAK,MAAM,aAAa,WAAY;QAClC,MAAM,kBAAkB,mBAAmB,GAAG,CAAC;QAC/C,gBAAgB,MAAM,CAAC;QAEvB,IAAI,gBAAgB,IAAI,KAAK,GAAG;YAC9B,mBAAmB,MAAM,CAAC;YAC1B,aAAa;QACf;IACF;IAEA,yEAAyE;IACzE,sCAAsC;IACtC,QAAQ,WAAW,GAAG;IAEtB,OAAO;AACT;AAEA;;;;CAIC,GACD,SAAS,aAAa,SAAoB;IACxC,qEAAqE;IACrE,wFAAwF;IACxF,QAAQ,WAAW,GAAG;IAEtB,MAAM,eAAe,gBAAgB,GAAG,CAAC;IACzC,IAAI,gBAAgB,MAAM;QACxB,OAAO;IACT;IACA,aAAa,MAAM,CAAC;IAEpB,KAAK,MAAM,YAAY,aAAc;QACnC,MAAM,eAAe,gBAAgB,GAAG,CAAC;QACzC,aAAa,MAAM,CAAC;QAEpB,MAAM,oBAAoB,aAAa,IAAI,KAAK;QAChD,IAAI,mBAAmB;YACrB,gBAAgB,MAAM,CAAC;YACvB,cAAc,UAAU;YACxB,iBAAiB,MAAM,CAAC;QAC1B;IACF;IAEA,OAAO;AACT;AAEA;;CAEC,GACD,SAAS,yBACP,QAAkB,EAClB,SAAoB;IAEpB,OAAO,kBAAkB,UAAU;QAAE,IAAI;QAAsB;IAAU;AAC3E;AAEA;;CAEC,GACD,SAAS,8BACP,QAAkB,EAClB,SAAoB;IAEpB,MAAM,SAAS,WAAW,CAAC,SAAS;IACpC,IAAI,QAAQ;QACV,IAAI,OAAO,KAAK,EAAE;YAChB,MAAM,OAAO,KAAK;QACpB;QACA,OAAO;IACT;IAEA,OAAO,kBAAkB,UAAU;QAAE,IAAI;QAAsB;IAAU;AAC3E;AAEA;;CAEC,GACD,SAAS,oBAAoB,SAAoB;IAC/C,OAAO,CAAC,EAAE,gBAAgB,EAAE,UACzB,KAAK,CAAC,KACN,GAAG,CAAC,CAAC,IAAM,mBAAmB,IAC9B,IAAI,CAAC,KAAK,CAAC;AAChB;AAEA;;CAEC,GACD,SAAS,kBACP,mBAAwC,EACxC,SAAoB;IAEpB,oBAAoB,IAAI,CAAC;QACvB,UAAU,IAAI;QACd,YAAY,IAAI,CAAC,MAAM,UAAU,IAAI;KACtC;IAED,+CAA+C;IAC/C,MAAM,SAAS,IAAI,IAAI,UAAU,MAAM,CAAC,GAAG,CAAC;IAC5C,mBAAmB,GAAG,CAAC,UAAU,IAAI,EAAE;IACvC,KAAK,MAAM,aAAa,OAAQ;QAC9B,IAAI,kBAAkB,mBAAmB,GAAG,CAAC;QAC7C,IAAI,CAAC,iBAAiB;YACpB,kBAAkB,IAAI,IAAI;gBAAC,UAAU,IAAI;aAAC;YAC1C,mBAAmB,GAAG,CAAC,WAAW;QACpC,OAAO;YACL,gBAAgB,GAAG,CAAC,UAAU,IAAI;QACpC;IACF;IAEA,IAAI,UAAU,MAAM,KAAK,SAAS;QAChC,uBAAuB,UAAU,IAAI;IACvC;AACF;AAEA;;;;CAIC,GACD,SAAS,uBAAuB,aAAwB;IACtD,kBAAkB,GAAG,CAAC;AACxB;AAEA,SAAS,cAAc,CACrB,WACA,cACA,cACkB;IAClB,KAAK,MAAM,CAAC,UAAU,cAAc,IAAI,OAAO,OAAO,CAAC,cAAe;QACpE,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE;YAC9B,eAAe,CAAC,SAAS,GAAG;QAC9B;QACA,iBAAiB,UAAU;IAC7B;IAEA,OAAO,QAAQ,aAAa,CAAC,WAAW;AAC1C;AAEA,WAAW,gCAAgC,KAAK,EAAE;AAElD,MAAM,uBAAuB,WAAW,qBAAqB;AAC7D,IAAI,MAAM,OAAO,CAAC,uBAAuB;IACvC,KAAK,MAAM,aAAa,qBAAsB;QAC5C,kBAAkB,WAAW,gCAAgC,EAAE;IACjE;AACF;AAEA,WAAW,qBAAqB,GAAG;IACjC,MAAM,CAAC;QACL,kBAAkB,WAAW,gCAAgC,EAAG;IAClE;AACF"}}, + {"offset": {"line": 1357, "column": 0}, "map": {"version":3,"sources":["turbopack://[turbopack]/browser/dev/runtime/dom/runtime-backend-dom.ts"],"sourcesContent":["/**\n * This file contains the runtime code specific to the Turbopack development\n * ECMAScript DOM runtime.\n *\n * It will be appended to the base development runtime code.\n */\n\n/// \n/// \n\ntype ChunkResolver = {\n resolved: boolean;\n resolve: () => void;\n reject: (error?: Error) => void;\n promise: Promise;\n};\n\nlet BACKEND: RuntimeBackend;\n\nfunction augmentContext(context: TurbopackDevBaseContext): TurbopackDevContext {\n return context;\n}\n\nfunction fetchWebAssembly(wasmChunkPath: ChunkPath) {\n return fetch(getChunkRelativeUrl(wasmChunkPath));\n}\n\nasync function loadWebAssembly(\n _source: SourceInfo,\n wasmChunkPath: ChunkPath,\n importsObj: WebAssembly.Imports\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath);\n\n const { instance } = await WebAssembly.instantiateStreaming(req, importsObj);\n\n return instance.exports;\n}\n\nasync function loadWebAssemblyModule(\n _source: SourceInfo,\n wasmChunkPath: ChunkPath\n): Promise {\n const req = fetchWebAssembly(wasmChunkPath);\n\n return await WebAssembly.compileStreaming(req);\n}\n\n(() => {\n BACKEND = {\n async registerChunk(chunkPath, params) {\n const resolver = getOrCreateResolver(chunkPath);\n resolver.resolve();\n\n if (params == null) {\n return;\n }\n\n for (const otherChunkData of params.otherChunks) {\n const otherChunkPath = getChunkPath(otherChunkData);\n // Chunk might have started loading, so we want to avoid triggering another load.\n getOrCreateResolver(otherChunkPath);\n }\n\n // This waits for chunks to be loaded, but also marks included items as available.\n await Promise.all(\n params.otherChunks.map((otherChunkData) =>\n loadChunk({ type: SourceType.Runtime, chunkPath }, otherChunkData)\n )\n );\n\n if (params.runtimeModuleIds.length > 0) {\n for (const moduleId of params.runtimeModuleIds) {\n getOrInstantiateRuntimeModule(moduleId, chunkPath);\n }\n }\n },\n\n loadChunk(chunkPath, source) {\n return doLoadChunk(chunkPath, source);\n },\n\n unloadChunk(chunkPath) {\n deleteResolver(chunkPath);\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n // TODO(PACK-2140): remove this once all filenames are guaranteed to be escaped.\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n if (chunkPath.endsWith(\".css\")) {\n const links = document.querySelectorAll(\n `link[href=\"${chunkUrl}\"],link[href^=\"${chunkUrl}?\"],link[href=\"${decodedChunkUrl}\"],link[href^=\"${decodedChunkUrl}?\"]`\n );\n for (const link of Array.from(links)) {\n link.remove();\n }\n } else if (chunkPath.endsWith(\".js\")) {\n // Unloading a JS chunk would have no effect, as it lives in the JS\n // runtime once evaluated.\n // However, we still want to remove the script tag from the DOM to keep\n // the HTML somewhat consistent from the user's perspective.\n const scripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n );\n for (const script of Array.from(scripts)) {\n script.remove();\n }\n } else {\n throw new Error(`can't infer type of chunk from path ${chunkPath}`);\n }\n },\n\n reloadChunk(chunkPath) {\n return new Promise((resolve, reject) => {\n if (!chunkPath.endsWith(\".css\")) {\n reject(new Error(\"The DOM backend can only reload CSS chunks\"));\n return;\n }\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n );\n\n if (previousLinks.length == 0) {\n reject(new Error(`No link element found for chunk ${chunkPath}`));\n return;\n }\n\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n\n if (navigator.userAgent.includes(\"Firefox\")) {\n // Firefox won't reload CSS files that were previously loaded on the current page,\n // we need to add a query param to make sure CSS is actually reloaded from the server.\n //\n // I believe this is this issue: https://bugzilla.mozilla.org/show_bug.cgi?id=1037506\n //\n // Safari has a similar issue, but only if you have a `` tag\n // pointing to the same URL as the stylesheet: https://bugs.webkit.org/show_bug.cgi?id=187726\n link.href = `${chunkUrl}?ts=${Date.now()}`;\n } else {\n link.href = chunkUrl;\n }\n\n link.onerror = () => {\n reject();\n };\n link.onload = () => {\n // First load the new CSS, then remove the old ones. This prevents visible\n // flickering that would happen in-between removing the previous CSS and\n // loading the new one.\n for (const previousLink of Array.from(previousLinks))\n previousLink.remove();\n\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolve();\n };\n\n // Make sure to insert the new CSS right after the previous one, so that\n // its precedence is higher.\n previousLinks[0].parentElement!.insertBefore(\n link,\n previousLinks[0].nextSibling\n );\n });\n },\n\n restart: () => self.location.reload(),\n };\n\n /**\n * Maps chunk paths to the corresponding resolver.\n */\n const chunkResolvers: Map = new Map();\n\n function getOrCreateResolver(chunkPath: ChunkPath): ChunkResolver {\n let resolver = chunkResolvers.get(chunkPath);\n if (!resolver) {\n let resolve: () => void;\n let reject: (error?: Error) => void;\n const promise = new Promise((innerResolve, innerReject) => {\n resolve = innerResolve;\n reject = innerReject;\n });\n resolver = {\n resolved: false,\n promise,\n resolve: () => {\n resolver!.resolved = true;\n resolve();\n },\n reject: reject!,\n };\n chunkResolvers.set(chunkPath, resolver);\n }\n return resolver;\n }\n\n function deleteResolver(chunkPath: ChunkPath) {\n chunkResolvers.delete(chunkPath);\n }\n\n /**\n * Loads the given chunk, and returns a promise that resolves once the chunk\n * has been loaded.\n */\n async function doLoadChunk(chunkPath: ChunkPath, source: SourceInfo) {\n const resolver = getOrCreateResolver(chunkPath);\n if (resolver.resolved) {\n return resolver.promise;\n }\n\n if (source.type === SourceType.Runtime) {\n // We don't need to load chunks references from runtime code, as they're already\n // present in the DOM.\n\n if (chunkPath.endsWith(\".css\")) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n }\n\n // We need to wait for JS chunks to register themselves within `registerChunk`\n // before we can start instantiating runtime modules, hence the absence of\n // `resolver.resolve()` in this branch.\n\n return resolver.promise;\n }\n\n const chunkUrl = getChunkRelativeUrl(chunkPath);\n const decodedChunkUrl = decodeURI(chunkUrl);\n\n if (chunkPath.endsWith(\".css\")) {\n const previousLinks = document.querySelectorAll(\n `link[rel=stylesheet][href=\"${chunkUrl}\"],link[rel=stylesheet][href^=\"${chunkUrl}?\"],link[rel=stylesheet][href=\"${decodedChunkUrl}\"],link[rel=stylesheet][href^=\"${decodedChunkUrl}?\"]`\n );\n if (previousLinks.length > 0) {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n } else {\n const link = document.createElement(\"link\");\n link.rel = \"stylesheet\";\n link.href = chunkUrl;\n link.onerror = () => {\n resolver.reject();\n };\n link.onload = () => {\n // CSS chunks do not register themselves, and as such must be marked as\n // loaded instantly.\n resolver.resolve();\n };\n document.body.appendChild(link);\n }\n } else if (chunkPath.endsWith(\".js\")) {\n const previousScripts = document.querySelectorAll(\n `script[src=\"${chunkUrl}\"],script[src^=\"${chunkUrl}?\"],script[src=\"${decodedChunkUrl}\"],script[src^=\"${decodedChunkUrl}?\"]`\n );\n if (previousScripts.length > 0) {\n // There is this edge where the script already failed loading, but we\n // can't detect that. The Promise will never resolve in this case.\n for (const script of Array.from(previousScripts)) {\n script.addEventListener(\"error\", () => {\n resolver.reject();\n });\n }\n } else {\n const script = document.createElement(\"script\");\n script.src = chunkUrl;\n // We'll only mark the chunk as loaded once the script has been executed,\n // which happens in `registerChunk`. Hence the absence of `resolve()` in\n // this branch.\n script.onerror = () => {\n resolver.reject();\n };\n document.body.appendChild(script);\n }\n } else {\n throw new Error(`can't infer type of chunk from path ${chunkPath}`);\n }\n\n return resolver.promise;\n }\n})();\n\nfunction _eval({ code, url, map }: EcmascriptModuleEntry): ModuleFactory {\n code += `\\n\\n//# sourceURL=${encodeURI(\n location.origin + CHUNK_BASE_PATH + url\n )}`;\n if (map) {\n code += `\\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${btoa(\n // btoa doesn't handle nonlatin characters, so escape them as \\x sequences\n // See https://stackoverflow.com/a/26603875\n unescape(encodeURIComponent(map))\n )}`;\n }\n\n return eval(code);\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAED,gDAAgD;AAChD,6DAA6D;AAS7D,IAAI;AAEJ,SAAS,eAAe,OAAgC;IACtD,OAAO;AACT;AAEA,SAAS,iBAAiB,aAAwB;IAChD,OAAO,MAAM,oBAAoB;AACnC;AAEA,eAAe,gBACb,OAAmB,EACnB,aAAwB,EACxB,UAA+B;IAE/B,MAAM,MAAM,iBAAiB;IAE7B,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,YAAY,oBAAoB,CAAC,KAAK;IAEjE,OAAO,SAAS,OAAO;AACzB;AAEA,eAAe,sBACb,OAAmB,EACnB,aAAwB;IAExB,MAAM,MAAM,iBAAiB;IAE7B,OAAO,MAAM,YAAY,gBAAgB,CAAC;AAC5C;AAEA,CAAC;IACC,UAAU;QACR,MAAM,eAAc,SAAS,EAAE,MAAM;YACnC,MAAM,WAAW,oBAAoB;YACrC,SAAS,OAAO;YAEhB,IAAI,UAAU,MAAM;gBAClB;YACF;YAEA,KAAK,MAAM,kBAAkB,OAAO,WAAW,CAAE;gBAC/C,MAAM,iBAAiB,aAAa;gBACpC,iFAAiF;gBACjF,oBAAoB;YACtB;YAEA,kFAAkF;YAClF,MAAM,QAAQ,GAAG,CACf,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,iBACtB,UAAU;oBAAE,MAAM,WAAW,OAAO;oBAAE;gBAAU,GAAG;YAIvD,IAAI,OAAO,gBAAgB,CAAC,MAAM,GAAG,GAAG;gBACtC,KAAK,MAAM,YAAY,OAAO,gBAAgB,CAAE;oBAC9C,8BAA8B,UAAU;gBAC1C;YACF;QACF;QAEA,WAAU,SAAS,EAAE,MAAM;YACzB,OAAO,YAAY,WAAW;QAChC;QAEA,aAAY,SAAS;YACnB,eAAe;YAEf,MAAM,WAAW,oBAAoB;YACrC,gFAAgF;YAChF,MAAM,kBAAkB,UAAU;YAElC,IAAI,UAAU,QAAQ,CAAC,SAAS;gBAC9B,MAAM,QAAQ,SAAS,gBAAgB,CACrC,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,SAAS,eAAe,EAAE,gBAAgB,eAAe,EAAE,gBAAgB,GAAG,CAAC;gBAEzH,KAAK,MAAM,QAAQ,MAAM,IAAI,CAAC,OAAQ;oBACpC,KAAK,MAAM;gBACb;YACF,OAAO,IAAI,UAAU,QAAQ,CAAC,QAAQ;gBACpC,mEAAmE;gBACnE,0BAA0B;gBAC1B,uEAAuE;gBACvE,4DAA4D;gBAC5D,MAAM,UAAU,SAAS,gBAAgB,CACvC,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,SAAS,gBAAgB,EAAE,gBAAgB,gBAAgB,EAAE,gBAAgB,GAAG,CAAC;gBAE7H,KAAK,MAAM,UAAU,MAAM,IAAI,CAAC,SAAU;oBACxC,OAAO,MAAM;gBACf;YACF,OAAO;gBACL,MAAM,IAAI,MAAM,CAAC,oCAAoC,EAAE,UAAU,CAAC;YACpE;QACF;QAEA,aAAY,SAAS;YACnB,OAAO,IAAI,QAAc,CAAC,SAAS;gBACjC,IAAI,CAAC,UAAU,QAAQ,CAAC,SAAS;oBAC/B,OAAO,IAAI,MAAM;oBACjB;gBACF;gBAEA,MAAM,WAAW,oBAAoB;gBACrC,MAAM,kBAAkB,UAAU;gBAElC,MAAM,gBAAgB,SAAS,gBAAgB,CAC7C,CAAC,2BAA2B,EAAE,SAAS,+BAA+B,EAAE,SAAS,+BAA+B,EAAE,gBAAgB,+BAA+B,EAAE,gBAAgB,GAAG,CAAC;gBAGzL,IAAI,cAAc,MAAM,IAAI,GAAG;oBAC7B,OAAO,IAAI,MAAM,CAAC,gCAAgC,EAAE,UAAU,CAAC;oBAC/D;gBACF;gBAEA,MAAM,OAAO,SAAS,aAAa,CAAC;gBACpC,KAAK,GAAG,GAAG;gBAEX,IAAI,UAAU,SAAS,CAAC,QAAQ,CAAC,YAAY;oBAC3C,kFAAkF;oBAClF,sFAAsF;oBACtF,EAAE;oBACF,qFAAqF;oBACrF,EAAE;oBACF,oFAAoF;oBACpF,6FAA6F;oBAC7F,KAAK,IAAI,GAAG,CAAC,EAAE,SAAS,IAAI,EAAE,KAAK,GAAG,GAAG,CAAC;gBAC5C,OAAO;oBACL,KAAK,IAAI,GAAG;gBACd;gBAEA,KAAK,OAAO,GAAG;oBACb;gBACF;gBACA,KAAK,MAAM,GAAG;oBACZ,0EAA0E;oBAC1E,wEAAwE;oBACxE,uBAAuB;oBACvB,KAAK,MAAM,gBAAgB,MAAM,IAAI,CAAC,eACpC,aAAa,MAAM;oBAErB,uEAAuE;oBACvE,oBAAoB;oBACpB;gBACF;gBAEA,wEAAwE;gBACxE,4BAA4B;gBAC5B,aAAa,CAAC,EAAE,CAAC,aAAa,CAAE,YAAY,CAC1C,MACA,aAAa,CAAC,EAAE,CAAC,WAAW;YAEhC;QACF;QAEA,SAAS,IAAM,KAAK,QAAQ,CAAC,MAAM;IACrC;IAEA;;GAEC,GACD,MAAM,iBAAgD,IAAI;IAE1D,SAAS,oBAAoB,SAAoB;QAC/C,IAAI,WAAW,eAAe,GAAG,CAAC;QAClC,IAAI,CAAC,UAAU;YACb,IAAI;YACJ,IAAI;YACJ,MAAM,UAAU,IAAI,QAAc,CAAC,cAAc;gBAC/C,UAAU;gBACV,SAAS;YACX;YACA,WAAW;gBACT,UAAU;gBACV;gBACA,SAAS;oBACP,SAAU,QAAQ,GAAG;oBACrB;gBACF;gBACA,QAAQ;YACV;YACA,eAAe,GAAG,CAAC,WAAW;QAChC;QACA,OAAO;IACT;IAEA,SAAS,eAAe,SAAoB;QAC1C,eAAe,MAAM,CAAC;IACxB;IAEA;;;GAGC,GACD,eAAe,YAAY,SAAoB,EAAE,MAAkB;QACjE,MAAM,WAAW,oBAAoB;QACrC,IAAI,SAAS,QAAQ,EAAE;YACrB,OAAO,SAAS,OAAO;QACzB;QAEA,IAAI,OAAO,IAAI,KAAK,WAAW,OAAO,EAAE;YACtC,gFAAgF;YAChF,sBAAsB;YAEtB,IAAI,UAAU,QAAQ,CAAC,SAAS;gBAC9B,uEAAuE;gBACvE,oBAAoB;gBACpB,SAAS,OAAO;YAClB;YAEA,8EAA8E;YAC9E,0EAA0E;YAC1E,uCAAuC;YAEvC,OAAO,SAAS,OAAO;QACzB;QAEA,MAAM,WAAW,oBAAoB;QACrC,MAAM,kBAAkB,UAAU;QAElC,IAAI,UAAU,QAAQ,CAAC,SAAS;YAC9B,MAAM,gBAAgB,SAAS,gBAAgB,CAC7C,CAAC,2BAA2B,EAAE,SAAS,+BAA+B,EAAE,SAAS,+BAA+B,EAAE,gBAAgB,+BAA+B,EAAE,gBAAgB,GAAG,CAAC;YAEzL,IAAI,cAAc,MAAM,GAAG,GAAG;gBAC5B,uEAAuE;gBACvE,oBAAoB;gBACpB,SAAS,OAAO;YAClB,OAAO;gBACL,MAAM,OAAO,SAAS,aAAa,CAAC;gBACpC,KAAK,GAAG,GAAG;gBACX,KAAK,IAAI,GAAG;gBACZ,KAAK,OAAO,GAAG;oBACb,SAAS,MAAM;gBACjB;gBACA,KAAK,MAAM,GAAG;oBACZ,uEAAuE;oBACvE,oBAAoB;oBACpB,SAAS,OAAO;gBAClB;gBACA,SAAS,IAAI,CAAC,WAAW,CAAC;YAC5B;QACF,OAAO,IAAI,UAAU,QAAQ,CAAC,QAAQ;YACpC,MAAM,kBAAkB,SAAS,gBAAgB,CAC/C,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,SAAS,gBAAgB,EAAE,gBAAgB,gBAAgB,EAAE,gBAAgB,GAAG,CAAC;YAE7H,IAAI,gBAAgB,MAAM,GAAG,GAAG;gBAC9B,qEAAqE;gBACrE,kEAAkE;gBAClE,KAAK,MAAM,UAAU,MAAM,IAAI,CAAC,iBAAkB;oBAChD,OAAO,gBAAgB,CAAC,SAAS;wBAC/B,SAAS,MAAM;oBACjB;gBACF;YACF,OAAO;gBACL,MAAM,SAAS,SAAS,aAAa,CAAC;gBACtC,OAAO,GAAG,GAAG;gBACb,yEAAyE;gBACzE,wEAAwE;gBACxE,eAAe;gBACf,OAAO,OAAO,GAAG;oBACf,SAAS,MAAM;gBACjB;gBACA,SAAS,IAAI,CAAC,WAAW,CAAC;YAC5B;QACF,OAAO;YACL,MAAM,IAAI,MAAM,CAAC,oCAAoC,EAAE,UAAU,CAAC;QACpE;QAEA,OAAO,SAAS,OAAO;IACzB;AACF,CAAC;AAED,SAAS,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAyB;IACtD,QAAQ,CAAC,kBAAkB,EAAE,UAC3B,SAAS,MAAM,GAAG,kBAAkB,KACpC,CAAC;IACH,IAAI,KAAK;QACP,QAAQ,CAAC,kEAAkE,EAAE,KAC3E,0EAA0E;QAC1E,2CAA2C;QAC3C,SAAS,mBAAmB,OAC5B,CAAC;IACL;IAEA,OAAO,KAAK;AACd"}}, + {"offset": {"line": 1583, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js new file mode 100644 index 0000000000000..75c546e9ee565 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js @@ -0,0 +1,10 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +console.log("Hello, world!"); + +}.call(this) }), +}]); + +//# sourceMappingURL=79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js.map new file mode 100644 index 0000000000000..7eb3e24b4b225 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/output/79fb1_turbopack-tests_tests_snapshot_runtime_default_dev_runtime_input_index_7e4b32.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 4, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/runtime/default_dev_runtime/input/index.js"],"sourcesContent":["console.log(\"Hello, world!\");\n"],"names":[],"mappings":"AAAA,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js new file mode 100644 index 0000000000000..4cb2138b5813a --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js @@ -0,0 +1,7 @@ +import styled from "styled-components"; + +const MyButton = styled.button` + background: blue; +`; + +console.log(MyButton); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/a587c_tests_snapshot_styled_components_styled_components_input_index_2f3cbd.js b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/a587c_tests_snapshot_styled_components_styled_components_input_index_2f3cbd.js new file mode 100644 index 0000000000000..ac496c373c192 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/a587c_tests_snapshot_styled_components_styled_components_input_index_2f3cbd.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_styled_components_styled_components_input_index_2f3cbd.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_ededc0._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/a587c_tests_snapshot_styled_components_styled_components_input_index_2f3cbd.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/a587c_tests_snapshot_styled_components_styled_components_input_index_2f3cbd.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/a587c_tests_snapshot_styled_components_styled_components_input_index_2f3cbd.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js new file mode 100644 index 0000000000000..bcc3d05e8620b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js @@ -0,0 +1,27 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_ededc0._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$styled$2d$components$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +const MyButton = __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$styled$2d$components$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"].button.withConfig({ + displayName: "input__MyButton", + componentId: "sc-86737cfc-0" +})` + background: blue; +`; +console.log(MyButton); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +"purposefully empty stub"; +"styled-components/index.js"; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_ededc0._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js.map new file mode 100644 index 0000000000000..237ff0b1db5de --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/output/crates_turbopack-tests_tests_snapshot_ededc0._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/styled_components/styled_components/input/index.js"],"sourcesContent":["import styled from \"styled-components\";\n\nconst MyButton = styled.button`\n background: blue;\n`;\n\nconsole.log(MyButton);\n"],"names":[],"mappings":";;;;AAEA,MAAM,WAAW,4LAAA,CAAA,UAAM,CAAC,MAAM;;;EAAA,CAAC;;AAE/B,CAAC;AAED,QAAQ,GAAG,CAAC"}}, + {"offset": {"line": 16, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/styled-components/index.js"],"sourcesContent":["\"purposefully empty stub\";\n\"styled-components/index.js\"\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 22, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/component b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/component new file mode 120000 index 0000000000000..82c219fbaeeb2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/component @@ -0,0 +1 @@ +../packages/component/ \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/react/jsx-runtime.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/react/jsx-runtime.js new file mode 100644 index 0000000000000..156aef9a8f32b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/react/jsx-runtime.js @@ -0,0 +1,3 @@ +export function jsx() { + // This is a stub to satisfy turbopack's resolution. Snapshot tests are never actually run. +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js new file mode 100644 index 0000000000000..c93fb2b288ac4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js @@ -0,0 +1,3 @@ +export default function ThirdPartyComponent() { + return
    Should not be transformed
    ; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js new file mode 100644 index 0000000000000..a50ed3983df32 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js @@ -0,0 +1,4 @@ +import MyApp from "component"; +import ThirdPartyComponent from "third_party_component"; + +console.log(MyApp, ThirdPartyComponent); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js new file mode 100644 index 0000000000000..5f0f0d4e46fde --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js @@ -0,0 +1,3 @@ +export default function MyApp() { + return
    App
    ; +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/options.json new file mode 100644 index 0000000000000..625d34733d610 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/options.json @@ -0,0 +1,3 @@ +{ + "entry": "input/packages/app/index.js" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/a587c_tests_snapshot_swc_transforms_mono_transforms_input_packages_app_index_754b2e.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/a587c_tests_snapshot_swc_transforms_mono_transforms_input_packages_app_index_754b2e.js new file mode 100644 index 0000000000000..99da1c7fdbc0c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/a587c_tests_snapshot_swc_transforms_mono_transforms_input_packages_app_index_754b2e.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_swc_transforms_mono_transforms_input_packages_app_index_754b2e.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_9cde7b._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/a587c_tests_snapshot_swc_transforms_mono_transforms_input_packages_app_index_754b2e.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/a587c_tests_snapshot_swc_transforms_mono_transforms_input_packages_app_index_754b2e.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/a587c_tests_snapshot_swc_transforms_mono_transforms_input_packages_app_index_754b2e.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js new file mode 100644 index 0000000000000..43cd9371a063c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js @@ -0,0 +1,54 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_9cde7b._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>MyApp +}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +function MyApp() { + return /*#__PURE__*/ (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$react$2f$jsx$2d$dev$2d$runtime$2e$js__$5b$test$5d$__$28$ecmascript$29$__["jsxDEV"])("div", { + children: "App" + }, void 0, false, { + fileName: "[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js", + lineNumber: 2, + columnNumber: 10 + }, this); +} + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$swc_transforms$2f$mono_transforms$2f$input$2f$packages$2f$component$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js [test] (ecmascript)"); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$swc_transforms$2f$mono_transforms$2f$input$2f$node_modules$2f$third_party_component$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$swc_transforms$2f$mono_transforms$2f$input$2f$packages$2f$component$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$swc_transforms$2f$mono_transforms$2f$input$2f$node_modules$2f$third_party_component$2f$index$2e$js__$5b$test$5d$__$28$ecmascript$29$__["default"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +"purposefully empty stub"; +"react/jsx-dev-runtime.js"; + +}.call(this) }), +"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "default": ()=>ThirdPartyComponent +}); +function ThirdPartyComponent() { + return
    Should not be transformed
    ; +} + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_9cde7b._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js.map new file mode 100644 index 0000000000000..91dd73c485cfb --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/output/crates_turbopack-tests_tests_snapshot_9cde7b._.js.map @@ -0,0 +1,13 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/component/index.js"],"sourcesContent":["export default function MyApp() {\n return
    App
    ;\n}\n"],"names":[],"mappings":";;;;;;AAAe,SAAS;IACtB,qBAAO,6MAAC;kBAAI;;;;;;AACd"}}, + {"offset": {"line": 20, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 25, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/packages/app/index.js"],"sourcesContent":["import MyApp from \"component\";\nimport ThirdPartyComponent from \"third_party_component\";\n\nconsole.log(MyApp, ThirdPartyComponent);\n"],"names":[],"mappings":";;;;;;AAGA,QAAQ,GAAG,CAAC,2NAAA,CAAA,UAAK,EAAE,2OAAA,CAAA,UAAmB"}}, + {"offset": {"line": 32, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 36, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/react/jsx-dev-runtime.js"],"sourcesContent":["\"purposefully empty stub\";\n\"react/jsx-dev-runtime.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 38, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 43, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/mono_transforms/input/node_modules/third_party_component/index.js"],"sourcesContent":["export default function ThirdPartyComponent() {\n return
    Should not be transformed
    ;\n}\n"],"names":[],"mappings":";;;AAAe,SAAS;IACtB,QAAQ,IAAI,yBAAyB,EAAE;AACzC"}}, + {"offset": {"line": 49, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js new file mode 100644 index 0000000000000..0aad75fade63b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js @@ -0,0 +1,3 @@ +class Foo {} + +console.log(Foo, [].includes("foo")); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/options.json new file mode 100644 index 0000000000000..2a21928019b83 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/options.json @@ -0,0 +1,3 @@ +{ + "browserslist": "ie 11" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/79fb1_turbopack-tests_tests_snapshot_swc_transforms_preset_env_input_index_06a68c.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/79fb1_turbopack-tests_tests_snapshot_swc_transforms_preset_env_input_index_06a68c.js new file mode 100644 index 0000000000000..90a77994dc957 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/79fb1_turbopack-tests_tests_snapshot_swc_transforms_preset_env_input_index_06a68c.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_swc_transforms_preset_env_input_index_06a68c.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/79fb1_turbopack-tests_tests_snapshot_swc_transforms_preset_env_input_index_06a68c.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/79fb1_turbopack-tests_tests_snapshot_swc_transforms_preset_env_input_index_06a68c.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/79fb1_turbopack-tests_tests_snapshot_swc_transforms_preset_env_input_index_06a68c.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js new file mode 100644 index 0000000000000..4a5a32df086c9 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f40$swc$2f$helpers$2f$_$2f$_class_call_check$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +var Foo = function Foo() { + "use strict"; + (0, __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f40$swc$2f$helpers$2f$_$2f$_class_call_check$2e$js__$5b$test$5d$__$28$ecmascript$29$__["_"])(this, Foo); +}; +console.log(Foo, [].includes("foo")); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js [test] (ecmascript)": (function({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname, m: module, e: exports, t: require }) { !function() { + +"purposefully empty stub"; +"@swc/helpers/_/_class_call_check.js"; + +}.call(this) }), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_f8ff4e._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js.map new file mode 100644 index 0000000000000..77af32e64bc3d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/output/crates_turbopack-tests_tests_snapshot_f8ff4e._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/swc_transforms/preset_env/input/index.js"],"sourcesContent":["class Foo {}\n\nconsole.log(Foo, [].includes(\"foo\"));\n"],"names":[],"mappings":";;;;;AAAA,IAAA,AAAM,MAAN,SAAM;;8NAAA;;AAEN,QAAQ,GAAG,CAAC,KAAK,EAAE,CAAC,QAAQ,CAAC"}}, + {"offset": {"line": 15, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 19, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/@swc/helpers/_/_class_call_check.js"],"sourcesContent":["\"purposefully empty stub\";\n\"@swc/helpers/_/_class_call_check.js\";\n"],"names":[],"mappings":"AAAA;AACA"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js new file mode 100644 index 0000000000000..e27e01cec18ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js @@ -0,0 +1,5 @@ +import { prop as globalFoo } from "foo"; +import { prop as localFoo } from "./foo"; +import { prop as atFoo } from "@/foo"; + +console.log(globalFoo, localFoo, atFoo); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/jsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/jsconfig.json new file mode 100644 index 0000000000000..6be0dc1c681c0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/jsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "foo": ["./prop"], + "./foo": ["./prop"], + "@/*": ["./*"], + } + }, + "include": ["./*.ts"] + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js new file mode 100644 index 0000000000000..2592244d35ea0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js @@ -0,0 +1 @@ +export const prop = 1; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/79fb1_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_index_c88e5b.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/79fb1_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_index_c88e5b.js new file mode 100644 index 0000000000000..faad968b03a3c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/79fb1_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_index_c88e5b.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/79fb1_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_index_c88e5b.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/79fb1_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_index_c88e5b.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/79fb1_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_index_c88e5b.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/79fb1_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_index_c88e5b.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js new file mode 100644 index 0000000000000..f9bba6e911057 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "prop": ()=>prop +}); +const prop = 1; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$jsconfig$2d$baseurl$2f$input$2f$prop$2e$js__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$jsconfig$2d$baseurl$2f$input$2f$prop$2e$js__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$jsconfig$2d$baseurl$2f$input$2f$prop$2e$js__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$jsconfig$2d$baseurl$2f$input$2f$prop$2e$js__$5b$test$5d$__$28$ecmascript$29$__["prop"]); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js.map new file mode 100644 index 0000000000000..42075eefdde27 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_jsconfig-baseurl_input_f8c7e6._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/prop.js"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/jsconfig-baseurl/input/index.js"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/foo.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/foo.ts new file mode 100644 index 0000000000000..7765b67ff7e72 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/foo.ts @@ -0,0 +1 @@ +export const prop = "prop"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts new file mode 100644 index 0000000000000..e27e01cec18ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts @@ -0,0 +1,5 @@ +import { prop as globalFoo } from "foo"; +import { prop as localFoo } from "./foo"; +import { prop as atFoo } from "@/foo"; + +console.log(globalFoo, localFoo, atFoo); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts new file mode 100644 index 0000000000000..2592244d35ea0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts @@ -0,0 +1 @@ +export const prop = 1; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/tsconfig.json new file mode 100644 index 0000000000000..6be0dc1c681c0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "foo": ["./prop"], + "./foo": ["./prop"], + "@/*": ["./*"], + } + }, + "include": ["./*.ts"] + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/options.json new file mode 100644 index 0000000000000..a3ff512d086c5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/options.json @@ -0,0 +1,3 @@ +{ + "entry": "input/index.ts" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/a587c_tests_snapshot_typescript_tsconfig-baseurl_input_index_ts_a8d962._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/a587c_tests_snapshot_typescript_tsconfig-baseurl_input_index_ts_a8d962._.js new file mode 100644 index 0000000000000..6257977c2f6a4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/a587c_tests_snapshot_typescript_tsconfig-baseurl_input_index_ts_a8d962._.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_typescript_tsconfig-baseurl_input_index_ts_a8d962._.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/a587c_tests_snapshot_typescript_tsconfig-baseurl_input_index_ts_a8d962._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/a587c_tests_snapshot_typescript_tsconfig-baseurl_input_index_ts_a8d962._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/a587c_tests_snapshot_typescript_tsconfig-baseurl_input_index_ts_a8d962._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js new file mode 100644 index 0000000000000..fc86bf93f1ccd --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "prop": ()=>prop +}); +const prop = 1; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$baseurl$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$baseurl$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$baseurl$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$baseurl$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"]); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js.map new file mode 100644 index 0000000000000..9a6b6568bdbe8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-baseurl_input_7bf5e3._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-baseurl/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts new file mode 100644 index 0000000000000..e27e01cec18ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts @@ -0,0 +1,5 @@ +import { prop as globalFoo } from "foo"; +import { prop as localFoo } from "./foo"; +import { prop as atFoo } from "@/foo"; + +console.log(globalFoo, localFoo, atFoo); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/tsconfig.json new file mode 100644 index 0000000000000..fcfdaa47a6e5c --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "tsconfig-mod/tsconfig.json" + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/options.json new file mode 100644 index 0000000000000..a3ff512d086c5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/options.json @@ -0,0 +1,3 @@ +{ + "entry": "input/index.ts" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/8562f_snapshot_typescript_tsconfig-extends-module-full-path_input_index_ts_4d2fc7._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/8562f_snapshot_typescript_tsconfig-extends-module-full-path_input_index_ts_4d2fc7._.js new file mode 100644 index 0000000000000..adcadc9c61bd8 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/8562f_snapshot_typescript_tsconfig-extends-module-full-path_input_index_ts_4d2fc7._.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/8562f_snapshot_typescript_tsconfig-extends-module-full-path_input_index_ts_4d2fc7._.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/8562f_snapshot_typescript_tsconfig-extends-module-full-path_input_index_ts_4d2fc7._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/8562f_snapshot_typescript_tsconfig-extends-module-full-path_input_index_ts_4d2fc7._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/8562f_snapshot_typescript_tsconfig-extends-module-full-path_input_index_ts_4d2fc7._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js new file mode 100644 index 0000000000000..c8382f5f9afed --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "prop": ()=>prop +}); +const prop = 1; + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_4a4ab7._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js.map new file mode 100644 index 0000000000000..4b3db24d5d025 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/output/crates_turbopack-tests_tests_snapshot_4a4ab7._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module-full-path/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,sLAAA,CAAA,OAAS,EAAE,sLAAA,CAAA,OAAQ,EAAE,sLAAA,CAAA,OAAK"}}, + {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts new file mode 100644 index 0000000000000..e27e01cec18ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts @@ -0,0 +1,5 @@ +import { prop as globalFoo } from "foo"; +import { prop as localFoo } from "./foo"; +import { prop as atFoo } from "@/foo"; + +console.log(globalFoo, localFoo, atFoo); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/tsconfig.json new file mode 100644 index 0000000000000..dc3f03a4a49ff --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "tsconfig-mod" + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/options.json new file mode 100644 index 0000000000000..a3ff512d086c5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/options.json @@ -0,0 +1,3 @@ +{ + "entry": "input/index.ts" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/a587c_tests_snapshot_typescript_tsconfig-extends-module_input_index_ts_7bfae2._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/a587c_tests_snapshot_typescript_tsconfig-extends-module_input_index_ts_7bfae2._.js new file mode 100644 index 0000000000000..5addca4b09372 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/a587c_tests_snapshot_typescript_tsconfig-extends-module_input_index_ts_7bfae2._.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_typescript_tsconfig-extends-module_input_index_ts_7bfae2._.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_5fc419._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/a587c_tests_snapshot_typescript_tsconfig-extends-module_input_index_ts_7bfae2._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/a587c_tests_snapshot_typescript_tsconfig-extends-module_input_index_ts_7bfae2._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/a587c_tests_snapshot_typescript_tsconfig-extends-module_input_index_ts_7bfae2._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js new file mode 100644 index 0000000000000..fa425a6bff8ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_5fc419._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$node_modules$2f$tsconfig$2d$mod$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"]); + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "prop": ()=>prop +}); +const prop = 1; + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_5fc419._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js.map new file mode 100644 index 0000000000000..a09d955edfee2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/output/crates_turbopack-tests_tests_snapshot_5fc419._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-module/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,sLAAA,CAAA,OAAS,EAAE,sLAAA,CAAA,OAAQ,EAAE,sLAAA,CAAA,OAAK"}}, + {"offset": {"line": 12, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 17, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/node_modules/tsconfig-mod/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/config/ts/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/config/ts/tsconfig.json new file mode 100644 index 0000000000000..fcc3230b8219b --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/config/ts/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": ".." + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/config/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/config/tsconfig.json new file mode 100644 index 0000000000000..007e7425a38e4 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/config/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": "..", + "paths": { + "foo": ["./prop"], + "./foo": ["./prop"], + "@/*": ["./*"], + } + }, + "include": ["../*.ts"] + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/foo.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/foo.ts new file mode 100644 index 0000000000000..7765b67ff7e72 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/foo.ts @@ -0,0 +1 @@ +export const prop = "prop"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts new file mode 100644 index 0000000000000..e27e01cec18ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts @@ -0,0 +1,5 @@ +import { prop as globalFoo } from "foo"; +import { prop as localFoo } from "./foo"; +import { prop as atFoo } from "@/foo"; + +console.log(globalFoo, localFoo, atFoo); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts new file mode 100644 index 0000000000000..2592244d35ea0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts @@ -0,0 +1 @@ +export const prop = 1; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/tsconfig.json new file mode 100644 index 0000000000000..513b54ad04c96 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./config/ts/tsconfig.json" + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/options.json new file mode 100644 index 0000000000000..a3ff512d086c5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/options.json @@ -0,0 +1,3 @@ +{ + "entry": "input/index.ts" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js new file mode 100644 index 0000000000000..f37f52cc5b0b3 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "prop": ()=>prop +}); +const prop = 1; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2d$relative$2d$dir$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2d$relative$2d$dir$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2d$relative$2d$dir$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2d$relative$2d$dir$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"]); + +})()), +}]); + +//# sourceMappingURL=a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js.map new file mode 100644 index 0000000000000..e7ac5ec2b50a1 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,oNAAA,CAAA,OAAS,EAAE,oNAAA,CAAA,OAAQ,EAAE,oNAAA,CAAA,OAAK"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_index_ts_19e057._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_index_ts_19e057._.js new file mode 100644 index 0000000000000..301a5ef0e3934 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_index_ts_19e057._.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_index_ts_19e057._.js", + {}, + {"otherChunks":["output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_d34519._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/input/index.ts [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_index_ts_19e057._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_index_ts_19e057._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-relative-dir/output/a587c_tests_snapshot_typescript_tsconfig-extends-relative-dir_input_index_ts_19e057._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/foo.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/foo.ts new file mode 100644 index 0000000000000..7765b67ff7e72 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/foo.ts @@ -0,0 +1 @@ +export const prop = "prop"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts new file mode 100644 index 0000000000000..e27e01cec18ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts @@ -0,0 +1,5 @@ +import { prop as globalFoo } from "foo"; +import { prop as localFoo } from "./foo"; +import { prop as atFoo } from "@/foo"; + +console.log(globalFoo, localFoo, atFoo); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts new file mode 100644 index 0000000000000..2592244d35ea0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts @@ -0,0 +1 @@ +export const prop = 1; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/tsconfig.base.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/tsconfig.base.json new file mode 100644 index 0000000000000..6be0dc1c681c0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/tsconfig.base.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "foo": ["./prop"], + "./foo": ["./prop"], + "@/*": ["./*"], + } + }, + "include": ["./*.ts"] + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/tsconfig.json new file mode 100644 index 0000000000000..9e4ce56cd1017 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig.base.json" + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/options.json new file mode 100644 index 0000000000000..a3ff512d086c5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/options.json @@ -0,0 +1,3 @@ +{ + "entry": "input/index.ts" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js new file mode 100644 index 0000000000000..1928fdb5dab07 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "prop": ()=>prop +}); +const prop = 1; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2d$without$2d$ext$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2d$without$2d$ext$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2d$without$2d$ext$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2d$without$2d$ext$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"]); + +})()), +}]); + +//# sourceMappingURL=a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js.map new file mode 100644 index 0000000000000..e85ad53ffe6cc --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,mNAAA,CAAA,OAAS,EAAE,mNAAA,CAAA,OAAQ,EAAE,mNAAA,CAAA,OAAK"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_index_ts_bd75ee._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_index_ts_bd75ee._.js new file mode 100644 index 0000000000000..e706bb0f6f498 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_index_ts_bd75ee._.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_index_ts_bd75ee._.js", + {}, + {"otherChunks":["output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_69f4f4._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/input/index.ts [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_index_ts_bd75ee._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_index_ts_bd75ee._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends-without-ext/output/a587c_tests_snapshot_typescript_tsconfig-extends-without-ext_input_index_ts_bd75ee._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/foo.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/foo.ts new file mode 100644 index 0000000000000..7765b67ff7e72 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/foo.ts @@ -0,0 +1 @@ +export const prop = "prop"; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts new file mode 100644 index 0000000000000..e27e01cec18ce --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts @@ -0,0 +1,5 @@ +import { prop as globalFoo } from "foo"; +import { prop as localFoo } from "./foo"; +import { prop as atFoo } from "@/foo"; + +console.log(globalFoo, localFoo, atFoo); diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts new file mode 100644 index 0000000000000..2592244d35ea0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts @@ -0,0 +1 @@ +export const prop = 1; diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/tsconfig.base.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/tsconfig.base.json new file mode 100644 index 0000000000000..6be0dc1c681c0 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/tsconfig.base.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "foo": ["./prop"], + "./foo": ["./prop"], + "@/*": ["./*"], + } + }, + "include": ["./*.ts"] + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/tsconfig.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/tsconfig.json new file mode 100644 index 0000000000000..9097626bb65d2 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig.base" + } diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/options.json b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/options.json new file mode 100644 index 0000000000000..a3ff512d086c5 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/options.json @@ -0,0 +1,3 @@ +{ + "entry": "input/index.ts" +} diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/a587c_tests_snapshot_typescript_tsconfig-extends_input_index_ts_3e0e16._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/a587c_tests_snapshot_typescript_tsconfig-extends_input_index_ts_3e0e16._.js new file mode 100644 index 0000000000000..a785ded2bbc4d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/a587c_tests_snapshot_typescript_tsconfig-extends_input_index_ts_3e0e16._.js @@ -0,0 +1,6 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + "output/a587c_tests_snapshot_typescript_tsconfig-extends_input_index_ts_3e0e16._.js", + {}, + {"otherChunks":["output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js"],"runtimeModuleIds":["[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts [test] (ecmascript)"]} +]); +// Dummy runtime \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/a587c_tests_snapshot_typescript_tsconfig-extends_input_index_ts_3e0e16._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/a587c_tests_snapshot_typescript_tsconfig-extends_input_index_ts_3e0e16._.js.map new file mode 100644 index 0000000000000..c15d7ec00382d --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/a587c_tests_snapshot_typescript_tsconfig-extends_input_index_ts_3e0e16._.js.map @@ -0,0 +1,5 @@ +{ + "version": 3, + "sources": [], + "sections": [] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js new file mode 100644 index 0000000000000..78d4ea7f67c22 --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js @@ -0,0 +1,26 @@ +(globalThis.TURBOPACK = globalThis.TURBOPACK || []).push(["output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js", { + +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({ + "prop": ()=>prop +}); +const prop = 1; + +})()), +"[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts [test] (ecmascript)": (({ r: __turbopack_require__, f: __turbopack_module_context__, i: __turbopack_import__, s: __turbopack_esm__, v: __turbopack_export_value__, n: __turbopack_export_namespace__, c: __turbopack_cache__, M: __turbopack_modules__, l: __turbopack_load__, j: __turbopack_dynamic__, P: __turbopack_resolve_absolute_path__, U: __turbopack_relative_url__, R: __turbopack_resolve_module_id_path__, g: global, __dirname }) => (() => { +"use strict"; + +__turbopack_esm__({}); +var __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__ = __turbopack_import__("[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts [test] (ecmascript)"); +"__TURBOPACK__ecmascript__hoisting__location__"; +; +; +; +console.log(__TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"], __TURBOPACK__imported__module__$5b$project$5d2f$crates$2f$turbopack$2d$tests$2f$tests$2f$snapshot$2f$typescript$2f$tsconfig$2d$extends$2f$input$2f$prop$2e$ts__$5b$test$5d$__$28$ecmascript$29$__["prop"]); + +})()), +}]); + +//# sourceMappingURL=crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js.map \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js.map b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js.map new file mode 100644 index 0000000000000..32896c3579eaa --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/output/crates_turbopack-tests_tests_snapshot_typescript_tsconfig-extends_input_72bd49._.js.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "sources": [], + "sections": [ + {"offset": {"line": 5, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/prop.ts"],"sourcesContent":["export const prop = 1;\n"],"names":[],"mappings":";;;AAAO,MAAM,OAAO"}}, + {"offset": {"line": 9, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}, + {"offset": {"line": 14, "column": 0}, "map": {"version":3,"sources":["turbopack://[project]/crates/turbopack-tests/tests/snapshot/typescript/tsconfig-extends/input/index.ts"],"sourcesContent":["import { prop as globalFoo } from \"foo\";\nimport { prop as localFoo } from \"./foo\";\nimport { prop as atFoo } from \"@/foo\";\n\nconsole.log(globalFoo, localFoo, atFoo);\n"],"names":[],"mappings":";;;;;;AAIA,QAAQ,GAAG,CAAC,iMAAA,CAAA,OAAS,EAAE,iMAAA,CAAA,OAAQ,EAAE,iMAAA,CAAA,OAAK"}}, + {"offset": {"line": 21, "column": 0}, "map": {"version":3,"sources":[],"names":[],"mappings":"A"}}] +} \ No newline at end of file diff --git a/turbopack/crates/turbopack-tests/tests/util.rs b/turbopack/crates/turbopack-tests/tests/util.rs new file mode 100644 index 0000000000000..d256f375ba71f --- /dev/null +++ b/turbopack/crates/turbopack-tests/tests/util.rs @@ -0,0 +1,12 @@ +use std::path::PathBuf; + +use dunce::canonicalize; +use once_cell::sync::Lazy; +use turbo_tasks::RcStr; + +/// The turbo repo root. Should be used as the root when building with turbopack +/// against fixtures in this crate. +pub static REPO_ROOT: Lazy = Lazy::new(|| { + let package_root = PathBuf::from(env!("TURBO_PNPM_WORKSPACE_DIR")); + canonicalize(package_root).unwrap().to_str().unwrap().into() +}); diff --git a/turbopack/crates/turbopack-trace-server/Cargo.toml b/turbopack/crates/turbopack-trace-server/Cargo.toml new file mode 100644 index 0000000000000..00516465c6a1c --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "turbopack-trace-server" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[[bin]] +name = "turbo-trace-server" +path = "src/main.rs" +bench = false + +[dependencies] +anyhow = { workspace = true, features = ["backtrace"] } +either = { workspace = true } +flate2 = { version = "1.0.28" } +indexmap = { workspace = true, features = ["serde"] } +itertools = { workspace = true } +postcard = { workspace = true } +rayon = "1" +rustc-demangle = "0.1" +serde = { workspace = true } +serde_json = { workspace = true } +tungstenite = { version = "0.21.0" } +turbopack-trace-utils = { workspace = true } +zstd = { version = "0.13.0" } diff --git a/turbopack/crates/turbopack-trace-server/src/bottom_up.rs b/turbopack/crates/turbopack-trace-server/src/bottom_up.rs new file mode 100644 index 0000000000000..39c025eb8d4de --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/bottom_up.rs @@ -0,0 +1,86 @@ +use std::{collections::HashMap, env, sync::Arc}; + +use crate::{ + span::{SpanBottomUp, SpanIndex}, + span_ref::SpanRef, +}; + +pub struct SpanBottomUpBuilder { + // These values won't change after creation: + pub self_spans: Vec, + pub children: HashMap, + pub example_span: SpanIndex, +} + +impl SpanBottomUpBuilder { + pub fn new(example_span: SpanIndex) -> Self { + Self { + self_spans: vec![], + children: HashMap::new(), + example_span, + } + } + + pub fn build(self) -> SpanBottomUp { + SpanBottomUp::new( + self.self_spans, + self.example_span, + self.children + .into_values() + .map(|child| Arc::new(child.build())) + .collect(), + ) + } +} + +pub fn build_bottom_up_graph<'a>( + spans: impl Iterator>, +) -> Vec> { + let max_depth = env::var("BOTTOM_UP_DEPTH") + .ok() + .and_then(|s| s.parse().ok()) + .unwrap_or(usize::MAX); + let mut roots = HashMap::new(); + + // unfortunately there is a rustc bug that fails the typechecking here + // when using Either. This error appears + // in certain cases when building next-swc. + // + // see here: https://github.com/rust-lang/rust/issues/124891 + let mut current_iterators: Vec>>> = + vec![Box::new(spans.flat_map(|span| span.children()))]; + + let mut current_path: Vec<(&'_ str, SpanIndex)> = vec![]; + while let Some(mut iter) = current_iterators.pop() { + if let Some(child) = iter.next() { + current_iterators.push(iter); + + let name = child.group_name(); + let (_, mut bottom_up) = roots + .raw_entry_mut() + .from_key(name) + .or_insert_with(|| (name.to_string(), SpanBottomUpBuilder::new(child.index()))); + bottom_up.self_spans.push(child.index()); + let mut prev = None; + for &(name, example_span) in current_path.iter().rev().take(max_depth) { + if prev == Some(name) { + continue; + } + let (_, child_bottom_up) = bottom_up + .children + .raw_entry_mut() + .from_key(name) + .or_insert_with(|| (name.to_string(), SpanBottomUpBuilder::new(example_span))); + child_bottom_up.self_spans.push(child.index()); + bottom_up = child_bottom_up; + prev = Some(name); + } + + current_path.push((child.group_name(), child.index())); + current_iterators.push(Box::new(child.children())); + } else { + current_path.pop(); + } + } + roots.into_values().map(|b| Arc::new(b.build())).collect() +} diff --git a/turbopack/crates/turbopack-trace-server/src/lib.rs b/turbopack/crates/turbopack-trace-server/src/lib.rs new file mode 100644 index 0000000000000..c6ad3db06ee51 --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/lib.rs @@ -0,0 +1,30 @@ +#![feature(iter_intersperse)] +#![feature(hash_raw_entry)] +#![feature(box_patterns)] + +use std::{path::PathBuf, sync::Arc}; + +use self::{reader::TraceReader, server::serve, store_container::StoreContainer}; + +mod bottom_up; +mod reader; +mod self_time_tree; +mod server; +mod span; +mod span_bottom_up_ref; +mod span_graph_ref; +mod span_ref; +mod store; +mod store_container; +mod u64_empty_string; +mod u64_string; +mod viewer; + +pub fn start_turbopack_trace_server(path: PathBuf) { + let store = Arc::new(StoreContainer::new()); + let reader = TraceReader::spawn(store.clone(), path); + + serve(store); + + reader.join().unwrap(); +} diff --git a/turbopack/crates/turbopack-trace-server/src/main.rs b/turbopack/crates/turbopack-trace-server/src/main.rs new file mode 100644 index 0000000000000..56f4dcdcb5888 --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/main.rs @@ -0,0 +1,37 @@ +#![feature(iter_intersperse)] +#![feature(hash_raw_entry)] +#![feature(box_patterns)] + +use std::{collections::HashSet, sync::Arc}; + +use self::{reader::TraceReader, server::serve, store_container::StoreContainer}; + +mod bottom_up; +mod reader; +mod self_time_tree; +mod server; +mod span; +mod span_bottom_up_ref; +mod span_graph_ref; +mod span_ref; +mod store; +mod store_container; +mod u64_empty_string; +mod u64_string; +mod viewer; + +fn main() { + let args: HashSet = std::env::args().skip(1).collect(); + + let arg = args + .iter() + .next() + .expect("missing argument: trace file path"); + + let store = Arc::new(StoreContainer::new()); + let reader = TraceReader::spawn(store.clone(), arg.into()); + + serve(store); + + reader.join().unwrap(); +} diff --git a/turbopack/crates/turbopack-trace-server/src/reader/heaptrack.rs b/turbopack/crates/turbopack-trace-server/src/reader/heaptrack.rs new file mode 100644 index 0000000000000..c328230fb6534 --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/reader/heaptrack.rs @@ -0,0 +1,518 @@ +use std::{ + collections::{HashMap, HashSet}, + env, + str::from_utf8, + sync::Arc, +}; + +use anyhow::{bail, Context, Result}; +use indexmap::{indexmap, map::Entry, IndexMap}; +use rustc_demangle::demangle; + +use super::TraceFormat; +use crate::{span::SpanIndex, store_container::StoreContainer}; + +#[derive(Debug, Clone, Copy)] +struct TraceNode { + ip_index: usize, + parent_index: usize, +} + +impl TraceNode { + pub fn read(s: &mut &[u8]) -> Result { + Ok(Self { + ip_index: read_hex_index(s)?, + parent_index: read_hex_index(s)?, + }) + } +} + +#[derive(Debug, Hash, PartialEq, Eq)] +struct InstructionPointer { + module_index: usize, + frames: Vec, + custom_name: Option, +} + +impl InstructionPointer { + pub fn read(s: &mut &[u8]) -> Result { + let _ip = read_hex(s)?; + Ok(Self { + module_index: read_hex_index(s)?, + frames: read_all(s, Frame::read)?, + custom_name: None, + }) + } +} + +#[derive(Debug, Hash, PartialEq, Eq)] +struct Frame { + function_index: usize, + file_index: usize, + line: u64, +} + +impl Frame { + pub fn read(s: &mut &[u8]) -> Result { + Ok(Self { + function_index: read_hex_index(s)?, + file_index: read_hex_index(s)?, + line: read_hex(s)?, + }) + } +} + +#[derive(Debug)] +struct AllocationInfo { + size: u64, + trace_index: usize, +} + +impl AllocationInfo { + pub fn read(s: &mut &[u8]) -> Result { + Ok(Self { + size: read_hex(s)?, + trace_index: read_hex_index(s)?, + }) + } +} + +struct InstructionPointerExtraInfo { + first_trace_of_ip: Option, +} + +#[derive(Clone, Copy)] +struct TraceData { + span_index: SpanIndex, + ip_index: usize, + parent_trace_index: usize, +} + +pub struct HeaptrackFormat { + store: Arc, + version: u32, + last_timestamp: u64, + strings: Vec, + traces: Vec, + ip_parent_map: HashMap<(usize, SpanIndex), usize>, + trace_instruction_pointers: Vec, + instruction_pointers: IndexMap, + allocations: Vec, + spans: usize, + collapse_crates: HashSet, + expand_crates: HashSet, + expand_recursion: bool, + allocated_memory: u64, + temp_allocated_memory: u64, +} + +const RECURSION_IP: usize = 1; + +impl HeaptrackFormat { + pub fn new(store: Arc) -> Self { + Self { + store, + version: 0, + last_timestamp: 0, + strings: vec!["".to_string()], + traces: vec![TraceData { + span_index: SpanIndex::new(usize::MAX).unwrap(), + ip_index: 0, + parent_trace_index: 0, + }], + ip_parent_map: HashMap::new(), + instruction_pointers: indexmap! { + InstructionPointer { + module_index: 0, + frames: Vec::new(), + custom_name: Some("root".to_string()) + } => InstructionPointerExtraInfo { + first_trace_of_ip: None, + }, + InstructionPointer { + module_index: 0, + frames: Vec::new(), + custom_name: Some("recursion".to_string()) + } => InstructionPointerExtraInfo { + first_trace_of_ip: None, + } + }, + trace_instruction_pointers: vec![0], + allocations: vec![], + spans: 0, + collapse_crates: env::var("COLLAPSE_CRATES") + .unwrap_or_default() + .split(',') + .map(|s| s.to_string()) + .collect(), + expand_crates: env::var("EXPAND_CRATES") + .unwrap_or_default() + .split(',') + .filter(|s| !s.is_empty()) + .map(|s| s.to_string()) + .collect(), + expand_recursion: env::var("EXPAND_RECURSION").is_ok(), + allocated_memory: 0, + temp_allocated_memory: 0, + } + } +} + +impl TraceFormat for HeaptrackFormat { + fn stats(&self) -> String { + format!( + "{} spans, {} strings, {} ips, {} traces, {} allocations, {:.2} GB allocated, {:.2} \ + GB temporarily allocated", + self.spans, + self.strings.len() - 1, + self.trace_instruction_pointers.len() - 1, + self.traces.len() - 1, + self.allocations.len() - 1, + (self.allocated_memory / 1024 / 1024) as f32 / 1024.0, + (self.temp_allocated_memory / 1024 / 1024) as f32 / 1024.0, + ) + } + + fn read(&mut self, mut buffer: &[u8]) -> anyhow::Result { + let mut bytes_read = 0; + let mut outdated_spans = HashSet::new(); + let mut store = self.store.write(); + 'outer: loop { + let Some(line_end) = buffer.iter().position(|b| *b == b'\n') else { + break; + }; + let full_line = &buffer[..line_end]; + buffer = &buffer[line_end + 1..]; + bytes_read += full_line.len() + 1; + + if full_line.is_empty() { + continue; + } + let ty = full_line[0]; + let mut line = &full_line[2..]; + + // For format see https://github.com/KDE/heaptrack/blob/b000a73e0bf0a275ec41eef0fe34701a0942cdd8/src/analyze/accumulatedtracedata.cpp#L151 + match ty { + b'v' => { + let _ = read_hex(&mut line)?; + self.version = read_hex(&mut line)? as u32; + if self.version != 2 && self.version != 3 { + bail!("Unsupported version: {} (expected 2 or 3)", self.version); + } + } + b's' => { + let string = if self.version == 2 { + String::from_utf8(line.to_vec())? + } else { + read_sized_string(&mut line)? + }; + self.strings.push(demangle(&string).to_string()); + } + b't' => { + let TraceNode { + ip_index, + parent_index, + } = TraceNode::read(&mut line)?; + let ip_index = *self + .trace_instruction_pointers + .get(ip_index) + .context("ip not found")?; + let (ip, ip_info) = self + .instruction_pointers + .get_index(ip_index) + .context("ip not found")?; + // Try to fix cut-off traces + if parent_index == 0 { + if let Some(trace_index) = ip_info.first_trace_of_ip { + let trace = self.traces.get(trace_index).context("trace not found")?; + self.traces.push(*trace); + continue; + } + } + // Lookup parent + let parent = if parent_index > 0 { + let parent = *self.traces.get(parent_index).context("parent not found")?; + // Check if we have an duplicate (can only happen due to cut-off traces) + if let Some(trace_index) = + self.ip_parent_map.get(&(ip_index, parent.span_index)) + { + let trace = self.traces.get(*trace_index).context("trace not found")?; + self.traces.push(*trace); + continue; + } + // Check if we repeat parent frame + if parent.ip_index == ip_index { + self.traces.push(parent); + continue; + } + if !self.expand_recursion { + // Check for recursion + let mut current = parent.parent_trace_index; + while current > 0 { + let current_parent = + self.traces.get(current).context("parent not found")?; + current = current_parent.parent_trace_index; + if current_parent.ip_index == ip_index { + if parent.ip_index == RECURSION_IP { + // Parent is recursion node, do nothing + self.traces.push(parent); + } else if let Some(trace_index) = + self.ip_parent_map.get(&(RECURSION_IP, parent.span_index)) + { + // There is already one recursion node, reuse it + let trace = self + .traces + .get(*trace_index) + .context("trace not found")?; + self.traces.push(*trace); + } else { + // create a new recursion node + let span_index = store.add_span( + Some(parent.span_index), + self.last_timestamp, + "".to_string(), + "recursion".to_string(), + Vec::new(), + &mut outdated_spans, + ); + store.complete_span(span_index); + let index = self.traces.len(); + self.traces.push(TraceData { + ip_index: RECURSION_IP, + parent_trace_index: parent_index, + span_index, + }); + self.ip_parent_map + .insert((RECURSION_IP, parent.span_index), index); + } + continue 'outer; + } + } + } + Some(parent.span_index) + } else { + None + }; + let InstructionPointer { + module_index, + frames, + custom_name, + } = ip; + let module = self + .strings + .get(*module_index) + .context("module not found")?; + let name = if let Some(name) = custom_name.as_ref() { + name.to_string() + } else if let Some(first_frame) = frames.first() { + let file = self + .strings + .get(first_frame.file_index) + .context("file not found")?; + let function = self + .strings + .get(first_frame.function_index) + .context("function not found")?; + format!("{} @ {file}:{}", function, first_frame.line) + } else { + "unknown".to_string() + }; + let mut args = Vec::new(); + for Frame { + function_index, + file_index, + line, + } in frames.iter() + { + let file = self.strings.get(*file_index).context("file not found")?; + let function = self + .strings + .get(*function_index) + .context("function not found")?; + args.push(( + "location".to_string(), + format!("{} @ {file}:{line}", function), + )); + } + + let span_index = store.add_span( + parent, + self.last_timestamp, + module.to_string(), + name, + args, + &mut outdated_spans, + ); + store.complete_span(span_index); + self.spans += 1; + let index = self.traces.len(); + self.traces.push(TraceData { + span_index, + ip_index, + parent_trace_index: parent_index, + }); + self.instruction_pointers + .get_index_mut(ip_index) + .unwrap() + .1 + .first_trace_of_ip + .get_or_insert(index); + if let Some(parent) = parent { + self.ip_parent_map.insert((ip_index, parent), index); + } + } + b'i' => { + let mut ip = InstructionPointer::read(&mut line)?; + if let Some(frame) = ip.frames.first() { + if let Some(function) = self.strings.get(frame.function_index) { + let crate_name = function + .strip_prefix('<') + .unwrap_or(function) + .split("::") + .next() + .unwrap() + .split('[') + .next() + .unwrap(); + if self.collapse_crates.contains(crate_name) + || !self.expand_crates.is_empty() + && !self.expand_crates.contains(crate_name) + { + ip.frames.clear(); + ip.custom_name = Some(crate_name.to_string()); + } + } + } + match self.instruction_pointers.entry(ip) { + Entry::Occupied(e) => { + self.trace_instruction_pointers.push(e.index()); + } + Entry::Vacant(e) => { + self.trace_instruction_pointers.push(e.index()); + e.insert(InstructionPointerExtraInfo { + first_trace_of_ip: None, + }); + } + } + } + b'#' => { + // comment + } + b'X' => { + let line = from_utf8(line)?; + println!("Debuggee: {line}"); + } + b'c' => { + // timestamp + let timestamp = read_hex(&mut line)?; + self.last_timestamp = timestamp; + } + b'a' => { + // allocation info + let info = AllocationInfo::read(&mut line)?; + self.allocations.push(info); + } + b'+' => { + // allocation + let index = read_hex_index(&mut line)?; + let AllocationInfo { size, trace_index } = self + .allocations + .get(index) + .context("allocation not found")?; + if *trace_index > 0 { + let TraceData { span_index, .. } = + self.traces.get(*trace_index).context("trace not found")?; + store.add_allocation(*span_index, *size, 1, &mut outdated_spans); + self.allocated_memory += *size; + } + } + b'-' => { + // deallocation + let index = read_hex_index(&mut line)?; + let AllocationInfo { size, trace_index } = self + .allocations + .get(index) + .context("allocation not found")?; + if *trace_index > 0 { + let TraceData { span_index, .. } = + self.traces.get(*trace_index).context("trace not found")?; + store.add_deallocation(*span_index, *size, 1, &mut outdated_spans); + self.allocated_memory -= *size; + self.temp_allocated_memory += *size; + } + } + b'R' => { + // RSS timestamp + } + b'A' => { + // attached + // ignore + } + b'S' => { + // embedded suppression + // ignore + } + b'I' => { + // System info + // ignore + } + _ => { + let line = from_utf8(line)?; + println!("{} {line}", ty as char) + } + } + } + store.invalidate_outdated_spans(&outdated_spans); + Ok(bytes_read) + } +} + +fn read_hex_index(s: &mut &[u8]) -> anyhow::Result { + Ok(read_hex(s)? as usize) +} + +fn read_hex(s: &mut &[u8]) -> anyhow::Result { + let mut n: u64 = 0; + loop { + if let Some(c) = s.first() { + match c { + b'0'..=b'9' => { + n *= 16; + n += (*c - b'0') as u64; + } + b'a'..=b'f' => { + n *= 16; + n += (*c - b'a' + 10) as u64; + } + b' ' => { + *s = &s[1..]; + return Ok(n); + } + _ => { + bail!("Expected hex char"); + } + } + *s = &s[1..]; + } else { + return Ok(n); + } + } +} + +fn read_sized_string(s: &mut &[u8]) -> anyhow::Result { + let size = read_hex(s)? as usize; + let str = &s[..size]; + *s = &s[size..]; + Ok(String::from_utf8(str.to_vec())?) +} + +fn read_all( + s: &mut &[u8], + f: impl Fn(&mut &[u8]) -> anyhow::Result, +) -> anyhow::Result> { + let mut res = Vec::new(); + while !s.is_empty() { + res.push(f(s)?); + } + Ok(res) +} diff --git a/turbopack/crates/turbopack-trace-server/src/reader/mod.rs b/turbopack/crates/turbopack-trace-server/src/reader/mod.rs new file mode 100644 index 0000000000000..eef48a775fced --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/reader/mod.rs @@ -0,0 +1,285 @@ +mod heaptrack; +mod nextjs; +mod turbopack; + +use std::{ + env, + fs::File, + io::{self, BufReader, Read, Seek, SeekFrom}, + path::PathBuf, + sync::Arc, + thread::{self, JoinHandle}, + time::Duration, +}; + +use anyhow::Result; +use flate2::bufread::GzDecoder; + +use crate::{ + reader::{heaptrack::HeaptrackFormat, nextjs::NextJsFormat, turbopack::TurbopackFormat}, + store_container::StoreContainer, +}; + +const MIN_INITIAL_REPORT_SIZE: u64 = 100 * 1024 * 1024; + +trait TraceFormat { + fn read(&mut self, buffer: &[u8]) -> Result; + fn stats(&self) -> String { + String::new() + } +} + +#[derive(Default)] +enum TraceFile { + Raw(File), + Zstd(zstd::Decoder<'static, BufReader>), + Gz(GzDecoder>), + #[default] + Unloaded, +} + +impl TraceFile { + fn read(&mut self, buffer: &mut [u8]) -> io::Result { + match self { + Self::Raw(file) => file.read(buffer), + Self::Zstd(decoder) => decoder.read(buffer), + Self::Gz(decoder) => decoder.read(buffer), + Self::Unloaded => unreachable!(), + } + } + + fn stream_position(&mut self) -> io::Result { + match self { + Self::Raw(file) => file.stream_position(), + Self::Zstd(decoder) => decoder.get_mut().stream_position(), + Self::Gz(decoder) => decoder.get_mut().stream_position(), + Self::Unloaded => unreachable!(), + } + } + + fn seek(&mut self, pos: SeekFrom) -> io::Result { + match self { + Self::Raw(file) => file.seek(pos), + Self::Zstd(decoder) => decoder.get_mut().seek(pos), + Self::Gz(decoder) => decoder.get_mut().seek(pos), + Self::Unloaded => unreachable!(), + } + } +} + +pub struct TraceReader { + store: Arc, + path: PathBuf, +} + +impl TraceReader { + pub fn spawn(store: Arc, path: PathBuf) -> JoinHandle<()> { + let mut reader = Self { store, path }; + std::thread::spawn(move || reader.run()) + } + + pub fn run(&mut self) { + loop { + self.try_read(); + thread::sleep(Duration::from_millis(500)); + } + } + + fn trace_file_from_file(&self, file: File) -> io::Result { + let path = &self.path.to_string_lossy(); + Ok(if path.ends_with(".zst") { + TraceFile::Zstd(zstd::Decoder::new(file)?) + } else if path.ends_with(".gz") { + TraceFile::Gz(GzDecoder::new(BufReader::new(file))) + } else { + TraceFile::Raw(file) + }) + } + + fn try_read(&mut self) -> bool { + let Ok(mut file) = File::open(&self.path) else { + return false; + }; + println!("Trace file opened"); + let stop_at = env::var("STOP_AT") + .unwrap_or_default() + .parse() + .map_or(u64::MAX, |v: u64| v * 1024 * 1024); + if stop_at != u64::MAX { + println!("Will stop reading file at {} MB", stop_at / 1024 / 1024) + } + + { + let mut store = self.store.write(); + store.reset(); + } + + let mut format: Option> = None; + + let mut current_read = 0; + let mut initial_read = { file.seek(SeekFrom::End(0)).ok() }; + if file.seek(SeekFrom::Start(0)).is_err() { + return false; + } + let mut file = match self.trace_file_from_file(file) { + Ok(f) => f, + Err(err) => { + println!("Error creating zstd decoder: {err}"); + return false; + } + }; + + let mut buffer = Vec::new(); + let mut index = 0; + + let mut chunk = vec![0; 64 * 1024 * 1024]; + loop { + match file.read(&mut chunk) { + Ok(bytes_read) => { + if bytes_read == 0 { + if let Some(value) = + self.wait_for_more_data(&mut file, &mut initial_read, format.as_deref()) + { + return value; + } + } else { + // If we have partially consumed some data, and we are at buffer capacity, + // remove the consumed data to make more space. + if index > 0 && buffer.len() + bytes_read > buffer.capacity() { + buffer.splice(..index, std::iter::empty()); + index = 0; + } + buffer.extend_from_slice(&chunk[..bytes_read]); + if format.is_none() && buffer.len() >= 8 { + if buffer.starts_with(b"TRACEv0") { + index = 7; + format = Some(Box::new(TurbopackFormat::new(self.store.clone()))); + } else if buffer.starts_with(b"[{\"name\"") { + format = Some(Box::new(NextJsFormat::new(self.store.clone()))); + } else if buffer.starts_with(b"v ") { + format = Some(Box::new(HeaptrackFormat::new(self.store.clone()))) + } else { + // Fallback to the format without magic bytes + // TODO Remove this after a while and show an error instead + format = Some(Box::new(TurbopackFormat::new(self.store.clone()))); + } + } + if let Some(format) = &mut format { + match format.read(&buffer[index..]) { + Ok(bytes_read) => { + index += bytes_read; + } + Err(err) => { + println!("Trace file error: {err}"); + return true; + } + } + if self.store.want_to_read() { + thread::yield_now(); + } + let prev_read = current_read; + current_read += bytes_read as u64; + if let Some(total) = &mut initial_read { + let old_mbs = prev_read / (97 * 1024 * 1024); + let new_mbs = current_read / (97 * 1024 * 1024); + if old_mbs != new_mbs { + let pos = file.stream_position().unwrap_or(current_read); + *total = (*total).max(pos); + let percentage = pos * 100 / *total; + let read = pos / (1024 * 1024); + let uncompressed = current_read / (1024 * 1024); + let total = *total / (1024 * 1024); + let stats = format.stats(); + print!("{}% read ({}/{} MB)", percentage, read, total); + if uncompressed != read { + print!(" ({} MB uncompressed)", uncompressed); + } + if stats.is_empty() { + println!(); + } else { + println!(" - {}", stats); + } + } + } + if current_read >= stop_at { + println!( + "Stopped reading file as requested by STOP_AT env var. \ + Waiting for new file..." + ); + self.wait_for_new_file(&mut file); + return true; + } + } + } + } + Err(err) => { + if err.kind() == io::ErrorKind::UnexpectedEof { + if let Some(value) = + self.wait_for_more_data(&mut file, &mut initial_read, format.as_deref()) + { + return value; + } + } else { + // Error reading file, maybe it was removed + println!("Error reading trace file: {err:?}"); + return true; + } + } + } + } + } + + fn wait_for_more_data( + &mut self, + file: &mut TraceFile, + initial_read: &mut Option, + format: Option<&dyn TraceFormat>, + ) -> Option { + let Ok(pos) = file.stream_position() else { + return Some(true); + }; + if let Some(total) = initial_read.take() { + if let Some(format) = format { + let stats = format.stats(); + println!("{}", stats); + } + if total > MIN_INITIAL_REPORT_SIZE { + println!("Initial read completed ({} MB)", total / (1024 * 1024)); + } + } + thread::sleep(Duration::from_millis(100)); + let Ok(end) = file.seek(SeekFrom::End(0)) else { + return Some(true); + }; + // No more data to read, sleep for a while to wait for more data + if end < pos { + // new file + return Some(true); + } else if end != pos { + // Seek to the same position. This will fail when the file was + // truncated. + let Ok(new_pos) = file.seek(SeekFrom::Start(pos)) else { + return Some(true); + }; + if new_pos != pos { + return Some(true); + } + } + None + } + + fn wait_for_new_file(&self, file: &mut TraceFile) { + let Ok(pos) = file.stream_position() else { + return; + }; + loop { + thread::sleep(Duration::from_millis(1000)); + let Ok(end) = file.seek(SeekFrom::End(0)) else { + return; + }; + if end < pos { + return; + } + } + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/reader/nextjs.rs b/turbopack/crates/turbopack-trace-server/src/reader/nextjs.rs new file mode 100644 index 0000000000000..2903ffd18770f --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/reader/nextjs.rs @@ -0,0 +1,143 @@ +use std::{ + borrow::Cow, + collections::{HashMap, HashSet}, + fmt::Display, + sync::Arc, +}; + +use indexmap::IndexMap; +use serde::Deserialize; + +use super::TraceFormat; +use crate::{span::SpanIndex, store_container::StoreContainer}; + +pub struct NextJsFormat { + store: Arc, + id_mapping: HashMap, + queued_children: HashMap>, +} + +impl NextJsFormat { + pub fn new(store: Arc) -> Self { + Self { + store, + id_mapping: HashMap::new(), + queued_children: HashMap::new(), + } + } +} + +impl TraceFormat for NextJsFormat { + fn read(&mut self, mut buffer: &[u8]) -> anyhow::Result { + let mut bytes_read = 0; + let mut outdated_spans = HashSet::new(); + loop { + let Some(line_end) = buffer.iter().position(|b| *b == b'\n') else { + break; + }; + let line = &buffer[..line_end]; + buffer = &buffer[line_end + 1..]; + bytes_read += line.len() + 1; + + let spans: Vec = serde_json::from_slice(line)?; + + let mut store = self.store.write(); + + for span in spans { + let NextJsSpan { + name, + duration, + timestamp, + id, + parent_id, + tags, + start_time: _, + trace_id: _, + } = span; + let (parent, queue_parent) = if let Some(parent) = parent_id { + if let Some(parent) = self.id_mapping.get(&parent) { + (Some(*parent), None) + } else { + (None, Some(parent)) + } + } else { + (None, None) + }; + let index = store.add_span( + parent, + timestamp, + "nextjs".to_string(), + name.into_owned(), + tags.iter() + .map(|(k, v)| { + ( + k.to_string(), + v.as_ref().map(|v| v.to_string()).unwrap_or_default(), + ) + }) + .collect(), + &mut outdated_spans, + ); + self.id_mapping.insert(id, index); + if let Some(parent) = queue_parent { + self.queued_children.entry(parent).or_default().push(index); + } + if let Some(children) = self.queued_children.remove(&id) { + for child in children { + store.set_parent(child, index, &mut outdated_spans); + } + } + store.set_total_time(index, timestamp, duration, &mut outdated_spans); + store.complete_span(index); + } + store.invalidate_outdated_spans(&outdated_spans); + drop(store); + } + Ok(bytes_read) + } +} + +#[derive(Debug, Deserialize)] +#[serde(untagged)] + +enum TagValue<'a> { + String(Cow<'a, str>), + Number(f64), + Bool(bool), + Array(Vec>), +} + +impl<'a> Display for TagValue<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + TagValue::String(s) => write!(f, "{}", s), + TagValue::Number(n) => write!(f, "{}", n), + TagValue::Bool(b) => write!(f, "{}", b), + TagValue::Array(a) => { + write!(f, "[")?; + for (i, v) in a.iter().enumerate() { + if i > 0 { + write!(f, ", ")?; + } + write!(f, "{}", v)?; + } + write!(f, "]") + } + } + } +} + +#[derive(Debug, Deserialize)] +#[serde(rename_all = "camelCase")] +struct NextJsSpan<'a> { + name: Cow<'a, str>, + duration: u64, + timestamp: u64, + id: u64, + parent_id: Option, + tags: IndexMap, Option>>, + #[allow(dead_code)] + start_time: u64, + #[allow(dead_code)] + trace_id: Cow<'a, str>, +} diff --git a/turbopack/crates/turbopack-trace-server/src/reader/turbopack.rs b/turbopack/crates/turbopack-trace-server/src/reader/turbopack.rs new file mode 100644 index 0000000000000..f42c599edd415 --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/reader/turbopack.rs @@ -0,0 +1,328 @@ +use std::{ + collections::{hash_map::Entry, HashMap, HashSet}, + sync::Arc, +}; + +use anyhow::Result; +use indexmap::IndexMap; +use turbopack_trace_utils::tracing::TraceRow; + +use super::TraceFormat; +use crate::{ + span::SpanIndex, + store_container::{StoreContainer, StoreWriteGuard}, +}; + +#[derive(Default)] +struct AllocationInfo { + allocations: u64, + deallocations: u64, + allocation_count: u64, + deallocation_count: u64, +} + +pub struct TurbopackFormat { + store: Arc, + active_ids: HashMap, + queued_rows: HashMap>>, + outdated_spans: HashSet, + thread_stacks: HashMap>, + thread_allocation_counters: HashMap, + self_time_started: HashMap<(SpanIndex, u64), u64>, +} + +impl TurbopackFormat { + pub fn new(store: Arc) -> Self { + Self { + store, + active_ids: HashMap::new(), + queued_rows: HashMap::new(), + outdated_spans: HashSet::new(), + thread_stacks: HashMap::new(), + thread_allocation_counters: HashMap::new(), + self_time_started: HashMap::new(), + } + } + + fn process(&mut self, store: &mut StoreWriteGuard, row: TraceRow<'_>) { + match row { + TraceRow::Start { + ts, + id, + parent, + name, + target, + values, + } => { + let parent = if let Some(parent) = parent { + if let Some(parent) = self.active_ids.get(&parent) { + Some(*parent) + } else { + self.queued_rows + .entry(parent) + .or_default() + .push(TraceRow::Start { + ts, + id, + parent: Some(parent), + name: name.into_owned().into(), + target: target.into_owned().into(), + values: values + .into_iter() + .map(|(k, v)| (k.into_owned().into(), v.into_static())) + .collect(), + }); + return; + } + } else { + None + }; + let span_id = store.add_span( + parent, + ts, + target.into_owned(), + name.into_owned(), + values + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + &mut self.outdated_spans, + ); + self.active_ids.insert(id, span_id); + } + TraceRow::Record { id, values } => { + let Some(&id) = self.active_ids.get(&id) else { + self.queued_rows + .entry(id) + .or_default() + .push(TraceRow::Record { + id, + values: values + .into_iter() + .map(|(k, v)| (k.into_owned().into(), v.into_static())) + .collect(), + }); + return; + }; + store.add_args( + id, + values + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + &mut self.outdated_spans, + ); + } + TraceRow::End { ts: _, id } => { + // id might be reused + let index = self.active_ids.remove(&id); + if let Some(index) = index { + store.complete_span(index); + } + } + TraceRow::Enter { ts, id, thread_id } => { + let Some(&id) = self.active_ids.get(&id) else { + self.queued_rows + .entry(id) + .or_default() + .push(TraceRow::Enter { ts, id, thread_id }); + return; + }; + let stack = self.thread_stacks.entry(thread_id).or_default(); + if let Some(&parent) = stack.last() { + if let Some(parent_start) = self.self_time_started.remove(&(parent, thread_id)) + { + store.add_self_time(parent, parent_start, ts, &mut self.outdated_spans); + } + } + stack.push(id); + self.self_time_started.insert((id, thread_id), ts); + } + TraceRow::Exit { ts, id, thread_id } => { + let Some(&id) = self.active_ids.get(&id) else { + self.queued_rows + .entry(id) + .or_default() + .push(TraceRow::Exit { ts, id, thread_id }); + return; + }; + let stack = self.thread_stacks.entry(thread_id).or_default(); + if let Some(pos) = stack.iter().rev().position(|&x| x == id) { + let stack_index = stack.len() - pos - 1; + stack.remove(stack_index); + if stack_index > 0 { + let parent = stack[stack_index - 1]; + self.self_time_started.insert((parent, thread_id), ts); + } + } + if let Some(start) = self.self_time_started.remove(&(id, thread_id)) { + store.add_self_time(id, start, ts, &mut self.outdated_spans); + } + } + TraceRow::Event { ts, parent, values } => { + let parent = if let Some(parent) = parent { + if let Some(parent) = self.active_ids.get(&parent) { + Some(*parent) + } else { + self.queued_rows + .entry(parent) + .or_default() + .push(TraceRow::Event { + ts, + parent: Some(parent), + values: values + .into_iter() + .map(|(k, v)| (k.into_owned().into(), v.into_static())) + .collect(), + }); + return; + } + } else { + None + }; + let mut values = values.into_iter().collect::>(); + let duration = values + .remove("duration") + .and_then(|v| v.as_u64()) + .unwrap_or(0); + let name = values + .remove("name") + .and_then(|v| v.as_str().map(|s| s.to_string())) + .unwrap_or("event".into()); + + let id = store.add_span( + parent, + ts.saturating_sub(duration), + "event".into(), + name, + values + .iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(), + &mut self.outdated_spans, + ); + store.add_self_time( + id, + ts.saturating_sub(duration), + ts, + &mut self.outdated_spans, + ); + } + TraceRow::Allocation { + ts: _, + thread_id, + allocations, + allocation_count, + deallocations, + deallocation_count, + } => { + let stack = self.thread_stacks.entry(thread_id).or_default(); + if let Some(&id) = stack.last() { + if allocations > 0 { + store.add_allocation( + id, + allocations, + allocation_count, + &mut self.outdated_spans, + ); + } + if deallocations > 0 { + store.add_deallocation( + id, + deallocations, + deallocation_count, + &mut self.outdated_spans, + ); + } + } + } + TraceRow::AllocationCounters { + ts: _, + thread_id, + allocations, + allocation_count, + deallocations, + deallocation_count, + } => { + let info = AllocationInfo { + allocations, + deallocations, + allocation_count, + deallocation_count, + }; + let mut diff = AllocationInfo::default(); + match self.thread_allocation_counters.entry(thread_id) { + Entry::Occupied(mut entry) => { + let counter = entry.get_mut(); + diff.allocations = info.allocations - counter.allocations; + diff.deallocations = info.deallocations - counter.deallocations; + diff.allocation_count = info.allocation_count - counter.allocation_count; + diff.deallocation_count = + info.deallocation_count - counter.deallocation_count; + counter.allocations = info.allocations; + counter.deallocations = info.deallocations; + counter.allocation_count = info.allocation_count; + counter.deallocation_count = info.deallocation_count; + } + Entry::Vacant(entry) => { + entry.insert(info); + } + } + let stack = self.thread_stacks.entry(thread_id).or_default(); + if let Some(&id) = stack.last() { + if diff.allocations > 0 { + store.add_allocation( + id, + diff.allocations, + diff.allocation_count, + &mut self.outdated_spans, + ); + } + if diff.deallocations > 0 { + store.add_deallocation( + id, + diff.deallocations, + diff.deallocation_count, + &mut self.outdated_spans, + ); + } + } + } + } + } +} + +impl TraceFormat for TurbopackFormat { + fn read(&mut self, mut buffer: &[u8]) -> Result { + let mut rows = Vec::new(); + let mut bytes_read = 0; + loop { + match postcard::take_from_bytes(buffer) { + Ok((row, remaining)) => { + bytes_read += buffer.len() - remaining.len(); + buffer = remaining; + rows.push(row); + } + Err(err) => { + if matches!(err, postcard::Error::DeserializeUnexpectedEnd) { + break; + } + return Err(err.into()); + } + } + } + if !rows.is_empty() { + let store = self.store.clone(); + let mut iter = rows.into_iter(); + { + let mut store = store.write(); + for row in iter.by_ref() { + self.process(&mut store, row); + } + store.invalidate_outdated_spans(&self.outdated_spans); + self.outdated_spans.clear(); + } + } + Ok(bytes_read) + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/self_time_tree.rs b/turbopack/crates/turbopack-trace-server/src/self_time_tree.rs new file mode 100644 index 0000000000000..f795d5b52cdd3 --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/self_time_tree.rs @@ -0,0 +1,252 @@ +use std::{ + cmp::{max, min}, + mem::{replace, take}, +}; + +const SPLIT_COUNT: usize = 128; + +pub struct SelfTimeTree { + entries: Vec>, + children: Option>>, + count: usize, +} + +struct SelfTimeEntry { + start: u64, + end: u64, + item: T, +} + +struct SelfTimeChildren { + /// Entries < split_point + left: SelfTimeTree, + split_point: u64, + /// Entries >= split_point + right: SelfTimeTree, +} + +impl Default for SelfTimeTree { + fn default() -> Self { + Self { + entries: Vec::new(), + children: None, + count: 0, + } + } +} + +impl SelfTimeTree { + pub fn new() -> Self { + Self::default() + } + + pub fn len(&self) -> usize { + self.count + } + + pub fn insert(&mut self, start: u64, end: u64, item: T) { + self.count += 1; + if let Some(children) = &mut self.children { + if end <= children.split_point { + children.left.insert(start, end, item); + } else if start >= children.split_point { + children.right.insert(start, end, item); + } else { + self.entries.push(SelfTimeEntry { start, end, item }); + } + self.rebalance(); + } else { + self.entries.push(SelfTimeEntry { start, end, item }); + if self.entries.len() >= SPLIT_COUNT { + self.split(); + } + } + } + + fn split(&mut self) { + if self.entries.is_empty() { + return; + } + let entries = take(&mut self.entries); + let start = entries.iter().min_by_key(|e| e.start).unwrap().start; + let end = entries.iter().max_by_key(|e| e.end).unwrap().end; + let middle = (start + end) / 2; + self.children = Some(Box::new(SelfTimeChildren { + left: SelfTimeTree::new(), + split_point: middle, + right: SelfTimeTree::new(), + })); + self.count = 0; + for entry in entries { + self.insert(entry.start, entry.end, entry.item); + } + } + + fn rebalance(&mut self) { + if let Some(box SelfTimeChildren { + left, + split_point, + right, + }) = &mut self.children + { + let SelfTimeTree { + count: left_count, + children: left_children, + entries: left_entries, + } = left; + let SelfTimeTree { + count: right_count, + children: right_children, + entries: right_entries, + } = right; + if *left_count > *right_count * 3 + left_entries.len() { + if let Some(box SelfTimeChildren { + left: left_left, + split_point: left_split_point, + right: left_right, + }) = left_children + { + let left_entries = take(left_entries); + *right = Self { + count: left_right.count + right.count + self.entries.len(), + entries: take(&mut self.entries), + children: Some(Box::new(SelfTimeChildren { + left: take(left_right), + split_point: *split_point, + right: take(right), + })), + }; + *split_point = *left_split_point; + *left = take(left_left); + let entries = replace(&mut self.entries, left_entries); + self.count = left.count + right.count + self.entries.len(); + for SelfTimeEntry { start, end, item } in entries { + self.insert(start, end, item); + } + } + } else if *right_count > *left_count * 3 + right_entries.len() { + if let Some(box SelfTimeChildren { + left: right_left, + split_point: right_split_point, + right: right_right, + }) = right_children + { + let right_entries = take(right_entries); + *left = Self { + count: left.count + right_left.count + self.entries.len(), + entries: take(&mut self.entries), + children: Some(Box::new(SelfTimeChildren { + left: take(left), + split_point: *split_point, + right: take(right_left), + })), + }; + *split_point = *right_split_point; + *right = take(right_right); + let entries = replace(&mut self.entries, right_entries); + self.count = left.count + right.count + self.entries.len(); + for SelfTimeEntry { start, end, item } in entries { + self.insert(start, end, item); + } + } + } + } + } + + pub fn lookup_range_count(&self, start: u64, end: u64) -> u64 { + let mut total_count = 0; + for entry in &self.entries { + if entry.start < end && entry.end > start { + let start = max(entry.start, start); + let end = min(entry.end, end); + let span = end - start; + total_count += span; + } + } + if let Some(children) = &self.children { + if start < children.split_point { + total_count += children.left.lookup_range_count(start, end); + } + if end > children.split_point { + total_count += children.right.lookup_range_count(start, end); + } + } + total_count + } + + pub fn for_each_in_range(&self, start: u64, end: u64, mut f: impl FnMut(u64, u64, &T)) { + self.for_each_in_range_ref(start, end, &mut f); + } + + fn for_each_in_range_ref(&self, start: u64, end: u64, f: &mut impl FnMut(u64, u64, &T)) { + for entry in &self.entries { + if entry.start < end && entry.end > start { + f(entry.start, entry.end, &entry.item); + } + } + if let Some(children) = &self.children { + if start < children.split_point { + children.left.for_each_in_range_ref(start, end, f); + } + if end > children.split_point { + children.right.for_each_in_range_ref(start, end, f); + } + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn print_tree(tree: &SelfTimeTree, indent: usize) { + if let Some(children) = &tree.children { + println!( + "{}{} items (split at {}, {} total)", + " ".repeat(indent), + tree.entries.len(), + children.split_point, + tree.count + ); + print_tree(&children.left, indent + 2); + print_tree(&children.right, indent + 2); + } else { + println!( + "{}{} items ({} total)", + " ".repeat(indent), + tree.entries.len(), + tree.count + ); + } + } + + #[test] + fn test_simple() { + let mut tree = SelfTimeTree::new(); + for i in 0..1000 { + tree.insert(i, i + 1, i); + } + assert_eq!(tree.lookup_range_count(0, 1000), 1000); + print_tree(&tree, 0); + } + + #[test] + fn test_overlapping() { + let mut tree = SelfTimeTree::new(); + for i in 0..1000 { + tree.insert(i, i + 100, i); + } + assert_eq!(tree.lookup_range_count(0, 1100), 1000 * 100); + print_tree(&tree, 0); + } + + #[test] + fn test_overlapping_heavy() { + let mut tree = SelfTimeTree::new(); + for i in 0..1000 { + tree.insert(i, i + 500, i); + } + assert_eq!(tree.lookup_range_count(0, 2000), 1000 * 500); + print_tree(&tree, 0); + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/server.rs b/turbopack/crates/turbopack-trace-server/src/server.rs new file mode 100644 index 0000000000000..3b42d5f3f667a --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/server.rs @@ -0,0 +1,365 @@ +use std::{ + net::{TcpListener, TcpStream}, + sync::{Arc, Mutex}, + thread::spawn, +}; + +use anyhow::{bail, Result}; +use serde::{Deserialize, Serialize}; +use tungstenite::{accept, Message}; + +use crate::{ + store::SpanId, + store_container::StoreContainer, + u64_string, + viewer::{Update, ViewLineUpdate, ViewMode, Viewer}, +}; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +#[serde(rename_all = "kebab-case")] +pub enum ServerToClientMessage { + ViewLine { + #[serde(flatten)] + update: ViewLineUpdate, + }, + ViewLinesCount { + count: usize, + max: u64, + }, + #[serde(rename_all = "camelCase")] + QueryResult { + #[serde(with = "u64_string")] + id: SpanId, + is_graph: bool, + start: u64, + end: u64, + duration: u64, + cpu: u64, + allocations: u64, + deallocations: u64, + allocation_count: u64, + persistent_allocations: u64, + args: Vec<(String, String)>, + path: Vec, + }, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "type")] +#[serde(rename_all = "kebab-case")] +pub enum ClientToServerMessage { + #[serde(rename_all = "camelCase")] + ViewRect { + view_rect: ViewRect, + }, + ViewMode { + #[serde(with = "u64_string")] + id: SpanId, + mode: String, + inherit: bool, + }, + ResetViewMode { + #[serde(with = "u64_string")] + id: SpanId, + }, + Query { + #[serde(with = "u64_string")] + id: SpanId, + }, + Ack, + CheckForMoreData, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SpanViewEvent { + pub start: u64, + pub duration: u64, + pub name: String, + pub id: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Filter { + pub op: Op, + pub value: u64, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "snake_case")] +pub enum Op { + Gt, + Lt, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ViewRect { + pub x: u64, + pub y: u64, + pub width: u64, + pub height: u64, + pub horizontal_pixels: u64, + pub query: String, + pub view_mode: String, + pub value_mode: String, + pub value_filter: Option, + pub count_filter: Option, +} + +struct ConnectionState { + store: Arc, + viewer: Viewer, + view_rect: ViewRect, + last_update_generation: usize, +} + +pub fn serve(store: Arc) { + let server = TcpListener::bind("127.0.0.1:5747").unwrap(); + for stream in server.incoming() { + let store = store.clone(); + + spawn(move || { + let websocket = accept(stream.unwrap()).unwrap(); + if let Err(err) = handle_connection(websocket, store) { + eprintln!("Error: {:?}", err); + } + }); + } +} + +fn handle_connection( + mut websocket: tungstenite::WebSocket, + store: Arc, +) -> Result<()> { + let state = Arc::new(Mutex::new(ConnectionState { + store, + viewer: Viewer::new(), + view_rect: ViewRect { + x: 0, + y: 0, + width: 1, + height: 1, + horizontal_pixels: 1, + query: String::new(), + view_mode: "aggregated".to_string(), + value_mode: "duration".to_string(), + count_filter: None, + value_filter: None, + }, + last_update_generation: 0, + })); + let mut update_skipped = false; + let mut ready_for_update = true; + + fn send_update( + websocket: &mut tungstenite::WebSocket, + state: &mut ConnectionState, + force_send: bool, + ready_for_update: &mut bool, + update_skipped: &mut bool, + ) -> Result<()> { + if !*ready_for_update { + if force_send { + *update_skipped = true; + } + return Ok(()); + } + let store = state.store.read(); + if !force_send && state.last_update_generation == store.generation() { + return Ok(()); + } + state.last_update_generation = store.generation(); + let Update { + lines: updates, + max, + } = state.viewer.compute_update(&store, &state.view_rect); + let count = updates.len(); + for update in updates { + let message = ServerToClientMessage::ViewLine { update }; + let message = serde_json::to_string(&message).unwrap(); + websocket.send(Message::Text(message))?; + } + let message = ServerToClientMessage::ViewLinesCount { count, max }; + let message = serde_json::to_string(&message).unwrap(); + websocket.send(Message::Text(message))?; + *ready_for_update = false; + Ok(()) + } + loop { + match websocket.read()? { + Message::Frame(_frame) => {} + Message::Text(text) => { + let message: ClientToServerMessage = serde_json::from_str(&text)?; + let mut state = state.lock().unwrap(); + match message { + ClientToServerMessage::CheckForMoreData => { + send_update( + &mut websocket, + &mut state, + false, + &mut ready_for_update, + &mut update_skipped, + )?; + } + ClientToServerMessage::ViewRect { view_rect } => { + state.view_rect = view_rect; + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; + } + ClientToServerMessage::ViewMode { id, mode, inherit } => { + let (mode, sorted) = if let Some(mode) = mode.strip_suffix("-sorted") { + (mode, true) + } else { + (mode.as_str(), false) + }; + match mode { + "raw-spans" => { + state.viewer.set_view_mode( + id, + Some((ViewMode::RawSpans { sorted }, inherit)), + ); + } + "aggregated" => { + state.viewer.set_view_mode( + id, + Some((ViewMode::Aggregated { sorted }, inherit)), + ); + } + "bottom-up" => { + state.viewer.set_view_mode( + id, + Some((ViewMode::BottomUp { sorted }, inherit)), + ); + } + "aggregated-bottom-up" => { + state.viewer.set_view_mode( + id, + Some((ViewMode::AggregatedBottomUp { sorted }, inherit)), + ); + } + _ => { + bail!("unknown view mode: {}", mode) + } + } + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; + } + ClientToServerMessage::ResetViewMode { id } => { + state.viewer.set_view_mode(id, None); + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; + } + ClientToServerMessage::Query { id } => { + let message = { + let store = state.store.read(); + if let Some((span, is_graph)) = store.span(id) { + let root_start = store.root_span().start(); + let span_start = span.start() - root_start; + let span_end = span.end() - root_start; + let duration = span.corrected_total_time(); + let cpu = span.total_time(); + let allocations = span.total_allocations(); + let deallocations = span.total_deallocations(); + let allocation_count = span.total_allocation_count(); + let persistent_allocations = span.total_persistent_allocations(); + let args = span + .args() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + let mut path = Vec::new(); + let mut current = span; + while let Some(parent) = current.parent() { + path.push(parent.nice_name().1.to_string()); + current = parent; + } + path.reverse(); + ServerToClientMessage::QueryResult { + id, + is_graph, + start: span_start, + end: span_end, + duration, + cpu, + allocations, + deallocations, + allocation_count, + persistent_allocations, + args, + path, + } + } else { + ServerToClientMessage::QueryResult { + id, + is_graph: false, + start: 0, + end: 0, + duration: 0, + cpu: 0, + allocations: 0, + deallocations: 0, + allocation_count: 0, + persistent_allocations: 0, + args: Vec::new(), + path: Vec::new(), + } + } + }; + let message = serde_json::to_string(&message).unwrap(); + websocket.send(Message::Text(message))?; + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; + + continue; + } + ClientToServerMessage::Ack => { + ready_for_update = true; + if update_skipped { + update_skipped = false; + send_update( + &mut websocket, + &mut state, + true, + &mut ready_for_update, + &mut update_skipped, + )?; + } + } + } + } + Message::Binary(_) => { + // This doesn't happen + } + Message::Close(_) => { + return Ok(()); + } + Message::Ping(d) => { + websocket.send(Message::Pong(d))?; + } + Message::Pong(_) => { + // thanks for the fish + } + } + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/span.rs b/turbopack/crates/turbopack-trace-server/src/span.rs new file mode 100644 index 0000000000000..93f5be1a73a4f --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/span.rs @@ -0,0 +1,178 @@ +use std::{ + collections::HashMap, + num::NonZeroUsize, + sync::{Arc, OnceLock}, +}; + +pub type SpanIndex = NonZeroUsize; + +pub struct Span { + // These values won't change after creation: + pub parent: Option, + pub depth: u32, + pub start: u64, + pub category: String, + pub name: String, + pub args: Vec<(String, String)>, + + // This might change during writing: + pub events: Vec, + pub is_complete: bool, + + // These values are computed automatically: + pub self_allocations: u64, + pub self_allocation_count: u64, + pub self_deallocations: u64, + pub self_deallocation_count: u64, + + // These values are computed when accessed (and maybe deleted during writing): + pub max_depth: OnceLock, + pub total_allocations: OnceLock, + pub total_deallocations: OnceLock, + pub total_persistent_allocations: OnceLock, + pub total_span_count: OnceLock, + pub total_allocation_count: OnceLock, + + // More nested fields, but memory lazily allocated + pub time_data: OnceLock>, + pub extra: OnceLock>, + pub names: OnceLock>, +} + +#[derive(Default)] +pub struct SpanTimeData { + // These values won't change after creation: + pub ignore_self_time: bool, + + // This might change during writing: + pub self_end: u64, + + // These values are computed automatically: + pub self_time: u64, + + // These values are computed when accessed (and maybe deleted during writing): + pub end: OnceLock, + pub total_time: OnceLock, + pub corrected_self_time: OnceLock, + pub corrected_total_time: OnceLock, +} + +#[derive(Default)] +pub struct SpanExtra { + pub graph: OnceLock>, + pub bottom_up: OnceLock>>, + pub search_index: OnceLock>>, +} + +#[derive(Default)] +pub struct SpanNames { + // These values are computed when accessed (and maybe deleted during writing): + pub nice_name: OnceLock<(String, String)>, + pub group_name: OnceLock, +} + +impl Span { + pub fn time_data(&self) -> &SpanTimeData { + self.time_data.get_or_init(|| { + Box::new(SpanTimeData { + self_end: self.start, + ignore_self_time: &self.name == "thread", + ..Default::default() + }) + }) + } + + pub fn time_data_mut(&mut self) -> &mut SpanTimeData { + self.time_data(); + self.time_data.get_mut().unwrap() + } + + pub fn extra(&self) -> &SpanExtra { + self.extra.get_or_init(Default::default) + } + + pub fn names(&self) -> &SpanNames { + self.names.get_or_init(Default::default) + } +} + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum SpanEvent { + SelfTime { start: u64, end: u64 }, + Child { index: SpanIndex }, +} + +#[derive(Clone)] +pub enum SpanGraphEvent { + // TODO(sokra) use events instead of children for visualizing span graphs + #[allow(dead_code)] + SelfTime { + duration: u64, + }, + Child { + child: Arc, + }, +} + +pub struct SpanGraph { + // These values won't change after creation: + pub root_spans: Vec, + pub recursive_spans: Vec, + + // These values are computed when accessed: + pub max_depth: OnceLock, + pub events: OnceLock>, + pub self_time: OnceLock, + pub self_allocations: OnceLock, + pub self_deallocations: OnceLock, + pub self_persistent_allocations: OnceLock, + pub self_allocation_count: OnceLock, + pub total_time: OnceLock, + pub total_allocations: OnceLock, + pub total_deallocations: OnceLock, + pub total_persistent_allocations: OnceLock, + pub total_allocation_count: OnceLock, + pub total_span_count: OnceLock, + pub corrected_self_time: OnceLock, + pub corrected_total_time: OnceLock, + pub bottom_up: OnceLock>>, +} + +pub struct SpanBottomUp { + // These values won't change after creation: + pub self_spans: Vec, + pub children: Vec>, + pub example_span: SpanIndex, + + // These values are computed when accessed: + pub max_depth: OnceLock, + pub events: OnceLock>, + pub self_time: OnceLock, + pub corrected_self_time: OnceLock, + pub self_allocations: OnceLock, + pub self_deallocations: OnceLock, + pub self_persistent_allocations: OnceLock, + pub self_allocation_count: OnceLock, +} + +impl SpanBottomUp { + pub fn new( + self_spans: Vec, + example_span: SpanIndex, + children: Vec>, + ) -> Self { + Self { + self_spans, + children, + example_span, + max_depth: OnceLock::new(), + events: OnceLock::new(), + self_time: OnceLock::new(), + corrected_self_time: OnceLock::new(), + self_allocations: OnceLock::new(), + self_deallocations: OnceLock::new(), + self_persistent_allocations: OnceLock::new(), + self_allocation_count: OnceLock::new(), + } + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/span_bottom_up_ref.rs b/turbopack/crates/turbopack-trace-server/src/span_bottom_up_ref.rs new file mode 100644 index 0000000000000..431a9858f0df3 --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/span_bottom_up_ref.rs @@ -0,0 +1,194 @@ +use std::{ + collections::VecDeque, + fmt::{Debug, Formatter}, + sync::Arc, +}; + +use indexmap::IndexMap; + +use crate::{ + span::{SpanBottomUp, SpanGraphEvent, SpanIndex}, + span_graph_ref::{event_map_to_list, SpanGraphEventRef, SpanGraphRef}, + span_ref::SpanRef, + store::{SpanId, Store}, +}; + +pub struct SpanBottomUpRef<'a> { + pub(crate) bottom_up: Arc, + pub(crate) store: &'a Store, +} + +impl<'a> SpanBottomUpRef<'a> { + pub fn id(&self) -> SpanId { + unsafe { SpanId::new_unchecked((self.bottom_up.example_span.get() << 1) | 1) } + } + + fn first_span(&self) -> SpanRef<'a> { + let index = self.bottom_up.self_spans[0].get(); + SpanRef { + span: &self.store.spans[index], + store: self.store, + index, + } + } + + fn example_span(&self) -> SpanRef<'a> { + let index = self.bottom_up.example_span.get(); + SpanRef { + span: &self.store.spans[index], + store: self.store, + index, + } + } + + pub fn spans(&self) -> impl Iterator> + '_ { + let store = self.store; + self.bottom_up.self_spans.iter().map(move |span| SpanRef { + span: &store.spans[span.get()], + store, + index: span.get(), + }) + } + + pub fn count(&self) -> usize { + self.bottom_up.self_spans.len() + } + + pub fn group_name(&self) -> &'a str { + self.first_span().group_name() + } + + pub fn nice_name(&self) -> (&'a str, &'a str) { + if self.count() == 1 { + self.example_span().nice_name() + } else { + ("", self.example_span().group_name()) + } + } + + pub fn children(&self) -> impl Iterator> + '_ { + self.bottom_up + .children + .iter() + .map(|bottom_up| SpanBottomUpRef { + bottom_up: bottom_up.clone(), + store: self.store, + }) + } + + #[allow(dead_code)] + pub fn graph(&self) -> impl Iterator> + '_ { + self.bottom_up + .events + .get_or_init(|| { + if self.count() == 1 { + let _ = self.first_span().graph(); + self.first_span().extra().graph.get().unwrap().clone() + } else { + let mut map: IndexMap<&str, (Vec, Vec)> = IndexMap::new(); + let mut queue = VecDeque::with_capacity(8); + for child in self.spans() { + let name = child.group_name(); + let (list, recursive_list) = map.entry(name).or_default(); + list.push(child.index()); + queue.push_back(child); + while let Some(child) = queue.pop_front() { + for nested_child in child.children() { + let nested_name = nested_child.group_name(); + if name == nested_name { + recursive_list.push(nested_child.index()); + queue.push_back(nested_child); + } + } + } + } + event_map_to_list(map) + } + }) + .iter() + .map(|graph| match graph { + SpanGraphEvent::SelfTime { duration } => SpanGraphEventRef::SelfTime { + duration: *duration, + }, + SpanGraphEvent::Child { child } => SpanGraphEventRef::Child { + graph: SpanGraphRef { + graph: child.clone(), + store: self.store, + }, + }, + }) + } + + pub fn max_depth(&self) -> u32 { + *self.bottom_up.max_depth.get_or_init(|| { + self.children() + .map(|bottom_up| bottom_up.max_depth() + 1) + .max() + .unwrap_or(0) + }) + } + + pub fn corrected_self_time(&self) -> u64 { + *self + .bottom_up + .corrected_self_time + .get_or_init(|| self.spans().map(|span| span.corrected_self_time()).sum()) + } + + pub fn self_time(&self) -> u64 { + *self + .bottom_up + .self_time + .get_or_init(|| self.spans().map(|span| span.self_time()).sum()) + } + + pub fn self_allocations(&self) -> u64 { + *self + .bottom_up + .self_allocations + .get_or_init(|| self.spans().map(|span| span.self_allocations()).sum()) + } + + pub fn self_deallocations(&self) -> u64 { + *self + .bottom_up + .self_deallocations + .get_or_init(|| self.spans().map(|span| span.self_deallocations()).sum()) + } + + pub fn self_persistent_allocations(&self) -> u64 { + *self.bottom_up.self_persistent_allocations.get_or_init(|| { + self.spans() + .map(|span| span.self_persistent_allocations()) + .sum() + }) + } + + pub fn self_allocation_count(&self) -> u64 { + *self + .bottom_up + .self_allocation_count + .get_or_init(|| self.spans().map(|span| span.self_allocation_count()).sum()) + } + + pub fn self_span_count(&self) -> u64 { + self.bottom_up.self_spans.len() as u64 + } +} + +impl<'a> Debug for SpanBottomUpRef<'a> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SpanBottomUpRef") + .field("group_name", &self.group_name()) + .field("max_depth", &self.max_depth()) + .field("corrected_self_time", &self.corrected_self_time()) + .field("self_allocations", &self.self_allocations()) + .field("self_deallocations", &self.self_deallocations()) + .field( + "self_persistent_allocations", + &self.self_persistent_allocations(), + ) + .field("self_allocation_count", &self.self_allocation_count()) + .finish() + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/span_graph_ref.rs b/turbopack/crates/turbopack-trace-server/src/span_graph_ref.rs new file mode 100644 index 0000000000000..03ce092894a54 --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/span_graph_ref.rs @@ -0,0 +1,376 @@ +use std::{ + collections::VecDeque, + fmt::{Debug, Formatter}, + sync::{Arc, OnceLock}, +}; + +use indexmap::IndexMap; + +use crate::{ + bottom_up::build_bottom_up_graph, + span::{SpanGraph, SpanGraphEvent, SpanIndex}, + span_bottom_up_ref::SpanBottomUpRef, + span_ref::SpanRef, + store::{SpanId, Store}, +}; + +#[derive(Clone)] +pub struct SpanGraphRef<'a> { + pub(crate) graph: Arc, + pub(crate) store: &'a Store, +} + +impl<'a> SpanGraphRef<'a> { + pub fn first_span(&self) -> SpanRef<'a> { + let index = self.graph.root_spans[0].get(); + SpanRef { + span: &self.store.spans[index], + store: self.store, + index, + } + } + + pub fn id(&self) -> SpanId { + unsafe { SpanId::new_unchecked((self.first_span().index << 1) | 1) } + } + + pub fn nice_name(&self) -> (&str, &str) { + if self.count() == 1 { + self.first_span().nice_name() + } else { + ("", self.first_span().group_name()) + } + } + + pub fn count(&self) -> usize { + self.graph.root_spans.len() + self.graph.recursive_spans.len() + } + + pub fn root_spans(&self) -> impl DoubleEndedIterator> + '_ { + self.graph.root_spans.iter().map(move |span| SpanRef { + span: &self.store.spans[span.get()], + store: self.store, + index: span.get(), + }) + } + + fn recursive_spans(&self) -> impl DoubleEndedIterator> + '_ { + self.graph + .root_spans + .iter() + .chain(self.graph.recursive_spans.iter()) + .map(move |span| SpanRef { + span: &self.store.spans[span.get()], + store: self.store, + index: span.get(), + }) + } + + pub fn events(&self) -> impl DoubleEndedIterator> + '_ { + self.graph + .events + .get_or_init(|| { + if self.count() == 1 { + let _ = self.first_span().graph(); + self.first_span().extra().graph.get().unwrap().clone() + } else { + let self_group = self.first_span().group_name(); + let mut map: IndexMap<&str, (Vec, Vec)> = IndexMap::new(); + let mut queue = VecDeque::with_capacity(8); + for span in self.recursive_spans() { + for span in span.children() { + let name = span.group_name(); + if name != self_group { + let (list, recusive_list) = map.entry(name).or_default(); + list.push(span.index()); + queue.push_back(span); + while let Some(child) = queue.pop_front() { + for nested_child in child.children() { + let nested_name = nested_child.group_name(); + if name == nested_name { + recusive_list.push(nested_child.index()); + queue.push_back(nested_child); + } + } + } + } + } + } + event_map_to_list(map) + } + }) + .iter() + .map(|graph| match graph { + SpanGraphEvent::SelfTime { duration } => SpanGraphEventRef::SelfTime { + duration: *duration, + }, + SpanGraphEvent::Child { child } => SpanGraphEventRef::Child { + graph: SpanGraphRef { + graph: child.clone(), + store: self.store, + }, + }, + }) + } + + pub fn children(&self) -> impl DoubleEndedIterator> + '_ { + self.events().filter_map(|event| match event { + SpanGraphEventRef::SelfTime { .. } => None, + SpanGraphEventRef::Child { graph: span } => Some(span), + }) + } + + pub fn bottom_up(&self) -> impl Iterator> + '_ { + self.graph + .bottom_up + .get_or_init(|| build_bottom_up_graph(self.root_spans())) + .iter() + .map(move |bottom_up| SpanBottomUpRef { + bottom_up: bottom_up.clone(), + store: self.store, + }) + } + + pub fn max_depth(&self) -> u32 { + *self.graph.max_depth.get_or_init(|| { + self.children() + .map(|graph| graph.max_depth() + 1) + .max() + .unwrap_or_default() + }) + } + + pub fn self_time(&self) -> u64 { + *self.graph.self_time.get_or_init(|| { + self.recursive_spans() + .map(|span| span.self_time()) + .reduce(|a, b| a + b) + .unwrap_or_default() + }) + } + + pub fn total_time(&self) -> u64 { + *self.graph.total_time.get_or_init(|| { + self.children() + .map(|graph| graph.total_time()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_time() + }) + } + + pub fn self_allocations(&self) -> u64 { + *self.graph.self_allocations.get_or_init(|| { + self.recursive_spans() + .map(|span| span.self_allocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + }) + } + + pub fn self_deallocations(&self) -> u64 { + *self.graph.self_deallocations.get_or_init(|| { + self.recursive_spans() + .map(|span| span.self_deallocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + }) + } + + pub fn self_persistent_allocations(&self) -> u64 { + *self.graph.self_persistent_allocations.get_or_init(|| { + self.recursive_spans() + .map(|span| span.self_persistent_allocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + }) + } + + pub fn self_allocation_count(&self) -> u64 { + *self.graph.self_allocation_count.get_or_init(|| { + self.recursive_spans() + .map(|span| span.self_allocation_count()) + .reduce(|a, b| a + b) + .unwrap_or_default() + }) + } + + pub fn self_span_count(&self) -> u64 { + self.graph.root_spans.len() as u64 + self.graph.recursive_spans.len() as u64 + } + + pub fn total_allocations(&self) -> u64 { + *self.graph.total_allocations.get_or_init(|| { + self.children() + .map(|graph| graph.total_allocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_allocations() + }) + } + + pub fn total_deallocations(&self) -> u64 { + *self.graph.total_deallocations.get_or_init(|| { + self.children() + .map(|graph| graph.total_deallocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_deallocations() + }) + } + + pub fn total_persistent_allocations(&self) -> u64 { + *self.graph.total_persistent_allocations.get_or_init(|| { + self.children() + .map(|graph| graph.total_persistent_allocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_persistent_allocations() + }) + } + + pub fn total_allocation_count(&self) -> u64 { + *self.graph.total_allocation_count.get_or_init(|| { + self.children() + .map(|graph| graph.total_allocation_count()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_allocation_count() + }) + } + + pub fn total_span_count(&self) -> u64 { + *self.graph.total_span_count.get_or_init(|| { + self.children() + .map(|graph| graph.total_span_count()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_span_count() + }) + } + + pub fn corrected_self_time(&self) -> u64 { + *self.graph.corrected_self_time.get_or_init(|| { + self.recursive_spans() + .map(|span| span.corrected_self_time()) + .reduce(|a, b| a + b) + .unwrap_or_default() + }) + } + + pub fn corrected_total_time(&self) -> u64 { + *self.graph.corrected_total_time.get_or_init(|| { + self.children() + .map(|graph| graph.corrected_total_time()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.corrected_self_time() + }) + } +} + +pub fn event_map_to_list( + map: IndexMap<&str, (Vec, Vec)>, +) -> Vec { + map.into_iter() + .map(|(_, (root_spans, recursive_spans))| { + let graph = SpanGraph { + root_spans, + recursive_spans, + max_depth: OnceLock::new(), + events: OnceLock::new(), + self_time: OnceLock::new(), + self_allocations: OnceLock::new(), + self_deallocations: OnceLock::new(), + self_persistent_allocations: OnceLock::new(), + self_allocation_count: OnceLock::new(), + total_time: OnceLock::new(), + total_allocations: OnceLock::new(), + total_deallocations: OnceLock::new(), + total_persistent_allocations: OnceLock::new(), + total_allocation_count: OnceLock::new(), + total_span_count: OnceLock::new(), + corrected_self_time: OnceLock::new(), + corrected_total_time: OnceLock::new(), + bottom_up: OnceLock::new(), + }; + SpanGraphEvent::Child { + child: Arc::new(graph), + } + }) + .collect() +} + +impl<'a> Debug for SpanGraphRef<'a> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SpanGraphRef") + .field("id", &self.id()) + .field("name", &self.nice_name()) + .field("count", &self.count()) + .field("max_depth", &self.max_depth()) + .field("self_time", &self.self_time()) + .field("self_allocations", &self.self_allocations()) + .field("total_time", &self.total_time()) + .field("total_allocations", &self.total_allocations()) + .finish() + } +} + +// TODO(sokra) use events instead of children for visualizing span graphs +#[allow(dead_code)] +#[derive(Clone)] +pub enum SpanGraphEventRef<'a> { + SelfTime { duration: u64 }, + Child { graph: SpanGraphRef<'a> }, +} + +impl<'a> SpanGraphEventRef<'a> { + pub fn corrected_total_time(&self) -> u64 { + match self { + SpanGraphEventRef::SelfTime { duration } => *duration, + SpanGraphEventRef::Child { graph } => graph.corrected_total_time(), + } + } + + pub fn total_time(&self) -> u64 { + match self { + SpanGraphEventRef::SelfTime { duration } => *duration, + SpanGraphEventRef::Child { graph } => graph.total_time(), + } + } + + pub fn total_allocations(&self) -> u64 { + match self { + SpanGraphEventRef::SelfTime { .. } => 0, + SpanGraphEventRef::Child { graph } => graph.total_allocations(), + } + } + + pub fn total_deallocations(&self) -> u64 { + match self { + SpanGraphEventRef::SelfTime { .. } => 0, + SpanGraphEventRef::Child { graph } => graph.total_deallocations(), + } + } + + pub fn total_persistent_allocations(&self) -> u64 { + match self { + SpanGraphEventRef::SelfTime { .. } => 0, + SpanGraphEventRef::Child { graph } => graph.total_persistent_allocations(), + } + } + + pub fn total_allocation_count(&self) -> u64 { + match self { + SpanGraphEventRef::SelfTime { .. } => 0, + SpanGraphEventRef::Child { graph } => graph.total_allocation_count(), + } + } + + pub fn total_span_count(&self) -> u64 { + match self { + SpanGraphEventRef::SelfTime { .. } => 0, + SpanGraphEventRef::Child { graph } => graph.total_span_count(), + } + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/span_ref.rs b/turbopack/crates/turbopack-trace-server/src/span_ref.rs new file mode 100644 index 0000000000000..7439ef9d128ff --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/span_ref.rs @@ -0,0 +1,426 @@ +use std::{ + cmp::max, + collections::{HashMap, HashSet, VecDeque}, + fmt::{Debug, Formatter}, + vec, +}; + +use indexmap::IndexMap; + +use crate::{ + bottom_up::build_bottom_up_graph, + span::{Span, SpanEvent, SpanExtra, SpanGraphEvent, SpanIndex, SpanNames, SpanTimeData}, + span_bottom_up_ref::SpanBottomUpRef, + span_graph_ref::{event_map_to_list, SpanGraphEventRef, SpanGraphRef}, + store::{SpanId, Store}, +}; + +#[derive(Copy, Clone)] +pub struct SpanRef<'a> { + pub(crate) span: &'a Span, + pub(crate) store: &'a Store, + pub(crate) index: usize, +} + +impl<'a> SpanRef<'a> { + pub fn id(&self) -> SpanId { + unsafe { SpanId::new_unchecked(self.index << 1) } + } + + pub fn index(&self) -> SpanIndex { + SpanIndex::new(self.index).unwrap() + } + + pub fn parent(&self) -> Option> { + self.span.parent.map(|index| SpanRef { + span: &self.store.spans[index.get()], + store: self.store, + index: index.get(), + }) + } + + pub fn start(&self) -> u64 { + self.span.start + } + + pub fn time_data(&self) -> &'a SpanTimeData { + self.span.time_data() + } + + pub fn extra(&self) -> &'a SpanExtra { + self.span.extra() + } + + pub fn names(&self) -> &'a SpanNames { + self.span.names() + } + + pub fn end(&self) -> u64 { + let time_data = self.time_data(); + *time_data.end.get_or_init(|| { + max( + time_data.self_end, + self.children() + .map(|child| child.end()) + .max() + .unwrap_or_default(), + ) + }) + } + + pub fn is_complete(&self) -> bool { + self.span.is_complete + } + + pub fn is_root(&self) -> bool { + self.index == 0 + } + + pub fn nice_name(&self) -> (&'a str, &'a str) { + let (category, title) = self.names().nice_name.get_or_init(|| { + if let Some(name) = self + .span + .args + .iter() + .find(|&(k, _)| k == "name") + .map(|(_, v)| v.as_str()) + { + if matches!( + self.span.name.as_str(), + "turbo_tasks::resolve_call" | "turbo_tasks::resolve_trait_call" + ) { + ( + format!("{} {}", self.span.name, self.span.category), + format!("*{name}"), + ) + } else { + ( + format!("{} {}", self.span.name, self.span.category), + name.to_string(), + ) + } + } else { + (self.span.category.to_string(), self.span.name.to_string()) + } + }); + (category, title) + } + + pub fn group_name(&self) -> &'a str { + self.names().group_name.get_or_init(|| { + if matches!(self.span.name.as_str(), "turbo_tasks::function") { + self.span + .args + .iter() + .find(|&(k, _)| k == "name") + .map(|(_, v)| v.to_string()) + .unwrap_or_else(|| self.span.name.to_string()) + } else if matches!( + self.span.name.as_str(), + "turbo_tasks::resolve_call" | "turbo_tasks::resolve_trait_call" + ) { + self.span + .args + .iter() + .find(|&(k, _)| k == "name") + .map(|(_, v)| format!("*{v}")) + .unwrap_or_else(|| self.span.name.to_string()) + } else { + self.span.name.to_string() + } + }) + } + + pub fn args(&self) -> impl Iterator { + self.span.args.iter().map(|(k, v)| (k.as_str(), v.as_str())) + } + + pub fn self_time(&self) -> u64 { + self.time_data().self_time + } + + pub fn self_allocations(&self) -> u64 { + // 32 bytes for the tracing itself + self.span.self_allocations.saturating_sub(32) + } + + pub fn self_deallocations(&self) -> u64 { + self.span.self_deallocations + } + + pub fn self_persistent_allocations(&self) -> u64 { + self.self_allocations() + .saturating_sub(self.span.self_deallocations) + } + + pub fn self_allocation_count(&self) -> u64 { + // 4 allocations for the tracing itself + self.span.self_allocation_count.saturating_sub(4) + } + + pub fn self_span_count(&self) -> u64 { + 1 + } + + // TODO(sokra) use events instead of children for visualizing span graphs + #[allow(dead_code)] + pub fn events_count(&self) -> usize { + self.span.events.len() + } + + // TODO(sokra) use events instead of children for visualizing span graphs + #[allow(dead_code)] + pub fn events(&self) -> impl Iterator> { + self.span.events.iter().map(|event| match event { + &SpanEvent::SelfTime { start, end } => SpanEventRef::SelfTime { start, end }, + SpanEvent::Child { index } => SpanEventRef::Child { + span: SpanRef { + span: &self.store.spans[index.get()], + store: self.store, + index: index.get(), + }, + }, + }) + } + + pub fn children(&self) -> impl DoubleEndedIterator> + 'a { + self.span.events.iter().filter_map(|event| match event { + SpanEvent::SelfTime { .. } => None, + SpanEvent::Child { index } => Some(SpanRef { + span: &self.store.spans[index.get()], + store: self.store, + index: index.get(), + }), + }) + } + + pub fn total_time(&self) -> u64 { + *self.time_data().total_time.get_or_init(|| { + self.children() + .map(|child| child.total_time()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_time() + }) + } + + pub fn total_allocations(&self) -> u64 { + *self.span.total_allocations.get_or_init(|| { + self.children() + .map(|child| child.total_allocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_allocations() + }) + } + + pub fn total_deallocations(&self) -> u64 { + *self.span.total_deallocations.get_or_init(|| { + self.children() + .map(|child| child.total_deallocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_deallocations() + }) + } + + pub fn total_persistent_allocations(&self) -> u64 { + *self.span.total_persistent_allocations.get_or_init(|| { + self.children() + .map(|child| child.total_persistent_allocations()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_persistent_allocations() + }) + } + + pub fn total_allocation_count(&self) -> u64 { + *self.span.total_allocation_count.get_or_init(|| { + self.children() + .map(|child| child.total_allocation_count()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.self_allocation_count() + }) + } + + pub fn total_span_count(&self) -> u64 { + *self.span.total_span_count.get_or_init(|| { + self.children() + .map(|child| child.total_span_count()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + 1 + }) + } + + pub fn corrected_self_time(&self) -> u64 { + let store = self.store; + *self.time_data().corrected_self_time.get_or_init(|| { + let mut self_time = 0; + for event in self.span.events.iter() { + if let SpanEvent::SelfTime { start, end } = event { + let duration = end - start; + if duration == 0 { + continue; + } + store.set_max_self_time_lookup(*end); + let concurrent_time = store.self_time_tree.lookup_range_count(*start, *end); + self_time += duration * duration / concurrent_time; + } + } + self_time + }) + } + + pub fn corrected_total_time(&self) -> u64 { + *self.time_data().corrected_total_time.get_or_init(|| { + self.children() + .map(|child| child.corrected_total_time()) + .reduce(|a, b| a + b) + .unwrap_or_default() + + self.corrected_self_time() + }) + } + + pub fn max_depth(&self) -> u32 { + *self.span.max_depth.get_or_init(|| { + self.children() + .map(|child| child.max_depth() + 1) + .max() + .unwrap_or_default() + }) + } + + pub fn graph(&self) -> impl Iterator> + '_ { + self.extra() + .graph + .get_or_init(|| { + let mut map: IndexMap<&str, (Vec, Vec)> = IndexMap::new(); + let mut queue = VecDeque::with_capacity(8); + for child in self.children() { + let name = child.group_name(); + let (list, recursive_list) = map.entry(name).or_default(); + list.push(child.index()); + queue.push_back(child); + while let Some(child) = queue.pop_front() { + for nested_child in child.children() { + let nested_name = nested_child.group_name(); + if name == nested_name { + recursive_list.push(nested_child.index()); + queue.push_back(nested_child); + } + } + } + } + event_map_to_list(map) + }) + .iter() + .map(|event| match event { + SpanGraphEvent::SelfTime { duration } => SpanGraphEventRef::SelfTime { + duration: *duration, + }, + SpanGraphEvent::Child { child } => SpanGraphEventRef::Child { + graph: SpanGraphRef { + graph: child.clone(), + store: self.store, + }, + }, + }) + } + + pub fn bottom_up(self) -> impl Iterator> { + self.extra() + .bottom_up + .get_or_init(|| build_bottom_up_graph([self].into_iter())) + .iter() + .map(move |bottom_up| SpanBottomUpRef { + bottom_up: bottom_up.clone(), + store: self.store, + }) + } + + pub fn search(&self, query: &str) -> impl Iterator> { + let index = self.search_index(); + let mut result = HashSet::new(); + for (key, spans) in index { + if key.contains(query) { + result.extend(spans.iter().copied()); + } + } + let store = self.store; + result.into_iter().map(move |index| SpanRef { + span: &store.spans[index.get()], + store, + index: index.get(), + }) + } + + fn search_index(&self) -> &HashMap> { + self.extra().search_index.get_or_init(|| { + let mut index: HashMap> = HashMap::new(); + let mut queue = VecDeque::with_capacity(8); + queue.push_back(*self); + while let Some(span) = queue.pop_front() { + if !span.is_root() { + let (cat, name) = span.nice_name(); + if !cat.is_empty() { + index + .raw_entry_mut() + .from_key(cat) + .and_modify(|_, v| v.push(span.index())) + .or_insert_with(|| (cat.to_string(), vec![span.index()])); + } + if !name.is_empty() { + index + .raw_entry_mut() + .from_key(name) + .and_modify(|_, v| v.push(span.index())) + .or_insert_with(|| (name.to_string(), vec![span.index()])); + } + for (_, value) in span.span.args.iter() { + index + .raw_entry_mut() + .from_key(value) + .and_modify(|_, v| v.push(span.index())) + .or_insert_with(|| (value.to_string(), vec![span.index()])); + } + if !span.is_complete() { + let name = "incomplete"; + index + .raw_entry_mut() + .from_key(name) + .and_modify(|_, v| v.push(span.index())) + .or_insert_with(|| (name.to_string(), vec![span.index()])); + } + } + for child in span.children() { + queue.push_back(child); + } + } + index + }) + } +} + +impl<'a> Debug for SpanRef<'a> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SpanRef") + .field("id", &self.id()) + .field("name", &self.nice_name()) + .field("start", &self.start()) + .field("end", &self.end()) + .field("is_complete", &self.is_complete()) + .field("self_time", &self.self_time()) + .field("total_time", &self.total_time()) + .field("max_depth", &self.max_depth()) + .finish() + } +} + +#[allow(dead_code)] +#[derive(Copy, Clone)] +pub enum SpanEventRef<'a> { + SelfTime { start: u64, end: u64 }, + Child { span: SpanRef<'a> }, +} diff --git a/turbopack/crates/turbopack-trace-server/src/store.rs b/turbopack/crates/turbopack-trace-server/src/store.rs new file mode 100644 index 0000000000000..73997782e582f --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/store.rs @@ -0,0 +1,375 @@ +use std::{ + cmp::{max, min}, + collections::HashSet, + mem::replace, + num::NonZeroUsize, + sync::{atomic::AtomicU64, OnceLock}, +}; + +use crate::{ + self_time_tree::SelfTimeTree, + span::{Span, SpanEvent, SpanIndex}, + span_ref::SpanRef, +}; + +pub type SpanId = NonZeroUsize; + +const CUT_OFF_DEPTH: u32 = 150; + +pub struct Store { + pub(crate) spans: Vec, + pub(crate) self_time_tree: SelfTimeTree, + max_self_time_lookup_time: AtomicU64, +} + +fn new_root_span() -> Span { + Span { + parent: None, + depth: 0, + start: u64::MAX, + category: "".into(), + name: "(root)".into(), + args: vec![], + events: vec![], + is_complete: true, + max_depth: OnceLock::new(), + self_allocations: 0, + self_allocation_count: 0, + self_deallocations: 0, + self_deallocation_count: 0, + total_allocations: OnceLock::new(), + total_deallocations: OnceLock::new(), + total_persistent_allocations: OnceLock::new(), + total_allocation_count: OnceLock::new(), + total_span_count: OnceLock::new(), + time_data: OnceLock::new(), + extra: OnceLock::new(), + names: OnceLock::new(), + } +} + +impl Store { + pub fn new() -> Self { + Self { + spans: vec![new_root_span()], + self_time_tree: SelfTimeTree::new(), + max_self_time_lookup_time: AtomicU64::new(0), + } + } + + pub fn reset(&mut self) { + self.spans.truncate(1); + self.spans[0] = new_root_span(); + self.self_time_tree = SelfTimeTree::new(); + *self.max_self_time_lookup_time.get_mut() = 0; + } + + pub fn has_time_info(&self) -> bool { + self.self_time_tree.len() > 0 + } + + pub fn add_span( + &mut self, + parent: Option, + start: u64, + category: String, + name: String, + args: Vec<(String, String)>, + outdated_spans: &mut HashSet, + ) -> SpanIndex { + let id = SpanIndex::new(self.spans.len()).unwrap(); + self.spans.push(Span { + parent, + depth: 0, + start, + category, + name, + args, + events: vec![], + is_complete: false, + max_depth: OnceLock::new(), + self_allocations: 0, + self_allocation_count: 0, + self_deallocations: 0, + self_deallocation_count: 0, + total_allocations: OnceLock::new(), + total_deallocations: OnceLock::new(), + total_persistent_allocations: OnceLock::new(), + total_allocation_count: OnceLock::new(), + total_span_count: OnceLock::new(), + time_data: OnceLock::new(), + extra: OnceLock::new(), + names: OnceLock::new(), + }); + let parent = if let Some(parent) = parent { + outdated_spans.insert(parent); + &mut self.spans[parent.get()] + } else { + &mut self.spans[0] + }; + parent.start = min(parent.start, start); + let depth = parent.depth + 1; + if depth < CUT_OFF_DEPTH { + parent.events.push(SpanEvent::Child { index: id }); + } + let span = &mut self.spans[id.get()]; + span.depth = depth; + id + } + + pub fn add_args( + &mut self, + span_index: SpanIndex, + args: Vec<(String, String)>, + outdated_spans: &mut HashSet, + ) { + let span = &mut self.spans[span_index.get()]; + span.args.extend(args); + outdated_spans.insert(span_index); + } + + pub fn set_max_self_time_lookup(&self, time: u64) { + let mut old = self + .max_self_time_lookup_time + .load(std::sync::atomic::Ordering::Relaxed); + while old < time { + match self.max_self_time_lookup_time.compare_exchange( + old, + time, + std::sync::atomic::Ordering::Relaxed, + std::sync::atomic::Ordering::Relaxed, + ) { + Ok(_) => break, + Err(real_old) => old = real_old, + } + } + } + + fn insert_self_time( + &mut self, + start: u64, + end: u64, + span_index: SpanIndex, + outdated_spans: &mut HashSet, + ) { + if *self.max_self_time_lookup_time.get_mut() >= start { + self.self_time_tree + .for_each_in_range(start, end, |_, _, span| { + outdated_spans.insert(*span); + }); + } + self.self_time_tree.insert(start, end, span_index); + } + + pub fn add_self_time( + &mut self, + span_index: SpanIndex, + start: u64, + end: u64, + outdated_spans: &mut HashSet, + ) { + let span = &mut self.spans[span_index.get()]; + let time_data = span.time_data_mut(); + if time_data.ignore_self_time { + return; + } + outdated_spans.insert(span_index); + time_data.self_time += end - start; + time_data.self_end = max(time_data.self_end, end); + span.events.push(SpanEvent::SelfTime { start, end }); + self.insert_self_time(start, end, span_index, outdated_spans); + } + + pub fn set_total_time( + &mut self, + span_index: SpanIndex, + start_time: u64, + total_time: u64, + outdated_spans: &mut HashSet, + ) { + let span = SpanRef { + span: &self.spans[span_index.get()], + store: self, + index: span_index.get(), + }; + let mut children = span + .children() + .map(|c| (c.span.start, c.span.time_data().self_end, c.index())) + .collect::>(); + children.sort(); + let self_end = start_time + total_time; + let mut self_time = 0; + let mut current = start_time; + let mut events = Vec::new(); + for (start, end, index) in children { + if start > current { + if start > self_end { + events.push(SpanEvent::SelfTime { + start: current, + end: self_end, + }); + self.insert_self_time(current, self_end, span_index, outdated_spans); + self_time += self_end - current; + break; + } + events.push(SpanEvent::SelfTime { + start: current, + end: start, + }); + self.insert_self_time(current, start, span_index, outdated_spans); + self_time += start - current; + } + events.push(SpanEvent::Child { index }); + current = max(current, end); + } + current -= start_time; + if current < total_time { + self_time += total_time - current; + events.push(SpanEvent::SelfTime { + start: current + start_time, + end: start_time + total_time, + }); + self.insert_self_time( + current + start_time, + start_time + total_time, + span_index, + outdated_spans, + ); + } + let span = &mut self.spans[span_index.get()]; + outdated_spans.insert(span_index); + let time_data = span.time_data_mut(); + time_data.self_time = self_time; + time_data.self_end = self_end; + span.events = events; + span.start = start_time; + } + + pub fn set_parent( + &mut self, + span_index: SpanIndex, + parent: SpanIndex, + outdated_spans: &mut HashSet, + ) { + outdated_spans.insert(span_index); + let span = &mut self.spans[span_index.get()]; + + let old_parent = replace(&mut span.parent, Some(parent)); + let old_parent = if let Some(parent) = old_parent { + outdated_spans.insert(parent); + &mut self.spans[parent.get()] + } else { + &mut self.spans[0] + }; + if let Some(index) = old_parent + .events + .iter() + .position(|event| *event == SpanEvent::Child { index: span_index }) + { + old_parent.events.remove(index); + } + + outdated_spans.insert(parent); + let parent = &mut self.spans[parent.get()]; + parent.events.push(SpanEvent::Child { index: span_index }); + } + + pub fn add_allocation( + &mut self, + span_index: SpanIndex, + allocation: u64, + count: u64, + outdated_spans: &mut HashSet, + ) { + let span = &mut self.spans[span_index.get()]; + outdated_spans.insert(span_index); + span.self_allocations += allocation; + span.self_allocation_count += count; + } + + pub fn add_deallocation( + &mut self, + span_index: SpanIndex, + deallocation: u64, + count: u64, + outdated_spans: &mut HashSet, + ) { + let span = &mut self.spans[span_index.get()]; + outdated_spans.insert(span_index); + span.self_deallocations += deallocation; + span.self_deallocation_count += count; + } + + pub fn complete_span(&mut self, span_index: SpanIndex) { + let span = &mut self.spans[span_index.get()]; + span.is_complete = true; + } + + pub fn invalidate_outdated_spans(&mut self, outdated_spans: &HashSet) { + fn invalidate_span(span: &mut Span) { + if let Some(time_data) = span.time_data.get_mut() { + time_data.end.take(); + time_data.total_time.take(); + time_data.corrected_self_time.take(); + time_data.corrected_total_time.take(); + } + span.total_allocations.take(); + span.total_deallocations.take(); + span.total_persistent_allocations.take(); + span.total_allocation_count.take(); + span.total_span_count.take(); + span.extra.take(); + } + + for id in outdated_spans.iter() { + let mut span = &mut self.spans[id.get()]; + loop { + invalidate_span(span); + let Some(parent) = span.parent else { + break; + }; + if outdated_spans.contains(&parent) { + break; + } + span = &mut self.spans[parent.get()]; + } + } + + invalidate_span(&mut self.spans[0]); + } + + pub fn root_spans(&self) -> impl Iterator> { + self.spans[0].events.iter().filter_map(|event| match event { + &SpanEvent::Child { index: id } => Some(SpanRef { + span: &self.spans[id.get()], + store: self, + index: id.get(), + }), + _ => None, + }) + } + + pub fn root_span(&self) -> SpanRef<'_> { + SpanRef { + span: &self.spans[0], + store: self, + index: 0, + } + } + + pub fn span(&self, id: SpanId) -> Option<(SpanRef<'_>, bool)> { + let id = id.get(); + let is_graph = id & 1 == 1; + let index = id >> 1; + self.spans.get(index).map(|span| { + ( + SpanRef { + span, + store: self, + index, + }, + is_graph, + ) + }) + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/store_container.rs b/turbopack/crates/turbopack-trace-server/src/store_container.rs new file mode 100644 index 0000000000000..ef5fc92979ddc --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/store_container.rs @@ -0,0 +1,89 @@ +use std::{ + ops::{Deref, DerefMut}, + sync::{ + atomic::{AtomicBool, Ordering}, + RwLock, RwLockReadGuard, RwLockWriteGuard, + }, +}; + +use crate::store::Store; + +pub struct StoreContainer { + store: RwLock, + want_to_read: AtomicBool, +} + +struct StoreWithGeneration { + store: Store, + generation: usize, +} + +impl StoreContainer { + pub fn new() -> Self { + Self { + store: RwLock::new(StoreWithGeneration { + store: Store::new(), + generation: 0, + }), + want_to_read: AtomicBool::new(false), + } + } + + pub fn read(&self) -> StoreReadGuard<'_> { + if let Ok(guard) = self.store.try_read() { + return StoreReadGuard { guard }; + } + self.want_to_read.store(true, Ordering::Relaxed); + let guard = StoreReadGuard { + guard: self.store.read().unwrap(), + }; + self.want_to_read.store(false, Ordering::Relaxed); + guard + } + + pub fn write(&self) -> StoreWriteGuard<'_> { + let mut guard = self.store.write().unwrap(); + guard.generation += 1; + StoreWriteGuard { guard } + } + + pub fn want_to_read(&self) -> bool { + self.want_to_read.load(Ordering::Relaxed) + } +} + +pub struct StoreReadGuard<'a> { + guard: RwLockReadGuard<'a, StoreWithGeneration>, +} + +impl<'a> StoreReadGuard<'a> { + pub fn generation(&self) -> usize { + self.guard.generation + } +} + +impl<'a> Deref for StoreReadGuard<'a> { + type Target = Store; + + fn deref(&self) -> &Self::Target { + &self.guard.store + } +} + +pub struct StoreWriteGuard<'a> { + guard: RwLockWriteGuard<'a, StoreWithGeneration>, +} + +impl<'a> Deref for StoreWriteGuard<'a> { + type Target = Store; + + fn deref(&self) -> &Self::Target { + &self.guard.store + } +} + +impl<'a> DerefMut for StoreWriteGuard<'a> { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.guard.store + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/u64_empty_string.rs b/turbopack/crates/turbopack-trace-server/src/u64_empty_string.rs new file mode 100644 index 0000000000000..5b00ae8aa3d2a --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/u64_empty_string.rs @@ -0,0 +1,24 @@ +use serde::{de, Deserialize, Deserializer, Serializer}; + +pub fn serialize(value: &u64, serializer: S) -> Result +where + S: Serializer, +{ + if *value == 0 { + serializer.serialize_str("") + } else { + serializer.collect_str(&value) + } +} + +pub fn deserialize<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let str = &String::deserialize(deserializer)?; + if str.is_empty() { + Ok(0) + } else { + str.parse().map_err(de::Error::custom) + } +} diff --git a/turbopack/crates/turbopack-trace-server/src/u64_string.rs b/turbopack/crates/turbopack-trace-server/src/u64_string.rs new file mode 100644 index 0000000000000..a9f66a48f3b9a --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/u64_string.rs @@ -0,0 +1,22 @@ +use std::{fmt::Display, str::FromStr}; + +use serde::{de, Deserialize, Deserializer, Serializer}; + +pub fn serialize(value: &T, serializer: S) -> Result +where + T: Display, + S: Serializer, +{ + serializer.collect_str(value) +} + +pub fn deserialize<'de, T, D>(deserializer: D) -> Result +where + T: FromStr, + T::Err: Display, + D: Deserializer<'de>, +{ + String::deserialize(deserializer)? + .parse() + .map_err(de::Error::custom) +} diff --git a/turbopack/crates/turbopack-trace-server/src/viewer.rs b/turbopack/crates/turbopack-trace-server/src/viewer.rs new file mode 100644 index 0000000000000..7e3271350ed27 --- /dev/null +++ b/turbopack/crates/turbopack-trace-server/src/viewer.rs @@ -0,0 +1,1183 @@ +use std::{ + cmp::{max, Reverse}, + collections::{HashMap, HashSet}, +}; + +use either::Either; +use itertools::Itertools; +use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; +use serde::{Deserialize, Serialize}; + +use crate::{ + server::ViewRect, + span_bottom_up_ref::SpanBottomUpRef, + span_graph_ref::{SpanGraphEventRef, SpanGraphRef}, + span_ref::SpanRef, + store::{SpanId, Store}, + u64_empty_string, +}; + +const EXTRA_WIDTH_PERCENTAGE: u64 = 50; +const EXTRA_HEIGHT: u64 = 5; + +#[derive(Default)] +pub struct Viewer { + span_options: HashMap, +} + +#[derive(Clone, Copy, Debug)] +pub enum ValueMode { + Duration, + Cpu, + Allocations, + Deallocations, + PersistentAllocations, + AllocationCount, + Count, + AllocationsPerTime, + PersistentAllocationsPerTime, + AllocationCountPerTime, +} + +impl ValueMode { + fn secondary(&self) -> ValueMode { + match self { + ValueMode::Duration => ValueMode::Cpu, + ValueMode::Cpu => ValueMode::Duration, + ValueMode::Allocations => ValueMode::PersistentAllocations, + ValueMode::Deallocations => ValueMode::PersistentAllocations, + ValueMode::PersistentAllocations => ValueMode::Allocations, + ValueMode::AllocationCount => ValueMode::Allocations, + ValueMode::Count => ValueMode::Count, + ValueMode::AllocationsPerTime => ValueMode::PersistentAllocationsPerTime, + ValueMode::PersistentAllocationsPerTime => ValueMode::AllocationsPerTime, + ValueMode::AllocationCountPerTime => ValueMode::AllocationsPerTime, + } + } + + fn value_from_span(&self, span: &SpanRef<'_>) -> u64 { + match self { + ValueMode::Duration => span.corrected_total_time(), + ValueMode::Cpu => span.total_time(), + ValueMode::Allocations => span.total_allocations(), + ValueMode::Deallocations => span.total_deallocations(), + ValueMode::PersistentAllocations => span.total_persistent_allocations(), + ValueMode::AllocationCount => span.total_allocation_count(), + ValueMode::Count => span.total_span_count(), + ValueMode::AllocationsPerTime => { + value_over_time(span.total_allocations(), span.corrected_total_time()) + } + ValueMode::AllocationCountPerTime => { + value_over_time(span.total_allocation_count(), span.corrected_total_time()) + } + ValueMode::PersistentAllocationsPerTime => value_over_time( + span.total_persistent_allocations(), + span.corrected_total_time(), + ), + } + } + + fn value_from_graph(&self, graph: &SpanGraphRef<'_>) -> u64 { + match self { + ValueMode::Duration => graph.corrected_total_time(), + ValueMode::Cpu => graph.total_time(), + ValueMode::Allocations => graph.total_allocations(), + ValueMode::Deallocations => graph.total_deallocations(), + ValueMode::PersistentAllocations => graph.total_persistent_allocations(), + ValueMode::AllocationCount => graph.total_allocation_count(), + ValueMode::Count => graph.total_span_count(), + ValueMode::AllocationsPerTime => { + value_over_time(graph.total_allocations(), graph.corrected_total_time()) + } + ValueMode::AllocationCountPerTime => { + value_over_time(graph.total_allocation_count(), graph.corrected_total_time()) + } + ValueMode::PersistentAllocationsPerTime => value_over_time( + graph.total_persistent_allocations(), + graph.corrected_total_time(), + ), + } + } + + fn value_from_graph_event(&self, event: &SpanGraphEventRef<'_>) -> u64 { + match self { + ValueMode::Duration => event.corrected_total_time(), + ValueMode::Cpu => event.total_time(), + ValueMode::Allocations => event.total_allocations(), + ValueMode::Deallocations => event.total_deallocations(), + ValueMode::PersistentAllocations => event.total_persistent_allocations(), + ValueMode::AllocationCount => event.total_allocation_count(), + ValueMode::Count => event.total_span_count(), + ValueMode::AllocationsPerTime => { + value_over_time(event.total_allocations(), event.corrected_total_time()) + } + ValueMode::AllocationCountPerTime => { + value_over_time(event.total_allocation_count(), event.corrected_total_time()) + } + ValueMode::PersistentAllocationsPerTime => value_over_time( + event.total_persistent_allocations(), + event.corrected_total_time(), + ), + } + } + + fn value_from_bottom_up(&self, bottom_up: &SpanBottomUpRef<'_>) -> u64 { + match self { + ValueMode::Duration => bottom_up.corrected_self_time(), + ValueMode::Cpu => bottom_up.self_time(), + ValueMode::Allocations => bottom_up.self_allocations(), + ValueMode::Deallocations => bottom_up.self_deallocations(), + ValueMode::PersistentAllocations => bottom_up.self_persistent_allocations(), + ValueMode::AllocationCount => bottom_up.self_allocation_count(), + ValueMode::Count => bottom_up.self_span_count(), + ValueMode::AllocationsPerTime => value_over_time( + bottom_up.self_allocations(), + bottom_up.corrected_self_time(), + ), + ValueMode::AllocationCountPerTime => value_over_time( + bottom_up.self_allocation_count(), + bottom_up.corrected_self_time(), + ), + ValueMode::PersistentAllocationsPerTime => value_over_time( + bottom_up.self_persistent_allocations(), + bottom_up.corrected_self_time(), + ), + } + } + + fn value_from_bottom_up_span(&self, bottom_up_span: &SpanRef<'_>) -> u64 { + match self { + ValueMode::Duration => bottom_up_span.corrected_self_time(), + ValueMode::Cpu => bottom_up_span.self_time(), + ValueMode::Allocations => bottom_up_span.self_allocations(), + ValueMode::Deallocations => bottom_up_span.self_deallocations(), + ValueMode::PersistentAllocations => bottom_up_span.self_persistent_allocations(), + ValueMode::AllocationCount => bottom_up_span.self_allocation_count(), + ValueMode::Count => bottom_up_span.self_span_count(), + ValueMode::AllocationsPerTime => value_over_time( + bottom_up_span.self_allocations(), + bottom_up_span.corrected_self_time(), + ), + ValueMode::AllocationCountPerTime => value_over_time( + bottom_up_span.self_allocation_count(), + bottom_up_span.corrected_self_time(), + ), + ValueMode::PersistentAllocationsPerTime => value_over_time( + bottom_up_span.self_persistent_allocations(), + bottom_up_span.corrected_self_time(), + ), + } + } +} + +/// this is unfortunately int division but itll have to do. +/// +/// cases where count per time is very low is probably not important +fn value_over_time(value: u64, time: u64) -> u64 { + if time == 0 { + 0 + } else { + value / time + } +} + +#[derive(Clone, Copy, Debug)] +pub enum ViewMode { + RawSpans { sorted: bool }, + Aggregated { sorted: bool }, + BottomUp { sorted: bool }, + AggregatedBottomUp { sorted: bool }, +} + +impl ViewMode { + fn as_spans(self) -> Self { + match self { + ViewMode::RawSpans { sorted } => ViewMode::RawSpans { sorted }, + ViewMode::Aggregated { sorted } => ViewMode::RawSpans { sorted }, + ViewMode::BottomUp { sorted } => ViewMode::BottomUp { sorted }, + ViewMode::AggregatedBottomUp { sorted } => ViewMode::BottomUp { sorted }, + } + } + + fn as_bottom_up(self) -> Self { + match self { + ViewMode::RawSpans { sorted } => ViewMode::BottomUp { sorted }, + ViewMode::Aggregated { sorted } => ViewMode::AggregatedBottomUp { sorted }, + ViewMode::BottomUp { sorted } => ViewMode::BottomUp { sorted }, + ViewMode::AggregatedBottomUp { sorted } => ViewMode::AggregatedBottomUp { sorted }, + } + } + + fn aggregate_children(&self) -> bool { + match self { + ViewMode::RawSpans { .. } => false, + ViewMode::Aggregated { .. } => true, + ViewMode::BottomUp { .. } => false, + ViewMode::AggregatedBottomUp { .. } => true, + } + } + + fn bottom_up(&self) -> bool { + match self { + ViewMode::RawSpans { .. } => false, + ViewMode::Aggregated { .. } => false, + ViewMode::BottomUp { .. } => true, + ViewMode::AggregatedBottomUp { .. } => true, + } + } + + fn sort_children(&self) -> bool { + match self { + ViewMode::RawSpans { sorted } => *sorted, + ViewMode::Aggregated { sorted } => *sorted, + ViewMode::BottomUp { sorted } => *sorted, + ViewMode::AggregatedBottomUp { sorted } => *sorted, + } + } +} + +#[derive(Default)] +struct SpanOptions { + view_mode: Option<(ViewMode, bool)>, +} + +pub struct Update { + pub lines: Vec, + pub max: u64, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ViewLineUpdate { + y: u64, + spans: Vec, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct ViewSpan { + #[serde(with = "u64_empty_string")] + id: u64, + #[serde(rename = "x")] + start: u64, + #[serde(rename = "w")] + width: u64, + #[serde(rename = "cat")] + category: String, + #[serde(rename = "t")] + text: String, + #[serde(rename = "c")] + count: u64, + #[serde(rename = "k")] + kind: u8, + #[serde(rename = "s")] + start_in_parent: u32, + #[serde(rename = "e")] + end_in_parent: u32, + #[serde(rename = "v")] + secondary: u64, +} + +#[derive(Debug)] +enum QueueItem<'a> { + Span(SpanRef<'a>), + SpanGraph(SpanGraphRef<'a>), + SpanBottomUp(SpanBottomUpRef<'a>), + SpanBottomUpSpan(SpanRef<'a>), +} + +impl<'a> QueueItem<'a> { + fn value(&self, value_mode: ValueMode) -> u64 { + match self { + QueueItem::Span(span) => value_mode.value_from_span(span), + QueueItem::SpanGraph(span_graph) => value_mode.value_from_graph(span_graph), + QueueItem::SpanBottomUp(span_bottom_up) => { + value_mode.value_from_bottom_up(span_bottom_up) + } + QueueItem::SpanBottomUpSpan(span) => value_mode.value_from_bottom_up_span(span), + } + } + + fn max_depth(&self) -> u32 { + match self { + QueueItem::Span(span) => span.max_depth(), + QueueItem::SpanGraph(span_graph) => span_graph.max_depth(), + QueueItem::SpanBottomUp(span_bottom_up) => span_bottom_up.max_depth(), + QueueItem::SpanBottomUpSpan(span) => span.max_depth(), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +enum FilterMode { + SelectedItem, + Parent, + Child, +} + +#[derive(Debug)] +struct QueueItemWithState<'a> { + item: QueueItem<'a>, + line_index: usize, + start: u64, + placeholder: bool, + view_mode: ViewMode, + filtered: Option, +} + +struct ChildItem<'a> { + item: QueueItemWithState<'a>, + depth: u32, + pixel_range: (u64, u64), +} + +impl Viewer { + pub fn new() -> Self { + Self::default() + } + + pub fn set_view_mode(&mut self, id: SpanId, view_mode: Option<(ViewMode, bool)>) { + self.span_options.entry(id).or_default().view_mode = view_mode; + } + + pub fn compute_update(&mut self, store: &Store, view_rect: &ViewRect) -> Update { + let mut highlighted_spans: HashSet = HashSet::new(); + let mut highlighted_span_parents: HashSet = HashSet::new(); + let search_mode = !view_rect.query.is_empty(); + let (query, focus_mode) = if let Some(query) = view_rect.query.strip_suffix('!') { + (query, true) + } else { + (view_rect.query.as_str(), false) + }; + + let default_view_mode = view_rect.view_mode.as_str(); + let (default_view_mode, default_sorted) = default_view_mode + .strip_suffix("-sorted") + .map_or((default_view_mode, false), |s| (s, true)); + let (default_view_mode, with_root) = match default_view_mode { + "aggregated" => ( + ViewMode::Aggregated { + sorted: default_sorted, + }, + false, + ), + "root-aggregated" => ( + ViewMode::Aggregated { + sorted: default_sorted, + }, + true, + ), + "raw-spans" => ( + ViewMode::RawSpans { + sorted: default_sorted, + }, + false, + ), + "bottom-up" => ( + ViewMode::BottomUp { + sorted: default_sorted, + }, + false, + ), + "aggregated-bottom-up" => ( + ViewMode::AggregatedBottomUp { + sorted: default_sorted, + }, + false, + ), + "root-aggregated-bottom-up" => ( + ViewMode::AggregatedBottomUp { + sorted: default_sorted, + }, + true, + ), + _ => ( + ViewMode::Aggregated { + sorted: default_sorted, + }, + false, + ), + }; + + let value_mode = match view_rect.value_mode.as_str() { + "duration" => ValueMode::Duration, + "cpu" => ValueMode::Cpu, + "allocations" => ValueMode::Allocations, + "deallocations" => ValueMode::Deallocations, + "persistent-deallocations" => ValueMode::PersistentAllocations, + "allocation-count" => ValueMode::AllocationCount, + "allocations-per-time" => ValueMode::AllocationsPerTime, + "allocation-count-per-time" => ValueMode::AllocationCountPerTime, + "persistent-allocations-per-time" => ValueMode::PersistentAllocationsPerTime, + "count" => ValueMode::Count, + _ => ValueMode::Duration, + }; + + if !store.has_time_info() && matches!(value_mode, ValueMode::Duration) { + return Update { + lines: vec![ViewLineUpdate { + spans: vec![ViewSpan { + id: 0, + start: 0, + width: 1, + category: "info".to_string(), + text: "No time info in trace".to_string(), + count: 1, + kind: 0, + start_in_parent: 0, + end_in_parent: 0, + secondary: 0, + }], + y: 0, + }], + max: 1, + }; + } + + let mut queue = Vec::new(); + + let root_spans = if with_root { + vec![store.root_span()] + } else { + let mut root_spans = store.root_spans().collect::>(); + root_spans.sort_by_key(|span| span.start()); + root_spans + }; + + let mut children = Vec::new(); + let mut current = 0; + let offset = root_spans + .iter() + .min_by_key(|span| span.start()) + .map_or(0, |span| span.start()); + root_spans.par_iter().for_each(|span| { + span.max_depth(); + QueueItem::Span(*span).value(value_mode); + }); + for span in root_spans { + if matches!(value_mode, ValueMode::Duration) { + // Move current to start if needed. + current = max(current, span.start() - offset); + } + if add_child_item( + &mut children, + &mut current, + view_rect, + 0, + default_view_mode, + value_mode, + QueueItem::Span(span), + Some(if search_mode { + FilterMode::Parent + } else { + FilterMode::SelectedItem + }), + ) && search_mode + { + let mut has_results = false; + for mut result in span.search(query) { + has_results = true; + highlighted_spans.insert(result.id()); + while let Some(parent) = result.parent() { + result = parent; + if !highlighted_span_parents.insert(result.id()) { + break; + } + } + } + if has_results { + highlighted_spans.insert(span.id()); + } else { + children.last_mut().unwrap().item.filtered = None; + } + } + } + enqueue_children(children, &mut queue); + queue.par_iter().for_each(|item| { + let QueueItem::Span(span) = item.item else { + return; + }; + let view_mode = if span.is_complete() { + item.view_mode + } else { + item.view_mode.as_spans() + }; + + match (view_mode.bottom_up(), view_mode.aggregate_children()) { + (false, false) => {} + (false, true) => { + span.graph() + .collect::>() + .par_iter() + .for_each(|event| { + value_mode.value_from_graph_event(event); + }); + } + (true, false) => { + span.bottom_up() + .collect::>() + .par_iter() + .for_each(|bu| { + bu.spans().collect::>().par_iter().for_each(|span| { + value_mode.value_from_bottom_up_span(span); + }); + }); + } + (true, true) => { + span.bottom_up() + .collect::>() + .par_iter() + .for_each(|bu| { + value_mode.value_from_bottom_up(bu); + }); + } + } + }); + + let mut lines: Vec>> = vec![]; + + while let Some(QueueItemWithState { + item: span, + line_index, + start, + placeholder, + view_mode, + mut filtered, + }) = queue.pop() + { + let line = get_line(&mut lines, line_index); + let width = span.value(value_mode); + let secondary = span.value(value_mode.secondary()); + + let skipped_by_focus = + focus_mode && matches!(filtered, Some(FilterMode::Parent) | None); + + let get_filter_mode = |span: SpanId| { + if focus_mode + && matches!(filtered, Some(FilterMode::SelectedItem | FilterMode::Child)) + { + Some(FilterMode::Child) + } else if search_mode { + if highlighted_spans.contains(&span) { + Some(FilterMode::SelectedItem) + } else if highlighted_span_parents.contains(&span) { + Some(FilterMode::Parent) + } else { + None + } + } else { + Some(FilterMode::SelectedItem) + } + }; + + // compute children + let mut children = Vec::new(); + let mut current = start; + let child_line_index = if skipped_by_focus { + line_index + } else { + line_index + 1 + }; + match &span { + QueueItem::Span(span) => { + let (selected_view_mode, inherit) = (!span.is_root()) + .then(|| self.span_options.get(&span.id()).and_then(|o| o.view_mode)) + .flatten() + .unwrap_or_else(|| { + ( + if span.is_complete() { + view_mode + } else { + view_mode.as_spans() + }, + false, + ) + }); + + let view_mode = if inherit { + selected_view_mode + } else { + view_mode + }; + + let selected_view_mode = + if search_mode && highlighted_span_parents.contains(&span.id()) { + selected_view_mode.as_spans() + } else { + selected_view_mode + }; + + if selected_view_mode.bottom_up() { + let bottom_up = span.bottom_up(); + if selected_view_mode.aggregate_children() { + let bottom_up = if selected_view_mode.sort_children() { + Either::Left(bottom_up.sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_bottom_up(child)) + })) + } else { + Either::Right(bottom_up) + }; + for child in bottom_up { + // TODO search + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::SpanBottomUp(child), + Some(FilterMode::SelectedItem), + ); + } + } else { + let bottom_up = bottom_up + .flat_map(|bottom_up| bottom_up.spans().collect::>()); + let bottom_up = if selected_view_mode.sort_children() { + Either::Left(bottom_up.sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_bottom_up_span(child)) + })) + } else { + Either::Right(bottom_up) + }; + for child in bottom_up { + let filtered = get_filter_mode(child.id()); + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::SpanBottomUpSpan(child), + filtered, + ); + } + } + } else if !selected_view_mode.aggregate_children() { + let spans = if selected_view_mode.sort_children() { + Either::Left(span.children().sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_span(child)) + })) + } else { + Either::Right(span.children()) + }; + for child in spans { + let filtered = get_filter_mode(child.id()); + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::Span(child), + filtered, + ); + } + } else { + let events = if selected_view_mode.sort_children() { + Either::Left(span.graph().sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_graph_event(child)) + })) + } else { + Either::Right(span.graph()) + }; + for event in events { + let filtered = if search_mode { + None + } else { + Some(FilterMode::SelectedItem) + }; + match event { + SpanGraphEventRef::SelfTime { duration: _ } => {} + SpanGraphEventRef::Child { graph } => { + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::SpanGraph(graph), + filtered, + ); + } + } + } + } + } + QueueItem::SpanGraph(span_graph) => { + let (selected_view_mode, inherit) = self + .span_options + .get(&span_graph.id()) + .and_then(|o| o.view_mode) + .unwrap_or((view_mode, false)); + + let view_mode = if inherit { + selected_view_mode + } else { + view_mode + }; + if selected_view_mode.bottom_up() { + let bottom_up = span_graph.bottom_up(); + if selected_view_mode.aggregate_children() { + let bottom_up = if selected_view_mode.sort_children() { + Either::Left(bottom_up.sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_bottom_up(child)) + })) + } else { + Either::Right(bottom_up) + }; + for child in bottom_up { + // TODO search + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::SpanBottomUp(child), + Some(FilterMode::SelectedItem), + ); + } + } else { + let bottom_up = bottom_up + .flat_map(|bottom_up| bottom_up.spans().collect::>()); + let bottom_up = if selected_view_mode.sort_children() { + Either::Left(bottom_up.sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_bottom_up_span(child)) + })) + } else { + Either::Right(bottom_up) + }; + for child in bottom_up { + let filtered = get_filter_mode(child.id()); + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::SpanBottomUpSpan(child), + filtered, + ); + } + } + } else if !selected_view_mode.aggregate_children() && span_graph.count() > 1 { + let spans = if selected_view_mode.sort_children() { + Either::Left(span_graph.root_spans().sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_span(child)) + })) + } else { + Either::Right(span_graph.root_spans()) + }; + for child in spans { + let filtered = get_filter_mode(child.id()); + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::Span(child), + filtered, + ); + } + } else { + let events = if selected_view_mode.sort_children() { + Either::Left(span_graph.events().sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_graph_event(child)) + })) + } else { + Either::Right(span_graph.events()) + }; + for child in events { + if let SpanGraphEventRef::Child { graph } = child { + let filtered = if search_mode { + None + } else { + Some(FilterMode::SelectedItem) + }; + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::SpanGraph(graph), + filtered, + ); + } + } + } + } + QueueItem::SpanBottomUp(bottom_up) => { + let view_mode = self + .span_options + .get(&bottom_up.id()) + .and_then(|o| o.view_mode) + .map(|(v, _)| v.as_bottom_up()) + .unwrap_or(view_mode); + + if view_mode.aggregate_children() { + let bottom_up = if view_mode.sort_children() { + Either::Left(bottom_up.children().sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_bottom_up(child)) + })) + } else { + Either::Right(bottom_up.children()) + }; + for child in bottom_up { + // TODO search + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::SpanBottomUp(child), + Some(FilterMode::SelectedItem), + ); + } + } else { + let spans = if view_mode.sort_children() { + Either::Left(bottom_up.spans().sorted_by_cached_key(|child| { + Reverse(value_mode.value_from_bottom_up_span(child)) + })) + } else { + Either::Right(bottom_up.spans()) + }; + for child in spans { + let filtered = get_filter_mode(child.id()); + add_child_item( + &mut children, + &mut current, + view_rect, + child_line_index, + view_mode, + value_mode, + QueueItem::SpanBottomUpSpan(child), + filtered, + ); + } + } + } + QueueItem::SpanBottomUpSpan(_) => { + // no children + } + } + + // When span size is smaller than a pixel, we only show the deepest child. + if placeholder { + let child = children + .into_iter() + .max_by_key(|ChildItem { item, depth, .. }| (item.filtered.is_some(), *depth)); + if let Some(ChildItem { + item: mut entry, .. + }) = child + { + entry.placeholder = true; + queue.push(entry); + } + + if !skipped_by_focus { + // add span to line + line.push(LineEntry { + start, + width, + secondary: 0, + ty: LineEntryType::Placeholder(filtered), + }); + } + } else { + // add children to queue + enqueue_children(children, &mut queue); + + // check if we should filter based on width or count + if !skipped_by_focus { + let count = match &span { + QueueItem::Span(_) => 1, + QueueItem::SpanGraph(span_graph) => span_graph.count(), + QueueItem::SpanBottomUp(bottom_up) => bottom_up.count(), + QueueItem::SpanBottomUpSpan(_) => 1, + }; + + if let Some(false) = view_rect.count_filter.as_ref().map(|filter| match filter + .op + { + crate::server::Op::Gt => count > filter.value as usize, + crate::server::Op::Lt => count < filter.value as usize, + }) { + filtered = Some(FilterMode::SelectedItem) + } + + if let Some(false) = view_rect.value_filter.as_ref().map(|filter| match filter + .op + { + crate::server::Op::Gt => width > filter.value, + crate::server::Op::Lt => width < filter.value, + }) { + filtered = Some(FilterMode::SelectedItem) + } + + // add span to line + line.push(LineEntry { + start, + width, + secondary, + ty: match span { + QueueItem::Span(span) => LineEntryType::Span { span, filtered }, + QueueItem::SpanGraph(span_graph) => { + LineEntryType::SpanGraph(span_graph, filtered) + } + QueueItem::SpanBottomUp(bottom_up) => { + LineEntryType::SpanBottomUp(bottom_up, filtered) + } + QueueItem::SpanBottomUpSpan(bottom_up_span) => { + LineEntryType::SpanBottomUpSpan(bottom_up_span, filtered) + } + }, + }); + } + } + } + + let lines = lines + .into_iter() + .enumerate() + .map(|(y, line)| ViewLineUpdate { + y: y as u64, + spans: line + .into_iter() + .map(|entry| match entry.ty { + LineEntryType::Placeholder(filtered) => ViewSpan { + id: 0, + start: entry.start, + width: entry.width, + category: String::new(), + text: String::new(), + count: 1, + kind: match filtered { + Some(_) => 1, + None => 11, + }, + start_in_parent: 0, + end_in_parent: 0, + secondary: 0, + }, + LineEntryType::Span { span, filtered } => { + let (category, text) = span.nice_name(); + let mut start_in_parent = 0; + let mut end_in_parent = 0; + if let Some(parent) = span.parent() { + let parent_start = parent.start(); + let parent_duration = parent.end() - parent_start; + if parent_duration > 0 { + start_in_parent = ((span.start() - parent_start) * 10000 + / parent_duration) + as u32; + end_in_parent = ((span.end() - parent_start) * 10000 + / parent_duration) + as u32; + } else { + start_in_parent = 0; + end_in_parent = 10000; + } + } + ViewSpan { + id: (!span.is_root()) + .then(|| span.id().get() as u64) + .unwrap_or_default(), + start: entry.start, + width: entry.width, + category: category.to_string(), + text: text.to_string(), + count: 1, + kind: match filtered { + Some(_) => 0, + None => 10, + }, + start_in_parent, + end_in_parent, + secondary: entry.secondary, + } + } + LineEntryType::SpanGraph(graph, filtered) => { + let (category, text) = graph.nice_name(); + ViewSpan { + id: graph.id().get() as u64, + start: entry.start, + width: entry.width, + category: category.to_string(), + text: text.to_string(), + count: graph.count() as u64, + kind: match filtered { + Some(_) => 0, + None => 10, + }, + start_in_parent: 0, + end_in_parent: 0, + secondary: entry.secondary, + } + } + LineEntryType::SpanBottomUp(bottom_up, filtered) => { + let (category, text) = bottom_up.nice_name(); + ViewSpan { + id: bottom_up.id().get() as u64, + start: entry.start, + width: entry.width, + category: category.to_string(), + text: text.to_string(), + count: bottom_up.count() as u64, + kind: match filtered { + Some(_) => 2, + None => 12, + }, + start_in_parent: 0, + end_in_parent: 0, + secondary: entry.secondary, + } + } + LineEntryType::SpanBottomUpSpan(bottom_up_span, filtered) => { + let (category, text) = bottom_up_span.nice_name(); + ViewSpan { + id: bottom_up_span.id().get() as u64, + start: entry.start, + width: entry.width, + category: category.to_string(), + text: text.to_string(), + count: 1, + kind: match filtered { + Some(_) => 2, + None => 12, + }, + start_in_parent: 0, + end_in_parent: 0, + secondary: entry.secondary, + } + } + }) + .collect(), + }) + .collect(); + + Update { + lines, + max: max(1, current), + } + } +} + +#[allow(clippy::too_many_arguments)] +fn add_child_item<'a>( + children: &mut Vec>, + current: &mut u64, + view_rect: &ViewRect, + line_index: usize, + view_mode: ViewMode, + value_mode: ValueMode, + child: QueueItem<'a>, + filtered: Option, +) -> bool { + let child_width = child.value(value_mode); + let max_depth = child.max_depth(); + let pixel1 = *current * view_rect.horizontal_pixels / view_rect.width; + let pixel2 = ((*current + child_width) * view_rect.horizontal_pixels + view_rect.width - 1) + / view_rect.width; + let start = *current; + *current += child_width; + + // filter by view rect (vertical) + if line_index > (view_rect.y + view_rect.height + EXTRA_HEIGHT) as usize { + return false; + } + + if line_index > 0 { + // filter by view rect (horizontal) + if start > view_rect.x + view_rect.width * (100 + EXTRA_WIDTH_PERCENTAGE) / 100 { + return false; + } + if *current + < view_rect + .x + .saturating_sub(view_rect.width * EXTRA_WIDTH_PERCENTAGE / 100) + { + return false; + } + } + + children.push(ChildItem { + item: QueueItemWithState { + item: child, + line_index, + start, + placeholder: false, + view_mode, + filtered, + }, + depth: max_depth, + pixel_range: (pixel1, pixel2), + }); + + true +} + +const MIN_VISIBLE_PIXEL_SIZE: u64 = 3; + +fn enqueue_children<'a>(mut children: Vec>, queue: &mut Vec>) { + children.reverse(); + let mut last_pixel = u64::MAX; + let mut last_max_depth = 0; + for ChildItem { + item: mut entry, + depth: max_depth, + pixel_range: (pixel1, pixel2), + } in children + { + if last_pixel <= pixel1 + MIN_VISIBLE_PIXEL_SIZE { + if last_max_depth < max_depth { + queue.pop(); + entry.placeholder = true; + } else { + if let Some(entry) = queue.last_mut() { + entry.placeholder = true; + } + continue; + } + }; + queue.push(entry); + last_max_depth = max_depth; + last_pixel = pixel2; + } +} + +fn get_line(lines: &mut Vec, i: usize) -> &mut T { + if i >= lines.len() { + lines.resize_with(i + 1, || Default::default()); + } + &mut lines[i] +} + +struct LineEntry<'a> { + start: u64, + width: u64, + secondary: u64, + ty: LineEntryType<'a>, +} + +enum LineEntryType<'a> { + Placeholder(Option), + Span { + span: SpanRef<'a>, + filtered: Option, + }, + SpanGraph(SpanGraphRef<'a>, Option), + SpanBottomUp(SpanBottomUpRef<'a>, Option), + SpanBottomUpSpan(SpanRef<'a>, Option), +} diff --git a/turbopack/crates/turbopack-trace-utils/Cargo.toml b/turbopack/crates/turbopack-trace-utils/Cargo.toml new file mode 100644 index 0000000000000..d0c0a11f276c2 --- /dev/null +++ b/turbopack/crates/turbopack-trace-utils/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "turbopack-trace-utils" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = { workspace = true } +crossbeam-channel = { workspace = true } +once_cell = { workspace = true } +postcard = { workspace = true, features = ["alloc", "use-std"] } +serde = { workspace = true, features = ["derive"] } +tokio = { workspace = true, features = ["macros", "signal", "sync", "rt"] } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +turbo-tasks-malloc = { workspace = true } diff --git a/turbopack/crates/turbopack-trace-utils/src/exit.rs b/turbopack/crates/turbopack-trace-utils/src/exit.rs new file mode 100644 index 0000000000000..f8177e48624ae --- /dev/null +++ b/turbopack/crates/turbopack-trace-utils/src/exit.rs @@ -0,0 +1,212 @@ +use std::{ + future::Future, + pin::Pin, + sync::{Arc, Mutex, OnceLock}, +}; + +use anyhow::Result; +use tokio::{select, sync::mpsc, task::JoinSet}; + +/// A guard for the exit handler. When dropped, the exit guard will be dropped. +/// It might also be dropped on Ctrl-C. +pub struct ExitGuard(Arc>>); + +impl Drop for ExitGuard { + fn drop(&mut self) { + drop(self.0.lock().unwrap().take()) + } +} + +impl ExitGuard { + /// Drop a guard when Ctrl-C is pressed or the [ExitGuard] is dropped. + pub fn new(guard: T) -> Result { + let guard = Arc::new(Mutex::new(Some(guard))); + { + let guard = guard.clone(); + tokio::spawn(async move { + tokio::signal::ctrl_c().await.unwrap(); + drop(guard.lock().unwrap().take()); + std::process::exit(0); + }); + } + Ok(ExitGuard(guard)) + } +} + +type BoxExitFuture = Pin + Send + 'static>>; + +/// The singular global ExitHandler. This is primarily used to ensure +/// `ExitHandler::listen` is only called once. +/// +/// The global handler is intentionally not exposed, so that APIs that depend on +/// exit behavior are required to take the `ExitHandler`. This ensures that the +/// `ExitHandler` is configured before these APIs are run, and that these +/// consumers can be used with a callback (e.g. a mock) instead. +static GLOBAL_EXIT_HANDLER: OnceLock> = OnceLock::new(); + +pub struct ExitHandler { + tx: mpsc::UnboundedSender, +} + +impl ExitHandler { + /// Waits for `SIGINT` using [`tokio::signal::ctrl_c`], and exits the + /// process with exit code `0` after running any futures scheduled with + /// [`ExitHandler::on_exit`]. + /// + /// As this uses global process signals, this must only be called once, and + /// will panic if called multiple times. Use this when you own the + /// process (e.g. `turbopack-cli`). + /// + /// If you don't own the process (e.g. you're called as a library, such as + /// in `next-swc`), use [`ExitHandler::new_trigger`] instead. + /// + /// This may listen for other signals, like `SIGTERM` or `SIGPIPE` in the + /// future. + pub fn listen() -> &'static Arc { + let (handler, receiver) = Self::new_receiver(); + if GLOBAL_EXIT_HANDLER.set(handler).is_err() { + panic!("ExitHandler::listen must only be called once"); + } + tokio::spawn(async move { + tokio::signal::ctrl_c() + .await + .expect("failed to set ctrl_c handler"); + receiver.run_exit_handler().await; + std::process::exit(0); + }); + GLOBAL_EXIT_HANDLER.get().expect("value is set") + } + + /// Creates an [`ExitHandler`] that can be manually controlled with an + /// [`ExitReceiver`]. + /// + /// This does not actually exit the process or listen for any signals. If + /// you'd like that behavior, use [`ExitHandler::listen`]. + /// + /// Because this API has no global side-effects and can be called many times + /// within the same process, it is possible to use it to provide a mock + /// [`ExitHandler`] inside unit tests. + pub fn new_receiver() -> (Arc, ExitReceiver) { + let (tx, rx) = mpsc::unbounded_channel(); + (Arc::new(ExitHandler { tx }), ExitReceiver { rx }) + } + + /// Register this given [`Future`] to run upon process exit. + /// + /// As there are many ways for a process be killed that are outside of a + /// process's own control (e.g. `SIGKILL` or `SIGSEGV`), this API is + /// provided on a best-effort basis. + pub fn on_exit(&self, fut: impl Future + Send + 'static) { + // realistically, this error case can only happen with the `new_receiver` API. + self.tx + .send(Box::pin(fut)) + .expect("cannot send future after process exit"); + } +} + +/// Provides a way to run futures scheduled with an [`ExitHandler`]. +pub struct ExitReceiver { + rx: mpsc::UnboundedReceiver, +} + +impl ExitReceiver { + /// Call this when the process exits to run the futures scheduled via + /// [`ExitHandler::on_exit`]. + /// + /// As this is intended to be used in a library context, this does not exit + /// the process. It is expected that the process will not exit until + /// this async method finishes executing. + /// + /// Additional work can be scheduled using [`ExitHandler::on_exit`] even + /// while this is running, and it will execute before this function + /// finishes. Work attempted to be scheduled after this finishes will panic. + pub async fn run_exit_handler(mut self) { + let mut set = JoinSet::new(); + while let Ok(fut) = self.rx.try_recv() { + set.spawn(fut); + } + loop { + select! { + biased; + Some(fut) = self.rx.recv() => { + set.spawn(fut); + }, + val = set.join_next() => { + match val { + Some(Ok(())) => {} + Some(Err(_)) => panic!("ExitHandler future panicked!"), + None => return, + } + }, + } + } + } +} + +#[cfg(test)] +mod tests { + use std::{ + future::Future, + pin::Pin, + sync::{ + atomic::{AtomicBool, AtomicU32, Ordering}, + Arc, + }, + }; + + use super::ExitHandler; + + #[tokio::test] + async fn test_on_exit() { + let (handler, receiver) = ExitHandler::new_receiver(); + + let called = Arc::new(AtomicBool::new(false)); + handler.on_exit({ + let called = Arc::clone(&called); + async move { + tokio::task::yield_now().await; + called.store(true, Ordering::SeqCst); + } + }); + + receiver.run_exit_handler().await; + assert_eq!(called.load(Ordering::SeqCst), true); + } + + #[tokio::test] + async fn test_queue_while_exiting() { + let (handler, receiver) = ExitHandler::new_receiver(); + let call_count = Arc::new(AtomicU32::new(0)); + + type BoxExitFuture = Pin + Send + 'static>>; + + // this struct is needed to construct the recursive closure type + #[derive(Clone)] + struct GetFut { + handler: Arc, + call_count: Arc, + } + + impl GetFut { + fn get(self) -> BoxExitFuture { + Box::pin(async move { + tokio::task::yield_now().await; + if self.call_count.fetch_add(1, Ordering::SeqCst) < 99 { + // queue more work while the exit handler is running + Arc::clone(&self.handler).on_exit(self.get()) + } + }) + } + } + + handler.on_exit( + GetFut { + handler: Arc::clone(&handler), + call_count: Arc::clone(&call_count), + } + .get(), + ); + receiver.run_exit_handler().await; + assert_eq!(call_count.load(Ordering::SeqCst), 100); + } +} diff --git a/turbopack/crates/turbopack-trace-utils/src/flavor.rs b/turbopack/crates/turbopack-trace-utils/src/flavor.rs new file mode 100644 index 0000000000000..688d5bea50813 --- /dev/null +++ b/turbopack/crates/turbopack-trace-utils/src/flavor.rs @@ -0,0 +1,23 @@ +use postcard::ser_flavors::Flavor; + +pub struct BufFlavor { + pub buf: Vec, +} + +impl Flavor for BufFlavor { + type Output = Vec; + + fn try_push(&mut self, data: u8) -> postcard::Result<()> { + self.buf.push(data); + Ok(()) + } + + fn finalize(self) -> postcard::Result { + Ok(self.buf) + } + + fn try_extend(&mut self, data: &[u8]) -> postcard::Result<()> { + self.buf.extend_from_slice(data); + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-trace-utils/src/lib.rs b/turbopack/crates/turbopack-trace-utils/src/lib.rs new file mode 100644 index 0000000000000..8b94c0e853ae9 --- /dev/null +++ b/turbopack/crates/turbopack-trace-utils/src/lib.rs @@ -0,0 +1,12 @@ +#![feature(async_closure)] +#![feature(min_specialization)] +#![feature(round_char_boundary)] +#![feature(thread_id_value)] +#![feature(arbitrary_self_types)] + +pub mod exit; +mod flavor; +pub mod raw_trace; +pub mod trace_writer; +pub mod tracing; +pub mod tracing_presets; diff --git a/turbopack/crates/turbopack-trace-utils/src/raw_trace.rs b/turbopack/crates/turbopack-trace-utils/src/raw_trace.rs new file mode 100644 index 0000000000000..9e4bc5f55f8ab --- /dev/null +++ b/turbopack/crates/turbopack-trace-utils/src/raw_trace.rs @@ -0,0 +1,199 @@ +use std::{borrow::Cow, fmt::Write, marker::PhantomData, thread, time::Instant}; + +use tracing::{ + field::{display, Visit}, + span, Subscriber, +}; +use tracing_subscriber::{registry::LookupSpan, Layer}; +use turbo_tasks_malloc::TurboMalloc; + +use crate::{ + flavor::BufFlavor, + trace_writer::TraceWriter, + tracing::{TraceRow, TraceValue}, +}; + +/// A tracing layer that writes raw trace data to a writer. The data format is +/// defined by [FullTraceRow]. +pub struct RawTraceLayer LookupSpan<'a>> { + trace_writer: TraceWriter, + start: Instant, + _phantom: PhantomData, +} + +impl LookupSpan<'a>> RawTraceLayer { + pub fn new(trace_writer: TraceWriter) -> Self { + Self { + trace_writer, + start: Instant::now(), + _phantom: PhantomData, + } + } + + fn write(&self, data: TraceRow<'_>) { + let start = TurboMalloc::allocation_counters(); + // Buffer is recycled + let buf = self.trace_writer.try_get_buffer().unwrap_or_default(); + let buf = postcard::serialize_with_flavor(&data, BufFlavor { buf }).unwrap(); + self.trace_writer.write(buf); + TurboMalloc::reset_allocation_counters(start); + } + + fn report_allocations(&self, ts: u64, thread_id: u64) { + let allocation_counters = turbo_tasks_malloc::TurboMalloc::allocation_counters(); + self.write(TraceRow::AllocationCounters { + ts, + thread_id, + allocations: allocation_counters.allocations as u64, + deallocations: allocation_counters.deallocations as u64, + allocation_count: allocation_counters.allocation_count as u64, + deallocation_count: allocation_counters.deallocation_count as u64, + }); + } +} + +impl LookupSpan<'a>> Layer for RawTraceLayer { + fn on_new_span( + &self, + attrs: &span::Attributes<'_>, + id: &span::Id, + ctx: tracing_subscriber::layer::Context<'_, S>, + ) { + let ts = self.start.elapsed().as_micros() as u64; + let mut values = ValuesVisitor::new(); + attrs.values().record(&mut values); + self.write(TraceRow::Start { + ts, + id: id.into_u64(), + parent: if attrs.is_contextual() { + ctx.current_span().id().map(|p| p.into_u64()) + } else { + attrs.parent().map(|p| p.into_u64()) + }, + name: attrs.metadata().name().into(), + target: attrs.metadata().target().into(), + values: values.values, + }); + } + + fn on_close(&self, id: span::Id, _ctx: tracing_subscriber::layer::Context<'_, S>) { + let ts = self.start.elapsed().as_micros() as u64; + self.write(TraceRow::End { + ts, + id: id.into_u64(), + }); + } + + fn on_enter(&self, id: &span::Id, _ctx: tracing_subscriber::layer::Context<'_, S>) { + let ts = self.start.elapsed().as_micros() as u64; + let thread_id = thread::current().id().as_u64().into(); + self.report_allocations(ts, thread_id); + self.write(TraceRow::Enter { + ts, + id: id.into_u64(), + thread_id, + }); + } + + fn on_exit(&self, id: &span::Id, _ctx: tracing_subscriber::layer::Context<'_, S>) { + let ts = self.start.elapsed().as_micros() as u64; + let thread_id = thread::current().id().as_u64().into(); + self.report_allocations(ts, thread_id); + self.write(TraceRow::Exit { + ts, + id: id.into_u64(), + thread_id, + }); + } + + fn on_event(&self, event: &tracing::Event<'_>, ctx: tracing_subscriber::layer::Context<'_, S>) { + let ts = self.start.elapsed().as_micros() as u64; + let mut values = ValuesVisitor::new(); + event.record(&mut values); + self.write(TraceRow::Event { + ts, + parent: if event.is_contextual() { + ctx.current_span().id().map(|p| p.into_u64()) + } else { + event.parent().map(|p| p.into_u64()) + }, + values: values.values, + }); + } + + fn on_record( + &self, + id: &span::Id, + record: &span::Record<'_>, + _ctx: tracing_subscriber::layer::Context<'_, S>, + ) { + let mut values = ValuesVisitor::new(); + record.record(&mut values); + self.write(TraceRow::Record { + id: id.into_u64(), + values: values.values, + }); + } +} + +struct ValuesVisitor { + values: Vec<(Cow<'static, str>, TraceValue<'static>)>, +} + +impl ValuesVisitor { + fn new() -> Self { + Self { values: Vec::new() } + } +} + +impl Visit for ValuesVisitor { + fn record_debug(&mut self, field: &tracing::field::Field, value: &dyn std::fmt::Debug) { + let mut str = String::new(); + let _ = write!(str, "{:?}", value); + self.values + .push((field.name().into(), TraceValue::String(str.into()))); + } + + fn record_f64(&mut self, field: &tracing::field::Field, value: f64) { + self.values + .push((field.name().into(), TraceValue::Float(value))); + } + + fn record_i64(&mut self, field: &tracing::field::Field, value: i64) { + self.values + .push((field.name().into(), TraceValue::Int(value))); + } + + fn record_u64(&mut self, field: &tracing::field::Field, value: u64) { + self.values + .push((field.name().into(), TraceValue::UInt(value))); + } + + fn record_i128(&mut self, field: &tracing::field::Field, value: i128) { + self.record_debug(field, &value) + } + + fn record_u128(&mut self, field: &tracing::field::Field, value: u128) { + self.record_debug(field, &value) + } + + fn record_bool(&mut self, field: &tracing::field::Field, value: bool) { + self.values + .push((field.name().into(), TraceValue::Bool(value))); + } + + fn record_str(&mut self, field: &tracing::field::Field, value: &str) { + self.values.push(( + field.name().into(), + TraceValue::String(value.to_string().into()), + )); + } + + fn record_error( + &mut self, + field: &tracing::field::Field, + value: &(dyn std::error::Error + 'static), + ) { + self.record_debug(field, &display(value)) + } +} diff --git a/turbopack/crates/turbopack-trace-utils/src/trace_writer.rs b/turbopack/crates/turbopack-trace-utils/src/trace_writer.rs new file mode 100644 index 0000000000000..97658c90747bd --- /dev/null +++ b/turbopack/crates/turbopack-trace-utils/src/trace_writer.rs @@ -0,0 +1,117 @@ +use std::{debug_assert, io::Write, thread::JoinHandle}; + +use crossbeam_channel::{bounded, unbounded, Receiver, Sender, TryRecvError}; + +#[derive(Clone, Debug)] +pub struct TraceWriter { + data_tx: Sender>, + return_rx: Receiver>, +} + +impl TraceWriter { + /// This is a non-blocking writer that writes a file in a background thread. + /// This is inspired by tracing-appender non_blocking, but has some + /// differences: + /// * It allows writing an owned Vec instead of a reference, so avoiding + /// additional allocation. + /// * It uses an unbounded channel to avoid slowing down the application at + /// all (memory) cost. + /// * It issues less writes by buffering the data into chunks of ~1MB, when + /// possible. + pub fn new(mut writer: W) -> (Self, TraceWriterGuard) { + let (data_tx, data_rx) = unbounded::>(); + let (return_tx, return_rx) = bounded::>(1024 * 10); + + let handle: std::thread::JoinHandle<()> = std::thread::spawn(move || { + let _ = writer.write(b"TRACEv0"); + let mut buf = Vec::with_capacity(1024 * 1024 * 1024); + 'outer: loop { + if !buf.is_empty() { + let _ = writer.write_all(&buf); + let _ = writer.flush(); + buf.clear(); + } + let Ok(mut data) = data_rx.recv() else { + break 'outer; + }; + if data.is_empty() { + break 'outer; + } + if data.len() > buf.capacity() { + let _ = writer.write_all(&data); + } else { + buf.extend_from_slice(&data); + } + data.clear(); + let _ = return_tx.try_send(data); + loop { + match data_rx.try_recv() { + Ok(data) => { + if data.is_empty() { + break 'outer; + } + if buf.len() + data.len() > buf.capacity() { + let _ = writer.write_all(&buf); + buf.clear(); + if data.len() > buf.capacity() { + let _ = writer.write_all(&data); + } else { + buf.extend_from_slice(&data); + } + } else { + buf.extend_from_slice(&data); + } + } + Err(TryRecvError::Disconnected) => { + break 'outer; + } + Err(TryRecvError::Empty) => { + break; + } + } + } + } + if !buf.is_empty() { + let _ = writer.write_all(&buf); + } + let _ = writer.flush(); + drop(writer); + }); + + ( + Self { + data_tx: data_tx.clone(), + return_rx: return_rx.clone(), + }, + TraceWriterGuard { + data_tx: Some(data_tx), + return_rx: Some(return_rx), + handle: Some(handle), + }, + ) + } + + pub fn write(&self, data: Vec) { + debug_assert!(!data.is_empty()); + let _ = self.data_tx.send(data); + } + + pub fn try_get_buffer(&self) -> Option> { + self.return_rx.try_recv().ok() + } +} + +pub struct TraceWriterGuard { + data_tx: Option>>, + return_rx: Option>>, + handle: Option>, +} + +impl Drop for TraceWriterGuard { + fn drop(&mut self) { + let _ = self.data_tx.take().unwrap().send(Vec::new()); + let return_rx = self.return_rx.take().unwrap(); + while return_rx.recv().is_ok() {} + let _ = self.handle.take().unwrap().join(); + } +} diff --git a/turbopack/crates/turbopack-trace-utils/src/tracing.rs b/turbopack/crates/turbopack-trace-utils/src/tracing.rs new file mode 100644 index 0000000000000..76e4ab159d297 --- /dev/null +++ b/turbopack/crates/turbopack-trace-utils/src/tracing.rs @@ -0,0 +1,150 @@ +use std::{ + borrow::Cow, + fmt::{Display, Formatter}, +}; + +use serde::{Deserialize, Serialize}; + +/// A raw trace line. +#[derive(Debug, Serialize, Deserialize)] +pub enum TraceRow<'a> { + /// A new span has been started, but not entered yet. + Start { + /// Timestamp + ts: u64, + /// Unique id for this span. + id: u64, + /// Id of the parent span, if any. + parent: Option, + /// The name of the span. + #[serde(borrow)] + name: Cow<'a, str>, + /// The target of the span. + #[serde(borrow)] + target: Cow<'a, str>, + /// A list of key-value pairs for all attributes of the span. + #[serde(borrow)] + values: Vec<(Cow<'a, str>, TraceValue<'a>)>, + }, + /// A span has ended. The id might be reused in future. + End { + /// Timestamp + ts: u64, + /// Unique id for this span. Must be created by a `Start` event before. + id: u64, + }, + /// A span has been entered. This means it is spending CPU time now. + Enter { + /// Timestamp + ts: u64, + /// Unique id for this span. Must be created by a `Start` event before. + id: u64, + /// The thread id of the thread that entered the span. + thread_id: u64, + }, + /// A span has been exited. This means it is not spending CPU time anymore. + Exit { + /// Timestamp + ts: u64, + /// Unique id for this span. Must be entered by a `Enter` event before. + id: u64, + /// The thread id of the thread that exits the span. + thread_id: u64, + }, + /// A event has happened for some span. + Event { + /// Timestamp + ts: u64, + /// Id of the parent span, if any. + parent: Option, + /// A list of key-value pairs for all attributes of the event. + #[serde(borrow)] + values: Vec<(Cow<'a, str>, TraceValue<'a>)>, + }, + /// Additional fields for a span + Record { + /// Unique id for this span. Must be created by a `Start` event before. + id: u64, + /// A list of key-value pairs for all attributes of the span. + #[serde(borrow)] + values: Vec<(Cow<'a, str>, TraceValue<'a>)>, + }, + /// Data about (de)allocations that happened + Allocation { + /// Timestamp + ts: u64, + /// The thread id of the thread where allocations happend. + thread_id: u64, + /// Allocations + allocations: u64, + /// Allocation count + allocation_count: u64, + /// Deallocations + deallocations: u64, + /// Deallocation count + deallocation_count: u64, + }, + /// Data about (de)allocations per thread counters. Actual allocations can + /// be computed from the difference. + AllocationCounters { + /// Timestamp + ts: u64, + /// The thread id of the thread where allocations happend. + thread_id: u64, + /// Allocations + allocations: u64, + /// Allocation count + allocation_count: u64, + /// Deallocations + deallocations: u64, + /// Deallocation count + deallocation_count: u64, + }, +} + +#[derive(Debug, Serialize, Deserialize)] +pub enum TraceValue<'a> { + String(#[serde(borrow)] Cow<'a, str>), + Bool(bool), + UInt(u64), + Int(i64), + Float(f64), +} + +impl Display for TraceValue<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + TraceValue::String(s) => write!(f, "{}", s), + TraceValue::Bool(b) => write!(f, "{}", b), + TraceValue::UInt(u) => write!(f, "{}", u), + TraceValue::Int(i) => write!(f, "{}", i), + TraceValue::Float(fl) => write!(f, "{}", fl), + } + } +} + +impl<'a> TraceValue<'a> { + pub fn as_u64(&self) -> Option { + match self { + TraceValue::UInt(u) => Some(*u), + _ => None, + } + } + + pub fn as_str(&self) -> Option<&str> { + match self { + TraceValue::String(s) => Some(s), + _ => None, + } + } + + pub fn into_static(self) -> TraceValue<'static> { + match self { + TraceValue::String(s) => TraceValue::String(s.into_owned().into()), + TraceValue::Bool(b) => TraceValue::Bool(b), + TraceValue::UInt(u) => TraceValue::UInt(u), + TraceValue::Int(i) => TraceValue::Int(i), + TraceValue::Float(fl) => TraceValue::Float(fl), + } + } +} diff --git a/turbopack/crates/turbopack-trace-utils/src/tracing_presets.rs b/turbopack/crates/turbopack-trace-utils/src/tracing_presets.rs new file mode 100644 index 0000000000000..eb8ea35900740 --- /dev/null +++ b/turbopack/crates/turbopack-trace-utils/src/tracing_presets.rs @@ -0,0 +1,75 @@ +use once_cell::sync::Lazy; + +pub static TRACING_OVERVIEW_TARGETS: Lazy> = Lazy::new(|| { + vec![ + "turbo_tasks=info", + "turbo_tasks_fs=info", + "turbopack=info", + "turbopack_binding=info", + "turbopack_nodejs=info", + "turbopack_cli=info", + "turbopack_cli_utils=info", + "turbopack_core=info", + "turbopack_css=info", + "turbopack_browser=info", + "turbopack_dev_server=info", + "turbopack_ecmascript=info", + "turbopack_ecmascript_hmr_protocol=info", + "turbopack_ecmascript_plugins=info", + "turbopack_ecmascript_runtime=info", + "turbopack_env=info", + "turbopack_image=info", + "turbopack_json=info", + "turbopack_mdx=info", + "turbopack_node=info", + "turbopack_static=info", + "turbopack_swc_utils=info", + "turbopack_wasm=info", + ] +}); +pub static TRACING_TURBOPACK_TARGETS: Lazy> = Lazy::new(|| { + [ + &TRACING_OVERVIEW_TARGETS[..], + &[ + "turbopack=trace", + "turbopack_binding=trace", + "turbopack_nodejs=trace", + "turbopack_cli=trace", + "turbopack_cli_utils=trace", + "turbopack_core=trace", + "turbopack_css=trace", + "turbopack_browser=trace", + "turbopack_dev_server=trace", + "turbopack_ecmascript=trace", + "turbopack_ecmascript_hmr_protocol=trace", + "turbopack_ecmascript_plugins=trace", + "turbopack_ecmascript_runtime=trace", + "turbopack_env=trace", + "turbopack_image=trace", + "turbopack_json=trace", + "turbopack_mdx=trace", + "turbopack_node=trace", + "turbopack_static=trace", + "turbopack_swc_utils=trace", + "turbopack_wasm=trace", + ], + ] + .concat() +}); +pub static TRACING_TURBO_TASKS_TARGETS: Lazy> = Lazy::new(|| { + [ + &TRACING_TURBOPACK_TARGETS[..], + &[ + "turbo_tasks=trace", + "turbo_tasks_auto_hash_map=trace", + "turbo_tasks_build=trace", + "turbo_tasks_bytes=trace", + "turbo_tasks_env=trace", + "turbo_tasks_fetch=trace", + "turbo_tasks_fs=trace", + "turbo_tasks_hash=trace", + "turbo_tasks_memory=trace", + ], + ] + .concat() +}); diff --git a/turbopack/crates/turbopack-wasm/Cargo.toml b/turbopack/crates/turbopack-wasm/Cargo.toml new file mode 100644 index 0000000000000..5628920ad32cb --- /dev/null +++ b/turbopack/crates/turbopack-wasm/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "turbopack-wasm" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +indexmap = { workspace = true } +indoc = { workspace = true } +serde = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } +wasmparser = "0.110.0" +wat = "1.0.69" + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-wasm/build.rs b/turbopack/crates/turbopack-wasm/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-wasm/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-wasm/src/analysis.rs b/turbopack/crates/turbopack-wasm/src/analysis.rs new file mode 100644 index 0000000000000..1e405d60b7815 --- /dev/null +++ b/turbopack/crates/turbopack-wasm/src/analysis.rs @@ -0,0 +1,77 @@ +use std::collections::BTreeMap; + +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_fs::FileContent; +use turbopack_core::asset::Asset; +use wasmparser::{Chunk, Parser, Payload}; + +use crate::source::WebAssemblySource; + +/// Imports and exports of a WebAssembly file. +#[turbo_tasks::value] +#[derive(Default)] +pub(crate) struct WebAssemblyAnalysis { + pub imports: BTreeMap>, + pub exports: Vec, +} + +/// Analyse a WebAssembly file. +/// +/// Extracts imports and exports. +#[turbo_tasks::function] +pub(crate) async fn analyze(source: Vc) -> Result> { + let content = source.content().file_content().await?; + + let mut analysis = WebAssemblyAnalysis::default(); + + let FileContent::Content(file) = &*content else { + return Ok(analysis.cell()); + }; + + let mut bytes = &*file.content().to_bytes()?; + + let mut parser = Parser::new(0); + loop { + let payload = match parser.parse(bytes, true)? { + Chunk::Parsed { consumed, payload } => { + bytes = &bytes[consumed..]; + payload + } + // this state isn't possible with `eof = true` + Chunk::NeedMoreData(_) => unreachable!(), + }; + + match payload { + Payload::ImportSection(s) => { + for import in s { + let import = import?; + + analysis + .imports + .entry(import.module.to_string()) + .or_default() + .push(import.name.to_string()); + } + } + Payload::ExportSection(s) => { + for export in s { + let export = export?; + + analysis.exports.push(export.name.to_string()); + } + } + + // skip over code sections + Payload::CodeSectionStart { size, .. } => { + parser.skip_section(); + bytes = &bytes[size as usize..]; + } + + Payload::End(_) => break, + _ => {} + } + } + + Ok(analysis.cell()) +} diff --git a/turbopack/crates/turbopack-wasm/src/lib.rs b/turbopack/crates/turbopack-wasm/src/lib.rs new file mode 100644 index 0000000000000..e55c70764c871 --- /dev/null +++ b/turbopack/crates/turbopack-wasm/src/lib.rs @@ -0,0 +1,24 @@ +//! WebAssembly support for turbopack. +//! +//! WASM assets are copied directly to the output folder. +//! +//! When imported from ES modules, they produce a thin module that loads and +//! instantiates the WebAssembly module. + +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +pub(crate) mod analysis; +pub(crate) mod loader; +pub mod module_asset; +pub(crate) mod output_asset; +pub mod raw; +pub mod source; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-wasm/src/loader.rs b/turbopack/crates/turbopack-wasm/src/loader.rs new file mode 100644 index 0000000000000..1a16107aaf960 --- /dev/null +++ b/turbopack/crates/turbopack-wasm/src/loader.rs @@ -0,0 +1,83 @@ +use std::fmt::Write; + +use anyhow::Result; +use indoc::{formatdoc, writedoc}; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::File; +use turbopack_core::{asset::AssetContent, source::Source, virtual_source::VirtualSource}; +use turbopack_ecmascript::utils::StringifyJs; + +use crate::{analysis::analyze, source::WebAssemblySource}; + +/// Create a javascript loader to instantiate the WebAssembly module with the +/// necessary imports and exports to be processed by [turbopack_ecmascript]. +#[turbo_tasks::function] +pub(crate) async fn instantiating_loader_source( + source: Vc, +) -> Result>> { + let analysis = analyze(source).await?; + + let mut code = String::new(); + + let mut imports_obj = "{".to_string(); + for (path, items) in &analysis.imports { + writeln!( + code, + "import {{ {} }} from {};", + items.join(", "), + StringifyJs(path) + )?; + + writeln!(imports_obj, "\n {}: {{", StringifyJs(path))?; + for item in items { + writeln!(imports_obj, " {}: {},", StringifyJs(item), item)?; + } + writeln!(imports_obj, " }},")?; + } + writeln!(imports_obj, "}}")?; + + writeln!(code, "import wasmPath from \"WASM_PATH\";")?; + + writeln!(code)?; + + writedoc!( + code, + r#" + const {{ {exports} }} = await __turbopack_wasm__(wasmPath, {imports}); + + export {{ {exports} }}; + "#, + imports = imports_obj, + exports = analysis.exports.join(", "), + )?; + + let code: RcStr = code.into(); + + Ok(Vc::upcast(VirtualSource::new( + source.ident().path().append("_.loader.mjs".into()), + AssetContent::file(File::from(code).into()), + ))) +} + +/// Create a javascript loader to compile the WebAssembly module and export it +/// without instantiating. +#[turbo_tasks::function] +pub(crate) async fn compiling_loader_source( + source: Vc, +) -> Result>> { + let code: RcStr = formatdoc! { + r#" + import wasmPath from "WASM_PATH"; + + const mod = await __turbopack_wasm_module__(wasmPath); + + export default mod; + "# + } + .into(); + + Ok(Vc::upcast(VirtualSource::new( + source.ident().path().append("_.loader.mjs".into()), + AssetContent::file(File::from(code).into()), + ))) +} diff --git a/turbopack/crates/turbopack-wasm/src/module_asset.rs b/turbopack/crates/turbopack-wasm/src/module_asset.rs new file mode 100644 index 0000000000000..da3381b6923e4 --- /dev/null +++ b/turbopack/crates/turbopack-wasm/src/module_asset.rs @@ -0,0 +1,264 @@ +use anyhow::{bail, Context, Result}; +use indexmap::indexmap; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{AsyncModuleInfo, ChunkItem, ChunkType, ChunkableModule, ChunkingContext}, + context::AssetContext, + ident::AssetIdent, + module::{Module, OptionModule}, + reference::ModuleReferences, + reference_type::ReferenceType, + resolve::{origin::ResolveOrigin, parse::Request}, + source::Source, +}; +use turbopack_ecmascript::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkItemOptions, + EcmascriptChunkPlaceable, EcmascriptChunkType, EcmascriptExports, + }, + references::async_module::OptionAsyncModule, +}; + +use crate::{ + loader::{compiling_loader_source, instantiating_loader_source}, + output_asset::WebAssemblyAsset, + raw::RawWebAssemblyModuleAsset, + source::WebAssemblySource, +}; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("wasm module".into()) +} + +/// Creates a javascript loader which instantiates the WebAssembly source and +/// re-exports its exports. +#[turbo_tasks::value] +#[derive(Clone)] +pub struct WebAssemblyModuleAsset { + source: Vc, + asset_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl WebAssemblyModuleAsset { + #[turbo_tasks::function] + pub fn new( + source: Vc, + asset_context: Vc>, + ) -> Vc { + Self::cell(WebAssemblyModuleAsset { + source, + asset_context, + }) + } + + #[turbo_tasks::function] + fn wasm_asset(&self, chunking_context: Vc>) -> Vc { + WebAssemblyAsset::new(self.source, chunking_context) + } + + #[turbo_tasks::function] + async fn loader_as_module(self: Vc) -> Result>> { + let this = self.await?; + let query = &*this.source.ident().query().await?; + + let loader_source = if query == "?module" { + compiling_loader_source(this.source) + } else { + instantiating_loader_source(this.source) + }; + + let module = this.asset_context.process( + loader_source, + Value::new(ReferenceType::Internal(Vc::cell(indexmap! { + "WASM_PATH".into() => Vc::upcast(RawWebAssemblyModuleAsset::new(this.source, this.asset_context)), + }))), + ).module(); + + Ok(module) + } + #[turbo_tasks::function] + async fn loader_as_resolve_origin(self: Vc) -> Result>> { + let module = self.loader_as_module(); + + let Some(esm_asset) = Vc::try_resolve_sidecast::>(module).await? + else { + bail!("WASM loader was not processed into an EcmascriptModuleAsset"); + }; + + Ok(esm_asset) + } + + #[turbo_tasks::function] + async fn loader(self: Vc) -> Result>> { + let module = self.loader_as_module(); + + let Some(esm_asset) = + Vc::try_resolve_sidecast::>(module).await? + else { + bail!("WASM loader was not processed into an EcmascriptModuleAsset"); + }; + + Ok(esm_asset) + } +} + +#[turbo_tasks::value_impl] +impl Module for WebAssemblyModuleAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source + .ident() + .with_modifier(modifier()) + .with_layer(self.asset_context.layer()) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Vc { + self.loader().references() + } +} + +#[turbo_tasks::value_impl] +impl Asset for WebAssemblyModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for WebAssemblyModuleAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + ModuleChunkItem { + module: self, + chunking_context, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for WebAssemblyModuleAsset { + #[turbo_tasks::function] + fn get_exports(self: Vc) -> Vc { + self.loader().get_exports() + } + + #[turbo_tasks::function] + fn get_async_module(self: Vc) -> Vc { + self.loader().get_async_module() + } +} + +#[turbo_tasks::value_impl] +impl ResolveOrigin for WebAssemblyModuleAsset { + #[turbo_tasks::function] + fn origin_path(&self) -> Vc { + self.source.ident().path() + } + + #[turbo_tasks::function] + fn asset_context(&self) -> Vc> { + self.asset_context + } + + #[turbo_tasks::function] + fn get_inner_asset(self: Vc, request: Vc) -> Vc { + self.loader_as_resolve_origin().get_inner_asset(request) + } +} + +#[turbo_tasks::value] +struct ModuleChunkItem { + module: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for ModuleChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let loader = self + .module + .loader() + .as_chunk_item(Vc::upcast(self.chunking_context)); + + Ok(loader.references()) + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } + + #[turbo_tasks::function] + fn is_self_async(self: Vc) -> Vc { + Vc::cell(true) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for ModuleChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + panic!("content() should not be called"); + } + + #[turbo_tasks::function] + async fn content_with_async_module_info( + &self, + async_module_info: Option>, + ) -> Result> { + let loader_asset = self.module.loader(); + let item = loader_asset.as_chunk_item(Vc::upcast(self.chunking_context)); + + let ecmascript_item = Vc::try_resolve_downcast::>(item) + .await? + .context("EcmascriptModuleAsset must implement EcmascriptChunkItem")?; + + let chunk_item_content = ecmascript_item + .content_with_async_module_info(async_module_info) + .await?; + + Ok(EcmascriptChunkItemContent { + options: EcmascriptChunkItemOptions { + wasm: true, + ..chunk_item_content.options.clone() + }, + ..chunk_item_content.clone_value() + } + .into()) + } +} diff --git a/turbopack/crates/turbopack-wasm/src/output_asset.rs b/turbopack/crates/turbopack-wasm/src/output_asset.rs new file mode 100644 index 0000000000000..d09ded683e061 --- /dev/null +++ b/turbopack/crates/turbopack-wasm/src/output_asset.rs @@ -0,0 +1,58 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::ChunkingContext, + ident::AssetIdent, + output::OutputAsset, + source::Source, +}; + +use crate::source::WebAssemblySource; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("wasm".into()) +} + +/// Emits the [WebAssemblySource] at a chunk path determined by the +/// [ChunkingContext]. +#[turbo_tasks::value] +pub(crate) struct WebAssemblyAsset { + source: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl WebAssemblyAsset { + #[turbo_tasks::function] + pub(crate) fn new( + source: Vc, + chunking_context: Vc>, + ) -> Vc { + Self::cell(WebAssemblyAsset { + source, + chunking_context, + }) + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for WebAssemblyAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let ident = self.source.ident().with_modifier(modifier()); + + let asset_path = self.chunking_context.chunk_path(ident, ".wasm".into()); + + Ok(AssetIdent::from_path(asset_path)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for WebAssemblyAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} diff --git a/turbopack/crates/turbopack-wasm/src/raw.rs b/turbopack/crates/turbopack-wasm/src/raw.rs new file mode 100644 index 0000000000000..44301c0abca22 --- /dev/null +++ b/turbopack/crates/turbopack-wasm/src/raw.rs @@ -0,0 +1,166 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext}, + context::AssetContext, + ident::AssetIdent, + module::Module, + output::OutputAsset, + reference::{ModuleReferences, SingleOutputAssetReference}, + source::Source, +}; +use turbopack_ecmascript::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkType, EcmascriptExports, + }, + utils::StringifyJs, +}; + +use crate::{output_asset::WebAssemblyAsset, source::WebAssemblySource}; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("wasm raw".into()) +} + +/// Exports the relative path to the WebAssembly file without loading it. +#[turbo_tasks::value] +#[derive(Clone)] +pub struct RawWebAssemblyModuleAsset { + source: Vc, + asset_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl RawWebAssemblyModuleAsset { + #[turbo_tasks::function] + pub fn new( + source: Vc, + asset_context: Vc>, + ) -> Vc { + Self::cell(RawWebAssemblyModuleAsset { + source, + asset_context, + }) + } + + #[turbo_tasks::function] + fn wasm_asset(&self, chunking_context: Vc>) -> Vc { + WebAssemblyAsset::new(self.source, chunking_context) + } +} + +#[turbo_tasks::value_impl] +impl Module for RawWebAssemblyModuleAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source + .ident() + .with_modifier(modifier()) + .with_layer(self.asset_context.layer()) + } +} + +#[turbo_tasks::value_impl] +impl Asset for RawWebAssemblyModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for RawWebAssemblyModuleAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + RawModuleChunkItem { + module: self, + chunking_context, + wasm_asset: self.wasm_asset(Vc::upcast(chunking_context)), + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for RawWebAssemblyModuleAsset { + #[turbo_tasks::function] + fn get_exports(self: Vc) -> Vc { + EcmascriptExports::Value.cell() + } +} + +#[turbo_tasks::value] +struct RawModuleChunkItem { + module: Vc, + chunking_context: Vc>, + wasm_asset: Vc, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for RawModuleChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + Ok(Vc::cell(vec![Vc::upcast(SingleOutputAssetReference::new( + Vc::upcast(self.wasm_asset), + Vc::cell(format!("wasm(url) {}", self.wasm_asset.ident().to_string().await?).into()), + ))])) + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for RawModuleChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let path = self.wasm_asset.ident().path().await?; + let output_root = self.chunking_context.output_root().await?; + + let Some(path) = output_root.get_path_to(&path) else { + bail!("WASM asset ident is not relative to output root"); + }; + + Ok(EcmascriptChunkItemContent { + inner_code: format!( + "__turbopack_export_value__({path});", + path = StringifyJs(path) + ) + .into(), + ..Default::default() + } + .into()) + } +} diff --git a/turbopack/crates/turbopack-wasm/src/source.rs b/turbopack/crates/turbopack-wasm/src/source.rs new file mode 100644 index 0000000000000..4502617819608 --- /dev/null +++ b/turbopack/crates/turbopack-wasm/src/source.rs @@ -0,0 +1,83 @@ +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, TaskInput, Vc}; +use turbo_tasks_fs::{File, FileContent}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + ident::AssetIdent, + source::Source, +}; + +#[derive( + PartialOrd, + Ord, + Eq, + PartialEq, + Hash, + Debug, + Copy, + Clone, + Serialize, + Deserialize, + TaskInput, + TraceRawVcs, +)] +pub enum WebAssemblySourceType { + /// Binary WebAssembly files (.wasm). + Binary, + /// WebAssembly text format (.wat). + Text, +} + +/// Returns the raw binary WebAssembly source or the assembled version of a text +/// format source. +#[turbo_tasks::value] +#[derive(Clone)] +pub struct WebAssemblySource { + source: Vc>, + source_ty: WebAssemblySourceType, +} + +#[turbo_tasks::value_impl] +impl WebAssemblySource { + #[turbo_tasks::function] + pub fn new(source: Vc>, source_ty: WebAssemblySourceType) -> Vc { + Self::cell(WebAssemblySource { source, source_ty }) + } +} + +#[turbo_tasks::value_impl] +impl Source for WebAssemblySource { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + match self.source_ty { + WebAssemblySourceType::Binary => self.source.ident(), + WebAssemblySourceType::Text => self + .source + .ident() + .with_path(self.source.ident().path().append("_.wasm".into())), + } + } +} + +#[turbo_tasks::value_impl] +impl Asset for WebAssemblySource { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let content = match self.source_ty { + WebAssemblySourceType::Binary => return Ok(self.source.content()), + WebAssemblySourceType::Text => self.source.content(), + }; + + let content = content.file_content().await?; + + let FileContent::Content(file) = &*content else { + return Ok(AssetContent::file(FileContent::NotFound.cell())); + }; + + let bytes = file.content().to_bytes()?; + let parsed = wat::parse_bytes(&bytes)?; + + Ok(AssetContent::file(File::from(&*parsed).into())) + } +} diff --git a/turbopack/crates/turbopack/.gitignore b/turbopack/crates/turbopack/.gitignore new file mode 100644 index 0000000000000..518a4fb2a2c1e --- /dev/null +++ b/turbopack/crates/turbopack/.gitignore @@ -0,0 +1,2 @@ +bench.json +.pnpm diff --git a/turbopack/crates/turbopack/Cargo.toml b/turbopack/crates/turbopack/Cargo.toml new file mode 100644 index 0000000000000..ff161cc2c61c2 --- /dev/null +++ b/turbopack/crates/turbopack/Cargo.toml @@ -0,0 +1,59 @@ +[package] +name = "turbopack" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[features] +test_persistent_cache = [] +bench_against_node_nft = [] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +async-recursion = { workspace = true } +indexmap = { workspace = true, features = ["serde"] } +lazy_static = { workspace = true } +regex = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +tokio = { workspace = true } +tracing = { workspace = true } + +turbo-tasks = { workspace = true } +turbo-tasks-env = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } +turbopack-css = { workspace = true } +turbopack-ecmascript = { workspace = true } +turbopack-env = { workspace = true } +turbopack-json = { workspace = true } +turbopack-mdx = { workspace = true } +turbopack-node = { workspace = true } +turbopack-resolve = { workspace = true } +turbopack-static = { workspace = true } +turbopack-wasm = { workspace = true } + +[dev-dependencies] +criterion = { workspace = true, features = ["async_tokio"] } +difference = "2.0" +futures = { workspace = true } +rstest = { workspace = true } +rstest_reuse = "0.5.0" +tokio = { workspace = true } +turbo-tasks-malloc = { workspace = true, default-features = false } +turbo-tasks-memory = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } + +[[bench]] +name = "mod" +harness = false diff --git a/turbopack/crates/turbopack/README.md b/turbopack/crates/turbopack/README.md new file mode 100644 index 0000000000000..c4155b2315d32 --- /dev/null +++ b/turbopack/crates/turbopack/README.md @@ -0,0 +1,55 @@ +

    + + + + + +

    Turbopack

    + +

    + +

    + + + + + + + + + + + + +

    + +## Getting Started + +Visit https://turbo.build/pack/docs to get started with Turbopack. + +## Documentation + +Visit https://turbo.build/pack to view the full documentation. + +## Community + +The Turborepo community can be found on [GitHub Discussions](https://github.com/vercel/turbo/discussions), where you can ask questions, voice ideas, and share your projects. + +To chat with other community members, you can join the [Turborepo Discord](https://turbo.build/discord). + +Our [Code of Conduct](https://github.com/vercel/turbo/blob/main/CODE_OF_CONDUCT.md) applies to all Turborepo community channels. + +## Updates + +Follow [@turborepo](https://x.com/turborepo) on X and for project updates + +## Authors + +- Tobias Koppers ([@wSokra](https://x.com/wSokra)) +- Maia Teegarden ([@padmaia](https://x.com/padmaia)) + +## Security + +If you believe you have found a security vulnerability in Turbo, we encourage you to responsibly disclose this and not open a public issue. We will investigate all legitimate reports. Email `security@vercel.com` to disclose any security vulnerabilities. + +https://vercel.com/security diff --git a/turbopack/crates/turbopack/architecture.md b/turbopack/crates/turbopack/architecture.md new file mode 100644 index 0000000000000..f61d13c7d912d --- /dev/null +++ b/turbopack/crates/turbopack/architecture.md @@ -0,0 +1,147 @@ +# Architecture + +## `turbopack` + +Currently `turbopack` splits into `turbopack-core`, `turbopack-css` +, `turbopack-ecmascript` and `turbopack` (facade). + +The `turbopack-*` crates (except for `turbopack-core`) add support for a certain +type of asset. + +Each of them export a `ModuleAsset`, an implementation of `Asset`, which is able +to extract references from this kind of asset (and in the future generate an +optimized (either for dev or prod) version of it). + +We are currently missing: + +- `turbopack-node` (node native modules) +- `turbopack-wasm` (WASM in node and on the web) +- `turbopack-image` (images on the web) +- probably more? (e.g. `turbopack-svg`). + +## `turbo-tasks` + +### `#[turbo_tasks::value]` + +`#[turbo_tasks::value]` is a macro to generate a `XxxVc` +wrapper type for some data (e.g. a struct `Xxx`). + +- `XxxVc` is like a Promise to some data stored somewhere +- You can read the data via `.await?` + (e.g. `let x: XxxVc; let data: Xxx = x.await?`); + +`turbo-tasks` values can also implement traits, +see `#[turbo_tasks::value_trait]` for examples. + +### `#[turbo_tasks::function]` + +`#[turbo_tasks::function]` infuses a function with `turbo-tasks` magic. + +This means: + +- the function is cached (calling it twice returns the same `XxxVc`). +- dependencies are tracked (reading a `XxxVc` via `.await?` is tracked). +- `turbo-tasks` will take care of re-executing the function when any dependency + has changed. + +From the outside `#[turbo_tasks::function]`s will always return an `XxxVc` (not +a `Result` or `Future`). + +From the inside you can write an `async fn() -> Result` and turbo-tasks +will hide that async and error in the `XxxVc`. + +`turbo-tasks` functions are mostly pure. Data is immutable once stored. + +### Tasks + +A combination of a function and its arguments is called a Task (basically an +invocation of a function). + +It's also possible to store data in a Task via `XxxVc::cell(value: Xxx)`. +This returns an `XxxVc`. + +When `#[turbo_tasks::value(shared)]` is +used, `let data: Xxx; let x: XxxVc = x.into();` does the same. + +### Registry + +Here is the global registry: [registry][] +For each `#[turbo_tasks::value]` we create a `ValueType`. + +When serialization is enabled we +use [`ValueType::new_with_any_serialization`][new_with_any_serialization]. +This stores Serialization and Deserialization implementations in the +ValueType. + +There is some rust generic magic happening +e.g. [`fn any_as_serialize(...)`][any_as_serialize] which casts an `Any` to a +`Serialize` for a concrete type. +In the background rust instantiates the `Serialize` logic for it based on serde. + +Deserialize is mostly the same idea, but a bit more involved in serde. It +looks like this: [AnyDeserializeSeed][] + +### Why `XxxVc` instead of `Vc` and what are all the build scripts for? + +Both of these are relevant for persistent caching and serialization of values. +We need to deserialize values without knowing the type of the value at +compile-time. + +We want to deserialize something like `Box`. +For that we need to have a map from some kind of type identifier to a concrete +deserialization implementation, that's what the register methods do. +They instantiate a concrete implementation/type and register that in a global +map. + +A similar problem exists with these `#[turbo_tasks::function]`. We need a global +map from identifier to the method. + +Usually you would use something like [ctor](https://crates.io/crates/ctor) for +that, to hide all these manual register calls, but that won't work in WebAssembly +or when dynamically loading libraries or plugins. + +That's why we went the more manual approach with register methods that work +without special linker logic. + +Most of that is automated via this build script. +It's worth looking into the generated file: + +> `TODO` will be a hash of the crate + deps in the future. + +```rust +// target/debug/build/turbo-tasks-{hash}/out/register.rs + +{ +crate::nothing::NOTHINGVC_IMPL_NEW_FUNCTION.register(r##"turbo-tasks@TODO::::nothing::NothingVc::new"##); +crate::display::VALUETOSTRING_TRAIT_TYPE.register(r##"turbo-tasks@TODO::::display::ValueToString"##); +crate::primitives::STRING_VALUE_TYPE.register(r##"turbo-tasks@TODO::::primitives::String"##); +crate::primitives::BOOL_VALUE_TYPE.register(r##"turbo-tasks@TODO::::primitives::Bool"##); +crate::nothing::NOTHING_VALUE_TYPE.register(r##"turbo-tasks@TODO::::nothing::Nothing"##); +crate::native_function::NATIVEFUNCTION_VALUE_TYPE.register(r##"turbo-tasks@TODO::::native_function::NativeFunction"##); +crate::completion::COMPLETION_VALUE_TYPE.register(r##"turbo-tasks@TODO::::completion::Completion"##); +} +``` + +This code is generated by the build script by looking for +all [`#[turbo_tasks::function]`](#turbo_tasksfunction) +and [`#[turbo_tasks::value]`](#turbo_tasksvalue) in the source code. + +The string is the global identifier: + +``` +{crate_name}@{hash}::{mod_path}::{name} + ^ ^ -------- ---- + | | | | + | | | the name of the item + | | the full path of the module the item is in + | hash of crate + deps + the name of the cargo crate the item is in +``` + +The hash will allow invalidating the cache, but also being able to differentiate +between versions when accessing a remote cache. + +[registry]: https://github.com/vercel/turbo/blob/678639772cadac8e96b5ccde3c2865678d1263c1/crates/turbo-tasks/src/registry.rs +[new_with_any_serialization]: https://github.com/vercel/turbo/blob/678639772cadac8e96b5ccde3c2865678d1263c1/crates/turbo-tasks/src/value_type.rs#L138 +[any_as_serialize]: https://github.com/vercel/turbo/blob/678639772cadac8e96b5ccde3c2865678d1263c1/crates/turbo-tasks/src/value_type.rs#L89-L99 +[anydeserializeseed]: https://github.com/vercel/turbo/blob/678639772cadac8e96b5ccde3c2865678d1263c1/crates/turbo-tasks/src/magic_any.rs#L174-L207 diff --git a/turbopack/crates/turbopack/benches/mod.rs b/turbopack/crates/turbopack/benches/mod.rs new file mode 100644 index 0000000000000..b1d1f6d977a1f --- /dev/null +++ b/turbopack/crates/turbopack/benches/mod.rs @@ -0,0 +1,6 @@ +use criterion::{criterion_group, criterion_main}; + +mod node_file_trace; + +criterion_group!(node_file_trace_benches, node_file_trace::benchmark); +criterion_main!(node_file_trace_benches); diff --git a/turbopack/crates/turbopack/benches/node_file_trace.rs b/turbopack/crates/turbopack/benches/node_file_trace.rs new file mode 100644 index 0000000000000..18920f74cd981 --- /dev/null +++ b/turbopack/crates/turbopack/benches/node_file_trace.rs @@ -0,0 +1,114 @@ +use std::{collections::HashMap, fs, path::PathBuf}; + +use criterion::{Bencher, BenchmarkId, Criterion}; +use regex::Regex; +use turbo_tasks::{RcStr, TurboTasks, Value, Vc}; +use turbo_tasks_fs::{DiskFileSystem, FileSystem, NullFileSystem}; +use turbo_tasks_memory::MemoryBackend; +use turbopack::{ + emit_with_completion, module_options::ModuleOptionsContext, rebase::RebasedAsset, register, + ModuleAssetContext, +}; +use turbopack_core::{ + compile_time_info::CompileTimeInfo, + context::AssetContext, + environment::{Environment, ExecutionEnvironment, NodeJsEnvironment}, + file_source::FileSource, + reference_type::ReferenceType, +}; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; + +// TODO this should move to the `node-file-trace` crate +pub fn benchmark(c: &mut Criterion) { + register(); + + let bench_filter = Regex::new(r"(empty|simple|dynamic-in-package|react|whatwg-url|axios|azure-cosmos|cowsay|env-var|fast-glob)\.js$").unwrap(); + + let tests_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("tests"); + let tests_dir = tests_root.join("node-file-trace/integration"); + + let mut group = c.benchmark_group("node-file-trace"); + group.sample_size(10); + + let results = fs::read_dir(tests_dir).unwrap(); + for result in results { + let entry = result.unwrap(); + if entry.file_type().unwrap().is_file() { + let name = entry.file_name().into_string().unwrap(); + if !bench_filter.is_match(&name) { + continue; + } + + let input = format!("node-file-trace/integration/{name}"); + let tests_root = tests_root.to_string_lossy().to_string(); + + let bench_input = BenchInput { tests_root, input }; + + group.bench_with_input( + BenchmarkId::new("emit", &bench_input.input), + &bench_input, + bench_emit, + ); + } + } + + group.finish(); +} + +struct BenchInput { + tests_root: String, + input: String, +} + +fn bench_emit(b: &mut Bencher, bench_input: &BenchInput) { + let rt = tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap(); + + b.to_async(rt).iter(move || { + let tt = TurboTasks::new(MemoryBackend::default()); + let tests_root: RcStr = bench_input.tests_root.clone().into(); + let input: RcStr = bench_input.input.clone().into(); + async move { + let task = tt.spawn_once_task(async move { + let input_fs = DiskFileSystem::new("tests".into(), tests_root.clone(), vec![]); + let input = input_fs.root().join(input.clone()); + + let input_dir = input.parent().parent(); + let output_fs: Vc = NullFileSystem.into(); + let output_dir = output_fs.root(); + + let source = FileSource::new(input); + let compile_time_info = CompileTimeInfo::builder(Environment::new(Value::new( + ExecutionEnvironment::NodeJsLambda(NodeJsEnvironment::default().into()), + ))) + .cell(); + let module_asset_context = ModuleAssetContext::new( + Vc::cell(HashMap::new()), + compile_time_info, + ModuleOptionsContext { + enable_types: true, + ..Default::default() + } + .cell(), + ResolveOptionsContext { + emulate_environment: Some(compile_time_info.environment().resolve().await?), + ..Default::default() + } + .cell(), + Vc::cell("node_file_trace".into()), + ); + let module = module_asset_context + .process(Vc::upcast(source), Value::new(ReferenceType::Undefined)) + .module(); + let rebased = RebasedAsset::new(Vc::upcast(module), input_dir, output_dir); + + emit_with_completion(Vc::upcast(rebased), output_dir).await?; + + Ok::, _>(Default::default()) + }); + tt.wait_task_completion(task, true).await.unwrap(); + } + }) +} diff --git a/turbopack/crates/turbopack/build.rs b/turbopack/crates/turbopack/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack/examples/turbopack.rs b/turbopack/crates/turbopack/examples/turbopack.rs new file mode 100644 index 0000000000000..80d5d1799f2dc --- /dev/null +++ b/turbopack/crates/turbopack/examples/turbopack.rs @@ -0,0 +1,94 @@ +#![feature(trivial_bounds)] + +use std::{ + collections::HashMap, + env::current_dir, + time::{Duration, Instant}, +}; + +use anyhow::Result; +use tokio::{spawn, time::sleep}; +use turbo_tasks::{util::FormatDuration, RcStr, TurboTasks, UpdateInfo, Value, Vc}; +use turbo_tasks_fs::{DiskFileSystem, FileSystem}; +use turbo_tasks_memory::MemoryBackend; +use turbopack::{emit_with_completion, rebase::RebasedAsset, register}; +use turbopack_core::{ + compile_time_info::CompileTimeInfo, + context::AssetContext, + environment::{Environment, ExecutionEnvironment, NodeJsEnvironment}, + file_source::FileSource, + PROJECT_FILESYSTEM_NAME, +}; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; + +#[tokio::main] +async fn main() -> Result<()> { + register(); + + let tt = TurboTasks::new(MemoryBackend::default()); + let start = Instant::now(); + + let task = tt.spawn_root_task(|| { + Box::pin(async { + let root: RcStr = current_dir().unwrap().to_str().unwrap().into(); + let disk_fs = DiskFileSystem::new(PROJECT_FILESYSTEM_NAME.into(), root, vec![]); + disk_fs.await?.start_watching()?; + + // Smart Pointer cast + let fs: Vc> = Vc::upcast(disk_fs); + let input = fs.root().join("demo".into()); + let output = fs.root().join("out".into()); + let entry = fs.root().join("demo/index.js".into()); + + let source = FileSource::new(entry); + let module_asset_context = turbopack::ModuleAssetContext::new( + Vc::cell(HashMap::new()), + CompileTimeInfo::new(Environment::new(Value::new( + ExecutionEnvironment::NodeJsLambda(NodeJsEnvironment::default().into()), + ))), + Default::default(), + ResolveOptionsContext { + enable_typescript: true, + enable_react: true, + enable_node_modules: Some(fs.root()), + custom_conditions: vec!["development".into()], + ..Default::default() + } + .cell(), + Vc::cell("default".into()), + ); + let module = module_asset_context + .process( + Vc::upcast(source), + Value::new(turbopack_core::reference_type::ReferenceType::Undefined), + ) + .module(); + let rebased = RebasedAsset::new(module, input, output); + emit_with_completion(Vc::upcast(rebased), output).await?; + + Ok::, _>(Default::default()) + }) + }); + spawn({ + let tt = tt.clone(); + async move { + tt.wait_task_completion(task, true).await.unwrap(); + println!("done in {}", FormatDuration(start.elapsed())); + + loop { + let UpdateInfo { + duration, tasks, .. + } = tt + .get_or_wait_aggregated_update_info(Duration::from_millis(100)) + .await; + println!("updated {} tasks in {}", tasks, FormatDuration(duration)); + } + } + }) + .await + .unwrap(); + + loop { + sleep(Duration::from_secs(10)).await; + } +} diff --git a/turbopack/crates/turbopack/src/evaluate_context.rs b/turbopack/crates/turbopack/src/evaluate_context.rs new file mode 100644 index 0000000000000..7a392575a2475 --- /dev/null +++ b/turbopack/crates/turbopack/src/evaluate_context.rs @@ -0,0 +1,98 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::FileSystem; +use turbopack_core::{ + compile_time_defines, + compile_time_info::CompileTimeInfo, + condition::ContextCondition, + context::AssetContext, + environment::{Environment, ExecutionEnvironment, NodeJsEnvironment}, + resolve::options::{ImportMap, ImportMapping}, +}; +use turbopack_ecmascript::TreeShakingMode; +use turbopack_node::execution_context::ExecutionContext; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; + +use crate::{ + module_options::ModuleOptionsContext, transition::TransitionsByName, ModuleAssetContext, +}; + +#[turbo_tasks::function] +pub fn node_build_environment() -> Vc { + Environment::new(Value::new(ExecutionEnvironment::NodeJsBuildTime( + NodeJsEnvironment::default().cell(), + ))) +} + +#[turbo_tasks::function] +pub async fn node_evaluate_asset_context( + execution_context: Vc, + import_map: Option>, + transitions: Option>, + layer: RcStr, +) -> Result>> { + let mut import_map = if let Some(import_map) = import_map { + import_map.await?.clone_value() + } else { + ImportMap::empty() + }; + import_map.insert_wildcard_alias( + "@vercel/turbopack-node/", + ImportMapping::PrimaryAlternative( + "./*".into(), + Some(turbopack_node::embed_js::embed_fs().root()), + ) + .cell(), + ); + let import_map = import_map.cell(); + let node_env: RcStr = + if let Some(node_env) = &*execution_context.env().read("NODE_ENV".into()).await? { + node_env.as_str().into() + } else { + "development".into() + }; + + // base context used for node_modules (and context for app code will be derived + // from this) + let resolve_options_context = ResolveOptionsContext { + enable_node_modules: Some(execution_context.project_path().root().resolve().await?), + enable_node_externals: true, + enable_node_native_modules: true, + custom_conditions: vec![node_env.clone(), "node".into()], + ..Default::default() + }; + // app code context, includes a rule to switch to the node_modules context + let resolve_options_context = ResolveOptionsContext { + enable_typescript: true, + import_map: Some(import_map), + rules: vec![( + ContextCondition::InDirectory("node_modules".to_string()), + resolve_options_context.clone().cell(), + )], + ..resolve_options_context + } + .cell(); + + Ok(Vc::upcast(ModuleAssetContext::new( + transitions.unwrap_or_else(|| Vc::cell(Default::default())), + CompileTimeInfo::builder(node_build_environment()) + .defines( + compile_time_defines!( + process.turbopack = true, + process.env.NODE_ENV = node_env.into_owned(), + process.env.TURBOPACK = true + ) + .cell(), + ) + .cell(), + ModuleOptionsContext { + enable_typescript_transform: Some(Default::default()), + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), + ..Default::default() + } + .cell(), + resolve_options_context, + Vc::cell(layer), + ))) +} diff --git a/turbopack/crates/turbopack/src/graph/mod.rs b/turbopack/crates/turbopack/src/graph/mod.rs new file mode 100644 index 0000000000000..2e2d37535db0d --- /dev/null +++ b/turbopack/crates/turbopack/src/graph/mod.rs @@ -0,0 +1,199 @@ +use std::collections::HashSet; + +use anyhow::Result; +use turbo_tasks::Vc; +use turbopack_core::output::OutputAsset; + +#[turbo_tasks::value(shared)] +pub enum AggregatedGraph { + Leaf(Vc>), + Node { + depth: usize, + content: HashSet>, + references: HashSet>, + }, +} + +#[turbo_tasks::value_impl] +impl AggregatedGraph { + #[turbo_tasks::function] + fn leaf(asset: Vc>) -> Vc { + Self::cell(AggregatedGraph::Leaf(asset)) + } +} + +impl AggregatedGraph { + fn depth(&self) -> usize { + match self { + AggregatedGraph::Leaf(_) => 0, + AggregatedGraph::Node { depth, .. } => *depth, + } + } +} + +#[turbo_tasks::value_impl] +impl AggregatedGraph { + #[turbo_tasks::function] + pub async fn content(self: Vc) -> Result> { + Ok(match *self.await? { + AggregatedGraph::Leaf(asset) => AggregatedGraphNodeContent::Asset(asset).into(), + AggregatedGraph::Node { ref content, .. } => { + AggregatedGraphNodeContent::Children(content.clone()).into() + } + }) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + Ok(match *self.await? { + AggregatedGraph::Leaf(asset) => { + let mut refs = HashSet::new(); + for reference in asset.references().await?.iter() { + let reference = reference.resolve().await?; + if asset != reference { + refs.insert(AggregatedGraph::leaf(reference)); + } + } + AggregatedGraphsSet { set: refs }.into() + } + AggregatedGraph::Node { ref references, .. } => { + let mut set = HashSet::new(); + for item in references + .iter() + .map(|&reference| aggregate_more(reference)) + .collect::>() + .into_iter() + { + set.insert(item.resolve().await?); + } + AggregatedGraphsSet { set }.into() + } + }) + } + + #[turbo_tasks::function] + async fn cost(self: Vc) -> Result> { + Ok(match *self.await? { + AggregatedGraph::Leaf(asset) => AggregationCost(asset.references().await?.len()).into(), + AggregatedGraph::Node { ref references, .. } => { + AggregationCost(references.len()).into() + } + }) + } + + #[turbo_tasks::function] + async fn valued_references(self: Vc) -> Result> { + let self_cost = self.cost().await?.0; + let mut inner = HashSet::new(); + let mut outer = HashSet::new(); + let mut references = HashSet::new(); + for (reference, cost) in self + .references() + .await? + .set + .iter() + .map(|&reference| (reference, reference.cost())) + .collect::>() + { + let cost = cost.await?.0; + if cost == 0 { + inner.insert(reference); + } else if cost > self_cost { + references.insert(reference); + } else { + outer.insert(reference); + } + } + Ok(AggregatedGraphsValuedReferences { + inner, + outer, + references, + } + .into()) + } +} + +#[turbo_tasks::function] +pub async fn aggregate(asset: Vc>) -> Result> { + let mut current = AggregatedGraph::leaf(asset); + loop { + if current.references().await?.set.is_empty() { + return Ok(current); + } + current = aggregate_more(current); + } +} + +#[turbo_tasks::value(shared)] +#[derive(Clone, Hash, Debug)] +struct AggregationCost(usize); + +#[turbo_tasks::function] +async fn aggregate_more(node: Vc) -> Result> { + let node_data = node.await?; + let depth = node_data.depth(); + let mut in_progress = HashSet::new(); + let mut content = HashSet::new(); + let mut references = HashSet::new(); + in_progress.insert(node); + + // only one kind of aggregation can't eliminate cycles with that + // number of nodes. Alternating the aggregation will get rid of all + // cycles + let aggregation = if depth > 0 && depth % 2 == 0 { 3 } else { 2 }; + for _ in 0..aggregation { + for &node in in_progress.iter() { + content.insert(node); + } + let valued_refs = in_progress + .drain() + .map(|node| node.valued_references()) + .collect::>(); + for valued_refs in valued_refs { + let valued_refs = valued_refs.await?; + for &reference in valued_refs.inner.iter() { + content.insert(reference); + } + for &reference in valued_refs.references.iter() { + if content.contains(&reference) { + continue; + } + references.insert(reference); + } + for &reference in valued_refs.outer.iter() { + if content.contains(&reference) { + continue; + } + references.remove(&reference); + in_progress.insert(reference); + } + } + } + for node in in_progress.into_iter() { + references.insert(node); + } + Ok(AggregatedGraph::Node { + depth: depth + 1, + content, + references, + } + .into()) +} + +#[turbo_tasks::value(shared)] +struct AggregatedGraphsSet { + pub set: HashSet>, +} + +#[turbo_tasks::value(shared)] +pub enum AggregatedGraphNodeContent { + Asset(Vc>), + Children(HashSet>), +} + +#[turbo_tasks::value(shared)] +struct AggregatedGraphsValuedReferences { + pub inner: HashSet>, + pub outer: HashSet>, + pub references: HashSet>, +} diff --git a/turbopack/crates/turbopack/src/lib.rs b/turbopack/crates/turbopack/src/lib.rs new file mode 100644 index 0000000000000..10449ebdabc40 --- /dev/null +++ b/turbopack/crates/turbopack/src/lib.rs @@ -0,0 +1,936 @@ +#![feature(box_patterns)] +#![feature(trivial_bounds)] +#![feature(min_specialization)] +#![feature(map_try_insert)] +#![feature(option_get_or_insert_default)] +#![feature(hash_set_entry)] +#![recursion_limit = "256"] +#![feature(arbitrary_self_types)] + +pub mod evaluate_context; +mod graph; +pub mod module_options; +pub mod rebase; +pub mod transition; +pub(crate) mod unsupported_sass; + +use std::{ + collections::{HashMap, HashSet}, + mem::swap, +}; + +use anyhow::{bail, Result}; +use css::{CssModuleAsset, ModuleCssAsset}; +use ecmascript::{ + chunk::EcmascriptChunkPlaceable, + references::{follow_reexports, FollowExportsResult}, + side_effect_optimization::facade::module::EcmascriptModuleFacadeModule, + EcmascriptModuleAsset, EcmascriptModuleAssetType, TreeShakingMode, +}; +use graph::{aggregate, AggregatedGraph, AggregatedGraphNodeContent}; +use module_options::{ModuleOptions, ModuleOptionsContext, ModuleRuleEffect, ModuleType}; +use tracing::Instrument; +use turbo_tasks::{Completion, RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::{glob::Glob, FileSystemPath}; +pub use turbopack_core::condition; +use turbopack_core::{ + asset::Asset, + compile_time_info::CompileTimeInfo, + context::{AssetContext, ProcessResult}, + ident::AssetIdent, + issue::{Issue, IssueExt, IssueStage, OptionStyledString, StyledString}, + module::Module, + output::OutputAsset, + raw_module::RawModule, + reference_type::{ + CssReferenceSubType, EcmaScriptModulesReferenceSubType, ImportWithType, InnerAssets, + ReferenceType, + }, + resolve::{ + options::ResolveOptions, origin::PlainResolveOrigin, parse::Request, resolve, ExternalType, + ModulePart, ModuleResolveResult, ModuleResolveResultItem, ResolveResult, + }, + source::Source, +}; +pub use turbopack_css as css; +pub use turbopack_ecmascript as ecmascript; +use turbopack_ecmascript::references::external_module::{CachedExternalModule, CachedExternalType}; +use turbopack_json::JsonModuleAsset; +use turbopack_mdx::MdxModuleAsset; +pub use turbopack_resolve::{resolve::resolve_options, resolve_options_context}; +use turbopack_resolve::{resolve_options_context::ResolveOptionsContext, typescript::type_resolve}; +use turbopack_static::StaticModuleAsset; +use turbopack_wasm::{module_asset::WebAssemblyModuleAsset, source::WebAssemblySource}; + +use self::{ + module_options::CustomModuleType, + transition::{Transition, TransitionsByName}, +}; + +#[turbo_tasks::value] +struct ModuleIssue { + ident: Vc, + title: Vc, + description: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for ModuleIssue { + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::ProcessModule.cell() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.ident.path() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + self.title + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some(self.description)) + } +} + +#[turbo_tasks::function] +async fn apply_module_type( + source: Vc>, + module_asset_context: Vc, + module_type: Vc, + reference_type: Value, + part: Option>, + inner_assets: Option>, + runtime_code: bool, +) -> Result> { + let module_type = &*module_type.await?; + Ok(ProcessResult::Module(match module_type { + ModuleType::Ecmascript { + transforms, + options, + } + | ModuleType::Typescript { + transforms, + tsx: _, + analyze_types: _, + options, + } + | ModuleType::TypescriptDeclaration { + transforms, + options, + } => { + let context_for_module = match module_type { + ModuleType::Typescript { analyze_types, .. } if *analyze_types => { + module_asset_context.with_types_resolving_enabled() + } + ModuleType::TypescriptDeclaration { .. } => { + module_asset_context.with_types_resolving_enabled() + } + _ => module_asset_context, + }; + let mut builder = EcmascriptModuleAsset::builder( + source, + Vc::upcast(context_for_module), + *transforms, + *options, + module_asset_context.compile_time_info(), + ); + match module_type { + ModuleType::Ecmascript { .. } => { + builder = builder.with_type(EcmascriptModuleAssetType::Ecmascript) + } + ModuleType::Typescript { + tsx, analyze_types, .. + } => { + builder = builder.with_type(EcmascriptModuleAssetType::Typescript { + tsx: *tsx, + analyze_types: *analyze_types, + }) + } + ModuleType::TypescriptDeclaration { .. } => { + builder = builder.with_type(EcmascriptModuleAssetType::TypescriptDeclaration) + } + _ => unreachable!(), + } + + if let Some(inner_assets) = inner_assets { + builder = builder.with_inner_assets(inner_assets); + } + + if runtime_code { + Vc::upcast(builder.build()) + } else { + let options = options.await?; + match options.tree_shaking_mode { + Some(TreeShakingMode::ModuleFragments) => { + let side_effect_free_packages = + module_asset_context.side_effect_free_packages(); + + let module = builder.clone().build(); + + Vc::upcast( + if let Some(part) = part { + if let ModulePart::Evaluation = *part.await? { + if *module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await? + { + return Ok(ProcessResult::Ignore.cell()); + } + } + + builder.build_part(part) + } else { + builder.build_part(ModulePart::facade()) + } + .await?, + ) + } + Some(TreeShakingMode::ReexportsOnly) => { + let side_effect_free_packages = + module_asset_context.side_effect_free_packages(); + + let module = builder.build(); + if let Some(part) = part { + match *part.await? { + ModulePart::Evaluation => { + if *module + .is_marked_as_side_effect_free(side_effect_free_packages) + .await? + { + return Ok(ProcessResult::Ignore.cell()); + } + if *module.get_exports().needs_facade().await? { + Vc::upcast(EcmascriptModuleFacadeModule::new( + Vc::upcast(module), + part, + )) + } else { + Vc::upcast(module) + } + } + ModulePart::Export(_) => { + if *module.get_exports().needs_facade().await? { + apply_reexport_tree_shaking( + Vc::upcast(EcmascriptModuleFacadeModule::new( + Vc::upcast(module), + ModulePart::exports(), + )), + part, + side_effect_free_packages, + ) + } else { + apply_reexport_tree_shaking( + Vc::upcast(module), + part, + side_effect_free_packages, + ) + } + } + _ => bail!( + "Invalid module part for reexports only tree shaking mode" + ), + } + } else if *module.get_exports().needs_facade().await? { + Vc::upcast(EcmascriptModuleFacadeModule::new( + Vc::upcast(module), + ModulePart::facade(), + )) + } else { + Vc::upcast(module) + } + } + None => Vc::upcast(builder.build()), + } + } + } + ModuleType::Json => Vc::upcast(JsonModuleAsset::new(source)), + ModuleType::Raw => Vc::upcast(RawModule::new(source)), + ModuleType::CssGlobal => { + return Ok(module_asset_context.process( + source, + Value::new(ReferenceType::Css(CssReferenceSubType::Internal)), + )) + } + ModuleType::CssModule => Vc::upcast(ModuleCssAsset::new( + source, + Vc::upcast(module_asset_context), + )), + ModuleType::Css { ty, use_swc_css } => Vc::upcast(CssModuleAsset::new( + source, + Vc::upcast(module_asset_context), + *ty, + *use_swc_css, + if let ReferenceType::Css(CssReferenceSubType::AtImport(import)) = + reference_type.into_value() + { + import + } else { + None + }, + )), + ModuleType::Static => Vc::upcast(StaticModuleAsset::new( + source, + Vc::upcast(module_asset_context), + )), + ModuleType::Mdx { + transforms, + options, + ecmascript_options, + } => Vc::upcast(MdxModuleAsset::new( + source, + Vc::upcast(module_asset_context), + *transforms, + *options, + *ecmascript_options, + )), + ModuleType::WebAssembly { source_ty } => Vc::upcast(WebAssemblyModuleAsset::new( + WebAssemblySource::new(source, *source_ty), + Vc::upcast(module_asset_context), + )), + ModuleType::Custom(custom) => custom.create_module(source, module_asset_context, part), + }) + .cell()) +} + +#[turbo_tasks::function] +async fn apply_reexport_tree_shaking( + module: Vc>, + part: Vc, + side_effect_free_packages: Vc, +) -> Result>> { + if let ModulePart::Export(export) = *part.await? { + let export = export.await?; + let FollowExportsResult { + module: final_module, + export_name: new_export, + .. + } = &*follow_reexports(module, export.clone_value(), side_effect_free_packages).await?; + let module = if let Some(new_export) = new_export { + if *new_export == *export { + Vc::upcast(*final_module) + } else { + Vc::upcast(EcmascriptModuleFacadeModule::new( + *final_module, + ModulePart::renamed_export(new_export.clone(), export.clone_value()), + )) + } + } else { + Vc::upcast(EcmascriptModuleFacadeModule::new( + *final_module, + ModulePart::renamed_namespace(export.clone_value()), + )) + }; + return Ok(module); + } + Ok(Vc::upcast(module)) +} + +#[turbo_tasks::value] +#[derive(Debug)] +pub struct ModuleAssetContext { + pub transitions: Vc, + pub compile_time_info: Vc, + pub module_options_context: Vc, + pub resolve_options_context: Vc, + pub layer: Vc, + transition: Option>>, +} + +#[turbo_tasks::value_impl] +impl ModuleAssetContext { + #[turbo_tasks::function] + pub fn new( + transitions: Vc, + compile_time_info: Vc, + module_options_context: Vc, + resolve_options_context: Vc, + layer: Vc, + ) -> Vc { + Self::cell(ModuleAssetContext { + transitions, + compile_time_info, + module_options_context, + resolve_options_context, + transition: None, + layer, + }) + } + + #[turbo_tasks::function] + pub fn new_transition( + transitions: Vc, + compile_time_info: Vc, + module_options_context: Vc, + resolve_options_context: Vc, + layer: Vc, + transition: Vc>, + ) -> Vc { + Self::cell(ModuleAssetContext { + transitions, + compile_time_info, + module_options_context, + resolve_options_context, + layer, + transition: Some(transition), + }) + } + + #[turbo_tasks::function] + pub async fn module_options_context(self: Vc) -> Result> { + Ok(self.await?.module_options_context) + } + + #[turbo_tasks::function] + pub async fn resolve_options_context(self: Vc) -> Result> { + Ok(self.await?.resolve_options_context) + } + + #[turbo_tasks::function] + pub async fn is_types_resolving_enabled(self: Vc) -> Result> { + let resolve_options_context = self.await?.resolve_options_context.await?; + Ok(Vc::cell( + resolve_options_context.enable_types && resolve_options_context.enable_typescript, + )) + } + + #[turbo_tasks::function] + pub async fn with_types_resolving_enabled(self: Vc) -> Result> { + if *self.is_types_resolving_enabled().await? { + return Ok(self); + } + let this = self.await?; + let resolve_options_context = this + .resolve_options_context + .with_types_enabled() + .resolve() + .await?; + + Ok(ModuleAssetContext::new( + this.transitions, + this.compile_time_info, + this.module_options_context, + resolve_options_context, + this.layer, + )) + } + + #[turbo_tasks::function] + fn process_default( + self: Vc, + source: Vc>, + reference_type: Value, + ) -> Vc { + process_default(self, source, reference_type, Vec::new()) + } +} + +#[turbo_tasks::function] +async fn process_default( + module_asset_context: Vc, + source: Vc>, + reference_type: Value, + processed_rules: Vec, +) -> Result> { + let span = tracing::info_span!( + "process module", + name = source.ident().to_string().await?.to_string(), + reference_type = display(&*reference_type) + ); + process_default_internal( + module_asset_context, + source, + reference_type, + processed_rules, + ) + .instrument(span) + .await +} + +async fn process_default_internal( + module_asset_context: Vc, + source: Vc>, + reference_type: Value, + processed_rules: Vec, +) -> Result> { + let ident = source.ident().resolve().await?; + let path_ref = ident.path().await?; + let options = ModuleOptions::new( + ident.path().parent(), + module_asset_context.module_options_context(), + module_asset_context.resolve_options_context(), + ); + + let reference_type = reference_type.into_value(); + let part: Option> = match &reference_type { + ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::ImportPart(part)) => { + Some(*part) + } + _ => None, + }; + let inner_assets = match &reference_type { + ReferenceType::Internal(inner_assets) => Some(*inner_assets), + _ => None, + }; + + let mut has_type_attribute = false; + + let mut current_source = source; + let mut current_module_type = match &reference_type { + ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::ImportWithType(ty)) => { + has_type_attribute = true; + + match ty { + ImportWithType::Json => Some(ModuleType::Json), + } + } + _ => None, + }; + + for (i, rule) in options.await?.rules.iter().enumerate() { + if has_type_attribute && current_module_type.is_some() { + continue; + } + if processed_rules.contains(&i) { + continue; + } + if rule.matches(source, &path_ref, &reference_type).await? { + for effect in rule.effects() { + match effect { + ModuleRuleEffect::SourceTransforms(transforms) => { + current_source = transforms.transform(current_source); + if current_source.ident().resolve().await? != ident { + // The ident has been changed, so we need to apply new rules. + let mut processed_rules = processed_rules.clone(); + processed_rules.push(i); + return Ok(process_default( + module_asset_context, + current_source, + Value::new(reference_type), + processed_rules, + )); + } + } + ModuleRuleEffect::ModuleType(module) => { + current_module_type = Some(*module); + } + ModuleRuleEffect::ExtendEcmascriptTransforms { prepend, append } => { + current_module_type = match current_module_type { + Some(ModuleType::Ecmascript { + transforms, + options, + }) => Some(ModuleType::Ecmascript { + transforms: prepend.extend(transforms).extend(*append), + options, + }), + Some(ModuleType::Typescript { + transforms, + tsx, + analyze_types, + options, + }) => Some(ModuleType::Typescript { + transforms: prepend.extend(transforms).extend(*append), + tsx, + analyze_types, + options, + }), + Some(ModuleType::Mdx { + transforms, + options, + ecmascript_options, + }) => Some(ModuleType::Mdx { + transforms: prepend.extend(transforms).extend(*append), + options, + ecmascript_options, + }), + Some(module_type) => { + ModuleIssue { + ident, + title: StyledString::Text("Invalid module type".into()).cell(), + description: StyledString::Text( + "The module type must be Ecmascript or Typescript to add \ + Ecmascript transforms" + .into(), + ) + .cell(), + } + .cell() + .emit(); + Some(module_type) + } + None => { + ModuleIssue { + ident, + title: StyledString::Text("Missing module type".into()).cell(), + description: StyledString::Text( + "The module type effect must be applied before adding \ + Ecmascript transforms" + .into(), + ) + .cell(), + } + .cell() + .emit(); + None + } + }; + } + } + } + } + } + + let module_type = match current_module_type { + Some(module_type) => module_type, + None => { + ModuleIssue { + ident, + title: StyledString::Text("Unknown module type".into()).cell(), + description: StyledString::Text( + r"This module doesn't have an associated type. Use a known file extension, or register a loader for it. + +Read more: https://nextjs.org/docs/app/api-reference/next-config-js/turbo#webpack-loaders".into(), + ) + .cell(), + } + .cell() + .emit(); + + return Ok(ProcessResult::Ignore.cell()); + } + }.cell(); + + Ok(apply_module_type( + current_source, + module_asset_context, + module_type, + Value::new(reference_type.clone()), + part, + inner_assets, + matches!(reference_type, ReferenceType::Runtime), + )) +} + +#[turbo_tasks::value_impl] +impl AssetContext for ModuleAssetContext { + #[turbo_tasks::function] + fn compile_time_info(&self) -> Vc { + self.compile_time_info + } + + #[turbo_tasks::function] + fn layer(&self) -> Vc { + self.layer + } + + #[turbo_tasks::function] + async fn resolve_options( + self: Vc, + origin_path: Vc, + _reference_type: Value, + ) -> Result> { + let this = self.await?; + let module_asset_context = if let Some(transition) = this.transition { + transition.process_context(self) + } else { + self + }; + // TODO move `apply_commonjs/esm_resolve_options` etc. to here + Ok(resolve_options( + origin_path.parent().resolve().await?, + module_asset_context.await?.resolve_options_context, + )) + } + + #[turbo_tasks::function] + async fn resolve_asset( + self: Vc, + origin_path: Vc, + request: Vc, + resolve_options: Vc, + reference_type: Value, + ) -> Result> { + let context_path = origin_path.parent().resolve().await?; + + let result = resolve( + context_path, + reference_type.clone(), + request, + resolve_options, + ); + let mut result = self.process_resolve_result(result.resolve().await?, reference_type); + + if *self.is_types_resolving_enabled().await? { + let types_result = type_resolve( + Vc::upcast(PlainResolveOrigin::new(Vc::upcast(self), origin_path)), + request, + ); + + result = ModuleResolveResult::alternatives(vec![result, types_result]); + } + + Ok(result) + } + + #[turbo_tasks::function] + async fn process_resolve_result( + self: Vc, + result: Vc, + reference_type: Value, + ) -> Result> { + let this = self.await?; + let transition = this.transition; + + let result = result + .await? + .map_module(|source| { + let reference_type = reference_type.clone(); + async move { + let process_result = if let Some(transition) = transition { + transition.process(source, self, reference_type) + } else { + self.process_default(source, reference_type) + }; + Ok(match *process_result.await? { + ProcessResult::Module(m) => ModuleResolveResultItem::Module(Vc::upcast(m)), + ProcessResult::Ignore => ModuleResolveResultItem::Ignore, + }) + } + }) + .await?; + + let result = + replace_externals(result, this.module_options_context.await?.import_externals).await?; + + Ok(result.cell()) + } + + #[turbo_tasks::function] + async fn process( + self: Vc, + asset: Vc>, + reference_type: Value, + ) -> Result> { + let this = self.await?; + if let Some(transition) = this.transition { + Ok(transition.process(asset, self, reference_type)) + } else { + Ok(self.process_default(asset, reference_type)) + } + } + + #[turbo_tasks::function] + async fn with_transition(&self, transition: RcStr) -> Result>> { + Ok( + if let Some(transition) = self.transitions.await?.get(&transition) { + Vc::upcast(ModuleAssetContext::new_transition( + self.transitions, + self.compile_time_info, + self.module_options_context, + self.resolve_options_context, + self.layer, + *transition, + )) + } else { + // TODO report issue + Vc::upcast(ModuleAssetContext::new( + self.transitions, + self.compile_time_info, + self.module_options_context, + self.resolve_options_context, + self.layer, + )) + }, + ) + } + + #[turbo_tasks::function] + async fn side_effect_free_packages(self: Vc) -> Result> { + let pkgs = &*self + .await? + .module_options_context + .await? + .side_effect_free_packages; + + let mut globs = Vec::with_capacity(pkgs.len()); + + for pkg in pkgs { + globs.push(Glob::new(format!("**/node_modules/{{{}}}/**", pkg).into())); + } + + Ok(Glob::alternatives(globs)) + } +} + +#[turbo_tasks::function] +pub async fn emit_with_completion( + asset: Vc>, + output_dir: Vc, +) -> Vc { + emit_assets_aggregated(asset, output_dir) +} + +#[turbo_tasks::function] +async fn emit_assets_aggregated( + asset: Vc>, + output_dir: Vc, +) -> Vc { + let aggregated = aggregate(asset); + emit_aggregated_assets(aggregated, output_dir) +} + +#[turbo_tasks::function] +async fn emit_aggregated_assets( + aggregated: Vc, + output_dir: Vc, +) -> Result> { + Ok(match &*aggregated.content().await? { + AggregatedGraphNodeContent::Asset(asset) => emit_asset_into_dir(*asset, output_dir), + AggregatedGraphNodeContent::Children(children) => { + for aggregated in children { + emit_aggregated_assets(*aggregated, output_dir).await?; + } + Completion::new() + } + }) +} + +#[turbo_tasks::function] +pub async fn emit_asset(asset: Vc>) -> Vc { + asset.content().write(asset.ident().path()) +} + +#[turbo_tasks::function] +pub async fn emit_asset_into_dir( + asset: Vc>, + output_dir: Vc, +) -> Result> { + let dir = &*output_dir.await?; + Ok(if asset.ident().path().await?.is_inside_ref(dir) { + emit_asset(asset) + } else { + Completion::new() + }) +} + +type OutputAssetSet = HashSet>>; + +#[turbo_tasks::value(shared)] +struct ReferencesList { + referenced_by: HashMap>, OutputAssetSet>, +} + +#[turbo_tasks::function] +async fn compute_back_references(aggregated: Vc) -> Result> { + Ok(match &*aggregated.content().await? { + &AggregatedGraphNodeContent::Asset(asset) => { + let mut referenced_by = HashMap::new(); + for reference in asset.references().await?.iter() { + referenced_by.insert(*reference, [asset].into_iter().collect()); + } + ReferencesList { referenced_by }.into() + } + AggregatedGraphNodeContent::Children(children) => { + let mut referenced_by = HashMap::>, OutputAssetSet>::new(); + let lists = children + .iter() + .map(|child| compute_back_references(*child)) + .collect::>(); + for list in lists { + for (key, values) in list.await?.referenced_by.iter() { + if let Some(set) = referenced_by.get_mut(key) { + for value in values { + set.insert(*value); + } + } else { + referenced_by.insert(*key, values.clone()); + } + } + } + ReferencesList { referenced_by }.into() + } + }) +} + +#[turbo_tasks::function] +async fn top_references(list: Vc) -> Result> { + let list = list.await?; + const N: usize = 5; + let mut top = Vec::<( + &Vc>, + &HashSet>>, + )>::new(); + for tuple in list.referenced_by.iter() { + let mut current = tuple; + for item in &mut top { + if item.1.len() < tuple.1.len() { + swap(item, &mut current); + } + } + if top.len() < N { + top.push(current); + } + } + Ok(ReferencesList { + referenced_by: top + .into_iter() + .map(|(asset, set)| (*asset, set.clone())) + .collect(), + } + .into()) +} + +/// Replaces the externals in the result with `ExternalModuleAsset` instances. +pub async fn replace_externals( + mut result: ModuleResolveResult, + import_externals: bool, +) -> Result { + for item in result.primary.values_mut() { + let ModuleResolveResultItem::External(request, ty) = item else { + continue; + }; + + let external_type = match ty { + ExternalType::CommonJs => CachedExternalType::CommonJs, + ExternalType::EcmaScriptModule => { + if import_externals { + CachedExternalType::EcmaScriptViaImport + } else { + CachedExternalType::EcmaScriptViaRequire + } + } + ExternalType::Url => { + // we don't want to wrap url externals. + continue; + } + }; + + let module = CachedExternalModule::new(request.clone(), external_type) + .resolve() + .await?; + + *item = ModuleResolveResultItem::Module(Vc::upcast(module)); + } + + Ok(result) +} + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_css::register(); + turbopack_ecmascript::register(); + turbopack_node::register(); + turbopack_env::register(); + turbopack_mdx::register(); + turbopack_json::register(); + turbopack_resolve::register(); + turbopack_static::register(); + turbopack_wasm::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack/src/module_options/custom_module_type.rs b/turbopack/crates/turbopack/src/module_options/custom_module_type.rs new file mode 100644 index 0000000000000..91c9cf987b484 --- /dev/null +++ b/turbopack/crates/turbopack/src/module_options/custom_module_type.rs @@ -0,0 +1,14 @@ +use turbo_tasks::Vc; +use turbopack_core::{module::Module, resolve::ModulePart, source::Source}; + +use crate::ModuleAssetContext; + +#[turbo_tasks::value_trait] +pub trait CustomModuleType { + fn create_module( + self: Vc, + source: Vc>, + module_asset_context: Vc, + part: Option>, + ) -> Vc>; +} diff --git a/turbopack/crates/turbopack/src/module_options/mod.rs b/turbopack/crates/turbopack/src/module_options/mod.rs new file mode 100644 index 0000000000000..d6c6e1ed313cb --- /dev/null +++ b/turbopack/crates/turbopack/src/module_options/mod.rs @@ -0,0 +1,605 @@ +pub(crate) mod custom_module_type; +pub mod module_options_context; +pub mod module_rule; +pub mod rule_condition; + +use anyhow::{Context, Result}; +pub use custom_module_type::CustomModuleType; +pub use module_options_context::*; +pub use module_rule::*; +pub use rule_condition::*; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::{glob::Glob, FileSystemPath}; +use turbopack_core::{ + reference_type::{CssReferenceSubType, ReferenceType, UrlReferenceSubType}, + resolve::options::{ImportMap, ImportMapping}, +}; +use turbopack_css::CssModuleAssetType; +use turbopack_ecmascript::{EcmascriptInputTransform, EcmascriptOptions, SpecifiedModuleType}; +use turbopack_node::transforms::{postcss::PostCssTransform, webpack::WebpackLoaders}; +use turbopack_wasm::source::WebAssemblySourceType; + +use crate::{ + evaluate_context::node_evaluate_asset_context, resolve_options_context::ResolveOptionsContext, +}; + +#[turbo_tasks::function] +async fn package_import_map_from_import_mapping( + package_name: RcStr, + package_mapping: Vc, +) -> Result> { + let mut import_map = ImportMap::default(); + import_map.insert_exact_alias( + format!("@vercel/turbopack/{}", package_name), + package_mapping, + ); + Ok(import_map.cell()) +} + +#[turbo_tasks::function] +async fn package_import_map_from_context( + package_name: RcStr, + context_path: Vc, +) -> Result> { + let mut import_map = ImportMap::default(); + import_map.insert_exact_alias( + format!("@vercel/turbopack/{}", package_name), + ImportMapping::PrimaryAlternative(package_name, Some(context_path)).cell(), + ); + Ok(import_map.cell()) +} + +#[turbo_tasks::value(cell = "new", eq = "manual")] +pub struct ModuleOptions { + pub rules: Vec, +} + +#[turbo_tasks::value_impl] +impl ModuleOptions { + #[turbo_tasks::function] + pub async fn new( + path: Vc, + module_options_context: Vc, + resolve_options_context: Vc, + ) -> Result> { + let ModuleOptionsContext { + enable_jsx, + enable_types, + tree_shaking_mode, + ref enable_typescript_transform, + ref decorators, + enable_mdx, + enable_mdx_rs, + enable_raw_css, + ref enable_postcss_transform, + ref enable_webpack_loaders, + preset_env_versions, + ref custom_rules, + execution_context, + ref rules, + esm_url_rewrite_behavior, + special_exports, + import_externals, + ignore_dynamic_requests, + use_swc_css, + ref enable_typeof_window_inlining, + .. + } = *module_options_context.await?; + let special_exports = special_exports.unwrap_or_default(); + + if !rules.is_empty() { + let path_value = path.await?; + + for (condition, new_context) in rules.iter() { + if condition.matches(&path_value).await? { + return Ok(ModuleOptions::new( + path, + *new_context, + resolve_options_context, + )); + } + } + } + + let mut refresh = false; + let mut transforms = vec![]; + + // Order of transforms is important. e.g. if the React transform occurs before + // Styled JSX, there won't be JSX nodes for Styled JSX to transform. + // If a custom plugin requires specific order _before_ core transform kicks in, + // should use `before_transform_plugins`. + if let Some(enable_jsx) = enable_jsx { + let jsx = enable_jsx.await?; + refresh = jsx.react_refresh; + + transforms.push(EcmascriptInputTransform::React { + development: jsx.development, + refresh: jsx.react_refresh, + import_source: Vc::cell(jsx.import_source.clone()), + runtime: Vc::cell(jsx.runtime.clone()), + }); + } + + let ecmascript_options = EcmascriptOptions { + tree_shaking_mode, + url_rewrite_behavior: esm_url_rewrite_behavior, + import_externals, + special_exports, + ignore_dynamic_requests, + refresh, + ..Default::default() + }; + let ecmascript_options_vc = ecmascript_options.cell(); + + if let Some(env) = preset_env_versions { + transforms.push(EcmascriptInputTransform::PresetEnv(env)); + } + + if let Some(enable_typeof_window_inlining) = enable_typeof_window_inlining { + transforms.push(EcmascriptInputTransform::GlobalTypeofs { + window_value: match enable_typeof_window_inlining { + TypeofWindow::Object => "object".to_string(), + TypeofWindow::Undefined => "undefined".to_string(), + }, + }); + } + + let ts_transform = if let Some(options) = enable_typescript_transform { + let options = options.await?; + Some(EcmascriptInputTransform::TypeScript { + use_define_for_class_fields: options.use_define_for_class_fields, + }) + } else { + None + }; + + let decorators_transform = if let Some(options) = &decorators { + let options = options.await?; + options + .decorators_kind + .as_ref() + .map(|kind| EcmascriptInputTransform::Decorators { + is_legacy: kind == &DecoratorsKind::Legacy, + is_ecma: kind == &DecoratorsKind::Ecma, + emit_decorators_metadata: options.emit_decorators_metadata, + use_define_for_class_fields: options.use_define_for_class_fields, + }) + } else { + None + }; + + let vendor_transforms = Vc::cell(vec![]); + let ts_app_transforms = if let Some(transform) = &ts_transform { + let base_transforms = if let Some(decorators_transform) = &decorators_transform { + vec![decorators_transform.clone(), transform.clone()] + } else { + vec![transform.clone()] + }; + Vc::cell( + base_transforms + .iter() + .cloned() + .chain(transforms.iter().cloned()) + .collect(), + ) + } else { + Vc::cell(transforms.clone()) + }; + + let mdx_transforms = Vc::cell( + if let Some(transform) = &ts_transform { + if let Some(decorators_transform) = &decorators_transform { + vec![decorators_transform.clone(), transform.clone()] + } else { + vec![transform.clone()] + } + } else { + vec![] + } + .iter() + .cloned() + .chain(transforms.iter().cloned()) + .collect(), + ); + + // Apply decorators transform for the ModuleType::Ecmascript as well after + // constructing ts_app_transforms. Ecmascript can have decorators for + // the cases of 1. using jsconfig, to enable ts-specific runtime + // decorators (i.e legacy) 2. ecma spec decorators + // + // Since typescript transform (`ts_app_transforms`) needs to apply decorators + // _before_ stripping types, we create ts_app_transforms first in a + // specific order with typescript, then apply decorators to app_transforms. + let app_transforms = Vc::cell( + if let Some(decorators_transform) = &decorators_transform { + vec![decorators_transform.clone()] + } else { + vec![] + } + .iter() + .cloned() + .chain(transforms.iter().cloned()) + .collect(), + ); + + let mut rules = vec![ + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".json".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Json)], + ), + ModuleRule::new_all( + ModuleRuleCondition::any(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".js".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".jsx".to_string()), + ]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { + transforms: app_transforms, + options: ecmascript_options_vc, + })], + ), + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".mjs".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { + transforms: app_transforms, + options: EcmascriptOptions { + specified_module_type: SpecifiedModuleType::EcmaScript, + ..ecmascript_options + } + .into(), + })], + ), + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".cjs".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { + transforms: app_transforms, + options: EcmascriptOptions { + specified_module_type: SpecifiedModuleType::CommonJs, + ..ecmascript_options + } + .into(), + })], + ), + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".ts".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Typescript { + transforms: ts_app_transforms, + tsx: false, + analyze_types: enable_types, + options: ecmascript_options_vc, + })], + ), + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".tsx".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Typescript { + transforms: ts_app_transforms, + tsx: true, + analyze_types: enable_types, + options: ecmascript_options_vc, + })], + ), + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".mts".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Typescript { + transforms: ts_app_transforms, + tsx: false, + analyze_types: enable_types, + options: EcmascriptOptions { + specified_module_type: SpecifiedModuleType::EcmaScript, + ..ecmascript_options + } + .into(), + })], + ), + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".mtsx".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Typescript { + transforms: ts_app_transforms, + tsx: true, + analyze_types: enable_types, + options: EcmascriptOptions { + specified_module_type: SpecifiedModuleType::EcmaScript, + ..ecmascript_options + } + .into(), + })], + ), + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".cts".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Typescript { + transforms: ts_app_transforms, + tsx: false, + analyze_types: enable_types, + options: EcmascriptOptions { + specified_module_type: SpecifiedModuleType::CommonJs, + ..ecmascript_options + } + .into(), + })], + ), + ModuleRule::new_all( + ModuleRuleCondition::ResourcePathEndsWith(".ctsx".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Typescript { + transforms: ts_app_transforms, + tsx: true, + analyze_types: enable_types, + options: EcmascriptOptions { + specified_module_type: SpecifiedModuleType::CommonJs, + ..ecmascript_options + } + .into(), + })], + ), + ModuleRule::new( + ModuleRuleCondition::ResourcePathEndsWith(".d.ts".to_string()), + vec![ModuleRuleEffect::ModuleType( + ModuleType::TypescriptDeclaration { + transforms: vendor_transforms, + options: ecmascript_options_vc, + }, + )], + ), + ModuleRule::new( + ModuleRuleCondition::any(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".apng".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".avif".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".gif".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".ico".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".jpg".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".jpeg".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".png".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".svg".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".webp".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".woff2".to_string()), + ]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Static)], + ), + ModuleRule::new( + ModuleRuleCondition::any(vec![ModuleRuleCondition::ResourcePathEndsWith( + ".node".to_string(), + )]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Raw)], + ), + ModuleRule::new( + ModuleRuleCondition::any(vec![ModuleRuleCondition::ResourcePathEndsWith( + ".wasm".to_string(), + )]), + vec![ModuleRuleEffect::ModuleType(ModuleType::WebAssembly { + source_ty: WebAssemblySourceType::Binary, + })], + ), + ModuleRule::new( + ModuleRuleCondition::any(vec![ModuleRuleCondition::ResourcePathEndsWith( + ".wat".to_string(), + )]), + vec![ModuleRuleEffect::ModuleType(ModuleType::WebAssembly { + source_ty: WebAssemblySourceType::Text, + })], + ), + ModuleRule::new( + ModuleRuleCondition::ResourcePathHasNoExtension, + vec![ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { + transforms: vendor_transforms, + options: ecmascript_options_vc, + })], + ), + ModuleRule::new( + ModuleRuleCondition::ReferenceType(ReferenceType::Url( + UrlReferenceSubType::Undefined, + )), + vec![ModuleRuleEffect::ModuleType(ModuleType::Static)], + ), + ]; + + if enable_raw_css { + rules.extend([ + ModuleRule::new( + ModuleRuleCondition::all(vec![ModuleRuleCondition::ResourcePathEndsWith( + ".css".to_string(), + )]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Css { + ty: CssModuleAssetType::Default, + use_swc_css, + })], + ), + ModuleRule::new( + ModuleRuleCondition::all(vec![ModuleRuleCondition::ResourcePathEndsWith( + ".module.css".to_string(), + )]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Css { + ty: CssModuleAssetType::Module, + use_swc_css, + })], + ), + ]); + } else { + if let Some(options) = enable_postcss_transform { + let options = options.await?; + let execution_context = execution_context + .context("execution_context is required for the postcss_transform")?; + + let import_map = if let Some(postcss_package) = options.postcss_package { + package_import_map_from_import_mapping("postcss".into(), postcss_package) + } else { + package_import_map_from_context("postcss".into(), path) + }; + + rules.push(ModuleRule::new( + ModuleRuleCondition::ResourcePathEndsWith(".css".to_string()), + vec![ModuleRuleEffect::SourceTransforms(Vc::cell(vec![ + Vc::upcast(PostCssTransform::new( + node_evaluate_asset_context( + execution_context, + Some(import_map), + None, + "postcss".into(), + ), + execution_context, + options.config_location, + )), + ]))], + )); + } + + rules.extend([ + ModuleRule::new( + ModuleRuleCondition::all(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".css".to_string()), + // Only create a global CSS asset if not `@import`ed from CSS already. + ModuleRuleCondition::not(ModuleRuleCondition::ReferenceType( + ReferenceType::Css(CssReferenceSubType::AtImport(None)), + )), + ]), + vec![ModuleRuleEffect::ModuleType(ModuleType::CssGlobal)], + ), + ModuleRule::new( + ModuleRuleCondition::all(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".module.css".to_string()), + // Only create a module CSS asset if not `@import`ed from CSS already. + // NOTE: `composes` references should not be treated as `@import`s and + // should also create a module CSS asset. + ModuleRuleCondition::not(ModuleRuleCondition::ReferenceType( + ReferenceType::Css(CssReferenceSubType::AtImport(None)), + )), + ]), + vec![ModuleRuleEffect::ModuleType(ModuleType::CssModule)], + ), + ModuleRule::new( + ModuleRuleCondition::all(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".css".to_string()), + // Create a normal CSS asset if `@import`ed from CSS already. + ModuleRuleCondition::ReferenceType(ReferenceType::Css( + CssReferenceSubType::AtImport(None), + )), + ]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Css { + ty: CssModuleAssetType::Default, + use_swc_css, + })], + ), + ModuleRule::new( + ModuleRuleCondition::all(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".module.css".to_string()), + // Create a normal CSS asset if `@import`ed from CSS already. + ModuleRuleCondition::ReferenceType(ReferenceType::Css( + CssReferenceSubType::AtImport(None), + )), + ]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Css { + ty: CssModuleAssetType::Module, + use_swc_css, + })], + ), + ModuleRule::new_internal( + ModuleRuleCondition::ResourcePathEndsWith(".css".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Css { + ty: CssModuleAssetType::Default, + use_swc_css, + })], + ), + ModuleRule::new_internal( + ModuleRuleCondition::ResourcePathEndsWith(".module.css".to_string()), + vec![ModuleRuleEffect::ModuleType(ModuleType::Css { + ty: CssModuleAssetType::Module, + use_swc_css, + })], + ), + ]); + } + + if enable_mdx || enable_mdx_rs.is_some() { + let (jsx_runtime, jsx_import_source, development) = if let Some(enable_jsx) = enable_jsx + { + let jsx = enable_jsx.await?; + ( + jsx.runtime.clone(), + jsx.import_source.clone(), + jsx.development, + ) + } else { + (None, None, false) + }; + + let mdx_options = &*enable_mdx_rs.unwrap_or(Default::default()).await?; + + let mdx_transform_options = (MdxTransformOptions { + development: Some(development), + jsx: Some(false), + jsx_runtime, + jsx_import_source, + ..(mdx_options.clone()) + }) + .cell(); + + rules.push(ModuleRule::new( + ModuleRuleCondition::any(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".md".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".mdx".to_string()), + ]), + vec![ModuleRuleEffect::ModuleType(ModuleType::Mdx { + transforms: mdx_transforms, + options: mdx_transform_options, + ecmascript_options: ecmascript_options_vc, + })], + )); + } + + if let Some(webpack_loaders_options) = enable_webpack_loaders { + let webpack_loaders_options = webpack_loaders_options.await?; + let execution_context = + execution_context.context("execution_context is required for webpack_loaders")?; + let import_map = if let Some(loader_runner_package) = + webpack_loaders_options.loader_runner_package + { + package_import_map_from_import_mapping( + "loader-runner".into(), + loader_runner_package, + ) + } else { + package_import_map_from_context("loader-runner".into(), path) + }; + for (glob, rule) in webpack_loaders_options.rules.await?.iter() { + rules.push(ModuleRule::new( + ModuleRuleCondition::All(vec![ + if !glob.contains('/') { + ModuleRuleCondition::ResourceBasePathGlob( + Glob::new(glob.clone()).await?, + ) + } else { + ModuleRuleCondition::ResourcePathGlob { + base: execution_context.project_path().await?, + glob: Glob::new(glob.clone()).await?, + } + }, + ModuleRuleCondition::not(ModuleRuleCondition::ResourceIsVirtualSource), + ]), + vec![ + // By default, loaders are expected to return ecmascript code. + // This can be overriden by specifying e. g. `as: "*.css"` in the rule. + ModuleRuleEffect::ModuleType(ModuleType::Ecmascript { + transforms: app_transforms, + options: ecmascript_options_vc, + }), + ModuleRuleEffect::SourceTransforms(Vc::cell(vec![Vc::upcast( + WebpackLoaders::new( + node_evaluate_asset_context( + execution_context, + Some(import_map), + None, + "webpack_loaders".into(), + ), + execution_context, + rule.loaders, + rule.rename_as.clone(), + resolve_options_context, + ), + )])), + ], + )); + } + } + + rules.extend(custom_rules.iter().cloned()); + + Ok(ModuleOptions::cell(ModuleOptions { rules })) + } +} diff --git a/turbopack/crates/turbopack/src/module_options/module_options_context.rs b/turbopack/crates/turbopack/src/module_options/module_options_context.rs new file mode 100644 index 0000000000000..5e1ddf7cbff72 --- /dev/null +++ b/turbopack/crates/turbopack/src/module_options/module_options_context.rs @@ -0,0 +1,164 @@ +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, RcStr, ValueDefault, Vc}; +use turbopack_core::{ + condition::ContextCondition, environment::Environment, resolve::options::ImportMapping, +}; +use turbopack_ecmascript::{references::esm::UrlRewriteBehavior, TreeShakingMode}; +pub use turbopack_mdx::MdxTransformOptions; +use turbopack_node::{ + execution_context::ExecutionContext, + transforms::{postcss::PostCssTransformOptions, webpack::WebpackLoaderItems}, +}; + +use super::ModuleRule; + +#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] +pub struct LoaderRuleItem { + pub loaders: Vc, + pub rename_as: Option, +} + +#[derive(Default)] +#[turbo_tasks::value(transparent)] +pub struct WebpackRules(IndexMap); + +#[derive(Default)] +#[turbo_tasks::value(transparent)] +pub struct OptionWebpackRules(Option>); + +#[turbo_tasks::value(shared)] +#[derive(Clone, Debug)] +pub struct WebpackLoadersOptions { + pub rules: Vc, + pub loader_runner_package: Option>, +} + +#[derive(Default)] +#[turbo_tasks::value(transparent)] +pub struct OptionWebpackLoadersOptions(Option>); + +/// The kind of decorators transform to use. +/// [TODO]: might need bikeshed for the name (Ecma) +#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] +pub enum DecoratorsKind { + Legacy, + Ecma, +} + +/// The types when replacing `typeof window` with a constant. +#[derive(Clone, PartialEq, Eq, Debug, TraceRawVcs, Serialize, Deserialize)] +pub enum TypeofWindow { + Object, + Undefined, +} + +/// Configuration options for the decorators transform. +/// This is not part of Typescript transform: while there are typescript +/// specific transforms (legay decorators), there is an ecma decorator transform +/// as well for the JS. +#[turbo_tasks::value(shared)] +#[derive(Default, Clone, Debug)] +pub struct DecoratorsOptions { + pub decorators_kind: Option, + /// Option to control whether to emit decorator metadata. + /// (https://www.typescriptlang.org/tsconfig#emitDecoratorMetadata) + /// This'll be applied only if `decorators_type` and + /// `enable_typescript_transform` is enabled. + pub emit_decorators_metadata: bool, + /// Mimic babel's `decorators.decoratorsBeforeExport` option. + /// This'll be applied only if `decorators_type` is enabled. + /// ref: https://github.com/swc-project/swc/blob/d4ebb5e6efbed0758f25e46e8f74d7c47ec6cb8f/crates/swc_ecma_parser/src/lib.rs#L327 + /// [TODO]: this option is not actively being used currently. + pub decorators_before_export: bool, + pub use_define_for_class_fields: bool, +} + +#[turbo_tasks::value_impl] +impl ValueDefault for DecoratorsOptions { + #[turbo_tasks::function] + fn value_default() -> Vc { + Self::default().cell() + } +} + +/// Subset of Typescript options configured via tsconfig.json or jsconfig.json, +/// which affects the runtime transform output. +#[turbo_tasks::value(shared)] +#[derive(Default, Clone, Debug)] +pub struct TypescriptTransformOptions { + pub use_define_for_class_fields: bool, +} + +#[turbo_tasks::value_impl] +impl ValueDefault for TypescriptTransformOptions { + #[turbo_tasks::function] + fn value_default() -> Vc { + Self::default().cell() + } +} + +// [TODO]: should enabled_react_refresh belong to this options? +#[turbo_tasks::value(shared)] +#[derive(Default, Clone, Debug)] +pub struct JsxTransformOptions { + pub development: bool, + pub react_refresh: bool, + pub import_source: Option, + pub runtime: Option, +} + +#[turbo_tasks::value(shared)] +#[derive(Clone, Default)] +#[serde(default)] +pub struct ModuleOptionsContext { + pub enable_typeof_window_inlining: Option, + pub enable_jsx: Option>, + pub enable_postcss_transform: Option>, + pub enable_webpack_loaders: Option>, + /// Follow type references and resolve declaration files in additional to + /// normal resolution. + pub enable_types: bool, + pub enable_typescript_transform: Option>, + pub decorators: Option>, + pub enable_mdx: bool, + /// This skips `GlobalCss` and `ModuleCss` module assets from being + /// generated in the module graph, generating only `Css` module assets. + /// + /// This is useful for node-file-trace, which tries to emit all assets in + /// the module graph, but neither asset types can be emitted directly. + pub enable_raw_css: bool, + // [Note]: currently mdx, and mdx_rs have different configuration entrypoint from next.config.js, + // however we might want to unify them in the future. + pub enable_mdx_rs: Option>, + pub preset_env_versions: Option>, + /// Custom rules to be applied after all default rules. + pub custom_rules: Vec, + pub execution_context: Option>, + /// A list of rules to use a different module option context for certain + /// context paths. The first matching is used. + pub rules: Vec<(ContextCondition, Vc)>, + pub placeholder_for_future_extensions: (), + pub tree_shaking_mode: Option, + pub esm_url_rewrite_behavior: Option, + pub special_exports: Option>>, + /// References to externals from ESM imports should use `import()` and make + /// async modules. + pub import_externals: bool, + /// Ignore very dynamic requests which doesn't have any static known part. + /// If false, they will reference the whole directory. If true, they won't + /// reference anything and lead to an runtime error instead. + pub ignore_dynamic_requests: bool, + + pub use_swc_css: bool, + + pub side_effect_free_packages: Vec, +} + +#[turbo_tasks::value_impl] +impl ValueDefault for ModuleOptionsContext { + #[turbo_tasks::function] + fn value_default() -> Vc { + Self::cell(Default::default()) + } +} diff --git a/turbopack/crates/turbopack/src/module_options/module_rule.rs b/turbopack/crates/turbopack/src/module_options/module_rule.rs new file mode 100644 index 0000000000000..710be28eaacad --- /dev/null +++ b/turbopack/crates/turbopack/src/module_options/module_rule.rs @@ -0,0 +1,141 @@ +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + reference_type::ReferenceType, source::Source, source_transform::SourceTransforms, +}; +use turbopack_css::CssModuleAssetType; +use turbopack_ecmascript::{EcmascriptInputTransforms, EcmascriptOptions}; +use turbopack_mdx::MdxTransformOptions; +use turbopack_wasm::source::WebAssemblySourceType; + +use super::{CustomModuleType, ModuleRuleCondition}; + +#[derive(Debug, Clone, Serialize, Deserialize, TraceRawVcs, PartialEq, Eq)] +pub struct ModuleRule { + condition: ModuleRuleCondition, + effects: Vec, + match_mode: MatchMode, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize, TraceRawVcs)] +enum MatchMode { + // Match all but internal references. + NonInternal, + // Only match internal references. + Internal, + // Match both internal and non-internal references. + All, +} + +impl MatchMode { + fn matches(&self, reference_type: &ReferenceType) -> bool { + matches!( + (self, reference_type.is_internal()), + (MatchMode::All, _) | (MatchMode::NonInternal, false) | (MatchMode::Internal, true) + ) + } +} + +impl ModuleRule { + /// Creates a new module rule. Will not match internal references. + pub fn new(condition: ModuleRuleCondition, effects: Vec) -> Self { + ModuleRule { + condition, + effects, + match_mode: MatchMode::NonInternal, + } + } + + /// Creates a new module rule. Will only matches internal references. + pub fn new_internal(condition: ModuleRuleCondition, effects: Vec) -> Self { + ModuleRule { + condition, + effects, + match_mode: MatchMode::Internal, + } + } + + /// Creates a new module rule. Will only matches internal references. + pub fn new_all(condition: ModuleRuleCondition, effects: Vec) -> Self { + ModuleRule { + condition, + effects, + match_mode: MatchMode::All, + } + } + + pub fn effects(&self) -> impl Iterator { + self.effects.iter() + } + + pub async fn matches( + &self, + source: Vc>, + path: &FileSystemPath, + reference_type: &ReferenceType, + ) -> Result { + Ok(self.match_mode.matches(reference_type) + && self.condition.matches(source, path, reference_type).await?) + } +} + +#[turbo_tasks::value(shared)] +#[derive(Debug, Clone)] +pub enum ModuleRuleEffect { + ModuleType(ModuleType), + /// Allow to extend an existing Ecmascript module rules for the additional + /// transforms. First argument will prepend the existing transforms, and + /// the second argument will append the new transforms. + ExtendEcmascriptTransforms { + prepend: Vc, + append: Vc, + }, + SourceTransforms(Vc), +} + +#[turbo_tasks::value(serialization = "auto_for_input", shared)] +#[derive(Hash, Debug, Copy, Clone)] +pub enum ModuleType { + Ecmascript { + transforms: Vc, + #[turbo_tasks(trace_ignore)] + options: Vc, + }, + Typescript { + transforms: Vc, + // parse JSX syntax. + tsx: bool, + // follow references to imported types. + analyze_types: bool, + #[turbo_tasks(trace_ignore)] + options: Vc, + }, + TypescriptDeclaration { + transforms: Vc, + #[turbo_tasks(trace_ignore)] + options: Vc, + }, + Json, + Raw, + // [TODO] We want to consolidate mdx as a type of ecma|typescript module types with + // its source transform. Refer `turbopack-mdx::into_ecmascript_module_asset` for the reason + // why we keep this separately. + Mdx { + transforms: Vc, + options: Vc, + ecmascript_options: Vc, + }, + CssGlobal, + CssModule, + Css { + ty: CssModuleAssetType, + use_swc_css: bool, + }, + Static, + WebAssembly { + source_ty: WebAssemblySourceType, + }, + Custom(Vc>), +} diff --git a/turbopack/crates/turbopack/src/module_options/rule_condition.rs b/turbopack/crates/turbopack/src/module_options/rule_condition.rs new file mode 100644 index 0000000000000..216d57ad1ff27 --- /dev/null +++ b/turbopack/crates/turbopack/src/module_options/rule_condition.rs @@ -0,0 +1,124 @@ +use anyhow::Result; +use async_recursion::async_recursion; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{primitives::Regex, trace::TraceRawVcs, ReadRef, Vc}; +use turbo_tasks_fs::{glob::Glob, FileSystemPath}; +use turbopack_core::{ + reference_type::ReferenceType, source::Source, virtual_source::VirtualSource, +}; + +#[derive(Debug, Clone, Serialize, Deserialize, TraceRawVcs, PartialEq, Eq)] +pub enum ModuleRuleCondition { + All(Vec), + Any(Vec), + Not(Box), + ReferenceType(ReferenceType), + ResourceIsVirtualSource, + ResourcePathEquals(ReadRef), + ResourcePathHasNoExtension, + ResourcePathEndsWith(String), + ResourcePathInDirectory(String), + ResourcePathInExactDirectory(ReadRef), + ResourcePathRegex(#[turbo_tasks(trace_ignore)] Regex), + /// For paths that are within the same filesystem as the `base`, it need to + /// match the relative path from base to resource. This includes `./` or + /// `../` prefix. For paths in a different filesystem, it need to match + /// the resource path in that filesystem without any prefix. This means + /// any glob starting with `./` or `../` will only match paths in the + /// project. Globs starting with `**` can match any path. + ResourcePathGlob { + base: ReadRef, + #[turbo_tasks(trace_ignore)] + glob: ReadRef, + }, + ResourceBasePathGlob(#[turbo_tasks(trace_ignore)] ReadRef), +} + +impl ModuleRuleCondition { + pub fn all(conditions: Vec) -> ModuleRuleCondition { + ModuleRuleCondition::All(conditions) + } + + pub fn any(conditions: Vec) -> ModuleRuleCondition { + ModuleRuleCondition::Any(conditions) + } + + #[allow(clippy::should_implement_trait)] + pub fn not(condition: ModuleRuleCondition) -> ModuleRuleCondition { + ModuleRuleCondition::Not(Box::new(condition)) + } +} + +impl ModuleRuleCondition { + #[async_recursion] + pub async fn matches( + &self, + source: Vc>, + path: &FileSystemPath, + reference_type: &ReferenceType, + ) -> Result { + Ok(match self { + ModuleRuleCondition::All(conditions) => { + for condition in conditions { + if !condition.matches(source, path, reference_type).await? { + return Ok(false); + } + } + true + } + ModuleRuleCondition::Any(conditions) => { + for condition in conditions { + if condition.matches(source, path, reference_type).await? { + return Ok(true); + } + } + false + } + ModuleRuleCondition::Not(condition) => { + !condition.matches(source, path, reference_type).await? + } + ModuleRuleCondition::ResourcePathEquals(other) => path == &**other, + ModuleRuleCondition::ResourcePathEndsWith(end) => path.path.ends_with(end), + ModuleRuleCondition::ResourcePathHasNoExtension => { + if let Some(i) = path.path.rfind('.') { + if let Some(j) = path.path.rfind('/') { + j > i + } else { + false + } + } else { + true + } + } + ModuleRuleCondition::ResourcePathInDirectory(dir) => { + path.path.starts_with(&format!("{dir}/")) || path.path.contains(&format!("/{dir}/")) + } + ModuleRuleCondition::ResourcePathInExactDirectory(parent_path) => { + path.is_inside_ref(parent_path) + } + ModuleRuleCondition::ReferenceType(condition_ty) => { + condition_ty.includes(reference_type) + } + ModuleRuleCondition::ResourceIsVirtualSource => { + Vc::try_resolve_downcast_type::(source) + .await? + .is_some() + } + ModuleRuleCondition::ResourcePathGlob { glob, base } => { + if let Some(path) = base.get_relative_path_to(path) { + glob.execute(&path) + } else { + glob.execute(&path.path) + } + } + ModuleRuleCondition::ResourceBasePathGlob(glob) => { + let basename = path + .path + .rsplit_once('/') + .map_or(path.path.as_str(), |(_, b)| b); + glob.execute(basename) + } + _ => todo!("not implemented yet"), + }) + } +} diff --git a/turbopack/crates/turbopack/src/rebase/mod.rs b/turbopack/crates/turbopack/src/rebase/mod.rs new file mode 100644 index 0000000000000..e33ff3e0d184e --- /dev/null +++ b/turbopack/crates/turbopack/src/rebase/mod.rs @@ -0,0 +1,74 @@ +use std::hash::Hash; + +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + asset::{Asset, AssetContent}, + ident::AssetIdent, + module::Module, + output::{OutputAsset, OutputAssets}, + reference::referenced_modules_and_affecting_sources, +}; + +/// Converts a [Module] graph into an [OutputAsset] graph by placing it into a +/// different directory. +#[turbo_tasks::value] +#[derive(Hash)] +pub struct RebasedAsset { + source: Vc>, + input_dir: Vc, + output_dir: Vc, +} + +#[turbo_tasks::value_impl] +impl RebasedAsset { + #[turbo_tasks::function] + pub fn new( + source: Vc>, + input_dir: Vc, + output_dir: Vc, + ) -> Vc { + Self::cell(RebasedAsset { + source, + input_dir, + output_dir, + }) + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for RebasedAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + AssetIdent::from_path(FileSystemPath::rebase( + self.source.ident().path(), + self.input_dir, + self.output_dir, + )) + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + let mut references = Vec::new(); + for &module in referenced_modules_and_affecting_sources(self.source) + .await? + .iter() + { + references.push(Vc::upcast(RebasedAsset::new( + module, + self.input_dir, + self.output_dir, + ))); + } + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for RebasedAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} diff --git a/turbopack/crates/turbopack/src/transition/context_transition.rs b/turbopack/crates/turbopack/src/transition/context_transition.rs new file mode 100644 index 0000000000000..a69ebfab68857 --- /dev/null +++ b/turbopack/crates/turbopack/src/transition/context_transition.rs @@ -0,0 +1,66 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Vc}; +use turbopack_core::compile_time_info::CompileTimeInfo; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; + +use crate::{module_options::ModuleOptionsContext, transition::Transition}; + +/// A transition that only affects the asset context. +#[turbo_tasks::value(shared)] +pub struct ContextTransition { + compile_time_info: Vc, + module_options_context: Vc, + resolve_options_context: Vc, + layer: Vc, +} + +#[turbo_tasks::value_impl] +impl ContextTransition { + #[turbo_tasks::function] + pub async fn new( + compile_time_info: Vc, + module_options_context: Vc, + resolve_options_context: Vc, + layer: Vc, + ) -> Result> { + Ok(ContextTransition { + module_options_context, + resolve_options_context, + compile_time_info, + layer, + } + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl Transition for ContextTransition { + #[turbo_tasks::function] + fn process_compile_time_info( + &self, + _compile_time_info: Vc, + ) -> Vc { + self.compile_time_info + } + + #[turbo_tasks::function] + fn process_layer(&self, _layer: Vc) -> Vc { + self.layer + } + + #[turbo_tasks::function] + fn process_module_options_context( + &self, + _context: Vc, + ) -> Vc { + self.module_options_context + } + + #[turbo_tasks::function] + fn process_resolve_options_context( + &self, + _context: Vc, + ) -> Vc { + self.resolve_options_context + } +} diff --git a/turbopack/crates/turbopack/src/transition/full_context_transition.rs b/turbopack/crates/turbopack/src/transition/full_context_transition.rs new file mode 100644 index 0000000000000..a479e998f2814 --- /dev/null +++ b/turbopack/crates/turbopack/src/transition/full_context_transition.rs @@ -0,0 +1,29 @@ +use anyhow::Result; +use turbo_tasks::Vc; + +use crate::{transition::Transition, ModuleAssetContext}; + +/// A transition that only affects the asset context. +#[turbo_tasks::value(shared)] +pub struct FullContextTransition { + module_context: Vc, +} + +#[turbo_tasks::value_impl] +impl FullContextTransition { + #[turbo_tasks::function] + pub async fn new(module_context: Vc) -> Result> { + Ok(FullContextTransition { module_context }.cell()) + } +} + +#[turbo_tasks::value_impl] +impl Transition for FullContextTransition { + #[turbo_tasks::function] + fn process_context( + &self, + _module_asset_context: Vc, + ) -> Vc { + self.module_context + } +} diff --git a/turbopack/crates/turbopack/src/transition/mod.rs b/turbopack/crates/turbopack/src/transition/mod.rs new file mode 100644 index 0000000000000..9540e365d362c --- /dev/null +++ b/turbopack/crates/turbopack/src/transition/mod.rs @@ -0,0 +1,111 @@ +pub(crate) mod context_transition; +pub(crate) mod full_context_transition; + +use std::collections::HashMap; + +use anyhow::Result; +pub use context_transition::ContextTransition; +pub use full_context_transition::FullContextTransition; +use turbo_tasks::{RcStr, Value, ValueDefault, Vc}; +use turbopack_core::{ + compile_time_info::CompileTimeInfo, context::ProcessResult, module::Module, + reference_type::ReferenceType, source::Source, +}; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; + +use crate::{module_options::ModuleOptionsContext, ModuleAssetContext}; + +/// Some kind of operation that is executed during reference processing. e. g. +/// you can transition to a different environment on a specific import +/// (reference). +#[turbo_tasks::value_trait] +pub trait Transition { + /// Apply modifications/wrapping to the source asset + fn process_source(self: Vc, asset: Vc>) -> Vc> { + asset + } + /// Apply modifications to the compile-time information + fn process_compile_time_info( + self: Vc, + compile_time_info: Vc, + ) -> Vc { + compile_time_info + } + /// Apply modifications to the layer + fn process_layer(self: Vc, layer: Vc) -> Vc { + layer + } + /// Apply modifications/wrapping to the module options context + fn process_module_options_context( + self: Vc, + module_options_context: Vc, + ) -> Vc { + module_options_context + } + /// Apply modifications/wrapping to the resolve options context + fn process_resolve_options_context( + self: Vc, + resolve_options_context: Vc, + ) -> Vc { + resolve_options_context + } + /// Apply modifications/wrapping to the final asset + fn process_module( + self: Vc, + module: Vc>, + _context: Vc, + ) -> Vc> { + module + } + /// Apply modifications to the context + async fn process_context( + self: Vc, + module_asset_context: Vc, + ) -> Result> { + let module_asset_context = module_asset_context.await?; + let compile_time_info = + self.process_compile_time_info(module_asset_context.compile_time_info); + let module_options_context = + self.process_module_options_context(module_asset_context.module_options_context); + let resolve_options_context = + self.process_resolve_options_context(module_asset_context.resolve_options_context); + let layer = self.process_layer(module_asset_context.layer); + let module_asset_context = ModuleAssetContext::new( + module_asset_context.transitions, + compile_time_info, + module_options_context, + resolve_options_context, + layer, + ); + Ok(module_asset_context) + } + /// Apply modification on the processing of the asset + async fn process( + self: Vc, + asset: Vc>, + module_asset_context: Vc, + reference_type: Value, + ) -> Result> { + let asset = self.process_source(asset); + let module_asset_context = self.process_context(module_asset_context); + let m = module_asset_context.process_default(asset, reference_type); + Ok(match *m.await? { + ProcessResult::Module(m) => { + ProcessResult::Module(self.process_module(m, module_asset_context)) + } + ProcessResult::Ignore => ProcessResult::Ignore, + } + .cell()) + } +} + +#[turbo_tasks::value(transparent)] +pub struct TransitionsByName(HashMap>>); + +#[turbo_tasks::value_impl] +impl ValueDefault for TransitionsByName { + #[turbo_tasks::function] + fn value_default() -> Vc { + Vc::cell(Default::default()) + } +} diff --git a/turbopack/crates/turbopack/src/unsupported_sass.rs b/turbopack/crates/turbopack/src/unsupported_sass.rs new file mode 100644 index 0000000000000..52ead7bfe6d7a --- /dev/null +++ b/turbopack/crates/turbopack/src/unsupported_sass.rs @@ -0,0 +1,101 @@ +//! TODO(WEB-741) Remove this file once Sass is supported. + +use anyhow::Result; +use turbo_tasks::{Value, Vc}; +use turbo_tasks_fs::{glob::Glob, FileSystemPath}; +use turbopack_core::{ + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, + reference_type::ReferenceType, + resolve::{ + parse::Request, + plugin::{AfterResolvePlugin, AfterResolvePluginCondition}, + ResolveResultOption, + }, +}; + +/// Resolve plugins that warns when importing a sass file. +#[turbo_tasks::value] +pub(crate) struct UnsupportedSassResolvePlugin { + root: Vc, +} + +#[turbo_tasks::value_impl] +impl UnsupportedSassResolvePlugin { + #[turbo_tasks::function] + pub fn new(root: Vc) -> Vc { + UnsupportedSassResolvePlugin { root }.cell() + } +} + +#[turbo_tasks::value_impl] +impl AfterResolvePlugin for UnsupportedSassResolvePlugin { + #[turbo_tasks::function] + fn after_resolve_condition(&self) -> Vc { + AfterResolvePluginCondition::new(self.root.root(), Glob::new("**/*.{sass,scss}".into())) + } + + #[turbo_tasks::function] + async fn after_resolve( + &self, + fs_path: Vc, + lookup_path: Vc, + _reference_type: Value, + request: Vc, + ) -> Result> { + let extension = fs_path.extension().await?; + if ["sass", "scss"].iter().any(|ext| *ext == &**extension) { + UnsupportedSassModuleIssue { + file_path: lookup_path, + request, + } + .cell() + .emit(); + } + + Ok(ResolveResultOption::none()) + } +} + +#[turbo_tasks::value(shared)] +struct UnsupportedSassModuleIssue { + file_path: Vc, + request: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for UnsupportedSassModuleIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Warning.into() + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + Ok(StyledString::Text( + format!( + "Unsupported Sass request: {}", + self.request.await?.request().as_deref().unwrap_or("N/A") + ) + .into(), + ) + .cell()) + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.file_path + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some( + StyledString::Text("Turbopack does not yet support importing Sass modules.".into()) + .cell(), + )) + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Unsupported.cell() + } +} diff --git a/turbopack/crates/turbopack/tests/helpers/mod.rs b/turbopack/crates/turbopack/tests/helpers/mod.rs new file mode 100644 index 0000000000000..92a468ed57791 --- /dev/null +++ b/turbopack/crates/turbopack/tests/helpers/mod.rs @@ -0,0 +1,59 @@ +use std::{collections::VecDeque, fmt::Write as _}; + +use difference::{Changeset, Difference}; + +pub fn print_changeset(changeset: &Changeset) -> String { + assert!(changeset.split == "\n"); + let mut result = String::from("--- DIFF ---\n- Expected\n+ Actual\n------------\n"); + const CONTEXT_LINES_COUNT: usize = 3; + let mut context_lines = VecDeque::with_capacity(CONTEXT_LINES_COUNT); + let mut context_lines_needed = CONTEXT_LINES_COUNT; + let mut has_spacing = false; + for diff in changeset.diffs.iter() { + match diff { + Difference::Same(content) => { + let lines = content + .rsplit('\n') + .take(context_lines_needed) + .collect::>() + .into_iter() + .rev(); + for line in lines { + if context_lines_needed > 0 { + writeln!(result, " {line}").unwrap(); + context_lines_needed -= 1; + } else { + if context_lines.len() == CONTEXT_LINES_COUNT { + has_spacing = true; + context_lines.pop_front(); + } + context_lines.push_back(line); + } + } + } + Difference::Add(line) => { + if has_spacing { + writeln!(result, "...").unwrap(); + has_spacing = false; + } + while let Some(line) = context_lines.pop_front() { + writeln!(result, " {line}").unwrap(); + } + writeln!(result, "+ {line}").unwrap(); + context_lines_needed = CONTEXT_LINES_COUNT; + } + Difference::Rem(line) => { + if has_spacing { + writeln!(result, "...").unwrap(); + has_spacing = false; + } + while let Some(line) = context_lines.pop_front() { + writeln!(result, " {line}").unwrap(); + } + writeln!(result, "- {line}").unwrap(); + context_lines_needed = CONTEXT_LINES_COUNT; + } + } + } + result +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace.rs b/turbopack/crates/turbopack/tests/node-file-trace.rs new file mode 100644 index 0000000000000..ad4f2c3e000df --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace.rs @@ -0,0 +1,764 @@ +#![allow(clippy::items_after_test_module)] +#![feature(arbitrary_self_types)] + +mod helpers; +#[cfg(feature = "bench_against_node_nft")] +use std::time::Instant; +use std::{ + collections::{HashMap, HashSet}, + env::temp_dir, + fmt::Display, + fs::{ + remove_dir_all, {self}, + }, + io::{ErrorKind, Write as _}, + path::{Path, PathBuf}, + sync::{Arc, Mutex}, + time::Duration, +}; + +use anyhow::{anyhow, Context, Result}; +use difference::Changeset; +use helpers::print_changeset; +use lazy_static::lazy_static; +use regex::Regex; +use rstest::*; +use rstest_reuse::{ + *, {self}, +}; +use serde::{Deserialize, Serialize}; +use tokio::{process::Command, time::timeout}; +use turbo_tasks::{backend::Backend, RcStr, ReadRef, TurboTasks, Value, ValueToString, Vc}; +use turbo_tasks_fs::{DiskFileSystem, FileSystem, FileSystemPath}; +use turbo_tasks_memory::MemoryBackend; +use turbopack::{ + emit_with_completion, module_options::ModuleOptionsContext, rebase::RebasedAsset, register, + ModuleAssetContext, +}; +use turbopack_core::{ + compile_time_info::CompileTimeInfo, + context::AssetContext, + environment::{Environment, ExecutionEnvironment, NodeJsEnvironment}, + file_source::FileSource, + output::OutputAsset, + reference_type::ReferenceType, +}; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; + +#[global_allocator] +static ALLOC: turbo_tasks_malloc::TurboMalloc = turbo_tasks_malloc::TurboMalloc; + +#[template] +#[rstest] +#[case::analytics_node("integration/analytics-node.js")] +#[case::array_map_require("integration/array-map-require/index.js")] +#[case::apollo("integration/apollo.js")] +#[case::argon2("integration/argon2.js")] +#[case::auth0("integration/auth0.js")] +#[case::aws_sdk("integration/aws-sdk.js")] +#[case::axios("integration/axios.js")] +#[case::azure_cosmos("integration/azure-cosmos.js")] +#[case::azure_storage("integration/azure-storage.js")] +#[case::bcrypt("integration/bcrypt.js")] +#[case::better_sqlite3("integration/better-sqlite3.js")] +#[cfg_attr( + not(feature = "bench_against_node_nft"), + should_panic(expected = "Error: Could not locate the bindings file."), + case::bindings_failure("integration/bindings-failure.js") +)] +#[case::browserify_middleware("integration/browserify-middleware.js")] +#[case::bugsnag_js("integration/bugsnag-js.js")] +#[case::bull("integration/bull.js")] +#[case::bull_mq("integration/bullmq.js")] +#[case::camaro("integration/camaro.js")] +#[case::canvas("integration/canvas.js")] +#[case::chromeless("integration/chromeless.js")] +#[case::core_js("integration/core-js.js")] +#[case::cosmosdb_query("integration/cosmosdb-query.js")] +#[case::cowsay("integration/cowsay.js")] +#[cfg_attr( + not(feature = "bench_against_node_nft"), + should_panic(expected = "Error: Cannot find module '../../out/node-file-trace'"), + case::dogfood("integration/dogfood.js") +)] +#[case::dynamic_in_package("integration/dynamic-in-package.js")] +#[case::empty("integration/empty.js")] +#[case::env_var("integration/env-var.js")] +#[case::es_get_iterator("integration/es-get-iterator.js")] +// This is flakey on Windows. Disable for now. +#[cfg_attr(not(target_os = "windows"), case::esbuild("integration/esbuild.js"))] +#[case::esm("integration/esm.js")] +#[case::express_consolidate("integration/express-consolidate.js")] +#[case::express_template_engine("integration/express-template-engine.js")] +#[case::express_template_pug("integration/express-template.js")] +#[case::express("integration/express.js")] +#[case::fast_glob("integration/fast-glob.js")] +#[case::fetch_h2("integration/fetch-h2.js")] +#[cfg_attr(target_arch = "x86_64", case::ffmpeg_js("integration/ffmpeg.js"))] +// Could not find ffmpeg executable +#[case::firebase_admin("integration/firebase-admin.js")] +#[case::firebase("integration/firebase.js")] +#[case::firestore("integration/firestore.js")] +#[case::fluent_ffmpeg("integration/fluent-ffmpeg.js")] +#[case::geo_tz("integration/geo-tz.js")] +#[case::google_bigquery("integration/google-bigquery.js")] +#[case::got("integration/got.js")] +#[case::highlights("integration/highlights.js")] +#[case::hot_shots("integration/hot-shots.js")] +#[case::ioredis("integration/ioredis.js")] +#[case::isomorphic_unfetch("integration/isomorphic-unfetch.js")] +#[case::jimp("integration/jimp.js")] +#[case::jugglingdb("integration/jugglingdb.js")] +#[case::koa("integration/koa.js")] +#[case::leveldown("integration/leveldown.js")] +#[case::lighthouse("integration/lighthouse.js")] +#[case::loopback("integration/loopback.js")] +#[case::mailgun("integration/mailgun.js")] +#[case::mariadb("integration/mariadb.js")] +#[case::memcached("integration/memcached.js")] +#[cfg_attr( + not(feature = "bench_against_node_nft"), + should_panic(expected = "Error [ERR_MODULE_NOT_FOUND]: Cannot find module"), + case::mdx("integration/mdx/index.cjs") +)] +#[case::mongoose("integration/mongoose.js")] +#[case::mysql("integration/mysql.js")] +#[case::npm("integration/npm.js")] +// unable to resolve esm request module 'spdx-license-ids' in +// node-file-trace/node_modules/npm/node_modules/spdx-correct oracledb doesn't support non x86 +// architectures +#[cfg_attr(target_arch = "x86_64", case::oracledb("integration/oracledb.js"))] +#[case::paraphrase("integration/paraphrase.js")] +#[case::passport_trakt("integration/passport-trakt.js")] +#[case::passport("integration/passport.js")] +#[case::path_platform("integration/path-platform.js")] +#[case::pixelmatch("integration/pixelmatch.js")] +#[case::pdf2json("integration/pdf2json.mjs")] +#[case::pdfkit("integration/pdfkit.js")] +#[case::pg("integration/pg.js")] +#[case::playwright_core("integration/playwright-core.js")] +#[case::pnpm_like("integration/pnpm/pnpm-like.js")] +#[case::polyfill_library("integration/polyfill-library.js")] +#[case::pug("integration/pug.js")] +#[case::react("integration/react.js")] +#[case::redis("integration/redis.js")] +#[case::remark_prism("integration/remark-prism.mjs")] +#[case::request("integration/request.js")] +#[case::rxjs("integration/rxjs.js")] +#[case::saslprep("integration/saslprep.js")] +#[case::semver("integration/semver.js")] +#[case::sentry("integration/sentry.js")] +#[case::sequelize("integration/sequelize.js")] +#[cfg_attr( + target_os = "windows", + should_panic(expected = "Something went wrong installing the \"sharp\" module"), + case::sharp("integration/sharp.js") +)] +#[cfg_attr(not(target_os = "windows"), case::sharp("integration/sharp.js"))] +#[case::simple("integration/simple.js")] +#[case::socket_io("integration/socket.io.js")] +#[case::source_map("integration/source-map/index.js")] +#[case::sparql_builder("integration/sparql-builder.js")] +#[case::sqlite("integration/sqlite.js")] +#[case::stripe("integration/stripe.js")] +#[case::strong_error_handler("integration/strong-error-handler.js")] +#[case::symlink_to_file("integration/symlink-to-file/index.js")] +#[case::tiny_json_http("integration/tiny-json-http.js")] +#[case::twilio("integration/twilio.js")] +#[case::ts_morph("integration/ts-morph.js")] +#[case::typescript("integration/typescript.js")] +#[case::uglify("integration/uglify.js")] +#[case::underscore("integration/underscore.js")] +#[case::vm2("integration/vm2.js")] +#[case::vue("integration/vue.js")] +#[case::webpack_target_node("integration/webpack-target-node/index.js")] +#[case::whatwg_url("integration/whatwg-url.js")] +#[case::when("integration/when.js")] +#[case::package_exports_alt_folders_base( + CaseInput::new("integration/package-exports/pass/alt-folders.js").expected_stderr("Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath") +)] +#[case::package_exports_folder( + CaseInput::new("integration/package-exports/pass/folder.js").expected_stderr("Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath") +)] +#[case::package_exports_alt_base("integration/package-exports/pass/alt.js")] +#[case::package_exports_catch_all("integration/package-exports/pass/catch-all.js")] +#[case::package_exports_direct("integration/package-exports/pass/direct.js")] +#[case::package_exports_double("integration/package-exports/pass/double.js")] +#[case::package_exports_nested("integration/package-exports/pass/nested.js")] +#[case::package_exports_package_root("integration/package-exports/pass/root.js")] +#[case::package_exports_package_single_export_root( + "integration/package-exports/pass/single-export-root.js" +)] +#[case::package_exports_package_sub_infix_sep("integration/package-exports/pass/sub-infix-sep.js")] +#[case::package_exports_package_sub_infix_base("integration/package-exports/pass/sub-infix.js")] +#[case::package_exports_package_sub_prefix_sep( + "integration/package-exports/pass/sub-prefix-sep.js" +)] +#[case::package_exports_package_sub_prefix("integration/package-exports/pass/sub-prefix.js")] +#[case::package_exports_package_sub_suffix_sep( + "integration/package-exports/pass/sub-suffix-sep.js" +)] +#[case::package_exports_package_sub_suffix_base("integration/package-exports/pass/sub-suffix.js")] +#[case::package_exports_alt_folders_multiple( + CaseInput::new("integration/package-exports/fail/alt-folders-multiple.js") + .expected_stderr("Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: Package subpath") +)] +#[case::package_exports_alt_multiple( + CaseInput::new("integration/package-exports/fail/alt-multiple.js") + .expected_stderr("Error [ERR_MODULE_NOT_FOUND]: Cannot find module") +)] +#[case::read_file("integration/read-file.mjs")] +#[cfg_attr( + not(feature = "bench_against_node_nft"), + //[TODO]: WEB-1188 reenable once fixed. + //case::ts_package_base("integration/ts-package/index.ts"), + //case::ts_package_extends("integration/ts-package-extends/index.ts"), + //case::ts_package_from_js("integration/ts-package-from-js/index.js"), + case::ts_paths_alt_base("integration/ts-paths/pass/alt.ts"), + case::ts_paths_catch_all("integration/ts-paths/pass/catch-all.ts"), + case::ts_paths_direct("integration/ts-paths/pass/direct.ts"), + case::ts_paths_nested("integration/ts-paths/pass/nested.ts"), + case::ts_paths_package_sub_prefix("integration/ts-paths/pass/sub-prefix.ts"), + case::ts_paths_package_sub_suffix_sep_base("integration/ts-paths/pass/sub-suffix-sep.ts"), + case::ts_paths_package_sub_suffix_base("integration/ts-paths/pass/sub-suffix.ts"), + case::ts_paths_alt_folders( + CaseInput::new("integration/ts-paths/fail/alt-folders.ts") + .expected_stderr("Cannot find module 'fixtures/alt-folders/alt1.js'") + ), + case::ts_paths_double( + CaseInput::new("integration/ts-paths/fail/double.ts") + .expected_stderr("Cannot find module 'double/sub' or its corresponding type declarations.") + ), + case::ts_paths_folder( + CaseInput::new("integration/ts-paths/fail/folder.ts") + .expected_stderr("Cannot find module 'folder/alt1' or its corresponding type declarations.") + ), + // TODO(alexkirsz) I expect the two following infix tests are only failing when using `tsconfig-paths`, since + // VSCode's TS language server can resolve them properly. We should pre-compile the TS files to JS and run Node.js + // on them directly instead. + case::ts_paths_package_sub_infix_sep( + CaseInput::new("integration/ts-paths/fail/sub-infix-sep.ts") + .expected_stderr("Cannot find module '@/sub/@'") + ), + case::ts_paths_package_sub_infix_base( + CaseInput::new("integration/ts-paths/fail/sub-infix.ts") + .expected_stderr("Cannot find module '@sub@'") + ), + case::ts_paths_sub_prefix_sep( + CaseInput::new("integration/ts-paths/fail/sub-prefix-sep.ts") + .expected_stderr("Cannot find module 'sub/@' or its corresponding type declarations") + ), +)] +#[cfg_attr( + //[TODO]: WEB-1188 reenable windows once fixed. + not(any(feature = "bench_against_node_nft", target_os = "windows")), + case::ts_package_base("integration/ts-package/index.ts"), + case::ts_package_extends("integration/ts-package-extends/index.ts"), + case::ts_package_from_js("integration/ts-package-from-js/index.js"), +)] +fn test_cases() {} + +#[apply(test_cases)] +fn node_file_trace_memory(#[case] input: CaseInput) { + node_file_trace( + input, + "memory", + false, + 1, + 120, + |_| TurboTasks::new(MemoryBackend::default()), + |tt| { + let b = tt.backend(); + b.with_all_cached_tasks(|task| { + b.with_task(task, |task| { + if task.is_pending() { + println!("PENDING: {task}"); + } + }) + }); + }, + ); +} + +#[cfg(feature = "test_persistent_cache")] +#[apply(test_cases)] +fn node_file_trace_rocksdb(#[case] input: CaseInput) { + use turbo_tasks_memory::MemoryBackendWithPersistedGraph; + use turbo_tasks_rocksdb::RocksDbPersistedGraph; + + node_file_trace( + input, + "rockdb", + false, + 2, + 240, + |directory_path| { + TurboTasks::new(MemoryBackendWithPersistedGraph::new( + RocksDbPersistedGraph::new(directory_path.join(".db")).unwrap(), + )) + }, + |_| {}, + ); +} + +#[cfg(feature = "bench_against_node_nft")] +#[apply(test_cases)] +fn bench_against_node_nft_st(#[case] input: CaseInput) { + bench_against_node_nft_inner(input, false); +} + +#[cfg(feature = "bench_against_node_nft")] +#[apply(test_cases)] +fn bench_against_node_nft_mt(#[case] input: CaseInput) { + bench_against_node_nft_inner(input, true); +} + +#[cfg(feature = "bench_against_node_nft")] +fn bench_against_node_nft_inner(input: CaseInput, multi_threaded: bool) { + node_file_trace( + input, + "memory", + multi_threaded, + 1, + 120, + |_| TurboTasks::new(MemoryBackend::default()), + |tt| { + let b = tt.backend(); + b.with_all_cached_tasks(|task| { + b.with_task(task, |task| { + if task.is_pending() { + println!("PENDING: {task}"); + } + }) + }); + }, + ); +} + +fn node_file_trace( + CaseInput { + path: input_path, + #[allow(unused)] + expected_stderr, + }: CaseInput, + mode: &str, + multi_threaded: bool, + run_count: i32, + timeout_len: u64, + create_turbo_tasks: impl Fn(&Path) -> Arc>, + handle_timeout_error: impl Fn(&Arc>), +) { + lazy_static! { + static ref BENCH_SUITES: Arc>> = Arc::new(Mutex::new(Vec::new())); + }; + + let r = &mut { + let mut builder = if multi_threaded { + tokio::runtime::Builder::new_multi_thread() + } else { + tokio::runtime::Builder::new_current_thread() + }; + builder.enable_all(); + if !multi_threaded { + builder.max_blocking_threads(20); + } + builder.build().unwrap() + }; + r.block_on(async move { + register(); + include!(concat!( + env!("OUT_DIR"), + "/register_test_node-file-trace.rs" + )); + let bench_suites = BENCH_SUITES.clone(); + let package_root = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + let mut tests_output_root = temp_dir(); + tests_output_root.push("tests_output"); + let package_root: RcStr = package_root.to_string_lossy().into(); + let input: RcStr = format!("node-file-trace/{input_path}").into(); + let directory_path = tests_output_root.join(format!("{mode}_{input}")); + let directory: RcStr = directory_path.to_string_lossy().into(); + + remove_dir_all(&directory) + .or_else(|err| { + if err.kind() == ErrorKind::NotFound { + Ok(()) + } else { + Err(err) + } + }) + .context(format!("Failed to remove directory: {directory}")) + .unwrap(); + + for _ in 0..run_count { + let bench_suites = bench_suites.clone(); + let package_root = package_root.clone(); + let input_string = input.clone(); + let directory = directory.clone(); + #[cfg(not(feature = "bench_against_node_nft"))] + let expected_stderr = expected_stderr.clone(); + let task = async move { + #[allow(unused)] + let bench_suites = bench_suites.clone(); + #[cfg(feature = "bench_against_node_nft")] + let before_start = Instant::now(); + let workspace_fs: Vc> = Vc::upcast(DiskFileSystem::new( + "workspace".into(), + package_root.clone(), + vec![], + )); + let input_dir = workspace_fs.root(); + let input = input_dir.join(format!("tests/{input_string}").into()); + + #[cfg(not(feature = "bench_against_node_nft"))] + let original_output = exec_node(package_root, input); + + let output_fs = DiskFileSystem::new("output".into(), directory.clone(), vec![]); + let output_dir = output_fs.root(); + + let source = FileSource::new(input); + let module_asset_context = ModuleAssetContext::new( + Vc::cell(HashMap::new()), + // TODO It's easy to make a mistake here as this should match the config in the + // binary. TODO These test cases should move into the + // `node-file-trace` crate and use the same config. + CompileTimeInfo::new(Environment::new(Value::new( + ExecutionEnvironment::NodeJsLambda(NodeJsEnvironment::default().into()), + ))), + ModuleOptionsContext { + enable_types: true, + enable_raw_css: true, + ..Default::default() + } + .cell(), + ResolveOptionsContext { + enable_node_native_modules: true, + enable_node_modules: Some(input_dir), + custom_conditions: vec!["node".into()], + ..Default::default() + } + .cell(), + Vc::cell("test".into()), + ); + let module = module_asset_context + .process(Vc::upcast(source), Value::new(ReferenceType::Undefined)) + .module(); + let rebased = RebasedAsset::new(Vc::upcast(module), input_dir, output_dir); + + #[cfg(not(feature = "bench_against_node_nft"))] + let output_path = rebased.ident().path(); + + print_graph(Vc::upcast(rebased)).await?; + + emit_with_completion(Vc::upcast(rebased), output_dir).await?; + + #[cfg(not(feature = "bench_against_node_nft"))] + { + let output = exec_node(directory.clone(), output_path); + let output = + assert_output(original_output, output, expected_stderr.map(From::from)); + output.await + } + #[cfg(feature = "bench_against_node_nft")] + { + let duration = before_start.elapsed(); + let node_start = Instant::now(); + exec_node(package_root, input.clone()).await?; + let node_duration = node_start.elapsed(); + let is_faster = node_duration > duration; + { + let mut bench_suites_lock = bench_suites.lock().unwrap(); + let rust_speedup = + node_duration.as_millis() as f32 / duration.as_millis() as f32 - 1.0; + let rust_duration = format!("{:?}", duration); + let node_duration = format!("{:?}", node_duration); + let rust_speedup = if rust_speedup > 1.0 { + format!("+{:.2}x", rust_speedup) + } else if rust_speedup > 0.0 { + format!("+{:.0}%", rust_speedup * 100.0) + } else { + format!("-{:.0}%", -rust_speedup * 100.0) + }; + bench_suites_lock.push(BenchSuite { + suite: input_string + .trim_start_matches("node-file-trace/integration/") + .to_string() + + (if multi_threaded { + " (multi-threaded)" + } else { + "" + }), + is_faster, + rust_duration, + node_duration, + rust_speedup, + }); + } + CommandOutput::cell(CommandOutput { + stdout: String::new(), + stderr: String::new(), + }) + .await + } + }; + let handle_result = |result: Result>| match result { + #[allow(unused)] + Ok(output) => { + #[cfg(not(feature = "bench_against_node_nft"))] + { + assert!( + output.is_empty(), + "emitted files behave differently when executed via node.js\n{output}" + ); + } + } + Err(err) => { + panic!("Execution failed: {:?}", err); + } + }; + + let tt = create_turbo_tasks(directory_path.as_path()); + let output = timeout(Duration::from_secs(timeout_len), tt.run_once(task)).await; + let _ = timeout(Duration::from_secs(2), tt.wait_background_done()).await; + let stop = timeout(Duration::from_secs(60), tt.stop_and_wait()).await; + match (output, stop) { + (Ok(result), Ok(_)) => handle_result(result), + (Err(err), _) => { + handle_timeout_error(&tt); + panic!("Execution is hanging (for > {timeout_len}s): {err}"); + } + (_, Err(err)) => { + panic!("Stopping is hanging (for > 60s): {err}"); + } + } + } + let bench_suites_lock = BENCH_SUITES.lock().unwrap(); + if !bench_suites_lock.is_empty() { + static BENCH_FILE_NAME: &str = "bench.json"; + let mut bench_result = fs::File::options() + .append(true) + .open(BENCH_FILE_NAME) + .unwrap_or_else(|_| fs::File::create(BENCH_FILE_NAME).unwrap()); + bench_result + .write_all( + { serde_json::to_string(bench_suites_lock.as_slice()).unwrap() + "\n" } + .as_bytes(), + ) + .unwrap(); + drop(bench_result); + } + }) +} + +#[turbo_tasks::value] +struct CommandOutput { + stdout: String, + stderr: String, +} + +#[cfg(not(feature = "bench_against_node_nft"))] +impl CommandOutput { + fn is_empty(&self) -> bool { + self.stderr.is_empty() && self.stdout.is_empty() + } +} + +impl Display for CommandOutput { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!( + f, + "---------- Stdout ----------\n{}\n---------- Stderr ----------\n{}", + &self.stdout, &self.stderr, + ) + } +} + +#[turbo_tasks::function] +async fn exec_node(directory: RcStr, path: Vc) -> Result> { + let mut cmd = Command::new("node"); + + let p = path.await?; + let f = Path::new(&directory).join(&p.path); + let dir = f.parent().unwrap(); + println!("[CWD]: {}", dir.display()); + let label = path.to_string().await?; + + if p.path.contains("mdx") { + cmd.arg("--experimental-loader=@mdx-js/node-loader") + .arg("--no-warnings"); + } + + #[cfg(not(feature = "bench_against_node_nft"))] + if p.path.ends_with(".ts") { + let mut ts_node = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + ts_node.push("tests"); + ts_node.push("node-file-trace"); + ts_node.push("node_modules"); + ts_node.push("ts-node"); + ts_node.push("dist"); + ts_node.push("bin.js"); + cmd.arg(&ts_node); + } + + #[cfg(feature = "bench_against_node_nft")] + { + let mut node_nft = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + node_nft.push("tests"); + node_nft.push("node-file-trace"); + node_nft.push("node_modules"); + node_nft.push("@vercel"); + node_nft.push("nft"); + node_nft.push("out"); + node_nft.push("cli.js"); + cmd.arg(&node_nft).arg("build"); + } + #[cfg(not(feature = "bench_against_node_nft"))] + { + cmd.arg(&f); + cmd.current_dir(dir); + } + #[cfg(feature = "bench_against_node_nft")] + { + let current_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + cmd.arg(&p.path); + cmd.current_dir(current_dir); + } + + println!("[CMD]: {:#?}", cmd); + + let output = timeout(Duration::from_secs(100), cmd.output()) + .await + .with_context(|| anyhow!("node execution of {label} is hanging"))? + .with_context(|| anyhow!("failed to spawn node process of {label}"))?; + + let output = CommandOutput { + stdout: String::from_utf8_lossy(&output.stdout).to_string(), + stderr: clean_stderr(String::from_utf8_lossy(&output.stderr).as_ref()), + }; + + println!("File: {}\n{}", f.display(), output,); + + Ok(CommandOutput::cell(output)) +} + +fn clean_stderr(str: &str) -> String { + lazy_static! { + static ref EXPERIMENTAL_WARNING: Regex = + Regex::new(r"\(node:\d+\) ExperimentalWarning:").unwrap(); + } + EXPERIMENTAL_WARNING + .replace_all(str, "(node:XXXX) ExperimentalWarning:") + .to_string() +} + +fn diff(expected: &str, actual: &str) -> String { + lazy_static! { + static ref JAVASCRIPT_TIMESTAMP: Regex = + Regex::new(r"\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z").unwrap(); + static ref JAVASCRIPT_DATE_TIME: Regex = + Regex::new(r"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{6}").unwrap(); + } + // Remove timestamps from the output. + if JAVASCRIPT_DATE_TIME.replace_all(JAVASCRIPT_TIMESTAMP.replace_all(actual, "").as_ref(), "") + == JAVASCRIPT_DATE_TIME + .replace_all(JAVASCRIPT_TIMESTAMP.replace_all(expected, "").as_ref(), "") + { + return String::new(); + } + print_changeset(&Changeset::new(expected.trim(), actual.trim(), "\n")) +} + +#[allow(unused)] +#[turbo_tasks::function] +async fn assert_output( + expected: Vc, + actual: Vc, + expected_stderr: Option, +) -> Result> { + let expected = expected.await?; + let actual = actual.await?; + Ok(CommandOutput::cell(CommandOutput { + stdout: diff(&expected.stdout, &actual.stdout), + stderr: if let Some(expected_stderr) = expected_stderr { + if actual.stderr.contains(&*expected_stderr) + && expected.stderr.contains(&*expected_stderr) + { + String::new() + } else { + let stderr_diff = diff(&expected.stderr, &actual.stderr); + format!( + "could not find `{}` in stderr\n{}", + expected_stderr, stderr_diff + ) + } + } else { + diff(&expected.stderr, &actual.stderr) + }, + })) +} + +#[derive(Debug, Serialize, Deserialize)] +struct BenchSuite { + suite: String, + node_duration: String, + rust_duration: String, + rust_speedup: String, + is_faster: bool, +} + +/// rstest's #[case] attribute does not allow for specifying default values. +/// However, it can automatically convert between types, so we can use a +/// custom input struct with the Builder pattern instead. +struct CaseInput { + /// The path to the JS or TS test file. + path: String, + /// The test will pass if the provided error message is included in both + /// stderr outputs. + expected_stderr: Option, +} + +impl CaseInput { + fn new(path: &str) -> Self { + Self { + path: path.to_owned(), + expected_stderr: None, + } + } + + fn expected_stderr(mut self, msg: &str) -> Self { + self.expected_stderr = Some(msg.to_owned()); + self + } +} + +impl std::str::FromStr for CaseInput { + type Err = std::convert::Infallible; + + fn from_str(s: &str) -> Result { + Ok(Self::new(s)) + } +} + +async fn print_graph(asset: Vc>) -> Result<()> { + let mut visited = HashSet::new(); + let mut queue = Vec::new(); + queue.push((0, asset)); + while let Some((depth, asset)) = queue.pop() { + let references = asset.references().await?; + let mut indent = String::new(); + for _ in 0..depth { + indent.push_str(" "); + } + if visited.insert(asset) { + for &asset in references.iter().rev() { + queue.push((depth + 1, asset)); + } + println!("{}{}", indent, asset.ident().to_string().await?); + } else if references.is_empty() { + println!("{}{} *", indent, asset.ident().to_string().await?); + } else { + println!("{}{} *...", indent, asset.ident().to_string().await?); + } + } + Ok(()) +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/.gitignore b/turbopack/crates/turbopack/tests/node-file-trace/.gitignore new file mode 100644 index 0000000000000..206259d6d954b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/.gitignore @@ -0,0 +1,5 @@ +/node_modules +dist +integration/**/dist + +!integration/**/node_modules \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/analytics-node.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/analytics-node.js new file mode 100644 index 0000000000000..ff3fe611324df --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/analytics-node.js @@ -0,0 +1,3 @@ +const Analytics = require("analytics-node"); + +new Analytics("YOUR_WRITE_KEY"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/apollo.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/apollo.js new file mode 100644 index 0000000000000..ee5a78455bd0a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/apollo.js @@ -0,0 +1,20 @@ +const express = require("express"); +const { ApolloServer, gql } = require("apollo-server-express"); + +// Construct a schema, using GraphQL schema language +const typeDefs = gql` + type Query { + hello: String + } +`; + +// Provide resolver functions for your schema fields +const resolvers = { + Query: { + hello: () => "Hello world!", + }, +}; + +const server = new ApolloServer({ typeDefs, resolvers }); +const app = express(); +server.applyMiddleware({ app }); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/argon2.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/argon2.js new file mode 100644 index 0000000000000..51c61e724cf72 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/argon2.js @@ -0,0 +1,2 @@ +const argon2 = require("argon2"); +console.log("argon is " + typeof argon2); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/dynamic/index.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/dynamic/index.js new file mode 100644 index 0000000000000..f6845aa698dfd --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/dynamic/index.js @@ -0,0 +1,16 @@ +const fs = require("fs"); + +const FILES = ["../lib/a.js", "../lib/b.js"].map(function (file) { + return require.resolve(file); +}); + +new Function( + "module", + (function () { + var code = FILES.map(function (file) { + return fs.readFileSync(file, "utf8"); + }); + code.push("module.exports = evaluate;"); + return code.join("\n\n"); + })() +)(module); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/index.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/index.js new file mode 100644 index 0000000000000..445cc6ac21604 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/index.js @@ -0,0 +1,3 @@ +const evaluate = require("./dynamic"); + +console.log(evaluate(10, 20)); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/lib/a.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/lib/a.js new file mode 100644 index 0000000000000..c7e721dbfd582 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/lib/a.js @@ -0,0 +1,3 @@ +function mul(a, b) { + return a * b; +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/lib/b.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/lib/b.js new file mode 100644 index 0000000000000..904ed3762473d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/array-map-require/lib/b.js @@ -0,0 +1,3 @@ +function evaluate(a, b) { + return a + mul(a, b); +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/auth0.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/auth0.js new file mode 100644 index 0000000000000..f33d51479e8f8 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/auth0.js @@ -0,0 +1,9 @@ +const ManagementClient = require("auth0").ManagementClient; + +try { + new ManagementClient(); +} catch (err) { + if (!/Management API SDK options must be an object/.test(err.message)) { + throw err; + } +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/aws-sdk.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/aws-sdk.js new file mode 100644 index 0000000000000..c03ae9e62a620 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/aws-sdk.js @@ -0,0 +1,3 @@ +const aws = require("aws-sdk"); + +new aws.S3(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/axios.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/axios.js new file mode 100644 index 0000000000000..3afd601dc3d64 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/axios.js @@ -0,0 +1,10 @@ +const axios = require("axios"); + +(async () => { + const { data } = await axios({ + url: "https://dog.ceo/api/breeds/image/random", + }); + if (data.status !== "success") { + throw new Error("Unexpected response: " + JSON.stringify(data)); + } +})(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/azure-cosmos.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/azure-cosmos.js new file mode 100644 index 0000000000000..ad1313851a3f3 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/azure-cosmos.js @@ -0,0 +1 @@ +require("@azure/cosmos"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/azure-storage.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/azure-storage.js new file mode 100644 index 0000000000000..18c07bb198dfc --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/azure-storage.js @@ -0,0 +1 @@ +require("azure-storage"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/bcrypt.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/bcrypt.js new file mode 100644 index 0000000000000..237aa1d22f18b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/bcrypt.js @@ -0,0 +1,8 @@ +const bcrypt = require("bcrypt"); + +// bcrypt.genSaltSync(10) +const salt = "$2b$10$V/DVgHU.feqOSsssV5gHY."; + +bcrypt.hash("pass", salt).then(function (hash) { + console.log(hash); +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/better-sqlite3.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/better-sqlite3.js new file mode 100644 index 0000000000000..22ee15735cea1 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/better-sqlite3.js @@ -0,0 +1,10 @@ +const { tmpdir } = require("os"); +const { join } = require("path"); + +const Database = require("better-sqlite3"); + +const database = new Database(join(tmpdir(), "db"), { + fileMustExist: false, +}); + +console.log(database.name); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/bindings-failure.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/bindings-failure.js new file mode 100644 index 0000000000000..bce5269605119 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/bindings-failure.js @@ -0,0 +1 @@ +require("bindings")("not-found"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/browserify-middleware.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/browserify-middleware.js new file mode 100644 index 0000000000000..a2b7a5870555d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/browserify-middleware.js @@ -0,0 +1 @@ +require("browserify-middleware"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/bugsnag-js.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/bugsnag-js.js new file mode 100644 index 0000000000000..70219374768b6 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/bugsnag-js.js @@ -0,0 +1,3 @@ +require("@bugsnag/js"); + +module.exports = () => {}; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/bull.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/bull.js new file mode 100644 index 0000000000000..bdf4200d069e2 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/bull.js @@ -0,0 +1,20 @@ +const { BULL_REDIS_CONNECTION } = process.env; + +if (!BULL_REDIS_CONNECTION) { + console.log("Skipping bull integration test"); + console.log( + 'Create cache on redislabs.com and export BULL_REDIS_CONNECTION="redis://:password@hostname:port"' + ); + return; +} + +const Queue = require("bull"); +const pdfQueue = new Queue("pdf transcoding", BULL_REDIS_CONNECTION); + +pdfQueue.process(function (job, done) { + job.progress(42); + done(); + pdfQueue.close(); +}); + +pdfQueue.add({ pdf: "http://example.com/file.pdf" }); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/bullmq.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/bullmq.js new file mode 100644 index 0000000000000..976ad4bcbbc49 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/bullmq.js @@ -0,0 +1,30 @@ +const { BULL_REDIS_CONNECTION } = process.env; + +if (!BULL_REDIS_CONNECTION) { + console.log("Skipping bullmq integration test"); + console.log( + 'Create cache on redislabs.com and export BULL_REDIS_CONNECTION="redis://:password@hostname:port"' + ); + return; +} + +const url = new URL(BULL_REDIS_CONNECTION); +const connection = { + username: url.username, + password: url.password, + host: url.hostname, + port: Number(url.port), +}; + +const { Queue } = require("bullmq"); + +async function main() { + const queue = new Queue("foo", { connection }); + await queue.add("job", { id: "one" }); + await queue.add("job", { id: "two" }); + await queue.close(); +} + +main() + .then(() => console.log("bullmq success")) + .catch(console.error); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/camaro.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/camaro.js new file mode 100644 index 0000000000000..b4359e9631062 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/camaro.js @@ -0,0 +1 @@ +require("camaro"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/canvas.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/canvas.js new file mode 100644 index 0000000000000..7dd18002507aa --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/canvas.js @@ -0,0 +1,6 @@ +const canvas = require("canvas"); +module.exports = () => { + const { createCanvas } = canvas; + const c = createCanvas(200, 200); + const ctx = c.getContext("2d"); +}; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/chromeless.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/chromeless.js new file mode 100644 index 0000000000000..712ebf1d45205 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/chromeless.js @@ -0,0 +1 @@ +require("chromeless"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/content/hello.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/content/hello.json new file mode 100644 index 0000000000000..f2a886f39de7d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/content/hello.json @@ -0,0 +1,3 @@ +{ + "hello": "world" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/core-js.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/core-js.js new file mode 100644 index 0000000000000..c8a5b90f93e08 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/core-js.js @@ -0,0 +1 @@ +require("core-js").Array.map([], () => {}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/cosmosdb-query.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/cosmosdb-query.js new file mode 100644 index 0000000000000..7f8a6d792dbd0 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/cosmosdb-query.js @@ -0,0 +1,8 @@ +const { default: query } = require("@zeit/cosmosdb-query"); + +const items = [{ id: "foo" }, { id: "bar" }]; + +const { result } = query("SELECT * FROM c WHERE c.id = @id").exec(items, { + parameters: [{ name: "@id", value: "foo" }], +}); +console.log(result); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/cowsay.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/cowsay.js new file mode 100644 index 0000000000000..e2a9749b78050 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/cowsay.js @@ -0,0 +1,6 @@ +const { say } = require("cowsay"); + +const nate = say({ text: "nate" }); +if (!(nate.indexOf("nate") > 0)) { + throw new Error('cowsay did not work. String "nate" not found in: ' + nate); +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/dogfood.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/dogfood.js new file mode 100644 index 0000000000000..6e75ca7b878ef --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/dogfood.js @@ -0,0 +1 @@ +require("../../out/node-file-trace"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/dynamic-in-package.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/dynamic-in-package.js new file mode 100644 index 0000000000000..0d38a2c76c27d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/dynamic-in-package.js @@ -0,0 +1,3 @@ +let imp = (path) => import(`unified/${path}.js`); + +imp("index"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/empty.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/empty.js new file mode 100644 index 0000000000000..5bb5f1fe0769d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/empty.js @@ -0,0 +1 @@ +console.log("simple"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/env-var.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/env-var.js new file mode 100644 index 0000000000000..ae4f5c3ccde39 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/env-var.js @@ -0,0 +1,3 @@ +const env = (process.env.NODE_ENV = "development"); + +module.exports = env; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/es-get-iterator.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/es-get-iterator.js new file mode 100644 index 0000000000000..d172b3c26f183 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/es-get-iterator.js @@ -0,0 +1 @@ +require("es-get-iterator"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/esbuild.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/esbuild.js new file mode 100644 index 0000000000000..4f2015bc51110 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/esbuild.js @@ -0,0 +1,13 @@ +const { buildSync } = require("esbuild"); +const { join } = require("path"); + +const entry = join(__dirname, "..", "package.json"); + +const result = buildSync({ + entryPoints: [entry], + write: false, +}); + +if (!result) { + throw new Error("esbuild failed"); +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/esm.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/esm.js new file mode 100644 index 0000000000000..ed7bd78a2d9b6 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/esm.js @@ -0,0 +1,3 @@ +require = require("esm")(module); +const assert = require("assert"); +assert.equal(require("./fixtures/es-module.js").p, 5); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/express-consolidate.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/express-consolidate.js new file mode 100644 index 0000000000000..5fd0e4d24a249 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/express-consolidate.js @@ -0,0 +1,21 @@ +const assert = require("assert"); +var express = require("express"), + cons = require("consolidate"), + app = express(); + +// assign the swig engine to .html files +app.engine("html", cons.swig); + +// set .html as the default extension +app.set("view engine", "html"); +app.set("views", __dirname + "/fixtures" + "/html"); + +app.render( + "index", + { + title: "Consolidate.js", + }, + function (err, rendered) { + assert.ok(rendered.startsWith("

    Consolidate.js

    ")); + } +); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/express-template-engine.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/express-template-engine.js new file mode 100644 index 0000000000000..082e1146692b5 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/express-template-engine.js @@ -0,0 +1,22 @@ +const assert = require("assert"); +const express = require("express"); +const path = require("path"); + +const app = express(); + +function customImplementation() {} + +app.engine("pug", customImplementation); +app.set("view engine", "pug"); +app.set("views", path.join(__dirname, "fixtures", "pug")); + +app.render( + "index", + { + title: "Consolidate.js", + }, + function (err, rendered) { + if (err) throw err; + assert.ok(rendered === undefined); + } +); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/express-template.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/express-template.js new file mode 100644 index 0000000000000..3dc27dabe5dd1 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/express-template.js @@ -0,0 +1,20 @@ +const assert = require("assert"); +const express = require("express"); +const path = require("path"); + +const app = express(); + +app.engine("pug", require("pug").__express); +app.set("view engine", "pug"); +app.set("views", "./fixtures/pug"); + +app.render( + "index", + { + title: "Consolidate.js", + }, + function (err, rendered) { + if (err) throw err; + assert.ok(rendered.includes("

    Consolidate.js

    ")); + } +); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/express.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/express.js new file mode 100644 index 0000000000000..6c2d79a242be9 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/express.js @@ -0,0 +1 @@ +const app = require("express"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/fast-glob.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/fast-glob.js new file mode 100644 index 0000000000000..0ba021d83be57 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/fast-glob.js @@ -0,0 +1 @@ +require("fast-glob"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/fetch-h2.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/fetch-h2.js new file mode 100644 index 0000000000000..9b5617dc8c5c4 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/fetch-h2.js @@ -0,0 +1 @@ +const fetch = require("fetch-h2"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ffmpeg.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ffmpeg.js new file mode 100644 index 0000000000000..f72ff3b3d51f8 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ffmpeg.js @@ -0,0 +1 @@ +let { path } = require("@ffmpeg-installer/ffmpeg"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/firebase-admin.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/firebase-admin.js new file mode 100644 index 0000000000000..e54a2d77b3072 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/firebase-admin.js @@ -0,0 +1 @@ +require("firebase-admin"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/firebase.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/firebase.js new file mode 100644 index 0000000000000..beb54c8f96f8d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/firebase.js @@ -0,0 +1,28 @@ +const firebase = require("firebase/app"); +require("firebase/firestore"); +require("firebase/database"); + +firebase.initializeApp({ projectId: "noop" }); +const store = firebase.firestore(); + +store + .collection("users") + .get() + .then( + () => { + process.exit(0); + }, + (e) => { + /* + Error: unresolvable extensions: 'extend google.protobuf.MethodOptions' in .google.api + at Root.resolveAll (/private/var/folders/c3/vytj6_h56b77f_g72smntm3m0000gn/T/node_modules/protobufjs/src/root.js:243:1) + at Object.loadSync (/private/var/folders/c3/vytj6_h56b77f_g72smntm3m0000gn/T/a707d6b7ee4afe5b484993180e617e2d/index.js:43406:16) + at loadProtos (/private/var/folders/c3/vytj6_h56b77f_g72smntm3m0000gn/T/a707d6b7ee4afe5b484993180e617e2d/index.js:16778:41) + at NodePlatform.module.exports.278.NodePlatform.loadConnection (/private/var/folders/c3/vytj6_h56b77f_g72smntm3m0000gn/T/a707d6b7ee4afe5b484993180e617e2d/index.js:16815:22) + at FirestoreClient.module.exports.278.FirestoreClient.initializeRest (/private/var/folders/c3/vytj6_h56b77f_g72smntm3m0000gn/T/a707d6b7ee4afe5b484993180e617e2d/index.js:28414:14) + at /private/var/folders/c3/vytj6_h56b77f_g72smntm3m0000gn/T/a707d6b7ee4afe5b484993180e617e2d/index.js:28239:64 + */ + console.error(e); + process.exit(1); + } + ); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/firestore.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/firestore.js new file mode 100644 index 0000000000000..e8de04a5e8f85 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/firestore.js @@ -0,0 +1 @@ +require("@google-cloud/firestore"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/es-module-dep.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/es-module-dep.js new file mode 100644 index 0000000000000..1413bf5968ad7 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/es-module-dep.js @@ -0,0 +1 @@ +export var p = 5; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/es-module.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/es-module.js new file mode 100644 index 0000000000000..b6937e2e51bda --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/es-module.js @@ -0,0 +1 @@ +export { p } from "./es-module-dep.js"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/html/index.html b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/html/index.html new file mode 100644 index 0000000000000..b6515528b8cc3 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/html/index.html @@ -0,0 +1 @@ +

    {{ title }}

    diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/pug/index.pug b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/pug/index.pug new file mode 100644 index 0000000000000..b0f02dc34753d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/pug/index.pug @@ -0,0 +1,5 @@ +html + head + title= title + body + h1= title \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/vercel.svg b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/vercel.svg new file mode 100644 index 0000000000000..76bea97e3e9a8 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/fixtures/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/fluent-ffmpeg.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/fluent-ffmpeg.js new file mode 100644 index 0000000000000..38b6d9c92ad8c --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/fluent-ffmpeg.js @@ -0,0 +1,2 @@ +const ffmpeg = require("fluent-ffmpeg"); +const proc = new ffmpeg({ source: "wat", nolog: true }); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/geo-tz.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/geo-tz.js new file mode 100644 index 0000000000000..58247ce4c821c --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/geo-tz.js @@ -0,0 +1,2 @@ +const { find } = require("geo-tz"); +const timezones = find(-21.2377437, 55.48997639438238); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/google-bigquery.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/google-bigquery.js new file mode 100644 index 0000000000000..fc326c087b534 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/google-bigquery.js @@ -0,0 +1,5 @@ +const { BigQuery } = require("@google-cloud/bigquery"); + +const bigquery = new BigQuery({ + projectId: "PROJECT_ID", +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/got.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/got.js new file mode 100644 index 0000000000000..00b0bc10f5bd8 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/got.js @@ -0,0 +1 @@ +require("got"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/highlights.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/highlights.js new file mode 100644 index 0000000000000..88b0a485529bd --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/highlights.js @@ -0,0 +1,6 @@ +const Highlights = require("highlights"); +const highlighter = new Highlights(); +highlighter.highlightSync({ + fileContents: 'var hello = "world";', + scopeName: "source.js", +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/hot-shots.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/hot-shots.js new file mode 100644 index 0000000000000..18967bedaaf5d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/hot-shots.js @@ -0,0 +1 @@ +require("hot-shots"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ioredis.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ioredis.js new file mode 100644 index 0000000000000..38ccc0d55b431 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ioredis.js @@ -0,0 +1 @@ +const ioredis = require("ioredis"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/isomorphic-unfetch.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/isomorphic-unfetch.js new file mode 100644 index 0000000000000..8cc132f6afc49 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/isomorphic-unfetch.js @@ -0,0 +1,9 @@ +const fetch = require("isomorphic-unfetch"); + +(async () => { + const res = await fetch("https://dog.ceo/api/breeds/image/random"); + const data = await res.json(); + if (data.status !== "success") { + throw new Error("Unexpected response: " + JSON.stringify(data)); + } +})(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/jimp.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/jimp.js new file mode 100644 index 0000000000000..904a73e871481 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/jimp.js @@ -0,0 +1 @@ +const jimp = require("jimp"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/jugglingdb.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/jugglingdb.js new file mode 100644 index 0000000000000..7bb2449c09d38 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/jugglingdb.js @@ -0,0 +1,2 @@ +require("jugglingdb"); +module.exports = () => {}; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/koa.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/koa.js new file mode 100644 index 0000000000000..8015588926f95 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/koa.js @@ -0,0 +1,3 @@ +const Koa = require("koa"); + +new Koa(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/leveldown.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/leveldown.js new file mode 100644 index 0000000000000..f517739fb0b10 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/leveldown.js @@ -0,0 +1,2 @@ +const leveldown = require("leveldown"); +const db = leveldown("tmp/db"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/lighthouse.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/lighthouse.js new file mode 100644 index 0000000000000..3594f9575bc3d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/lighthouse.js @@ -0,0 +1 @@ +require("lighthouse"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/loopback.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/loopback.js new file mode 100644 index 0000000000000..e925de5360d18 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/loopback.js @@ -0,0 +1 @@ +require("loopback"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mailgun.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/mailgun.js new file mode 100644 index 0000000000000..16bbb9fdbb199 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mailgun.js @@ -0,0 +1 @@ +const mailgun = require("mailgun"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mariadb.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/mariadb.js new file mode 100644 index 0000000000000..2e728352df293 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mariadb.js @@ -0,0 +1 @@ +require("mariadb"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/example.mdx b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/example.mdx new file mode 100644 index 0000000000000..163fe309116c9 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/example.mdx @@ -0,0 +1,10 @@ +import { Chart } from "./snowfall.js"; +export const year = 2018; + +# Last year’s snowfall + +In {year}, the snowfall was above average. +It was followed by a warm spring which caused +flood conditions in many of the nearby rivers. + + diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/index.cjs b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/index.cjs new file mode 100644 index 0000000000000..a453cd7ba637d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/index.cjs @@ -0,0 +1,15 @@ +const os = require("os"); + +// also trace the react and react/jsx-runtime +require("react"); +require("react/jsx-runtime"); + +import("@mdx-js/node-loader"); + +import("./mdx.js"); + +const { existsSync } = eval("require")("fs"); + +if (__dirname.startsWith(os.tmpdir()) && existsSync("./snowfall.jsx")) { + throw new Error("snowfall.jsx should not exist"); +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/mdx.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/mdx.js new file mode 100644 index 0000000000000..9a5f1d36f61bc --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/mdx.js @@ -0,0 +1 @@ +import Example from "./example.mdx"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/package.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/package.json new file mode 100644 index 0000000000000..cc4876a4c4aa5 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/package.json @@ -0,0 +1,5 @@ +{ + "version": "0.0.0", + "name": "@turbo/tracing-mdx-test", + "type": "module" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/snowfall.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/snowfall.js new file mode 100644 index 0000000000000..e50ce9d03290a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mdx/snowfall.js @@ -0,0 +1,3 @@ +export function Chart({ year, color }) { + return { year } - { color }; +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/memcached.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/memcached.js new file mode 100644 index 0000000000000..6f5290f7716ef --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/memcached.js @@ -0,0 +1,2 @@ +const Memcached = require("memcached"); +Memcached.config.poolSize = 25; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mongoose.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/mongoose.js new file mode 100644 index 0000000000000..51c807357faab --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mongoose.js @@ -0,0 +1,15 @@ +const mongoose = require("mongoose"); +const Schema = mongoose.Schema; + +const blogSchema = new Schema({ + title: String, + author: String, + body: String, + comments: [{ body: String, date: Date }], + date: { type: Date, default: Date.now }, + hidden: Boolean, + meta: { + votes: Number, + favs: Number, + }, +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/mysql.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/mysql.js new file mode 100644 index 0000000000000..524c08197bb02 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/mysql.js @@ -0,0 +1,8 @@ +const mysql = require("mysql"); + +var connection = mysql.createConnection({ + host: "localhost", + user: "me", + password: "secret", + database: "my_db", +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/npm.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/npm.js new file mode 100644 index 0000000000000..69b0a0e7a8d33 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/npm.js @@ -0,0 +1,18 @@ +const npm = require("npm"); +const install = require("npm/lib/install"); +const rimraf = require("rimraf"); + +npm.load((err) => { + if (err) { + throw err; + } + npm.config.set("audit", false); + npm.config.set("package-lock", false); + npm.config.set("progress", false); + if (process.env.NPM_REGISTRY_URL) { + npm.config.set("registry", process.env.NPM_REGISTRY_URL); + } + const args = [`lodash@4.1.17`]; + install("./asdf", args, () => {}); + rimraf.sync("./asdf"); +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/oracledb.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/oracledb.js new file mode 100644 index 0000000000000..67c4924252d98 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/oracledb.js @@ -0,0 +1 @@ +require("oracledb"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/fail/alt-folders-multiple.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/fail/alt-folders-multiple.js new file mode 100644 index 0000000000000..ca7fdeeb27212 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/fail/alt-folders-multiple.js @@ -0,0 +1,3 @@ +import { alt1 } from "fixtures/alt-folders/alt1.js"; +import { alt2 } from "fixtures/alt-folders/alt2.js"; +console.log(alt1, alt2); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/fail/alt-multiple.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/fail/alt-multiple.js new file mode 100644 index 0000000000000..c56db3ba2dd60 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/fail/alt-multiple.js @@ -0,0 +1,3 @@ +import { alt1 } from "fixtures/alt/alt1"; +import { alt2 } from "fixtures/alt/alt2"; +console.log(alt1, alt2); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixture-single-export/package.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixture-single-export/package.json new file mode 100644 index 0000000000000..4b4762e726c2f --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixture-single-export/package.json @@ -0,0 +1,4 @@ +{ + "type": "module", + "exports": "./root.js" +} \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixture-single-export/root.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixture-single-export/root.js new file mode 100644 index 0000000000000..b10a2a48b0590 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixture-single-export/root.js @@ -0,0 +1 @@ +export const root = "root" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/alt1/alt1.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/alt1/alt1.js new file mode 100644 index 0000000000000..dc9c8f2040a2e --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/alt1/alt1.js @@ -0,0 +1 @@ +export const alt1 = "alt1" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/alt2/alt2.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/alt2/alt2.js new file mode 100644 index 0000000000000..d4eadada7229b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/alt2/alt2.js @@ -0,0 +1 @@ +export const alt2 = "alt2" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/catch-all.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/catch-all.js new file mode 100644 index 0000000000000..74cf7f12af547 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/catch-all.js @@ -0,0 +1 @@ +export const catchAll = "catchAll" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/direct-renamed.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/direct-renamed.js new file mode 100644 index 0000000000000..29237a50e3fde --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/direct-renamed.js @@ -0,0 +1 @@ +export const direct = "direct" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/double/sub/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/double/sub/sub.js new file mode 100644 index 0000000000000..b186f15cc85b6 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/double/sub/sub.js @@ -0,0 +1 @@ +export const doubleSub = "doubleSub" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/nested-renamed/once/mod.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/nested-renamed/once/mod.js new file mode 100644 index 0000000000000..96913dd7cb39e --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/nested-renamed/once/mod.js @@ -0,0 +1 @@ +export const nestedOnce = "nestedOnce" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/package.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/package.json new file mode 100644 index 0000000000000..aa11f5be8054a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/package.json @@ -0,0 +1,19 @@ +{ + "type": "module", + "exports": { + ".": "./root.js", + "./direct": "./direct-renamed.js", + "./folder/": "./alt1/", + "./alt-folders/": ["./alt1/", "./alt2/"], + "./alt/*": ["./alt1/*.js", "./alt2/*.js"], + "./catch-all*": "./catch-all.js", + "./double/*": "./double/*/*.js", + "./nested/*": "./nested-renamed/*.js", + "./@*@": "./sub-infix/*.js", + "./@/*/@": "./sub-infix-sep/*.js", + "./*@": "./sub-prefix/*.js", + "./*/@": "./sub-prefix-sep/*.js", + "./@*": "./sub-suffix/*.js", + "./@/*": "./sub-suffix-sep/*.js" + } +} \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/root.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/root.js new file mode 100644 index 0000000000000..b10a2a48b0590 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/root.js @@ -0,0 +1 @@ +export const root = "root" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-infix-sep/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-infix-sep/sub.js new file mode 100644 index 0000000000000..7f2ad0333d834 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-infix-sep/sub.js @@ -0,0 +1 @@ +export const subInfixSep = "subInfixSep" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-infix/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-infix/sub.js new file mode 100644 index 0000000000000..28a77cf08c1fc --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-infix/sub.js @@ -0,0 +1 @@ +export const subInfix = "subInfix" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-prefix-sep/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-prefix-sep/sub.js new file mode 100644 index 0000000000000..75b8d9b7b6ae6 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-prefix-sep/sub.js @@ -0,0 +1 @@ +export const subPrefixSep = "subPrefixSep" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-prefix/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-prefix/sub.js new file mode 100644 index 0000000000000..3a595808ebd34 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-prefix/sub.js @@ -0,0 +1 @@ +export const subPrefix = "subPrefix" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-suffix-sep/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-suffix-sep/sub.js new file mode 100644 index 0000000000000..5b3516f148ee1 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-suffix-sep/sub.js @@ -0,0 +1 @@ +export const subSuffixSep = "subSuffixSep" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-suffix/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-suffix/sub.js new file mode 100644 index 0000000000000..76f23787c2907 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/node_modules/fixtures/sub-suffix/sub.js @@ -0,0 +1 @@ +export const subSuffix = "subSuffix" \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/package.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/package.json new file mode 100644 index 0000000000000..3dbc1ca591c05 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/package.json @@ -0,0 +1,3 @@ +{ + "type": "module" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/alt-folders.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/alt-folders.js new file mode 100644 index 0000000000000..ac4e7344643fc --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/alt-folders.js @@ -0,0 +1,2 @@ +import { alt1 } from "fixtures/alt-folders/alt1.js"; +console.log(alt1); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/alt.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/alt.js new file mode 100644 index 0000000000000..1c4e0915c4bd0 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/alt.js @@ -0,0 +1,2 @@ +import { alt1 } from "fixtures/alt/alt1"; +console.log(alt1); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/catch-all.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/catch-all.js new file mode 100644 index 0000000000000..4ba0a3b1a4045 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/catch-all.js @@ -0,0 +1,3 @@ +import { catchAll as catchAll1 } from "fixtures/catch-all1"; +import { catchAll as catchAll2 } from "fixtures/catch-all2"; +console.log(catchAll1, catchAll2); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/direct.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/direct.js new file mode 100644 index 0000000000000..362beae996c6e --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/direct.js @@ -0,0 +1,2 @@ +import { direct } from "fixtures/direct"; +console.log(direct); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/double.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/double.js new file mode 100644 index 0000000000000..edfc2c057935b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/double.js @@ -0,0 +1,2 @@ +import { doubleSub } from "fixtures/double/sub"; +console.log(doubleSub); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/folder.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/folder.js new file mode 100644 index 0000000000000..4be62f8b30b58 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/folder.js @@ -0,0 +1,2 @@ +import { alt1 } from "fixtures/folder/alt1.js"; +console.log(alt1); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/nested.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/nested.js new file mode 100644 index 0000000000000..d23b57eb56529 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/nested.js @@ -0,0 +1,2 @@ +import { nestedOnce } from "fixtures/nested/once/mod"; +console.log(nestedOnce); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/root.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/root.js new file mode 100644 index 0000000000000..caac7d5736283 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/root.js @@ -0,0 +1,2 @@ +import { root } from "fixtures"; +console.log(root); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/single-export-root.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/single-export-root.js new file mode 100644 index 0000000000000..b2a6077e256b4 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/single-export-root.js @@ -0,0 +1,2 @@ +import { root } from "fixture-single-export"; +console.log(root); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-infix-sep.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-infix-sep.js new file mode 100644 index 0000000000000..358683b93b776 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-infix-sep.js @@ -0,0 +1,2 @@ +import { subInfixSep } from "fixtures/@/sub/@"; +console.log(subInfixSep); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-infix.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-infix.js new file mode 100644 index 0000000000000..9eda3689d1a3b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-infix.js @@ -0,0 +1,2 @@ +import { subInfix } from "fixtures/@sub@"; +console.log(subInfix); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-prefix-sep.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-prefix-sep.js new file mode 100644 index 0000000000000..e8ffa03e89d79 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-prefix-sep.js @@ -0,0 +1,2 @@ +import { subPrefixSep } from "fixtures/sub/@"; +console.log(subPrefixSep); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-prefix.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-prefix.js new file mode 100644 index 0000000000000..79d07ad375a7a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-prefix.js @@ -0,0 +1,2 @@ +import { subPrefix } from "fixtures/sub@"; +console.log(subPrefix); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-suffix-sep.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-suffix-sep.js new file mode 100644 index 0000000000000..af921ffe5ee22 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-suffix-sep.js @@ -0,0 +1,2 @@ +import { subSuffixSep } from "fixtures/@/sub"; +console.log(subSuffixSep); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-suffix.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-suffix.js new file mode 100644 index 0000000000000..cb912262c9f7d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/package-exports/pass/sub-suffix.js @@ -0,0 +1,2 @@ +import { subSuffix } from "fixtures/@sub"; +console.log(subSuffix); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/paraphrase.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/paraphrase.js new file mode 100644 index 0000000000000..7d19ba348a90d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/paraphrase.js @@ -0,0 +1 @@ +const paraphrase = require("paraphrase/percent"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/passport-trakt.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/passport-trakt.js new file mode 100644 index 0000000000000..787b862b7b23a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/passport-trakt.js @@ -0,0 +1,2 @@ +require("passport"); +require("passport-trakt"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/passport.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/passport.js new file mode 100644 index 0000000000000..52fdb1e0df0ed --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/passport.js @@ -0,0 +1,2 @@ +require("passport"); +require("passport-google-oauth"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/path-platform.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/path-platform.js new file mode 100644 index 0000000000000..71f0c8cdc3386 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/path-platform.js @@ -0,0 +1 @@ +require("path-platform"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pdf2json.mjs b/turbopack/crates/turbopack/tests/node-file-trace/integration/pdf2json.mjs new file mode 100644 index 0000000000000..16d07b392d32b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pdf2json.mjs @@ -0,0 +1,8 @@ +import { parse } from "url"; +import PDFParser from "pdf2json"; + +export default function (req, res) { + const { query } = parse(req.url, true); + const { name = "World" } = query; + res.end(`Hello ${name}!`); +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pdfkit.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/pdfkit.js new file mode 100644 index 0000000000000..02bc913a6dfe7 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pdfkit.js @@ -0,0 +1,6 @@ +const fs = require("fs"); +const PDFDocument = require("pdfkit"); + +const doc = new PDFDocument(); +doc.fontSize(15).text("Hi there", 50, 50); +doc.end(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pg.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/pg.js new file mode 100644 index 0000000000000..5e4bc326ae363 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pg.js @@ -0,0 +1,2 @@ +const { Client } = require("pg"); +const client = new Client(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pixelmatch.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/pixelmatch.js new file mode 100644 index 0000000000000..ae0a7598c1b92 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pixelmatch.js @@ -0,0 +1,3 @@ +const pixelmatch = require("pixelmatch"); + +pixelmatch(new Uint8Array(), new Uint8Array(), null, 0, 0); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/playwright-core.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/playwright-core.js new file mode 100644 index 0000000000000..a21210d7fe968 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/playwright-core.js @@ -0,0 +1,7 @@ +const playwright = require("playwright-core"); + +if (playwright.chromium.name() !== "chromium") + throw new Error("playwright-core: could not get name"); + +if (!playwright.chromium.executablePath()) + throw new Error("playwright-core: could not get executablePath"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/foo/index.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/foo/index.js new file mode 100644 index 0000000000000..465beeef5367f --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/foo/index.js @@ -0,0 +1,3 @@ +const { map } = require('lodash-pnpm-test') + +module.exports.foo = function foo(arr) { return map(arr, (item) => item + 1) }; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/foo/package.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/foo/package.json new file mode 100644 index 0000000000000..269450ab0399b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/foo/package.json @@ -0,0 +1,5 @@ +{ + "name": "foo", + "version": "2.1.0", + "main": "./index.js" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/lodash-pnpm-test b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/lodash-pnpm-test new file mode 120000 index 0000000000000..7975b9568ca6e --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/foo@2.1.0/node_modules/lodash-pnpm-test @@ -0,0 +1 @@ +../../lodash-pnpm-test@1.0.0/node_modules/lodash-pnpm-test \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/lodash-pnpm-test@1.0.0/node_modules/lodash-pnpm-test/index.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/lodash-pnpm-test@1.0.0/node_modules/lodash-pnpm-test/index.js new file mode 100644 index 0000000000000..67943294b2a3a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/lodash-pnpm-test@1.0.0/node_modules/lodash-pnpm-test/index.js @@ -0,0 +1 @@ +module.exports.map = function map(arr, func) { return arr.map(func) }; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/lodash-pnpm-test@1.0.0/node_modules/lodash-pnpm-test/package.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/lodash-pnpm-test@1.0.0/node_modules/lodash-pnpm-test/package.json new file mode 100644 index 0000000000000..00e0315072df2 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/.pnpm/lodash-pnpm-test@1.0.0/node_modules/lodash-pnpm-test/package.json @@ -0,0 +1,5 @@ +{ + "name": "lodash-pnpm-test", + "version": "1.0.0", + "main": "./index.js" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/foo b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/foo new file mode 120000 index 0000000000000..4fe71b63dd6eb --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/node_modules/foo @@ -0,0 +1 @@ +.pnpm/foo@2.1.0/node_modules/foo \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/pnpm-like.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/pnpm-like.js new file mode 100644 index 0000000000000..af1f83a4ead22 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pnpm/pnpm-like.js @@ -0,0 +1,3 @@ +const { foo } = require("foo"); + +console.log(foo([1, 2, 3])); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/polyfill-library.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/polyfill-library.js new file mode 100644 index 0000000000000..81b9609f66371 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/polyfill-library.js @@ -0,0 +1,13 @@ +const polyfill = require("polyfill-library"); + +async function handler() { + const script = await polyfill.getPolyfillString({ + minify: false, + features: { es6: { flags: ["gated"] } }, + }); + return script; +} + +handler() + .then((script) => console.log(typeof script)) + .catch(console.error); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/pug.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/pug.js new file mode 100644 index 0000000000000..5240b3232d1ea --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/pug.js @@ -0,0 +1,2 @@ +const pug = require("pug"); +pug.compile("string of pug"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/react.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/react.js new file mode 100644 index 0000000000000..01cff3775a13a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/react.js @@ -0,0 +1,7 @@ +const React = require("react"); +const { renderToString } = require("react-dom/server"); + +const html = renderToString(React.createElement("h1")); +if (html !== '

    ') { + throw new Error("Bad react SSR: " + html); +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/read-file.mjs b/turbopack/crates/turbopack/tests/node-file-trace/integration/read-file.mjs new file mode 100644 index 0000000000000..ef14cbd36fa6d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/read-file.mjs @@ -0,0 +1,10 @@ +import fs from "fs"; +import path from "path"; + +function getData() { + return JSON.parse( + fs.readFileSync(path.join(process.cwd(), "content/hello.json"), "utf8") + ); +} + +console.log(getData()); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/redis.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/redis.js new file mode 100644 index 0000000000000..4a70187e7ce32 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/redis.js @@ -0,0 +1,3 @@ +const redis = require("redis"); + +redis.add_command("test"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/remark-prism.mjs b/turbopack/crates/turbopack/tests/node-file-trace/integration/remark-prism.mjs new file mode 100644 index 0000000000000..4b0037ef0b0fa --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/remark-prism.mjs @@ -0,0 +1,7 @@ +import { unified } from "unified"; +import parse from "remark-parse"; +import prism from "remark-prism"; + +const engine = unified().use(parse).use(prism); +const ast = engine.parse("# markdown"); +engine.runSync(ast); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/request.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/request.js new file mode 100644 index 0000000000000..e16c081c79c1f --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/request.js @@ -0,0 +1,14 @@ +const request = require("request"); +const url = "https://dog.ceo/api/breeds/image/random"; + +(async () => { + await new Promise((resolve, reject) => { + request.get(url, { json: true }, (err, resp, body) => { + if (err) return reject(err); + if (body.status != "success") { + return reject(new Error("Bad api response: " + JSON.stringify(body))); + } + resolve(); + }); + }); +})(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/rxjs.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/rxjs.js new file mode 100644 index 0000000000000..44a641654a435 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/rxjs.js @@ -0,0 +1,9 @@ +const { Observable, Subject, ReplaySubject, from, of, range } = require("rxjs"); +const { map, filter, switchMap } = require("rxjs/operators"); + +range(1, 200) + .pipe( + filter((x) => x % 2 === 1), + map((x) => x + x) + ) + .subscribe((x) => x); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/saslprep.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/saslprep.js new file mode 100644 index 0000000000000..b5896c7f49bab --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/saslprep.js @@ -0,0 +1,3 @@ +const saslprep = require("saslprep"); + +saslprep("password\u00AD"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/semver.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/semver.js new file mode 100644 index 0000000000000..1f628dca28a9f --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/semver.js @@ -0,0 +1,9 @@ +const semver = require("semver"); + +const v1 = "1.0.0"; +const v2 = "2.0.0"; + +semver.gt(v1, v2); +semver.lt(v1, v2); +semver.eq(v1, v2); +semver.coerce(v1); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/sentry.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/sentry.js new file mode 100644 index 0000000000000..b0eb9964e8b90 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/sentry.js @@ -0,0 +1 @@ +const sentry = require("@sentry/node"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/sequelize.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/sequelize.js new file mode 100644 index 0000000000000..c85416eea9ffd --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/sequelize.js @@ -0,0 +1,6 @@ +const Sequelize = require("sequelize"); + +const db = new Sequelize({ + dialect: "mariadb", + dialectModule: require("mariadb"), +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/sharp.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/sharp.js new file mode 100644 index 0000000000000..10704fcda3f81 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/sharp.js @@ -0,0 +1,13 @@ +const sharp = require("sharp"); +const path = require("path"); + +const roundedCorners = Buffer.from( + '' +); + +sharp(roundedCorners).resize(200, 200).png().toBuffer(); + +sharp(path.resolve(__dirname, "fixtures/vercel.svg")) + .resize({ width: 100, height: 100 }) + .jpeg() + .toBuffer(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/simple.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/simple.js new file mode 100644 index 0000000000000..6cd2b533a5403 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/simple.js @@ -0,0 +1,2 @@ +require("./empty.js"); +console.log("simple"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/socket.io.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/socket.io.js new file mode 100644 index 0000000000000..5e8181f54b0fc --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/socket.io.js @@ -0,0 +1,8 @@ +const http = require("http"); +const io = require("socket.io"); +const opts = { port: 3000 }; +const server = http.createServer((req, res) => {}); +server.listen(opts.port); +server.close(() => { + process.exit(0); +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/constants.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/constants.js new file mode 100644 index 0000000000000..f65726d00f950 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/constants.js @@ -0,0 +1,69 @@ +"use strict"; +/* + * Copyright 2019 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = + exports.DEFAULT_MAX_SEND_MESSAGE_LENGTH = + exports.Propagate = + exports.LogVerbosity = + exports.Status = + void 0; +var Status; +(function (Status) { + Status[(Status["OK"] = 0)] = "OK"; + Status[(Status["CANCELLED"] = 1)] = "CANCELLED"; + Status[(Status["UNKNOWN"] = 2)] = "UNKNOWN"; + Status[(Status["INVALID_ARGUMENT"] = 3)] = "INVALID_ARGUMENT"; + Status[(Status["DEADLINE_EXCEEDED"] = 4)] = "DEADLINE_EXCEEDED"; + Status[(Status["NOT_FOUND"] = 5)] = "NOT_FOUND"; + Status[(Status["ALREADY_EXISTS"] = 6)] = "ALREADY_EXISTS"; + Status[(Status["PERMISSION_DENIED"] = 7)] = "PERMISSION_DENIED"; + Status[(Status["RESOURCE_EXHAUSTED"] = 8)] = "RESOURCE_EXHAUSTED"; + Status[(Status["FAILED_PRECONDITION"] = 9)] = "FAILED_PRECONDITION"; + Status[(Status["ABORTED"] = 10)] = "ABORTED"; + Status[(Status["OUT_OF_RANGE"] = 11)] = "OUT_OF_RANGE"; + Status[(Status["UNIMPLEMENTED"] = 12)] = "UNIMPLEMENTED"; + Status[(Status["INTERNAL"] = 13)] = "INTERNAL"; + Status[(Status["UNAVAILABLE"] = 14)] = "UNAVAILABLE"; + Status[(Status["DATA_LOSS"] = 15)] = "DATA_LOSS"; + Status[(Status["UNAUTHENTICATED"] = 16)] = "UNAUTHENTICATED"; +})((Status = exports.Status || (exports.Status = {}))); +var LogVerbosity; +(function (LogVerbosity) { + LogVerbosity[(LogVerbosity["DEBUG"] = 0)] = "DEBUG"; + LogVerbosity[(LogVerbosity["INFO"] = 1)] = "INFO"; + LogVerbosity[(LogVerbosity["ERROR"] = 2)] = "ERROR"; +})((LogVerbosity = exports.LogVerbosity || (exports.LogVerbosity = {}))); +/** + * NOTE: This enum is not currently used in any implemented API in this + * library. It is included only for type parity with the other implementation. + */ +var Propagate; +(function (Propagate) { + Propagate[(Propagate["DEADLINE"] = 1)] = "DEADLINE"; + Propagate[(Propagate["CENSUS_STATS_CONTEXT"] = 2)] = "CENSUS_STATS_CONTEXT"; + Propagate[(Propagate["CENSUS_TRACING_CONTEXT"] = 4)] = + "CENSUS_TRACING_CONTEXT"; + Propagate[(Propagate["CANCELLATION"] = 8)] = "CANCELLATION"; + // https://github.com/grpc/grpc/blob/master/include/grpc/impl/codegen/propagation_bits.h#L43 + Propagate[(Propagate["DEFAULTS"] = 65535)] = "DEFAULTS"; +})((Propagate = exports.Propagate || (exports.Propagate = {}))); +// -1 means unlimited +exports.DEFAULT_MAX_SEND_MESSAGE_LENGTH = -1; +// 4 MB default +exports.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH = 4 * 1024 * 1024; +//# sourceMappingURL=constants.js.map diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/constants.js.map b/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/constants.js.map new file mode 100644 index 0000000000000..6152809f2541f --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/constants.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "file": "constants.js", + "sourceRoot": "", + "names": [], + "mappings": ";AAAA;;;;;;;;;;;;;;;GAeG;;;AAEH,IAAY,MAkBX;AAlBD,WAAY,MAAM;IAChB,+BAAM,CAAA;IACN,6CAAS,CAAA;IACT,yCAAO,CAAA;IACP,2DAAgB,CAAA;IAChB,6DAAiB,CAAA;IACjB,6CAAS,CAAA;IACT,uDAAc,CAAA;IACd,6DAAiB,CAAA;IACjB,+DAAkB,CAAA;IAClB,iEAAmB,CAAA;IACnB,0CAAO,CAAA;IACP,oDAAY,CAAA;IACZ,sDAAa,CAAA;IACb,4CAAQ,CAAA;IACR,kDAAW,CAAA;IACX,8CAAS,CAAA;IACT,0DAAe,CAAA;AACjB,CAAC,EAlBW,MAAM,GAAN,cAAM,KAAN,cAAM,QAkBjB;AAED,IAAY,YAIX;AAJD,WAAY,YAAY;IACtB,iDAAS,CAAA;IACT,+CAAI,CAAA;IACJ,iDAAK,CAAA;AACP,CAAC,EAJW,YAAY,GAAZ,oBAAY,KAAZ,oBAAY,QAIvB;AAED;;;GAGG;AACH,IAAY,SAOX;AAPD,WAAY,SAAS;IACnB,iDAAY,CAAA;IACZ,yEAAwB,CAAA;IACxB,6EAA0B,CAAA;IAC1B,yDAAgB,CAAA;IAChB,4FAA4F;IAC5F,qDAAmI,CAAA;AACrI,CAAC,EAPW,SAAS,GAAT,iBAAS,KAAT,iBAAS,QAOpB;AAED,qBAAqB;AACR,QAAA,+BAA+B,GAAG,CAAC,CAAC,CAAC;AAElD,eAAe;AACF,QAAA,kCAAkC,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/index.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/index.js new file mode 100644 index 0000000000000..5ae123ce235d2 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/source-map/index.js @@ -0,0 +1,10 @@ +const { readFileSync } = require("fs"); +const { join } = require("path"); + +const { Status } = require("./constants"); + +console.log(Status.OK); +// prevent analyzer from `readFileSync` +const filename = ["constants", "js", "map"]; +const cm = readFileSync(join(__dirname, filename.join("."))).toString("utf8"); +console.log(JSON.parse(cm).version); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/sparql-builder.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/sparql-builder.js new file mode 100644 index 0000000000000..b94c59bdd2dd7 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/sparql-builder.js @@ -0,0 +1 @@ +require("@tpluscode/sparql-builder"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/sqlite.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/sqlite.js new file mode 100644 index 0000000000000..997a358c7a152 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/sqlite.js @@ -0,0 +1,3 @@ +const sqlite3 = require("sqlite3"); + +console.log(sqlite3.VERSION); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/stripe.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/stripe.js new file mode 100644 index 0000000000000..ce9ba1cb91d2a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/stripe.js @@ -0,0 +1 @@ +const stripe = require("stripe"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/strong-error-handler.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/strong-error-handler.js new file mode 100644 index 0000000000000..122ca05229bb1 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/strong-error-handler.js @@ -0,0 +1 @@ +require("strong-error-handler"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/index.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/index.js new file mode 100644 index 0000000000000..de1425cf8ffa1 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/index.js @@ -0,0 +1,3 @@ +const { compute } = require("./linked"); + +console.log(compute()); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/linked.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/linked.js new file mode 120000 index 0000000000000..b93d9cd838d4a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/linked.js @@ -0,0 +1 @@ +real.js \ No newline at end of file diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/real.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/real.js new file mode 100644 index 0000000000000..268b235910257 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/symlink-to-file/real.js @@ -0,0 +1,3 @@ +module.exports.compute = function compute() { + return "real"; +}; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/tiny-json-http.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/tiny-json-http.js new file mode 100644 index 0000000000000..16aeafd43c39d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/tiny-json-http.js @@ -0,0 +1 @@ +const tiny = require("tiny-json-http"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-morph.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-morph.js new file mode 100644 index 0000000000000..4ada77827fe50 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-morph.js @@ -0,0 +1 @@ +require("ts-morph"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/index.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/index.ts new file mode 100644 index 0000000000000..632afa12faf30 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/index.ts @@ -0,0 +1,8 @@ +import debug from "debug"; +import { value } from "./module"; +import { value as imported } from "imported"; +import { a } from "utils/a"; +import { b } from "utils/b"; +import { c } from "utils"; + +console.log(value, imported as any, a, b, c); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/module.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/module.ts new file mode 100644 index 0000000000000..b45c73d2ce868 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/module.ts @@ -0,0 +1 @@ +export const value = "module"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/tsconfig.extended.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/tsconfig.extended.json new file mode 100644 index 0000000000000..dcc166a32860b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/tsconfig.extended.json @@ -0,0 +1,3 @@ +{ + "extends": "../ts-package/tsconfig.json" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/tsconfig.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/tsconfig.json new file mode 100644 index 0000000000000..d160ce3184b70 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-extends/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig.extended.json" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/base/imported/index.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/base/imported/index.ts new file mode 100644 index 0000000000000..d0162d67049cc --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/base/imported/index.ts @@ -0,0 +1 @@ +export const value = "imported"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/base/imported/package.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/base/imported/package.json new file mode 100644 index 0000000000000..68d0c54093585 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/base/imported/package.json @@ -0,0 +1,3 @@ +{ + "main": "./index.ts" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/index.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/index.js new file mode 100644 index 0000000000000..da7ce630481d8 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/index.js @@ -0,0 +1,4 @@ +require("ts-node").register(); +require("tsconfig-paths").register(); + +require("./index.ts"); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/index.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/index.ts new file mode 100644 index 0000000000000..632afa12faf30 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/index.ts @@ -0,0 +1,8 @@ +import debug from "debug"; +import { value } from "./module"; +import { value as imported } from "imported"; +import { a } from "utils/a"; +import { b } from "utils/b"; +import { c } from "utils"; + +console.log(value, imported as any, a, b, c); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/module.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/module.ts new file mode 100644 index 0000000000000..b45c73d2ce868 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/module.ts @@ -0,0 +1 @@ +export const value = "module"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/more-utils/b.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/more-utils/b.ts new file mode 100644 index 0000000000000..59d1689930e55 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/more-utils/b.ts @@ -0,0 +1 @@ +export const b = "b"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/tsconfig.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/tsconfig.json new file mode 100644 index 0000000000000..e8f3d3cd3cf21 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "allowJs": true, + "baseUrl": "./base", + "module": "CommonJS", + "moduleResolution": "node", + "paths": { + "utils": ["../utils.ts"], + "utils/*": ["../utils/*", "../more-utils/*"] + } + } +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/utils.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/utils.ts new file mode 100644 index 0000000000000..7f2cfac777f20 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/utils.ts @@ -0,0 +1 @@ +export const c = "c"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/utils/a.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/utils/a.ts new file mode 100644 index 0000000000000..9233cce2f0e18 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package-from-js/utils/a.ts @@ -0,0 +1 @@ +export const a = "a"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/base/imported/index.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/base/imported/index.ts new file mode 100644 index 0000000000000..d0162d67049cc --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/base/imported/index.ts @@ -0,0 +1 @@ +export const value = "imported"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/base/imported/package.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/base/imported/package.json new file mode 100644 index 0000000000000..68d0c54093585 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/base/imported/package.json @@ -0,0 +1,3 @@ +{ + "main": "./index.ts" +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/index.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/index.ts new file mode 100644 index 0000000000000..632afa12faf30 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/index.ts @@ -0,0 +1,8 @@ +import debug from "debug"; +import { value } from "./module"; +import { value as imported } from "imported"; +import { a } from "utils/a"; +import { b } from "utils/b"; +import { c } from "utils"; + +console.log(value, imported as any, a, b, c); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/module.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/module.ts new file mode 100644 index 0000000000000..b45c73d2ce868 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/module.ts @@ -0,0 +1 @@ +export const value = "module"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/more-utils/b.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/more-utils/b.ts new file mode 100644 index 0000000000000..59d1689930e55 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/more-utils/b.ts @@ -0,0 +1 @@ +export const b = "b"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/tsconfig.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/tsconfig.json new file mode 100644 index 0000000000000..04e82465bd218 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "allowJs": true, + "baseUrl": "./base", + "module": "CommonJS", + "moduleResolution": "node", + "paths": { + "utils": ["../utils.ts"], + "utils/*": ["../utils/*", "../more-utils/*"] + } + }, + // comment + /* + comment + */ + "ts-node": { + "require": ["tsconfig-paths/register"] + }, // trailing comma +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/utils.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/utils.ts new file mode 100644 index 0000000000000..7f2cfac777f20 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/utils.ts @@ -0,0 +1 @@ +export const c = "c"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/utils/a.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/utils/a.ts new file mode 100644 index 0000000000000..9233cce2f0e18 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-package/utils/a.ts @@ -0,0 +1 @@ +export const a = "a"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/alt-folders.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/alt-folders.ts new file mode 100644 index 0000000000000..ca7fdeeb27212 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/alt-folders.ts @@ -0,0 +1,3 @@ +import { alt1 } from "fixtures/alt-folders/alt1.js"; +import { alt2 } from "fixtures/alt-folders/alt2.js"; +console.log(alt1, alt2); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/double.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/double.ts new file mode 100644 index 0000000000000..05226ec254c43 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/double.ts @@ -0,0 +1,2 @@ +import { doubleSub } from "double/sub"; +console.log(doubleSub); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/folder.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/folder.ts new file mode 100644 index 0000000000000..32dbe0b167add --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/folder.ts @@ -0,0 +1,2 @@ +import { alt1 } from "folder/alt1"; +console.log(alt1); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-infix-sep.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-infix-sep.ts new file mode 100644 index 0000000000000..de2bdbe41f24d --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-infix-sep.ts @@ -0,0 +1,2 @@ +import { subInfixSep } from "@/sub/@"; +console.log(subInfixSep); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-infix.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-infix.ts new file mode 100644 index 0000000000000..500a06bfe9bfc --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-infix.ts @@ -0,0 +1,2 @@ +import { subInfix } from "@sub@"; +console.log(subInfix); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-prefix-sep.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-prefix-sep.ts new file mode 100644 index 0000000000000..b03aa3edbc8f9 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fail/sub-prefix-sep.ts @@ -0,0 +1,2 @@ +import { subPrefixSep } from "sub/@"; +console.log(subPrefixSep); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/alt1/alt1.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/alt1/alt1.js new file mode 100644 index 0000000000000..beedbda19a1ec --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/alt1/alt1.js @@ -0,0 +1 @@ +export const alt1 = "alt1"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/alt2/alt2.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/alt2/alt2.js new file mode 100644 index 0000000000000..683efb155f8a9 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/alt2/alt2.js @@ -0,0 +1 @@ +export const alt2 = "alt2"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/catch-all.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/catch-all.js new file mode 100644 index 0000000000000..753d6bf3bb97f --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/catch-all.js @@ -0,0 +1 @@ +export const catchAll = "catchAll"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/direct-renamed.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/direct-renamed.js new file mode 100644 index 0000000000000..ed80b2adb44b7 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/direct-renamed.js @@ -0,0 +1 @@ +export const direct = "direct"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/double/sub/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/double/sub/sub.js new file mode 100644 index 0000000000000..99284cf3ed79e --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/double/sub/sub.js @@ -0,0 +1 @@ +export const doubleSub = "doubleSub"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/nested-renamed/once/mod.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/nested-renamed/once/mod.js new file mode 100644 index 0000000000000..02d3f2eaa95a0 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/nested-renamed/once/mod.js @@ -0,0 +1 @@ +export const nestedOnce = "nestedOnce"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/root.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/root.js new file mode 100644 index 0000000000000..f7ed909411d59 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/root.js @@ -0,0 +1 @@ +export const root = "root"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-infix-sep/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-infix-sep/sub.js new file mode 100644 index 0000000000000..d7c7c4d47fa66 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-infix-sep/sub.js @@ -0,0 +1 @@ +export const subInfixSep = "subInfixSep"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-infix/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-infix/sub.js new file mode 100644 index 0000000000000..9c5b089bb84b3 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-infix/sub.js @@ -0,0 +1 @@ +export const subInfix = "subInfix"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-prefix-sep/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-prefix-sep/sub.js new file mode 100644 index 0000000000000..2b741511e9269 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-prefix-sep/sub.js @@ -0,0 +1 @@ +export const subPrefixSep = "subPrefixSep"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-prefix/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-prefix/sub.js new file mode 100644 index 0000000000000..c5826f66ceda4 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-prefix/sub.js @@ -0,0 +1 @@ +export const subPrefix = "subPrefix"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-suffix-sep/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-suffix-sep/sub.js new file mode 100644 index 0000000000000..f9ed8bc9cb459 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-suffix-sep/sub.js @@ -0,0 +1 @@ +export const subSuffixSep = "subSuffixSep"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-suffix/sub.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-suffix/sub.js new file mode 100644 index 0000000000000..f9f00c133e4e2 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/fixtures/sub-suffix/sub.js @@ -0,0 +1 @@ +export const subSuffix = "subSuffix"; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/alt.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/alt.ts new file mode 100644 index 0000000000000..52149474debe5 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/alt.ts @@ -0,0 +1,3 @@ +import { alt1 } from "alt/alt1"; +import { alt2 } from "alt/alt2"; +console.log(alt1, alt2); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/catch-all.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/catch-all.ts new file mode 100644 index 0000000000000..3d487d2299ae0 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/catch-all.ts @@ -0,0 +1,3 @@ +import { catchAll as catchAll1 } from "catch-all1"; +import { catchAll as catchAll2 } from "catch-all2"; +console.log(catchAll1, catchAll2); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/direct.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/direct.ts new file mode 100644 index 0000000000000..d8bfffb3cb21a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/direct.ts @@ -0,0 +1,2 @@ +import { direct } from "direct"; +console.log(direct); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/nested.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/nested.ts new file mode 100644 index 0000000000000..f9064eb1fc6ee --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/nested.ts @@ -0,0 +1,2 @@ +import { nestedOnce } from "nested/once/mod"; +console.log(nestedOnce); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-prefix.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-prefix.ts new file mode 100644 index 0000000000000..6737fd12f72de --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-prefix.ts @@ -0,0 +1,2 @@ +import { subPrefix } from "sub@"; +console.log(subPrefix); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-suffix-sep.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-suffix-sep.ts new file mode 100644 index 0000000000000..2d3dd84fb2597 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-suffix-sep.ts @@ -0,0 +1,2 @@ +import { subSuffixSep } from "@/sub"; +console.log(subSuffixSep); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-suffix.ts b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-suffix.ts new file mode 100644 index 0000000000000..e10152a0bd277 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/pass/sub-suffix.ts @@ -0,0 +1,2 @@ +import { subSuffix } from "@sub"; +console.log(subSuffix); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/tsconfig.json b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/tsconfig.json new file mode 100644 index 0000000000000..2c7a618115d05 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/ts-paths/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "allowJs": true, + "baseUrl": ".", + "module": "CommonJS", + "moduleResolution": "node", + "paths": { + "direct": ["./fixtures/direct-renamed"], + "folder/": ["./fixtures/alt1/"], + "alt-folders/": ["./fixtures/alt1/", "./fixtures/alt2/"], + "alt/*": ["./fixtures/alt1/*", "./fixtures/alt2/*"], + "catch-all*": ["./fixtures/catch-all"], + "double/*": ["./fixtures/double/*/*.js"], + "nested/*": ["./fixtures/nested-renamed/*.js"], + "@*@": ["./fixtures/sub-infix/*.js"], + "@/*/@": ["./fixtures/sub-infix-sep/*.js"], + "*@": ["./fixtures/sub-prefix/*.js"], + "*/@": ["./fixtures/sub-prefix-sep/*.js"], + "@*": ["./fixtures/sub-suffix/*.js"], + "@/*": ["./fixtures/sub-suffix-sep/*.js"] + }, + "types": ["node"] + }, + "ts-node": { + "require": ["tsconfig-paths/register"] + } +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/twilio.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/twilio.js new file mode 100644 index 0000000000000..1495448875f94 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/twilio.js @@ -0,0 +1,8 @@ +const twilio = require("twilio"); +try { + twilio(); +} catch (err) { + if (!/username is required/.test(err.message)) { + throw err; + } +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/typescript.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/typescript.js new file mode 100644 index 0000000000000..b96504caf7c99 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/typescript.js @@ -0,0 +1,22 @@ +const { spawn } = require("child_process"); +const tsc = require.resolve("typescript/bin/tsc"); +const tscjs = require.resolve("typescript/lib/tsc.js"); +const cwd = __dirname; + +if (!tsc.endsWith("tsc")) { + throw new Error("Expected tsc cli but found " + tsc); +} + +if (!tscjs.endsWith("tsc.js")) { + throw new Error("Expected tsc.js but found " + tscjs); +} + +const child = spawn("node", [tscjs, "--version"], { cwd }); +child.stdout.on("data", (data) => { + if (!data || data.toString().length === 0) { + throw new Error("Expected stdout output but found none"); + } +}); +child.stderr.on("data", (data) => { + throw new Error("Unexpected stderr output: " + data.toString()); +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/uglify.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/uglify.js new file mode 100644 index 0000000000000..5a592276152e7 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/uglify.js @@ -0,0 +1,4 @@ +const UglifyJS = require("uglify-js"); +const code = "function add(first, second) { return first + second; }"; +const result = UglifyJS.minify(code); +console.log(result); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/underscore.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/underscore.js new file mode 100644 index 0000000000000..7b84018e4c4d1 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/underscore.js @@ -0,0 +1,3 @@ +const _ = require("underscore"); + +console.log(_.flatten([[1, 2, 3], [4]])); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/vm2.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/vm2.js new file mode 100644 index 0000000000000..3af4f6fb50ed6 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/vm2.js @@ -0,0 +1,2 @@ +const { VM } = require("vm2"); +new VM().run('console.log("HELLO WORLD")'); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/vue.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/vue.js new file mode 100644 index 0000000000000..9fea387b2ada7 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/vue.js @@ -0,0 +1,8 @@ +const Vue = require("vue"); +const renderer = require("vue-server-renderer").createRenderer(); + +const app = new Vue({ + data: () => ({ date: Date.now() }), + template: `
    Hello World {{ date }}
    `, +}); +renderer.renderToString(app); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/chunk.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/chunk.js new file mode 100644 index 0000000000000..417bf17765161 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/chunk.js @@ -0,0 +1,53 @@ +"use strict"; +(() => { +var exports = {}; +exports.id = 829; +exports.ids = [829]; +exports.modules = { + +/***/ 354: +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +// ESM COMPAT FLAG +__webpack_require__.r(__webpack_exports__); + +// EXPORTS +__webpack_require__.d(__webpack_exports__, { + "default": () => (/* binding */ handler) +}); + +;// CONCATENATED MODULE: external "fs/promises" +const promises_namespaceObject = require("fs/promises"); +;// CONCATENATED MODULE: ./pages/api/users.ts + +// Fake users data +const users = [ + { + id: 1 + }, + { + id: 2 + }, + { + id: 3 + } +]; +async function handler(_req, res) { + const hello = await (0,promises_namespaceObject.readFile)(__dirname + "/hello.txt", "utf-8"); + return hello; +} + + +/***/ }) + +}; +; + +// load runtime +var __webpack_require__ = require("./webpack-api-runtime.js"); +__webpack_require__.C(exports); +var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId)) +var __webpack_exports__ = (__webpack_exec__(354)); +module.exports = __webpack_exports__; + +})(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/hello.txt b/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/hello.txt new file mode 100644 index 0000000000000..e965047ad7c57 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/hello.txt @@ -0,0 +1 @@ +Hello diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/index.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/index.js new file mode 100644 index 0000000000000..20a9e6e3948bb --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/index.js @@ -0,0 +1,5 @@ +const sayHello = require('./chunk').default; + +sayHello().then((h) => { + console.log(h) +}); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/webpack-api-runtime.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/webpack-api-runtime.js new file mode 100644 index 0000000000000..b89b6c1215dbb --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/webpack-target-node/webpack-api-runtime.js @@ -0,0 +1,148 @@ +/******/ (() => { // webpackBootstrap +/******/ "use strict"; +/******/ var __webpack_modules__ = ({}); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ var threw = true; +/******/ try { +/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); +/******/ threw = false; +/******/ } finally { +/******/ if(threw) delete __webpack_module_cache__[moduleId]; +/******/ } +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __webpack_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/ensure chunk */ +/******/ (() => { +/******/ __webpack_require__.f = {}; +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __webpack_require__.e = (chunkId) => { +/******/ return Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => { +/******/ __webpack_require__.f[key](chunkId, promises); +/******/ return promises; +/******/ }, [])); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get javascript chunk filename */ +/******/ (() => { +/******/ // This function allow to reference async chunks and sibling chunks for the entrypoint +/******/ __webpack_require__.u = (chunkId) => { +/******/ // return url for filenames based on template +/******/ return undefined; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __webpack_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/startup entrypoint */ +/******/ (() => { +/******/ __webpack_require__.X = (result, chunkIds, fn) => { +/******/ // arguments: chunkIds, moduleId are deprecated +/******/ var moduleId = chunkIds; +/******/ if(!fn) chunkIds = result, fn = () => (__webpack_require__(__webpack_require__.s = moduleId)); +/******/ chunkIds.map(__webpack_require__.e, __webpack_require__) +/******/ var r = fn(); +/******/ return r === undefined ? result : r; +/******/ } +/******/ })(); +/******/ +/******/ /* webpack/runtime/require chunk loading */ +/******/ (() => { +/******/ // no baseURI +/******/ +/******/ // object to store loaded chunks +/******/ // "1" means "loaded", otherwise not loaded yet +/******/ var installedChunks = { +/******/ 165: 1 +/******/ }; +/******/ +/******/ // no on chunks loaded +/******/ +/******/ var installChunk = (chunk) => { +/******/ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime; +/******/ for(var moduleId in moreModules) { +/******/ if(__webpack_require__.o(moreModules, moduleId)) { +/******/ __webpack_require__.m[moduleId] = moreModules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) runtime(__webpack_require__); +/******/ for(var i = 0; i < chunkIds.length; i++) +/******/ installedChunks[chunkIds[i]] = 1; +/******/ +/******/ }; +/******/ +/******/ // require() chunk loading for javascript +/******/ __webpack_require__.f.require = (chunkId, promises) => { +/******/ // "1" is the signal for "already loaded" +/******/ if(!installedChunks[chunkId]) { +/******/ if(165 != chunkId) { +/******/ installChunk(require("./chunks/" + __webpack_require__.u(chunkId))); +/******/ } else installedChunks[chunkId] = 1; +/******/ } +/******/ }; +/******/ +/******/ module.exports = __webpack_require__; +/******/ __webpack_require__.C = installChunk; +/******/ +/******/ // no HMR +/******/ +/******/ // no HMR manifest +/******/ })(); +/******/ +/************************************************************************/ +/******/ +/******/ +/******/ })() +; diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/whatwg-url.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/whatwg-url.js new file mode 100644 index 0000000000000..476ebb4dec320 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/whatwg-url.js @@ -0,0 +1,3 @@ +var { URL } = require("whatwg-url"); + +console.log(new URL("https://example.com/path?query")); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/integration/when.js b/turbopack/crates/turbopack/tests/node-file-trace/integration/when.js new file mode 100644 index 0000000000000..f59410c729c0b --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/integration/when.js @@ -0,0 +1,3 @@ +var when = require("when"); + +var deferred = when.defer(); diff --git a/turbopack/crates/turbopack/tests/node-file-trace/package.json b/turbopack/crates/turbopack/tests/node-file-trace/package.json new file mode 100644 index 0000000000000..395ee7d93bf6a --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/package.json @@ -0,0 +1,124 @@ +{ + "name": "@vercel/nft-tests", + "version": "0.0.0", + "private": true, + "devDependencies": { + "@azure/cosmos": "^2.1.7", + "@bugsnag/js": "^6.3.2", + "@ffmpeg-installer/ffmpeg": "^1.0.19", + "@google-cloud/bigquery": "^4.1.4", + "@google-cloud/firestore": "^4.11.0", + "@mdx-js/node-loader": "^2.2.1", + "@sentry/node": "^5.5.0", + "@tpluscode/sparql-builder": "^0.3.12", + "@types/bindings": "^1.3.0", + "@types/debug": "^4.1.7", + "@types/estree": "^0.0.47", + "@types/glob": "^7.1.2", + "@types/graceful-fs": "^4.1.5", + "@types/micromatch": "^4.0.1", + "@types/node": "14.18.29", + "@vercel/nft": "^0.22.1", + "@zeit/cosmosdb-query": "^0.7.2", + "analytics-node": "^3.4.0-beta.1", + "apollo-server-express": "^2.14.2", + "argon2": "^0.27.2", + "auth0": "^2.27.1", + "aws-sdk": "^2.1218.0", + "axios": "^0.21.2", + "azure-storage": "^2.10.3", + "bcrypt": "^5.1.0", + "better-sqlite3": "^9.2.2", + "bindings": "^1.5.0", + "browserify-middleware": "^8.1.1", + "bull": "^3.10.0", + "bullmq": "^1.87.1", + "camaro": "^6.1.0", + "canvas": "^2.11.2", + "chromeless": "^1.5.2", + "codecov": "^3.8.1", + "consolidate": "^0.15.1", + "copy": "^0.3.2", + "core-js": "2", + "cowsay": "^1.4.0", + "debug": "^4.3.4", + "es-get-iterator": "^1.1.0", + "esbuild": "^0.15.7", + "esm": "^3.2.25", + "express": "^4.17.1", + "fast-glob": "^3.1.1", + "fetch-h2": "^2.2.0", + "firebase": "^7", + "firebase-admin": "^9.7.0", + "fluent-ffmpeg": "^2.1.2", + "geo-tz": "^7.0.1", + "got": "11", + "graphql": "^14.4.2", + "highlights": "^3.1.6", + "hot-shots": "^9.0.0", + "ioredis": "^4.11.1", + "isomorphic-unfetch": "^3.0.0", + "jest": "^27.4.5", + "jimp": "^0.6.4", + "jugglingdb": "^2.0.1", + "koa": "^2.7.0", + "leveldown": "^5.6.0", + "lighthouse": "^5.1.0", + "loopback": "^3.26.0", + "mailgun": "^0.5.0", + "mariadb": "^2.0.5", + "memcached": "^2.2.2", + "mongoose": "^5.7.5", + "mysql": "^2.17.1", + "npm": "^6.14.6", + "paraphrase": "1.8.0", + "passport": "^0.4.0", + "passport-google-oauth": "^2.0.0", + "passport-trakt": "^1.0.4", + "path-platform": "^0.11.15", + "pdf2json": "^2.1.0", + "pdfkit": "^0.10.0", + "pg": "^7.11.0", + "phantomjs-prebuilt": "^2.1.16", + "pixelmatch": "^5.3.0", + "playwright-core": "^1.17.1", + "polyfill-library": "3.93.0", + "prismjs": "^1.25.0", + "pug": "^3.0.1", + "react": "^16.14.0", + "react-dom": "^16.14.0", + "redis": "^3.1.1", + "remark-parse": "^10.0.0", + "remark-prism": "^1.3.6", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "rxjs": "^6.5.2", + "saslprep": "^1.0.3", + "semver": "^7.1.1", + "sequelize": "^5.9.3", + "sharp": "^0.30.0", + "socket.io": "^2.4.0", + "socket.io-client": "^2.2.0", + "sqlite3": "^5.0.8", + "stripe": "^7.4.0", + "strong-error-handler": "^4.0.0", + "swig": "^1.4.2", + "tiny-json-http": "^7.1.2", + "ts-morph": "^15.1.0", + "ts-node": "^10.7.0", + "tsconfig-paths": "^3.14.1", + "twilio": "^3.33.0", + "typescript": "^4.8.4", + "uglify-js": "^3.6.0", + "underscore": "^1.13.4", + "unified": "^10.1.0", + "vm2": "^3.9.6", + "vue": "^2.6.10", + "vue-server-renderer": "^2.6.10", + "whatwg-url": "5.0.0", + "when": "^3.7.8" + }, + "optionalDependencies": { + "oracledb": "^4.2.0" + } +} diff --git a/turbopack/crates/turbopack/tests/node-file-trace/pnpm-lock.yaml b/turbopack/crates/turbopack/tests/node-file-trace/pnpm-lock.yaml new file mode 100644 index 0000000000000..7245201e35325 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/pnpm-lock.yaml @@ -0,0 +1,18510 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + optionalDependencies: + oracledb: + specifier: ^4.2.0 + version: 4.2.0 + devDependencies: + '@azure/cosmos': + specifier: ^2.1.7 + version: 2.1.7 + '@bugsnag/js': + specifier: ^6.3.2 + version: 6.5.2 + '@ffmpeg-installer/ffmpeg': + specifier: ^1.0.19 + version: 1.1.0 + '@google-cloud/bigquery': + specifier: ^4.1.4 + version: 4.7.0 + '@google-cloud/firestore': + specifier: ^4.11.0 + version: 4.15.1 + '@mdx-js/node-loader': + specifier: ^2.2.1 + version: 2.2.1 + '@sentry/node': + specifier: ^5.5.0 + version: 5.30.0 + '@tpluscode/sparql-builder': + specifier: ^0.3.12 + version: 0.3.24(@zazuko/rdf-vocabularies@2023.1.19)(clownface@1.5.1)(safe-identifier@0.4.2)(sparql-http-client@2.4.2)(ts-morph@15.1.0)(ts-node@10.9.1) + '@types/bindings': + specifier: ^1.3.0 + version: 1.5.1 + '@types/debug': + specifier: ^4.1.7 + version: 4.1.7 + '@types/estree': + specifier: ^0.0.47 + version: 0.0.47 + '@types/glob': + specifier: ^7.1.2 + version: 7.2.0 + '@types/graceful-fs': + specifier: ^4.1.5 + version: 4.1.5 + '@types/micromatch': + specifier: ^4.0.1 + version: 4.0.2 + '@types/node': + specifier: 14.18.29 + version: 14.18.29 + '@vercel/nft': + specifier: ^0.22.1 + version: 0.22.1 + '@zeit/cosmosdb-query': + specifier: ^0.7.2 + version: 0.7.2 + analytics-node: + specifier: ^3.4.0-beta.1 + version: 3.5.0(debug@4.3.4) + apollo-server-express: + specifier: ^2.14.2 + version: 2.26.1(graphql@14.7.0) + argon2: + specifier: ^0.27.2 + version: 0.27.2 + auth0: + specifier: ^2.27.1 + version: 2.44.0(debug@4.3.4) + aws-sdk: + specifier: ^2.1218.0 + version: 2.1240.0 + axios: + specifier: ^0.21.2 + version: 0.21.4(debug@4.3.4) + azure-storage: + specifier: ^2.10.3 + version: 2.10.7 + bcrypt: + specifier: ^5.1.0 + version: 5.1.0 + better-sqlite3: + specifier: ^9.2.2 + version: 9.2.2 + bindings: + specifier: ^1.5.0 + version: 1.5.0 + browserify-middleware: + specifier: ^8.1.1 + version: 8.1.1 + bull: + specifier: ^3.10.0 + version: 3.29.3 + bullmq: + specifier: ^1.87.1 + version: 1.91.1 + camaro: + specifier: ^6.1.0 + version: 6.2.0 + canvas: + specifier: ^2.11.2 + version: 2.11.2 + chromeless: + specifier: ^1.5.2 + version: 1.5.2 + codecov: + specifier: ^3.8.1 + version: 3.8.3 + consolidate: + specifier: ^0.15.1 + version: 0.15.1(pug@3.0.2)(react-dom@16.14.0)(react@16.14.0)(swig@1.4.2)(underscore@1.13.6) + copy: + specifier: ^0.3.2 + version: 0.3.2 + core-js: + specifier: '2' + version: 2.6.12 + cowsay: + specifier: ^1.4.0 + version: 1.5.0 + debug: + specifier: ^4.3.4 + version: 4.3.4 + es-get-iterator: + specifier: ^1.1.0 + version: 1.1.2 + esbuild: + specifier: ^0.15.7 + version: 0.15.12 + esm: + specifier: ^3.2.25 + version: 3.2.25 + express: + specifier: ^4.17.1 + version: 4.18.2 + fast-glob: + specifier: ^3.1.1 + version: 3.2.12 + fetch-h2: + specifier: ^2.2.0 + version: 2.5.1 + firebase: + specifier: ^7 + version: 7.24.0 + firebase-admin: + specifier: ^9.7.0 + version: 9.12.0(@firebase/app-compat@0.2.15)(@firebase/app-types@0.9.0) + fluent-ffmpeg: + specifier: ^2.1.2 + version: 2.1.2 + geo-tz: + specifier: ^7.0.1 + version: 7.0.3 + got: + specifier: '11' + version: 11.8.5 + graphql: + specifier: ^14.4.2 + version: 14.7.0 + highlights: + specifier: ^3.1.6 + version: 3.1.6 + hot-shots: + specifier: ^9.0.0 + version: 9.3.0 + ioredis: + specifier: ^4.11.1 + version: 4.28.5 + isomorphic-unfetch: + specifier: ^3.0.0 + version: 3.1.0 + jest: + specifier: ^27.4.5 + version: 27.5.1(canvas@2.11.2)(ts-node@10.9.1) + jimp: + specifier: ^0.6.4 + version: 0.6.8 + jugglingdb: + specifier: ^2.0.1 + version: 2.0.1 + koa: + specifier: ^2.7.0 + version: 2.13.4 + leveldown: + specifier: ^5.6.0 + version: 5.6.0 + lighthouse: + specifier: ^5.1.0 + version: 5.6.0 + loopback: + specifier: ^3.26.0 + version: 3.28.0 + mailgun: + specifier: ^0.5.0 + version: 0.5.0 + mariadb: + specifier: ^2.0.5 + version: 2.5.6 + memcached: + specifier: ^2.2.2 + version: 2.2.2 + mongoose: + specifier: ^5.7.5 + version: 5.13.15 + mysql: + specifier: ^2.17.1 + version: 2.18.1 + npm: + specifier: ^6.14.6 + version: 6.14.17 + paraphrase: + specifier: 1.8.0 + version: 1.8.0 + passport: + specifier: ^0.4.0 + version: 0.4.1 + passport-google-oauth: + specifier: ^2.0.0 + version: 2.0.0 + passport-trakt: + specifier: ^1.0.4 + version: 1.0.4 + path-platform: + specifier: ^0.11.15 + version: 0.11.15 + pdf2json: + specifier: ^2.1.0 + version: 2.1.0 + pdfkit: + specifier: ^0.10.0 + version: 0.10.0 + pg: + specifier: ^7.11.0 + version: 7.18.2 + phantomjs-prebuilt: + specifier: ^2.1.16 + version: 2.1.16 + pixelmatch: + specifier: ^5.3.0 + version: 5.3.0 + playwright-core: + specifier: ^1.17.1 + version: 1.27.1 + polyfill-library: + specifier: 3.93.0 + version: 3.93.0 + prismjs: + specifier: ^1.25.0 + version: 1.29.0 + pug: + specifier: ^3.0.1 + version: 3.0.2 + react: + specifier: ^16.14.0 + version: 16.14.0 + react-dom: + specifier: ^16.14.0 + version: 16.14.0(react@16.14.0) + redis: + specifier: ^3.1.1 + version: 3.1.2 + remark-parse: + specifier: ^10.0.0 + version: 10.0.1 + remark-prism: + specifier: ^1.3.6 + version: 1.3.6(canvas@2.11.2) + request: + specifier: ^2.88.2 + version: 2.88.2 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + rxjs: + specifier: ^6.5.2 + version: 6.6.7 + saslprep: + specifier: ^1.0.3 + version: 1.0.3 + semver: + specifier: ^7.1.1 + version: 7.3.8 + sequelize: + specifier: ^5.9.3 + version: 5.22.5 + sharp: + specifier: ^0.30.0 + version: 0.30.7 + socket.io: + specifier: ^2.4.0 + version: 2.5.0 + socket.io-client: + specifier: ^2.2.0 + version: 2.5.0 + sqlite3: + specifier: ^5.0.8 + version: 5.1.2 + stripe: + specifier: ^7.4.0 + version: 7.63.1 + strong-error-handler: + specifier: ^4.0.0 + version: 4.0.0 + swig: + specifier: ^1.4.2 + version: 1.4.2 + tiny-json-http: + specifier: ^7.1.2 + version: 7.4.2 + ts-morph: + specifier: ^15.1.0 + version: 15.1.0 + ts-node: + specifier: ^10.7.0 + version: 10.9.1(@types/node@14.18.29)(typescript@4.8.4) + tsconfig-paths: + specifier: ^3.14.1 + version: 3.14.1 + twilio: + specifier: ^3.33.0 + version: 3.83.0(debug@4.3.4) + typescript: + specifier: ^4.8.4 + version: 4.8.4 + uglify-js: + specifier: ^3.6.0 + version: 3.17.4 + underscore: + specifier: ^1.13.4 + version: 1.13.6 + unified: + specifier: ^10.1.0 + version: 10.1.2 + vm2: + specifier: ^3.9.6 + version: 3.9.11 + vue: + specifier: ^2.6.10 + version: 2.7.13 + vue-server-renderer: + specifier: ^2.6.10 + version: 2.7.13 + whatwg-url: + specifier: 5.0.0 + version: 5.0.0 + when: + specifier: ^3.7.8 + version: 3.7.8 + +packages: + + /@ampproject/remapping@2.2.0: + resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.1.1 + '@jridgewell/trace-mapping': 0.3.17 + dev: true + + /@apollo/protobufjs@1.2.2: + resolution: {integrity: sha512-vF+zxhPiLtkwxONs6YanSt1EpwpGilThpneExUN5K3tCymuxNnVq2yojTvnpRjv2QfsEIt/n7ozPIIzBLwGIDQ==} + hasBin: true + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + '@types/node': 10.17.60 + long: 4.0.0 + dev: true + + /@apollographql/apollo-tools@0.5.4(graphql@14.7.0): + resolution: {integrity: sha512-shM3q7rUbNyXVVRkQJQseXv6bnYM3BUma/eZhwXR4xsuM+bqWnJKvW7SAfRjP7LuSCocrexa5AXhjjawNHrIlw==} + engines: {node: '>=8', npm: '>=6'} + peerDependencies: + graphql: ^14.2.1 || ^15.0.0 || ^16.0.0 + dependencies: + graphql: 14.7.0 + dev: true + + /@apollographql/graphql-playground-html@1.6.27: + resolution: {integrity: sha512-tea2LweZvn6y6xFV11K0KC8ETjmm52mQrW+ezgB2O/aTQf8JGyFmMcRPFgUaQZeHbWdm8iisDC6EjOKsXu0nfw==} + dependencies: + xss: 1.0.14 + dev: true + + /@apollographql/graphql-upload-8-fork@8.1.4(graphql@14.7.0): + resolution: {integrity: sha512-lHAj/PUegYu02zza9Pg0bQQYH5I0ah1nyIzu2YIqOv41P0vu3GCBISAmQCfFHThK7N3dy7dLFPhoKcXlXRLPoQ==} + engines: {node: '>=8.5'} + peerDependencies: + graphql: 0.13.1 - 15 + dependencies: + '@types/express': 4.17.14 + '@types/fs-capacitor': 2.0.0 + '@types/koa': 2.13.5 + busboy: 0.3.1 + fs-capacitor: 2.0.4 + graphql: 14.7.0 + http-errors: 1.8.1 + object-path: 0.11.8 + dev: true + + /@assemblyscript/loader@0.10.1: + resolution: {integrity: sha512-H71nDOOL8Y7kWRLqf6Sums+01Q5msqBW2KhDUTemh1tvY04eSkSXrK0uj/4mmY0Xr16/3zyZmsrxN7CKuRbNRg==} + dev: true + + /@azure/cosmos@2.1.7: + resolution: {integrity: sha512-kIfpgTM7q7o059NDQuGrr0ZrNUx7PaazUgyBLwu4rQhokVG3wWY2xsh1VzGJasPvkOBXxX3lHRmApQm3jY1CBA==} + requiresBuild: true + dependencies: + binary-search-bounds: 2.0.3 + create-hmac: 1.1.7 + priorityqueuejs: 1.0.0 + semaphore: 1.0.5 + stream-http: 2.8.3 + tslib: 1.14.1 + tunnel: 0.0.5 + dev: true + + /@babel/code-frame@7.18.6: + resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + dev: true + + /@babel/compat-data@7.19.4: + resolution: {integrity: sha512-CHIGpJcUQ5lU9KrPHTjBMhVwQG6CQjxfg36fGXl3qk/Gik1WwWachaXFuo0uCWJT/mStOKtcbFJCaVLihC1CMw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.19.6: + resolution: {integrity: sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.0 + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.19.6 + '@babel/helper-compilation-targets': 7.19.3(@babel/core@7.19.6) + '@babel/helper-module-transforms': 7.19.6 + '@babel/helpers': 7.19.4 + '@babel/parser': 7.19.6 + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.6 + '@babel/types': 7.19.4 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.1 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.19.6: + resolution: {integrity: sha512-oHGRUQeoX1QrKeJIKVe0hwjGqNnVYsM5Nep5zo0uE0m42sLH+Fsd2pStJ5sRM1bNyTUUoz0pe2lTeMJrb/taTA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.4 + '@jridgewell/gen-mapping': 0.3.2 + jsesc: 2.5.2 + dev: true + + /@babel/generator@7.6.2: + resolution: {integrity: sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==} + dependencies: + '@babel/types': 7.19.4 + jsesc: 2.5.2 + lodash: 4.17.21 + source-map: 0.5.7 + dev: true + + /@babel/helper-compilation-targets@7.19.3(@babel/core@7.19.6): + resolution: {integrity: sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.19.4 + '@babel/core': 7.19.6 + '@babel/helper-validator-option': 7.18.6 + browserslist: 4.21.4 + semver: 6.3.0 + dev: true + + /@babel/helper-environment-visitor@7.18.9: + resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name@7.19.0: + resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.19.4 + dev: true + + /@babel/helper-hoist-variables@7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.4 + dev: true + + /@babel/helper-module-imports@7.18.6: + resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.4 + dev: true + + /@babel/helper-module-transforms@7.19.6: + resolution: {integrity: sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-module-imports': 7.18.6 + '@babel/helper-simple-access': 7.19.4 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.6 + '@babel/types': 7.19.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-plugin-utils@7.19.0: + resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-simple-access@7.19.4: + resolution: {integrity: sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.4 + dev: true + + /@babel/helper-split-export-declaration@7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.19.4 + dev: true + + /@babel/helper-string-parser@7.19.4: + resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.18.6: + resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helpers@7.19.4: + resolution: {integrity: sha512-G+z3aOx2nfDHwX/kyVii5fJq+bgscg89/dJNWpYeKeBv3v9xX8EIabmx1k6u9LS04H7nROFVRVK+e3k0VHp+sw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.18.10 + '@babel/traverse': 7.19.6 + '@babel/types': 7.19.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.19.6: + resolution: {integrity: sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.19.4 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.19.6): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.19.6): + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.19.6): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.19.6): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.19.6): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.19.6): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.19.6): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.19.6): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.19.6): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.19.6): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.19.6): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.19.6): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/plugin-syntax-typescript@7.18.6(@babel/core@7.19.6): + resolution: {integrity: sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.19.6 + '@babel/helper-plugin-utils': 7.19.0 + dev: true + + /@babel/runtime@7.19.4: + resolution: {integrity: sha512-EXpLCrk55f+cYqmHsSR+yD/0gAIMxxA9QK9lnQWzhMCvt+YmoBN7Zx94s++Kv0+unHk39vxNO8t+CMA2WSS3wA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.10 + dev: true + + /@babel/template@7.18.10: + resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/parser': 7.19.6 + '@babel/types': 7.19.4 + dev: true + + /@babel/traverse@7.19.6: + resolution: {integrity: sha512-6l5HrUCzFM04mfbG09AagtYyR2P0B71B1wN7PfSPiksDPz2k5H9CBC1tcZpz2M8OxbKTPccByoOJ22rUKbpmQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.19.6 + '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.19.6 + '@babel/types': 7.19.4 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/traverse@7.6.2: + resolution: {integrity: sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==} + dependencies: + '@babel/code-frame': 7.18.6 + '@babel/generator': 7.19.6 + '@babel/helper-function-name': 7.19.0 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.19.6 + '@babel/types': 7.19.4 + debug: 4.3.4 + globals: 11.12.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.19.4: + resolution: {integrity: sha512-M5LK7nAeS6+9j7hAq+b3fQs+pNfUtTGq+yFFfHnauFA8zQtLRfmuipmsKDKKLuyG+wC8ABW43A153YNawNTEtw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.19.4 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + dev: true + + /@bcoe/v8-coverage@0.2.3: + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + dev: true + + /@bugsnag/browser@6.5.2: + resolution: {integrity: sha512-XFKKorJc92ivLnlHHhLiPvkP03tZ5y7n0Z2xO6lOU7t+jWF5YapgwqQAda/TWvyYO38B/baWdnOpWMB3QmjhkA==} + dev: true + + /@bugsnag/js@6.5.2: + resolution: {integrity: sha512-4ibw624fM5+Y/WSuo3T/MsJVtslsPV8X0MxFuRxdvpKVUXX216d8hN8E/bG4hr7aipqQOGhBYDqSzeL2wgmh0Q==} + requiresBuild: true + dependencies: + '@bugsnag/browser': 6.5.2 + '@bugsnag/node': 6.5.2 + dev: true + + /@bugsnag/node@6.5.2: + resolution: {integrity: sha512-KQ1twKoOttMCYsHv7OXUVsommVcrk6RGQ5YoZGlTbREhccbzsvjbiXPKiY31Qc7OXKvaJwSXhnOKrQTpRleFUg==} + dependencies: + byline: 5.0.0 + error-stack-parser: 2.1.4 + iserror: 0.0.2 + pump: 3.0.0 + stack-generator: 2.0.10 + dev: true + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@esbuild/android-arm@0.15.12: + resolution: {integrity: sha512-IC7TqIqiyE0MmvAhWkl/8AEzpOtbhRNDo7aph47We1NbE5w2bt/Q+giAhe0YYeVpYnIhGMcuZY92qDK6dQauvA==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.15.12: + resolution: {integrity: sha512-tZEowDjvU7O7I04GYvWQOS4yyP9E/7YlsB0jjw1Ycukgr2ycEzKyIk5tms5WnLBymaewc6VmRKnn5IJWgK4eFw==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@ffmpeg-installer/darwin-arm64@4.1.5: + resolution: {integrity: sha512-hYqTiP63mXz7wSQfuqfFwfLOfwwFChUedeCVKkBtl/cliaTM7/ePI9bVzfZ2c+dWu3TqCwLDRWNSJ5pqZl8otA==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@ffmpeg-installer/darwin-x64@4.1.0: + resolution: {integrity: sha512-Z4EyG3cIFjdhlY8wI9aLUXuH8nVt7E9SlMVZtWvSPnm2sm37/yC2CwjUzyCQbJbySnef1tQwGG2Sx+uWhd9IAw==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@ffmpeg-installer/ffmpeg@1.1.0: + resolution: {integrity: sha512-Uq4rmwkdGxIa9A6Bd/VqqYbT7zqh1GrT5/rFwCwKM70b42W5gIjWeVETq6SdcL0zXqDtY081Ws/iJWhr1+xvQg==} + requiresBuild: true + optionalDependencies: + '@ffmpeg-installer/darwin-arm64': 4.1.5 + '@ffmpeg-installer/darwin-x64': 4.1.0 + '@ffmpeg-installer/linux-arm': 4.1.3 + '@ffmpeg-installer/linux-arm64': 4.1.4 + '@ffmpeg-installer/linux-ia32': 4.1.0 + '@ffmpeg-installer/linux-x64': 4.1.0 + '@ffmpeg-installer/win32-ia32': 4.1.0 + '@ffmpeg-installer/win32-x64': 4.1.0 + dev: true + + /@ffmpeg-installer/linux-arm64@4.1.4: + resolution: {integrity: sha512-dljEqAOD0oIM6O6DxBW9US/FkvqvQwgJ2lGHOwHDDwu/pX8+V0YsDL1xqHbj1DMX/+nP9rxw7G7gcUvGspSoKg==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@ffmpeg-installer/linux-arm@4.1.3: + resolution: {integrity: sha512-NDf5V6l8AfzZ8WzUGZ5mV8O/xMzRag2ETR6+TlGIsMHp81agx51cqpPItXPib/nAZYmo55Bl2L6/WOMI3A5YRg==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@ffmpeg-installer/linux-ia32@4.1.0: + resolution: {integrity: sha512-0LWyFQnPf+Ij9GQGD034hS6A90URNu9HCtQ5cTqo5MxOEc7Rd8gLXrJvn++UmxhU0J5RyRE9KRYstdCVUjkNOQ==} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@ffmpeg-installer/linux-x64@4.1.0: + resolution: {integrity: sha512-Y5BWhGLU/WpQjOArNIgXD3z5mxxdV8c41C+U15nsE5yF8tVcdCGet5zPs5Zy3Ta6bU7haGpIzryutqCGQA/W8A==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@ffmpeg-installer/win32-ia32@4.1.0: + resolution: {integrity: sha512-FV2D7RlaZv/lrtdhaQ4oETwoFUsUjlUiasiZLDxhEUPdNDWcH1OU9K1xTvqz+OXLdsmYelUDuBS/zkMOTtlUAw==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@ffmpeg-installer/win32-x64@4.1.0: + resolution: {integrity: sha512-Drt5u2vzDnIONf4ZEkKtFlbvwj6rI3kxw1Ck9fpudmtgaZIHD4ucsWB2lCZBXRxJgXR+2IMSti+4rtM4C4rXgg==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@financial-times/polyfill-useragent-normaliser@1.10.2: + resolution: {integrity: sha512-/9xHARfrKdWHt1ZXoT+/GpKx2N7uX88U1m6tF61AYSGaJFYaFlSoL1I4WbQOGH4eTQVb1z0a9LfwXaWblpRTBg==} + engines: {node: '>=8'} + dependencies: + '@financial-times/useragent_parser': 1.6.3 + semver: 7.3.8 + dev: true + + /@financial-times/useragent_parser@1.6.3: + resolution: {integrity: sha512-TlQiXt/vS5ZwY0V3salvlyQzIzMGZEyw9inmJA25A8heL2kBVENbToiEc64R6ETNf5YHa2lwnc2I7iNHP9SqeQ==} + dev: true + + /@firebase/analytics-types@0.4.0: + resolution: {integrity: sha512-Jj2xW+8+8XPfWGkv9HPv/uR+Qrmq37NPYT352wf7MvE9LrstpLVmFg3LqG6MCRr5miLAom5sen2gZ+iOhVDeRA==} + dev: true + + /@firebase/analytics@0.6.0(@firebase/app-types@0.6.1)(@firebase/app@0.6.11): + resolution: {integrity: sha512-6qYEOPUVYrMhqvJ46Z5Uf1S4uULd6d7vGpMP5Qz+u8kIWuOQGcPdJKQap+Hla6Rq164or9gC2HRXuYXKlgWfpw==} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + dependencies: + '@firebase/analytics-types': 0.4.0 + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/installations': 0.4.17(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/logger': 0.2.6 + '@firebase/util': 0.3.2 + tslib: 1.14.1 + dev: true + + /@firebase/app-compat@0.2.15: + resolution: {integrity: sha512-ttEbOEtO1SSz27cRPrwXAmrqDjdQ33sQc7rqqQuSMUuPRdYCQEcYdqzpkbvqgdkzGksx2kfH4JqQ6R/hI12nDw==} + dependencies: + '@firebase/app': 0.9.15 + '@firebase/component': 0.6.4 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.9.3 + tslib: 2.6.1 + dev: true + + /@firebase/app-types@0.6.1: + resolution: {integrity: sha512-L/ZnJRAq7F++utfuoTKX4CLBG5YR7tFO3PLzG1/oXXKEezJ0kRL3CMRoueBEmTCzVb/6SIs2Qlaw++uDgi5Xyg==} + dev: true + + /@firebase/app-types@0.6.3: + resolution: {integrity: sha512-/M13DPPati7FQHEQ9Minjk1HGLm/4K4gs9bR4rzLCWJg64yGtVC0zNg9gDpkw9yc2cvol/mNFxqTtd4geGrwdw==} + dev: true + + /@firebase/app-types@0.7.0: + resolution: {integrity: sha512-6fbHQwDv2jp/v6bXhBw2eSRbNBpxHcd1NBF864UksSMVIqIyri9qpJB1Mn6sGZE+bnDsSQBC5j2TbMxYsJQkQg==} + dev: true + + /@firebase/app-types@0.9.0: + resolution: {integrity: sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==} + dev: true + + /@firebase/app@0.6.11: + resolution: {integrity: sha512-FH++PaoyTzfTAVuJ0gITNYEIcjT5G+D0671La27MU8Vvr6MTko+5YUZ4xS9QItyotSeRF4rMJ1KR7G8LSyySiA==} + dependencies: + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/logger': 0.2.6 + '@firebase/util': 0.3.2 + dom-storage: 2.1.0 + tslib: 1.14.1 + xmlhttprequest: 1.8.0 + dev: true + + /@firebase/app@0.9.15: + resolution: {integrity: sha512-xxQi6mkhRjtXeFUwleSF4zU7lwEH+beNhLE7VmkzEzjEsjAS14QPQPZ35gpgSD+/NigOeho7wgEXd4C/bOkRfA==} + dependencies: + '@firebase/component': 0.6.4 + '@firebase/logger': 0.4.0 + '@firebase/util': 1.9.3 + idb: 7.1.1 + tslib: 2.6.1 + dev: true + + /@firebase/auth-interop-types@0.1.5(@firebase/app-types@0.6.1)(@firebase/util@0.3.2): + resolution: {integrity: sha512-88h74TMQ6wXChPA6h9Q3E1Jg6TkTHep2+k63OWg3s0ozyGVMeY+TTOti7PFPzq5RhszQPQOoCi59es4MaRvgCw==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 0.x + dependencies: + '@firebase/app-types': 0.6.1 + '@firebase/util': 0.3.2 + dev: true + + /@firebase/auth-interop-types@0.1.6(@firebase/app-types@0.9.0)(@firebase/util@1.5.2): + resolution: {integrity: sha512-etIi92fW3CctsmR9e3sYM3Uqnoq861M0Id9mdOPF6PWIg38BXL5k4upCNBggGUpLIS0H1grMOvy/wn1xymwe2g==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 1.x + dependencies: + '@firebase/app-types': 0.9.0 + '@firebase/util': 1.5.2 + dev: true + + /@firebase/auth-types@0.10.1(@firebase/app-types@0.6.1)(@firebase/util@0.3.2): + resolution: {integrity: sha512-/+gBHb1O9x/YlG7inXfxff/6X3BPZt4zgBv4kql6HEmdzNQCodIRlEYnI+/da+lN+dha7PjaFH7C7ewMmfV7rw==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 0.x + dependencies: + '@firebase/app-types': 0.6.1 + '@firebase/util': 0.3.2 + dev: true + + /@firebase/auth@0.15.0(@firebase/app-types@0.6.1)(@firebase/app@0.6.11)(@firebase/util@0.3.2): + resolution: {integrity: sha512-IFuzhxS+HtOQl7+SZ/Mhaghy/zTU7CENsJFWbC16tv2wfLZbayKF5jYGdAU3VFLehgC8KjlcIWd10akc3XivfQ==} + peerDependencies: + '@firebase/app': 0.x + dependencies: + '@firebase/app': 0.6.11 + '@firebase/auth-types': 0.10.1(@firebase/app-types@0.6.1)(@firebase/util@0.3.2) + transitivePeerDependencies: + - '@firebase/app-types' + - '@firebase/util' + dev: true + + /@firebase/component@0.1.19: + resolution: {integrity: sha512-L0S3g8eqaerg8y0zox3oOHSTwn/FE8RbcRHiurnbESvDViZtP5S5WnhuAPd7FnFxa8ElWK0z1Tr3ikzWDv1xdQ==} + dependencies: + '@firebase/util': 0.3.2 + tslib: 1.14.1 + dev: true + + /@firebase/component@0.5.13: + resolution: {integrity: sha512-hxhJtpD8Ppf/VU2Rlos6KFCEV77TGIGD5bJlkPK1+B/WUe0mC6dTjW7KhZtXTc+qRBp9nFHWcsIORnT8liHP9w==} + dependencies: + '@firebase/util': 1.5.2 + tslib: 2.4.0 + dev: true + + /@firebase/component@0.6.4: + resolution: {integrity: sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==} + dependencies: + '@firebase/util': 1.9.3 + tslib: 2.6.1 + dev: true + + /@firebase/database-compat@0.1.8(@firebase/app-compat@0.2.15)(@firebase/app-types@0.9.0): + resolution: {integrity: sha512-dhXr5CSieBuKNdU96HgeewMQCT9EgOIkfF1GNy+iRrdl7BWLxmlKuvLfK319rmIytSs/vnCzcD9uqyxTeU/A3A==} + peerDependencies: + '@firebase/app-compat': 0.x + dependencies: + '@firebase/app-compat': 0.2.15 + '@firebase/component': 0.5.13 + '@firebase/database': 0.12.8(@firebase/app-types@0.9.0) + '@firebase/database-types': 0.9.7 + '@firebase/logger': 0.3.2 + '@firebase/util': 1.5.2 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app-types' + dev: true + + /@firebase/database-types@0.5.2: + resolution: {integrity: sha512-ap2WQOS3LKmGuVFKUghFft7RxXTyZTDr0Xd8y2aqmWsbJVjgozi0huL/EUMgTjGFrATAjcf2A7aNs8AKKZ2a8g==} + dependencies: + '@firebase/app-types': 0.6.1 + dev: true + + /@firebase/database-types@0.7.3: + resolution: {integrity: sha512-dSOJmhKQ0nL8O4EQMRNGpSExWCXeHtH57gGg0BfNAdWcKhC8/4Y+qfKLfWXzyHvrSecpLmO0SmAi/iK2D5fp5A==} + dependencies: + '@firebase/app-types': 0.6.3 + dev: true + + /@firebase/database-types@0.9.7: + resolution: {integrity: sha512-EFhgL89Fz6DY3kkB8TzdHvdu8XaqqvzcF2DLVOXEnQ3Ms7L755p5EO42LfxXoJqb9jKFvgLpFmKicyJG25WFWw==} + dependencies: + '@firebase/app-types': 0.7.0 + '@firebase/util': 1.5.2 + dev: true + + /@firebase/database@0.12.8(@firebase/app-types@0.9.0): + resolution: {integrity: sha512-JBQVfFLzfhxlQbl4OU6ov9fdsddkytBQdtSSR49cz48homj38ccltAhK6seum+BI7f28cV2LFHF9672lcN+qxA==} + dependencies: + '@firebase/auth-interop-types': 0.1.6(@firebase/app-types@0.9.0)(@firebase/util@1.5.2) + '@firebase/component': 0.5.13 + '@firebase/logger': 0.3.2 + '@firebase/util': 1.5.2 + faye-websocket: 0.11.4 + tslib: 2.4.0 + transitivePeerDependencies: + - '@firebase/app-types' + dev: true + + /@firebase/database@0.6.13(@firebase/app-types@0.6.1): + resolution: {integrity: sha512-NommVkAPzU7CKd1gyehmi3lz0K78q0KOfiex7Nfy7MBMwknLm7oNqKovXSgQV1PCLvKXvvAplDSFhDhzIf9obA==} + dependencies: + '@firebase/auth-interop-types': 0.1.5(@firebase/app-types@0.6.1)(@firebase/util@0.3.2) + '@firebase/component': 0.1.19 + '@firebase/database-types': 0.5.2 + '@firebase/logger': 0.2.6 + '@firebase/util': 0.3.2 + faye-websocket: 0.11.3 + tslib: 1.14.1 + transitivePeerDependencies: + - '@firebase/app-types' + dev: true + + /@firebase/firestore-types@1.14.0(@firebase/app-types@0.6.1): + resolution: {integrity: sha512-WF8IBwHzZDhwyOgQnmB0pheVrLNP78A8PGxk1nxb/Nrgh1amo4/zYvFMGgSsTeaQK37xMYS/g7eS948te/dJxw==} + peerDependencies: + '@firebase/app-types': 0.x + dependencies: + '@firebase/app-types': 0.6.1 + dev: true + + /@firebase/firestore@1.18.0(@firebase/app-types@0.6.1)(@firebase/app@0.6.11): + resolution: {integrity: sha512-maMq4ltkrwjDRusR2nt0qS4wldHQMp+0IDSfXIjC+SNmjnWY/t/+Skn9U3Po+dB38xpz3i7nsKbs+8utpDnPSw==} + engines: {node: ^8.13.0 || >=10.10.0} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + dependencies: + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/firestore-types': 1.14.0(@firebase/app-types@0.6.1) + '@firebase/logger': 0.2.6 + '@firebase/util': 0.3.2 + '@firebase/webchannel-wrapper': 0.4.0 + '@grpc/grpc-js': 1.7.3 + '@grpc/proto-loader': 0.5.6 + node-fetch: 2.6.1 + tslib: 1.14.1 + dev: true + + /@firebase/functions-types@0.3.17: + resolution: {integrity: sha512-DGR4i3VI55KnYk4IxrIw7+VG7Q3gA65azHnZxo98Il8IvYLr2UTBlSh72dTLlDf25NW51HqvJgYJDKvSaAeyHQ==} + dev: true + + /@firebase/functions@0.5.1(@firebase/app-types@0.6.1)(@firebase/app@0.6.11): + resolution: {integrity: sha512-yyjPZXXvzFPjkGRSqFVS5Hc2Y7Y48GyyMH+M3i7hLGe69r/59w6wzgXKqTiSYmyE1pxfjxU4a1YqBDHNkQkrYQ==} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + dependencies: + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/functions-types': 0.3.17 + '@firebase/messaging-types': 0.5.0(@firebase/app-types@0.6.1) + node-fetch: 2.6.1 + tslib: 1.14.1 + dev: true + + /@firebase/installations-types@0.3.4(@firebase/app-types@0.6.1): + resolution: {integrity: sha512-RfePJFovmdIXb6rYwtngyxuEcWnOrzdZd9m7xAW0gRxDIjBT20n3BOhjpmgRWXo/DAxRmS7bRjWAyTHY9cqN7Q==} + peerDependencies: + '@firebase/app-types': 0.x + dependencies: + '@firebase/app-types': 0.6.1 + dev: true + + /@firebase/installations@0.4.17(@firebase/app-types@0.6.1)(@firebase/app@0.6.11): + resolution: {integrity: sha512-AE/TyzIpwkC4UayRJD419xTqZkKzxwk0FLht3Dci8WI2OEKHSwoZG9xv4hOBZebe+fDzoV2EzfatQY8c/6Avig==} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + dependencies: + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/installations-types': 0.3.4(@firebase/app-types@0.6.1) + '@firebase/util': 0.3.2 + idb: 3.0.2 + tslib: 1.14.1 + dev: true + + /@firebase/logger@0.2.6: + resolution: {integrity: sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==} + dev: true + + /@firebase/logger@0.3.2: + resolution: {integrity: sha512-lzLrcJp9QBWpo40OcOM9B8QEtBw2Fk1zOZQdvv+rWS6gKmhQBCEMc4SMABQfWdjsylBcDfniD1Q+fUX1dcBTXA==} + dependencies: + tslib: 2.4.0 + dev: true + + /@firebase/logger@0.4.0: + resolution: {integrity: sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==} + dependencies: + tslib: 2.6.1 + dev: true + + /@firebase/messaging-types@0.5.0(@firebase/app-types@0.6.1): + resolution: {integrity: sha512-QaaBswrU6umJYb/ZYvjR5JDSslCGOH6D9P136PhabFAHLTR4TWjsaACvbBXuvwrfCXu10DtcjMxqfhdNIB1Xfg==} + peerDependencies: + '@firebase/app-types': 0.x + dependencies: + '@firebase/app-types': 0.6.1 + dev: true + + /@firebase/messaging@0.7.1(@firebase/app-types@0.6.1)(@firebase/app@0.6.11): + resolution: {integrity: sha512-iev/ST9v0xd/8YpGYrZtDcqdD9J6ZWzSuceRn8EKy5vIgQvW/rk2eTQc8axzvDpQ36ZfphMYuhW6XuNrR3Pd2Q==} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + dependencies: + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/installations': 0.4.17(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/messaging-types': 0.5.0(@firebase/app-types@0.6.1) + '@firebase/util': 0.3.2 + idb: 3.0.2 + tslib: 1.14.1 + dev: true + + /@firebase/performance-types@0.0.13: + resolution: {integrity: sha512-6fZfIGjQpwo9S5OzMpPyqgYAUZcFzZxHFqOyNtorDIgNXq33nlldTL/vtaUZA8iT9TT5cJlCrF/jthKU7X21EA==} + dev: true + + /@firebase/performance@0.4.2(@firebase/app-types@0.6.1)(@firebase/app@0.6.11): + resolution: {integrity: sha512-irHTCVWJ/sxJo0QHg+yQifBeVu8ZJPihiTqYzBUz/0AGc51YSt49FZwqSfknvCN2+OfHaazz/ARVBn87g7Ex8g==} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + dependencies: + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/installations': 0.4.17(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/logger': 0.2.6 + '@firebase/performance-types': 0.0.13 + '@firebase/util': 0.3.2 + tslib: 1.14.1 + dev: true + + /@firebase/polyfill@0.3.36: + resolution: {integrity: sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg==} + dependencies: + core-js: 3.6.5 + promise-polyfill: 8.1.3 + whatwg-fetch: 2.0.4 + dev: true + + /@firebase/remote-config-types@0.1.9: + resolution: {integrity: sha512-G96qnF3RYGbZsTRut7NBX0sxyczxt1uyCgXQuH/eAfUCngxjEGcZQnBdy6mvSdqdJh5mC31rWPO4v9/s7HwtzA==} + dev: true + + /@firebase/remote-config@0.1.28(@firebase/app-types@0.6.1)(@firebase/app@0.6.11): + resolution: {integrity: sha512-4zSdyxpt94jAnFhO8toNjG8oMKBD+xTuBIcK+Nw8BdQWeJhEamgXlupdBARUk1uf3AvYICngHH32+Si/dMVTbw==} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + dependencies: + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/installations': 0.4.17(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/logger': 0.2.6 + '@firebase/remote-config-types': 0.1.9 + '@firebase/util': 0.3.2 + tslib: 1.14.1 + dev: true + + /@firebase/storage-types@0.3.13(@firebase/app-types@0.6.1)(@firebase/util@0.3.2): + resolution: {integrity: sha512-pL7b8d5kMNCCL0w9hF7pr16POyKkb3imOW7w0qYrhBnbyJTdVxMWZhb0HxCFyQWC0w3EiIFFmxoz8NTFZDEFog==} + peerDependencies: + '@firebase/app-types': 0.x + '@firebase/util': 0.x + dependencies: + '@firebase/app-types': 0.6.1 + '@firebase/util': 0.3.2 + dev: true + + /@firebase/storage@0.3.43(@firebase/app-types@0.6.1)(@firebase/app@0.6.11): + resolution: {integrity: sha512-Jp54jcuyimLxPhZHFVAhNbQmgTu3Sda7vXjXrNpPEhlvvMSq4yuZBR6RrZxe/OrNVprLHh/6lTCjwjOVSo3bWA==} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-types': 0.x + dependencies: + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/component': 0.1.19 + '@firebase/storage-types': 0.3.13(@firebase/app-types@0.6.1)(@firebase/util@0.3.2) + '@firebase/util': 0.3.2 + tslib: 1.14.1 + dev: true + + /@firebase/util@0.3.2: + resolution: {integrity: sha512-Dqs00++c8rwKky6KCKLLY2T1qYO4Q+X5t+lF7DInXDNF4ae1Oau35bkD+OpJ9u7l1pEv7KHowP6CUKuySCOc8g==} + dependencies: + tslib: 1.14.1 + dev: true + + /@firebase/util@1.5.2: + resolution: {integrity: sha512-YvBH2UxFcdWG2HdFnhxZptPl2eVFlpOyTH66iDo13JPEYraWzWToZ5AMTtkyRHVmu7sssUpQlU9igy1KET7TOw==} + dependencies: + tslib: 2.4.0 + dev: true + + /@firebase/util@1.9.3: + resolution: {integrity: sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==} + dependencies: + tslib: 2.6.1 + dev: true + + /@firebase/webchannel-wrapper@0.4.0: + resolution: {integrity: sha512-8cUA/mg0S+BxIZ72TdZRsXKBP5n5uRcE3k29TZhZw6oIiHBt9JA7CTb/4pE1uKtE/q5NeTY2tBDcagoZ+1zjXQ==} + dev: true + + /@formatjs/intl-pluralrules@1.5.9: + resolution: {integrity: sha512-37E1ZG+Oqo3qrpUfumzNcFTV+V+NCExmTkkQ9Zw4FSlvJ4WhbbeYdieVapUVz9M0cLy8XrhCkfuM/Kn03iKReg==} + dependencies: + '@formatjs/intl-utils': 2.3.0 + dev: true + + /@formatjs/intl-relativetimeformat@3.1.0: + resolution: {integrity: sha512-xSW9RMJtZZTGAlT7qCom+0INLYgshowpBN0Xf+j4kME+U/g/ogTVRFeGvCZX3nDQ21vdTHAabR3AIGQRX7NU1g==} + dependencies: + '@formatjs/intl-utils': 1.6.0 + dev: true + + /@formatjs/intl-utils@1.6.0: + resolution: {integrity: sha512-5D0C4tQgNFJNaJ17BYum0GfAcKNK3oa1VWzgkv/AN7i52fg4r69ZLcpEGpf6tZiX9Qld8CDwTQOeFt6fuOqgVw==} + deprecated: the package is rather renamed to @formatjs/ecma-abstract with some changes in functionality (primarily selectUnit is removed and we don't plan to make any further changes to this package + dev: true + + /@formatjs/intl-utils@2.3.0: + resolution: {integrity: sha512-KWk80UPIzPmUg+P0rKh6TqspRw0G6eux1PuJr+zz47ftMaZ9QDwbGzHZbtzWkl5hgayM/qrKRutllRC7D/vVXQ==} + deprecated: the package is rather renamed to @formatjs/ecma-abstract with some changes in functionality (primarily selectUnit is removed and we don't plan to make any further changes to this package + dev: true + + /@gar/promisify@1.1.3: + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + requiresBuild: true + dev: true + optional: true + + /@google-cloud/bigquery@4.7.0: + resolution: {integrity: sha512-u3VN1VUWcbVaW2vH5v2t0Zn5RSC4Hj3VCpf6sUO5xqcNTcHQyrjSd21aIBk28HgQO1H+9Gd1E0tGBfknGNONHw==} + engines: {node: '>=8.10.0'} + requiresBuild: true + dependencies: + '@google-cloud/common': 2.4.0 + '@google-cloud/paginator': 2.0.3 + '@google-cloud/promisify': 1.0.4 + arrify: 2.0.1 + big.js: 5.2.2 + duplexify: 4.1.2 + extend: 3.0.2 + is: 3.3.0 + stream-events: 1.0.5 + string-format-obj: 1.1.1 + uuid: 3.4.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@google-cloud/common@2.4.0: + resolution: {integrity: sha512-zWFjBS35eI9leAHhjfeOYlK5Plcuj/77EzstnrJIZbKgF/nkqjcQuGiMCpzCwOfPyUbz8ZaEOYgbHa759AKbjg==} + engines: {node: '>=8.10.0'} + dependencies: + '@google-cloud/projectify': 1.0.4 + '@google-cloud/promisify': 1.0.4 + arrify: 2.0.1 + duplexify: 3.7.1 + ent: 2.2.0 + extend: 3.0.2 + google-auth-library: 5.10.1 + retry-request: 4.2.2 + teeny-request: 6.0.3 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@google-cloud/firestore@4.15.1: + resolution: {integrity: sha512-2PWsCkEF1W02QbghSeRsNdYKN1qavrHBP3m72gPDMHQSYrGULOaTi7fSJquQmAtc4iPVB2/x6h80rdLHTATQtA==} + engines: {node: '>=10.10.0'} + requiresBuild: true + dependencies: + fast-deep-equal: 3.1.3 + functional-red-black-tree: 1.0.1 + google-gax: 2.30.5 + protobufjs: 6.11.3 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@google-cloud/paginator@2.0.3: + resolution: {integrity: sha512-kp/pkb2p/p0d8/SKUu4mOq8+HGwF8NPzHWkj+VKrIPQPyMRw8deZtrO/OcSiy9C/7bpfU5Txah5ltUNfPkgEXg==} + engines: {node: '>=8.10.0'} + dependencies: + arrify: 2.0.1 + extend: 3.0.2 + dev: true + + /@google-cloud/paginator@3.0.7: + resolution: {integrity: sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + arrify: 2.0.1 + extend: 3.0.2 + dev: true + optional: true + + /@google-cloud/projectify@1.0.4: + resolution: {integrity: sha512-ZdzQUN02eRsmTKfBj9FDL0KNDIFNjBn/d6tHQmA/+FImH5DO6ZV8E7FzxMgAUiVAUq41RFAkb25p1oHOZ8psfg==} + engines: {node: '>=8.10.0'} + dev: true + + /@google-cloud/projectify@2.1.1: + resolution: {integrity: sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==} + engines: {node: '>=10'} + requiresBuild: true + dev: true + optional: true + + /@google-cloud/promisify@1.0.4: + resolution: {integrity: sha512-VccZDcOql77obTnFh0TbNED/6ZbbmHDf8UMNnzO1d5g9V0Htfm4k5cllY8P1tJsRKC3zWYGRLaViiupcgVjBoQ==} + engines: {node: '>=8.10.0'} + dev: true + + /@google-cloud/promisify@2.0.4: + resolution: {integrity: sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==} + engines: {node: '>=10'} + requiresBuild: true + dev: true + optional: true + + /@google-cloud/storage@5.20.5: + resolution: {integrity: sha512-lOs/dCyveVF8TkVFnFSF7IGd0CJrTm91qiK6JLu+Z8qiT+7Ag0RyVhxZIWkhiACqwABo7kSHDm8FdH8p2wxSSw==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + '@google-cloud/paginator': 3.0.7 + '@google-cloud/projectify': 2.1.1 + '@google-cloud/promisify': 2.0.4 + abort-controller: 3.0.0 + arrify: 2.0.1 + async-retry: 1.3.3 + compressible: 2.0.18 + configstore: 5.0.1 + duplexify: 4.1.2 + ent: 2.2.0 + extend: 3.0.2 + gaxios: 4.3.3 + google-auth-library: 7.14.1 + hash-stream-validation: 0.2.4 + mime: 3.0.0 + mime-types: 2.1.35 + p-limit: 3.1.0 + pumpify: 2.0.1 + retry-request: 4.2.2 + stream-events: 1.0.5 + teeny-request: 7.2.0 + uuid: 8.3.2 + xdg-basedir: 4.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + optional: true + + /@grpc/grpc-js@1.6.12: + resolution: {integrity: sha512-JmvQ03OTSpVd9JTlj/K3IWHSz4Gk/JMLUTtW7Zb0KvO1LcOYGATh5cNuRYzCAeDR3O8wq+q8FZe97eO9MBrkUw==} + engines: {node: ^8.13.0 || >=10.10.0} + dependencies: + '@grpc/proto-loader': 0.7.3 + '@types/node': 14.18.29 + dev: true + + /@grpc/grpc-js@1.7.3: + resolution: {integrity: sha512-H9l79u4kJ2PVSxUNA08HMYAnUBLj9v6KjYQ7SQ71hOZcEXhShE/y5iQCesP8+6/Ik/7i2O0a10bPquIcYfufog==} + engines: {node: ^8.13.0 || >=10.10.0} + dependencies: + '@grpc/proto-loader': 0.7.3 + '@types/node': 14.18.29 + dev: true + + /@grpc/proto-loader@0.5.6: + resolution: {integrity: sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ==} + engines: {node: '>=6'} + dependencies: + lodash.camelcase: 4.3.0 + protobufjs: 6.11.3 + dev: true + + /@grpc/proto-loader@0.6.13: + resolution: {integrity: sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==} + engines: {node: '>=6'} + hasBin: true + dependencies: + '@types/long': 4.0.2 + lodash.camelcase: 4.3.0 + long: 4.0.0 + protobufjs: 6.11.3 + yargs: 16.2.0 + dev: true + + /@grpc/proto-loader@0.7.3: + resolution: {integrity: sha512-5dAvoZwna2Py3Ef96Ux9jIkp3iZ62TUsV00p3wVBPNX5K178UbNi8Q7gQVqwXT1Yq9RejIGG9G2IPEo93T6RcA==} + engines: {node: '>=6'} + hasBin: true + dependencies: + '@types/long': 4.0.2 + lodash.camelcase: 4.3.0 + long: 4.0.0 + protobufjs: 7.1.2 + yargs: 16.2.0 + dev: true + + /@ioredis/commands@1.2.0: + resolution: {integrity: sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg==} + dev: true + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/console@27.5.1: + resolution: {integrity: sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + chalk: 4.1.2 + jest-message-util: 27.5.1 + jest-util: 27.5.1 + slash: 3.0.0 + dev: true + + /@jest/core@27.5.1(canvas@2.11.2)(ts-node@10.9.1): + resolution: {integrity: sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/console': 27.5.1 + '@jest/reporters': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.8.1 + exit: 0.1.2 + graceful-fs: 4.2.10 + jest-changed-files: 27.5.1 + jest-config: 27.5.1(canvas@2.11.2)(ts-node@10.9.1) + jest-haste-map: 27.5.1 + jest-message-util: 27.5.1 + jest-regex-util: 27.5.1 + jest-resolve: 27.5.1 + jest-resolve-dependencies: 27.5.1 + jest-runner: 27.5.1(canvas@2.11.2) + jest-runtime: 27.5.1 + jest-snapshot: 27.5.1 + jest-util: 27.5.1 + jest-validate: 27.5.1 + jest-watcher: 27.5.1 + micromatch: 4.0.5 + rimraf: 3.0.2 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /@jest/environment@27.5.1: + resolution: {integrity: sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/fake-timers': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + jest-mock: 27.5.1 + dev: true + + /@jest/fake-timers@27.5.1: + resolution: {integrity: sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + '@sinonjs/fake-timers': 8.1.0 + '@types/node': 14.18.29 + jest-message-util: 27.5.1 + jest-mock: 27.5.1 + jest-util: 27.5.1 + dev: true + + /@jest/globals@27.5.1: + resolution: {integrity: sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.5.1 + '@jest/types': 27.5.1 + expect: 27.5.1 + dev: true + + /@jest/reporters@27.5.1: + resolution: {integrity: sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + chalk: 4.1.2 + collect-v8-coverage: 1.0.1 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + istanbul-lib-coverage: 3.2.0 + istanbul-lib-instrument: 5.2.1 + istanbul-lib-report: 3.0.0 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.5 + jest-haste-map: 27.5.1 + jest-resolve: 27.5.1 + jest-util: 27.5.1 + jest-worker: 27.5.1 + slash: 3.0.0 + source-map: 0.6.1 + string-length: 4.0.2 + terminal-link: 2.1.1 + v8-to-istanbul: 8.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/source-map@27.5.1: + resolution: {integrity: sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + callsites: 3.1.0 + graceful-fs: 4.2.10 + source-map: 0.6.1 + dev: true + + /@jest/test-result@27.5.1: + resolution: {integrity: sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/console': 27.5.1 + '@jest/types': 27.5.1 + '@types/istanbul-lib-coverage': 2.0.4 + collect-v8-coverage: 1.0.1 + dev: true + + /@jest/test-sequencer@27.5.1: + resolution: {integrity: sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/test-result': 27.5.1 + graceful-fs: 4.2.10 + jest-haste-map: 27.5.1 + jest-runtime: 27.5.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/transform@27.5.1: + resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@babel/core': 7.19.6 + '@jest/types': 27.5.1 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.9.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.10 + jest-haste-map: 27.5.1 + jest-regex-util: 27.5.1 + jest-util: 27.5.1 + micromatch: 4.0.5 + pirates: 4.0.5 + slash: 3.0.0 + source-map: 0.6.1 + write-file-atomic: 3.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types@27.5.1: + resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 14.18.29 + '@types/yargs': 16.0.4 + chalk: 4.1.2 + dev: true + + /@jimp/bmp@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-uxVgSkI62uAzk5ZazYHEHBehow590WAkLKmDXLzkr/XP/Hv2Fx1T4DKwJ/15IY5ktq5VAhAUWGXTyd8KWFsx7w==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + bmp-js: 0.1.0 + core-js: 2.6.12 + dev: true + + /@jimp/core@0.6.8: + resolution: {integrity: sha512-JOFqBBcSNiDiMZJFr6OJqC6viXj5NVBQISua0eacoYvo4YJtTajOIxC4MqWyUmGrDpRMZBR8QhSsIOwsFrdROA==} + dependencies: + '@jimp/utils': 0.6.8 + any-base: 1.1.0 + buffer: 5.7.1 + core-js: 2.6.12 + exif-parser: 0.1.12 + file-type: 9.0.0 + load-bmfont: 1.4.1 + mkdirp: 0.5.1 + phin: 2.9.3 + pixelmatch: 4.0.2 + tinycolor2: 1.4.2 + dev: true + + /@jimp/custom@0.6.8: + resolution: {integrity: sha512-FrYlzZRVXP2vuVwd7Nc2dlK+iZk4g6IaT1Ib8Z6vU5Kkwlt83FJIPJ2UUFABf3bF5big0wkk8ZUihWxE4Nzdng==} + dependencies: + '@jimp/core': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/gif@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-yyOlujjQcgz9zkjM5ihZDEppn9d1brJ7jQHP5rAKmqep0G7FU1D0AKcV+Ql18RhuI/CgWs10wAVcrQpmLnu4Yw==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + omggif: 1.0.10 + dev: true + + /@jimp/jpeg@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-rGtXbYpFXAn471qLpTGvhbBMNHJo5KiufN+vC5AWyufntmkt5f0Ox2Cx4ijuBMDtirZchxbMLtrfGjznS4L/ew==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + jpeg-js: 0.3.7 + dev: true + + /@jimp/plugin-blit@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-7Tl6YpKTSpvwQbnGNhsfX2zyl3jRVVopd276Y2hF2zpDz9Bycow7NdfNU/4Nx1jaf96X6uWOtSVINcQ7rGd47w==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-blur@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-NpZCMKxXHLDQsX9zPlWtpMA660DQStY6/z8ZetyxCDbqrLe9YCXpeR4MNhdJdABIiwTm1W5FyFF4kp81PHJx3Q==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-color@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-jjFyU0zNmGOH2rjzHuOMU4kaia0oo82s/7UYfn5h7OUkmUZTd6Do3ZSK1PiXA7KR+s4B76/Omm6Doh/0SGb7BQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + tinycolor2: 1.4.2 + dev: true + + /@jimp/plugin-contain@0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-blit@0.6.8)(@jimp/plugin-resize@0.6.8)(@jimp/plugin-scale@0.6.8): + resolution: {integrity: sha512-p/P2wCXhAzbmEgXvGsvmxLmbz45feF6VpR4m9suPSOr8PC/i/XvTklTqYEUidYYAft4vHgsYJdS74HKSMnH8lw==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-blit': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + '@jimp/plugin-scale': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/plugin-blit': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-resize': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-scale': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-resize@0.6.8) + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-cover@0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-crop@0.6.8)(@jimp/plugin-resize@0.6.8)(@jimp/plugin-scale@0.6.8): + resolution: {integrity: sha512-2PvWgk+PJfRsfWDI1G8Fpjrsu0ZlpNyZxO2+fqWlVo6y/y2gP4v08FqvbkcqSjNlOu2IDWIFXpgyU0sTINWZLg==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-crop': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + '@jimp/plugin-scale': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/plugin-crop': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-resize': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-scale': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-resize@0.6.8) + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-crop@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-CbrcpWE2xxPK1n/JoTXzhRUhP4mO07mTWaSavenCg664oQl/9XCtL+A0FekuNHzIvn4myEqvkiTwN7FsbunS/Q==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-displace@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-RmV2bPxoPE6mrPxtYSPtHxm2cGwBQr5a2p+9gH6SPy+eUMrbGjbvjwKNfXWUYD0leML+Pt5XOmAS9pIROmuruQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-dither@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-x6V/qjxe+xypjpQm7GbiMNqci1EW5UizrcebOhHr8AHijOEqHd2hjXh5f6QIGfrkTFelc4/jzq1UyCsYntqz9Q==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-flip@0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-rotate@0.6.8): + resolution: {integrity: sha512-4il6Da6G39s9MyWBEee4jztEOUGJ40E6OlPjkMrdpDNvge6hYEAB31BczTYBP/CEY74j4LDSoY5LbcU4kv06yA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-rotate': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/plugin-rotate': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-blit@0.6.8)(@jimp/plugin-crop@0.6.8)(@jimp/plugin-resize@0.6.8) + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-gaussian@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-pVOblmjv7stZjsqloi4YzHVwAPXKGdNaHPhp4KP4vj41qtc6Hxd9z/+VWGYRTunMFac84gUToe0UKIXd6GhoKw==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-invert@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-11zuLiXDHr6tFv4U8aieXqNXQEKbDbSBG/h+X62gGTNFpyn8EVPpncHhOqrAFtZUaPibBqMFlNJ15SzwC7ExsQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-mask@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-hZJ0OiKGJyv7hDSATwJDkunB1Ie80xJnONMgpUuUseteK45YeYNBOiZVUe8vum8QI1UwavgBzcvQ9u4fcgXc9g==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-normalize@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-Q4oYhU+sSyTJI7pMZlg9/mYh68ujLfOxXzQGEXuw0sHGoGQs3B0Jw7jmzGa6pIS06Hup5hD2Zuh1ppvMdjJBfQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-print@0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-blit@0.6.8): + resolution: {integrity: sha512-2aokejGn4Drv1FesnZGqh5KEq0FQtR0drlmtyZrBH+r9cx7hh0Qgf4D1BOTDEgXkfSSngjGRjKKRW/fwOrVXYw==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-blit': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/plugin-blit': 0.6.8(@jimp/custom@0.6.8) + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + load-bmfont: 1.4.1 + dev: true + + /@jimp/plugin-resize@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-27nPh8L1YWsxtfmV/+Ub5dOTpXyC0HMF2cu52RQSCYxr+Lm1+23dJF70AF1poUbUe+FWXphwuUxQzjBJza9UoA==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-rotate@0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-blit@0.6.8)(@jimp/plugin-crop@0.6.8)(@jimp/plugin-resize@0.6.8): + resolution: {integrity: sha512-GbjETvL05BDoLdszNUV4Y0yLkHf177MnqGqilA113LIvx9aD0FtUopGXYfRGVvmtTOTouoaGJUc+K6qngvKxww==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-blit': '>=0.3.5' + '@jimp/plugin-crop': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/plugin-blit': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-crop': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-resize': 0.6.8(@jimp/custom@0.6.8) + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugin-scale@0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-resize@0.6.8): + resolution: {integrity: sha512-GzIYWR/oCUK2jAwku23zt19V1ssaEU4pL0x2XsLNKuuJEU6DvEytJyTMXCE7OLG/MpDBQcQclJKHgiyQm5gIOQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + '@jimp/plugin-resize': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/plugin-resize': 0.6.8(@jimp/custom@0.6.8) + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + dev: true + + /@jimp/plugins@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-fMcTI72Vn/Lz6JftezTURmyP5ml/xGMe0Ljx2KRJ85IWyP33vDmGIUuutFiBEbh2+y7lRT+aTSmjs0QGa/xTmQ==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/plugin-blit': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-blur': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-color': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-contain': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-blit@0.6.8)(@jimp/plugin-resize@0.6.8)(@jimp/plugin-scale@0.6.8) + '@jimp/plugin-cover': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-crop@0.6.8)(@jimp/plugin-resize@0.6.8)(@jimp/plugin-scale@0.6.8) + '@jimp/plugin-crop': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-displace': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-dither': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-flip': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-rotate@0.6.8) + '@jimp/plugin-gaussian': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-invert': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-mask': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-normalize': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-print': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-blit@0.6.8) + '@jimp/plugin-resize': 0.6.8(@jimp/custom@0.6.8) + '@jimp/plugin-rotate': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-blit@0.6.8)(@jimp/plugin-crop@0.6.8)(@jimp/plugin-resize@0.6.8) + '@jimp/plugin-scale': 0.6.8(@jimp/custom@0.6.8)(@jimp/plugin-resize@0.6.8) + core-js: 2.6.12 + timm: 1.7.1 + dev: true + + /@jimp/png@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-JHHg/BZ7KDtHQrcG+a7fztw45rdf7okL/YwkN4qU5FH7Fcrp41nX5QnRviDtD9hN+GaNC7kvjvcqRAxW25qjew==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/utils': 0.6.8 + core-js: 2.6.12 + pngjs: 3.4.0 + dev: true + + /@jimp/tiff@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-iWHbxd+0IKWdJyJ0HhoJCGYmtjPBOusz1z1HT/DnpePs/Lo3TO4d9ALXqYfUkyG74ZK5jULZ69KLtwuhuJz1bg==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/custom': 0.6.8 + core-js: 2.6.12 + utif: 2.0.1 + dev: true + + /@jimp/types@0.6.8(@jimp/custom@0.6.8): + resolution: {integrity: sha512-vCZ/Cp2osy69VP21XOBACfHI5HeR60Rfd4Jidj4W73UL+HrFWOtyQiJ7hlToyu1vI5mR/NsUQpzyQvz56ADm5A==} + peerDependencies: + '@jimp/custom': '>=0.3.5' + dependencies: + '@jimp/bmp': 0.6.8(@jimp/custom@0.6.8) + '@jimp/custom': 0.6.8 + '@jimp/gif': 0.6.8(@jimp/custom@0.6.8) + '@jimp/jpeg': 0.6.8(@jimp/custom@0.6.8) + '@jimp/png': 0.6.8(@jimp/custom@0.6.8) + '@jimp/tiff': 0.6.8(@jimp/custom@0.6.8) + core-js: 2.6.12 + timm: 1.7.1 + dev: true + + /@jimp/utils@0.6.8: + resolution: {integrity: sha512-7RDfxQ2C/rarNG9iso5vmnKQbcvlQjBIlF/p7/uYj72WeZgVCB+5t1fFBKJSU4WhniHX4jUMijK+wYGE3Y3bGw==} + dependencies: + core-js: 2.6.12 + dev: true + + /@josephg/resolvable@1.0.1: + resolution: {integrity: sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg==} + dev: true + + /@jridgewell/gen-mapping@0.1.1: + resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@jridgewell/gen-mapping@0.3.2: + resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/trace-mapping': 0.3.17 + dev: true + + /@jridgewell/resolve-uri@3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/trace-mapping@0.3.17: + resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@mapbox/node-pre-gyp@1.0.10: + resolution: {integrity: sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==} + hasBin: true + dependencies: + detect-libc: 2.0.1 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.6.12 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.3.8 + tar: 6.1.11 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@mdx-js/mdx@2.2.1: + resolution: {integrity: sha512-hZ3ex7exYLJn6FfReq8yTvA6TE53uW9UHJQM9IlSauOuS55J9y8RtA7W+dzp6Yrzr00/U1sd7q+Wf61q6SfiTQ==} + dependencies: + '@types/estree-jsx': 1.0.0 + '@types/mdx': 2.0.3 + estree-util-build-jsx: 2.2.2 + estree-util-is-identifier-name: 2.0.1 + estree-util-to-js: 1.1.0 + estree-walker: 3.0.2 + hast-util-to-estree: 2.2.1 + markdown-extensions: 1.1.1 + periscopic: 3.0.4 + remark-mdx: 2.2.1 + remark-parse: 10.0.1 + remark-rehype: 10.1.0 + unified: 10.1.2 + unist-util-position-from-estree: 1.1.1 + unist-util-stringify-position: 3.0.2 + unist-util-visit: 4.1.1 + vfile: 5.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@mdx-js/node-loader@2.2.1: + resolution: {integrity: sha512-Ku2xqaDPSYZ1zxtulFBQ1wkBZZllJD1Rxj/TxVrTuRqRSJzglmLyrddk7m1kOUB3LQMZcDJCEIlDzLuIwTuNlg==} + dependencies: + '@mdx-js/mdx': 2.2.1 + vfile: 5.3.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@msgpackr-extract/msgpackr-extract-darwin-arm64@2.2.0: + resolution: {integrity: sha512-Z9LFPzfoJi4mflGWV+rv7o7ZbMU5oAU9VmzCgL240KnqDW65Y2HFCT3MW06/ITJSnbVLacmcEJA8phywK7JinQ==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@msgpackr-extract/msgpackr-extract-darwin-x64@2.2.0: + resolution: {integrity: sha512-vq0tT8sjZsy4JdSqmadWVw6f66UXqUCabLmUVHZwUFzMgtgoIIQjT4VVRHKvlof3P/dMCkbMJ5hB1oJ9OWHaaw==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@msgpackr-extract/msgpackr-extract-linux-arm64@2.2.0: + resolution: {integrity: sha512-hlxxLdRmPyq16QCutUtP8Tm6RDWcyaLsRssaHROatgnkOxdleMTgetf9JsdncL8vLh7FVy/RN9i3XR5dnb9cRA==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@msgpackr-extract/msgpackr-extract-linux-arm@2.2.0: + resolution: {integrity: sha512-SaJ3Qq4lX9Syd2xEo9u3qPxi/OB+5JO/ngJKK97XDpa1C587H9EWYO6KD8995DAjSinWvdHKRrCOXVUC5fvGOg==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@msgpackr-extract/msgpackr-extract-linux-x64@2.2.0: + resolution: {integrity: sha512-94y5PJrSOqUNcFKmOl7z319FelCLAE0rz/jPCWS+UtdMZvpa4jrQd+cJPQCLp2Fes1yAW/YUQj/Di6YVT3c3Iw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@msgpackr-extract/msgpackr-extract-win32-x64@2.2.0: + resolution: {integrity: sha512-XrC0JzsqQSvOyM3t04FMLO6z5gCuhPE6k4FXuLK5xf52ZbdvcFe1yBmo7meCew9B8G2f0T9iu9t3kfTYRYROgA==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.13.0 + dev: true + + /@npmcli/fs@1.1.1: + resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} + requiresBuild: true + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.3.8 + dev: true + optional: true + + /@npmcli/move-file@1.1.2: + resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} + engines: {node: '>=10'} + deprecated: This functionality has been moved to @npmcli/fs + requiresBuild: true + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + dev: true + optional: true + + /@panva/asn1.js@1.0.0: + resolution: {integrity: sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==} + engines: {node: '>=10.13.0'} + dev: true + + /@phc/format@1.0.0: + resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==} + engines: {node: '>=10'} + dev: true + + /@protobufjs/aspromise@1.1.2: + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + dev: true + + /@protobufjs/base64@1.1.2: + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + dev: true + + /@protobufjs/codegen@2.0.4: + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + dev: true + + /@protobufjs/eventemitter@1.1.0: + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + dev: true + + /@protobufjs/fetch@1.1.0: + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + dev: true + + /@protobufjs/float@1.0.2: + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + dev: true + + /@protobufjs/inquire@1.1.0: + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + dev: true + + /@protobufjs/path@1.1.2: + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + dev: true + + /@protobufjs/pool@1.1.0: + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + dev: true + + /@protobufjs/utf8@1.1.0: + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + dev: true + + /@rdf-esm/data-model@0.5.4: + resolution: {integrity: sha512-EINrtebCO6aT9e8vLmkaFFs317sCRj9cdFlKexvZA+7bLwcKrmcQLwC+nnnyBurtypHzWlokbLvp1SZHQWiH3w==} + engines: {node: '>=12'} + hasBin: true + dependencies: + '@rdfjs/data-model': 1.3.4 + dev: true + + /@rdf-esm/namespace@0.5.5: + resolution: {integrity: sha512-JF26H4Mx+N93qIOu3KMsjdUW6As+dhvq9wP2Q03fjiS4l1rG+gKwfKUop8CHtVETVeDcNsO3+Srrq0wiQgAPDw==} + engines: {node: '>=12'} + dependencies: + '@rdf-esm/data-model': 0.5.4 + '@rdfjs/namespace': 1.1.0 + '@types/rdfjs__namespace': 2.0.0 + dev: true + + /@rdf-esm/term-map@0.5.1: + resolution: {integrity: sha512-Yq/5hBFt90q/eru2i9NVBxAayaGI/oWTPH1+6VoFueiaKSVl4Pf4lMX98/Hg/si5Ql0gG4B4wqBbFItl4LDI0A==} + engines: {node: '>=12'} + dependencies: + '@rdf-esm/to-ntriples': 0.6.0 + '@rdfjs/term-map': 1.1.0 + dev: true + + /@rdf-esm/term-set@0.5.0: + resolution: {integrity: sha512-vWh8VtGUX1n4pEHmr/NyNzE0+yqCOcx3vUYbMVpk0Q0mgAB2n3+8yl/RXE8203z3PXsS4C1UPlO6YCSPbQS2rw==} + engines: {node: '>=12'} + dependencies: + '@rdf-esm/to-ntriples': 0.5.0 + '@rdfjs/term-set': 1.1.0 + dev: true + + /@rdf-esm/to-ntriples@0.5.0: + resolution: {integrity: sha512-VIcqRv68V/s0NS6bFy58CcsHwV0UCM/DHhAc1MYLB/yue1nyhKsX4uyu/SB5gbbY2r4BIH4G6O+arxf59KzgwQ==} + engines: {node: '>=12'} + deprecated: Use @rdfjs/to-ntriples + dev: true + + /@rdf-esm/to-ntriples@0.6.0: + resolution: {integrity: sha512-984lPZhKmFuLuJ74Q8SqtwzDDS43V98QXjpvu6jmlXEF2xQHwItmQk0AZ9Cyf26f3EiTVfLn3JHGWwkB0AK8IQ==} + engines: {node: '>=12'} + deprecated: Use @rdfjs/to-ntriples + dependencies: + '@rdfjs/to-ntriples': 2.0.0 + dev: true + + /@rdfjs/data-model@1.3.4: + resolution: {integrity: sha512-iKzNcKvJotgbFDdti7GTQDCYmL7GsGldkYStiP0K8EYtN7deJu5t7U11rKTz+nR7RtesUggT+lriZ7BakFv8QQ==} + hasBin: true + dependencies: + '@rdfjs/types': 1.1.0 + dev: true + + /@rdfjs/dataset@1.1.1: + resolution: {integrity: sha512-BNwCSvG0cz0srsG5esq6CQKJc1m8g/M0DZpLuiEp0MMpfwguXX7VeS8TCg4UUG3DV/DqEvhy83ZKSEjdsYseeA==} + hasBin: true + dependencies: + '@rdfjs/data-model': 1.3.4 + dev: true + + /@rdfjs/namespace@1.1.0: + resolution: {integrity: sha512-utO5rtaOKxk8B90qzaQ0N+J5WrCI28DtfAY/zExCmXE7cOfC5uRI/oMKbLaVEPj2P7uArekt/T4IPATtj7Tjug==} + engines: {node: '>=6'} + dependencies: + '@rdfjs/data-model': 1.3.4 + dev: true + + /@rdfjs/parser-n3@1.1.4: + resolution: {integrity: sha512-PUKSNlfD2Zq3GcQZuOF2ndfrLbc+N96FUe2gNIzARlR2er0BcOHBHEFUJvVGg1Xmsg3hVKwfg0nwn1JZ7qKKMw==} + dependencies: + '@rdfjs/data-model': 1.3.4 + '@rdfjs/sink': 1.0.3 + n3: 1.16.2 + readable-stream: 3.6.0 + readable-to-readable: 0.1.3 + dev: true + + /@rdfjs/sink@1.0.3: + resolution: {integrity: sha512-2KfYa8mAnptRNeogxhQqkWNXqfYVWO04jQThtXKepySrIwYmz83+WlevQtA4VDLFe+kFd2TwgL29ekPe5XVUfA==} + engines: {node: '>=6'} + dev: true + + /@rdfjs/term-map@1.1.0: + resolution: {integrity: sha512-utCLVQEZdEL664XoYuBQwMIk0Q5MD6qNPEt12DcmuAlQUS0b0kQ+WL50wyJP1BpWYjOJLokIVTUtphZWnj25BQ==} + dependencies: + '@rdfjs/to-ntriples': 2.0.0 + dev: true + + /@rdfjs/term-set@1.1.0: + resolution: {integrity: sha512-QQ4yzVe1Rvae/GN9SnOhweHNpaxQtnAjeOVciP/yJ0Gfxtbphy2tM56ZsRLV04Qq5qMcSclZIe6irYyEzx/UwQ==} + dependencies: + '@rdfjs/to-ntriples': 2.0.0 + dev: true + + /@rdfjs/to-ntriples@1.0.2: + resolution: {integrity: sha512-ngw5XAaGHjgGiwWWBPGlfdCclHftonmbje5lMys4G2j4NvfExraPIuRZgjSnd5lg4dnulRVUll8tRbgKO+7EDA==} + engines: {node: '>=6'} + dev: true + + /@rdfjs/to-ntriples@2.0.0: + resolution: {integrity: sha512-nDhpfhx6W6HKsy4HjyLp3H1nbrX1CiUCWhWQwKcYZX1s9GOjcoQTwY7GUUbVec0hzdJDQBR6gnjxtENBDt482Q==} + dev: true + + /@rdfjs/types@1.1.0: + resolution: {integrity: sha512-5zm8bN2/CC634dTcn/0AhTRLaQRjXDZs3QfcAsQKNturHT7XVWcKy/8p3P5gXl+YkZTAmy7T5M/LyiT/jbkENw==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@segment/loosely-validate-event@2.0.0: + resolution: {integrity: sha512-ZMCSfztDBqwotkl848ODgVcAmN4OItEWDCkshcKz0/W6gGSQayuuCtWV/MlodFivAZD793d6UgANd6wCXUfrIw==} + dependencies: + component-type: 1.2.1 + join-component: 1.1.0 + dev: true + + /@sentry/core@5.30.0: + resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} + engines: {node: '>=6'} + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + dev: true + + /@sentry/hub@5.30.0: + resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} + engines: {node: '>=6'} + dependencies: + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + dev: true + + /@sentry/minimal@5.30.0: + resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} + engines: {node: '>=6'} + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/types': 5.30.0 + tslib: 1.14.1 + dev: true + + /@sentry/node@5.30.0: + resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} + engines: {node: '>=6'} + requiresBuild: true + dependencies: + '@sentry/core': 5.30.0 + '@sentry/hub': 5.30.0 + '@sentry/tracing': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@sentry/tracing@5.30.0: + resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} + engines: {node: '>=6'} + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + dev: true + + /@sentry/types@5.30.0: + resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} + engines: {node: '>=6'} + dev: true + + /@sentry/utils@5.30.0: + resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} + engines: {node: '>=6'} + dependencies: + '@sentry/types': 5.30.0 + tslib: 1.14.1 + dev: true + + /@sindresorhus/is@0.7.0: + resolution: {integrity: sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==} + engines: {node: '>=4'} + dev: true + + /@sindresorhus/is@4.6.0: + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + dev: true + + /@sinonjs/commons@1.8.3: + resolution: {integrity: sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==} + dependencies: + type-detect: 4.0.8 + dev: true + + /@sinonjs/fake-timers@8.1.0: + resolution: {integrity: sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==} + dependencies: + '@sinonjs/commons': 1.8.3 + dev: true + + /@swc/helpers@0.3.17: + resolution: {integrity: sha512-tb7Iu+oZ+zWJZ3HJqwx8oNwSDIU440hmVMDPhpACWQWnrZHK99Bxs70gT1L2dnr5Hg50ZRWEFkQCAnOVVV0z1Q==} + dependencies: + tslib: 2.4.0 + dev: true + + /@szmarczak/http-timer@4.0.6: + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + dependencies: + defer-to-connect: 2.0.1 + dev: true + + /@tootallnate/once@1.1.2: + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + dev: true + + /@tootallnate/once@2.0.0: + resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} + engines: {node: '>= 10'} + requiresBuild: true + dev: true + optional: true + + /@tpluscode/rdf-ns-builders@2.0.1(@zazuko/rdf-vocabularies@2022.6.29)(clownface@1.5.1)(safe-identifier@0.4.2)(ts-morph@15.1.0)(ts-node@10.9.1): + resolution: {integrity: sha512-P/pwfjhcj/JOZF3epheHiDd/f9tSkceydQBqBuqThpNX2NIg+4BSgwtG2YfKBa24mmGFfyzN6RVeFclhA8wZBw==} + hasBin: true + peerDependencies: + '@zazuko/rdf-vocabularies': '*' + clownface: ^1 + safe-identifier: ^0.4.2 + ts-morph: '>=11' + ts-node: '>= 8' + dependencies: + '@rdf-esm/data-model': 0.5.4 + '@rdf-esm/namespace': 0.5.5 + '@rdfjs/types': 1.1.0 + '@zazuko/rdf-vocabularies': 2022.6.29 + clownface: 1.5.1 + commander: 7.2.0 + fs-extra: 10.1.0 + safe-identifier: 0.4.2 + ts-morph: 15.1.0 + ts-node: 10.9.1(@types/node@14.18.29)(typescript@4.8.4) + dev: true + + /@tpluscode/rdf-ns-builders@2.0.1(@zazuko/rdf-vocabularies@2023.1.19)(clownface@1.5.1)(safe-identifier@0.4.2)(ts-morph@15.1.0)(ts-node@10.9.1): + resolution: {integrity: sha512-P/pwfjhcj/JOZF3epheHiDd/f9tSkceydQBqBuqThpNX2NIg+4BSgwtG2YfKBa24mmGFfyzN6RVeFclhA8wZBw==} + hasBin: true + peerDependencies: + '@zazuko/rdf-vocabularies': '*' + clownface: ^1 + safe-identifier: ^0.4.2 + ts-morph: '>=11' + ts-node: '>= 8' + dependencies: + '@rdf-esm/data-model': 0.5.4 + '@rdf-esm/namespace': 0.5.5 + '@rdfjs/types': 1.1.0 + '@zazuko/rdf-vocabularies': 2023.1.19 + clownface: 1.5.1 + commander: 7.2.0 + fs-extra: 10.1.0 + safe-identifier: 0.4.2 + ts-morph: 15.1.0 + ts-node: 10.9.1(@types/node@14.18.29)(typescript@4.8.4) + dev: true + + /@tpluscode/rdf-string@0.2.26(clownface@1.5.1)(safe-identifier@0.4.2)(ts-morph@15.1.0)(ts-node@10.9.1): + resolution: {integrity: sha512-zfNGMmY8D9jVuJ9qHwNrIWMwhibIkO42/1KtCfo59m4vXYTfJrXcn1ny9pj5kuhbpSubRbJ69zmYxP4UrXVPQw==} + dependencies: + '@rdf-esm/data-model': 0.5.4 + '@rdf-esm/term-map': 0.5.1 + '@rdfjs/types': 1.1.0 + '@tpluscode/rdf-ns-builders': 2.0.1(@zazuko/rdf-vocabularies@2022.6.29)(clownface@1.5.1)(safe-identifier@0.4.2)(ts-morph@15.1.0)(ts-node@10.9.1) + '@zazuko/rdf-vocabularies': 2022.6.29 + transitivePeerDependencies: + - clownface + - safe-identifier + - ts-morph + - ts-node + dev: true + + /@tpluscode/sparql-builder@0.3.24(@zazuko/rdf-vocabularies@2023.1.19)(clownface@1.5.1)(safe-identifier@0.4.2)(sparql-http-client@2.4.2)(ts-morph@15.1.0)(ts-node@10.9.1): + resolution: {integrity: sha512-5DjQafLbdAOn3BwHv6eianSfO8jV54IJDy8usY6rO8Rz81e+BkpdUcqzx9gHoghISVgffgq2hwSLL44Fa/PG+Q==} + peerDependencies: + sparql-http-client: ^2.2.0 + dependencies: + '@rdf-esm/data-model': 0.5.4 + '@rdf-esm/term-set': 0.5.0 + '@rdfjs/types': 1.1.0 + '@tpluscode/rdf-ns-builders': 2.0.1(@zazuko/rdf-vocabularies@2023.1.19)(clownface@1.5.1)(safe-identifier@0.4.2)(ts-morph@15.1.0)(ts-node@10.9.1) + '@tpluscode/rdf-string': 0.2.26(clownface@1.5.1)(safe-identifier@0.4.2)(ts-morph@15.1.0)(ts-node@10.9.1) + debug: 4.3.4 + sparql-http-client: 2.4.2 + transitivePeerDependencies: + - '@zazuko/rdf-vocabularies' + - clownface + - safe-identifier + - supports-color + - ts-morph + - ts-node + dev: true + + /@ts-morph/common@0.16.0: + resolution: {integrity: sha512-SgJpzkTgZKLKqQniCjLaE3c2L2sdL7UShvmTmPBejAKd2OKV/yfMpQ2IWpAuA+VY5wy7PkSUaEObIqEK6afFuw==} + dependencies: + fast-glob: 3.2.12 + minimatch: 5.1.0 + mkdirp: 1.0.4 + path-browserify: 1.0.1 + dev: true + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.3: + resolution: {integrity: sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==} + dev: true + + /@turf/along@5.1.5: + resolution: {integrity: sha512-N7BN1xvj6VWMe3UpjQDdVI0j0oY/EZ0bWgOgBXc4DlJ411uEsKCh6iBv0b2MSxQ3YUXEez3oc5FcgO9eVSs7iQ==} + dependencies: + '@turf/bearing': 5.1.5 + '@turf/destination': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + dev: true + + /@turf/area@5.1.5: + resolution: {integrity: sha512-lz16gqtvoz+j1jD9y3zj0Z5JnGNd3YfS0h+DQY1EcZymvi75Frm9i5YbEyth0RfxYZeOVufY7YIS3LXbJlI57g==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/bbox-clip@5.1.5: + resolution: {integrity: sha512-KP64aoTvjcXxWHeM/Hs25vOQUBJgyJi7DlRVEoZofFJiR1kPnmDQrK7Xj+60lAk5cxuqzFnaPPxUk9Q+3v4p1Q==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + lineclip: 1.1.5 + dev: true + + /@turf/bbox-polygon@5.1.5: + resolution: {integrity: sha512-PKVPF5LABFWZJud8KzzfesLGm5ihiwLbVa54HJjYySe6yqU/cr5q/qcN9TWptynOFhNktG1dr0KXVG0I2FZmfw==} + dependencies: + '@turf/helpers': 5.1.5 + dev: true + + /@turf/bbox@5.1.5: + resolution: {integrity: sha512-sYQU4fqsOYYJoD8UndC1n2hy8hV/lGIAmMLKWuzwmPUWqWOuSKWUcoRWDi9mGB0GvQQe/ow2IxZr8UaVaGz3sQ==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/bearing@5.1.5: + resolution: {integrity: sha512-PrvZuJjnXGseB8hUatIjsrK3tgD3wttyRnVYXTbSfXYJZzaOfHDMplgO4lxXQp7diraZhGhCdSlbMvRRXItbUQ==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/bearing@6.5.0: + resolution: {integrity: sha512-dxINYhIEMzgDOztyMZc20I7ssYVNEpSv04VbMo5YPQsqa80KO3TFvbuCahMsCAW5z8Tncc8dwBlEFrmRjJG33A==} + dependencies: + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + dev: true + + /@turf/bezier-spline@5.1.5: + resolution: {integrity: sha512-Y9NoComaGgFFFe9TWWE/cEMg2+EnBfU1R3112ec2wlx21ygDmFGXs4boOS71WM4ySwm/dbS3wxnbVxs4j68sKw==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/boolean-clockwise@5.1.5: + resolution: {integrity: sha512-FqbmEEOJ4rU4/2t7FKx0HUWmjFEVqR+NJrFP7ymGSjja2SQ7Q91nnBihGuT+yuHHl6ElMjQ3ttsB/eTmyCycxA==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/boolean-contains@5.1.5: + resolution: {integrity: sha512-x2HeEieeE9vBQrTdCuj4swnAXlpKbj9ChxMdDTV479c0m2gVmfea83ocmkj3w+9cvAaS63L8WqFyNVSmkwqljQ==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/boolean-point-on-line': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/boolean-crosses@5.1.5: + resolution: {integrity: sha512-odljvS7INr9k/8yXeyXQVry7GqEaChOmXawP0+SoTfGO3hgptiik59TLU/Yjn/SLFjE2Ul54Ga1jKFSL7vvH0Q==} + dependencies: + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/line-intersect': 5.1.5 + '@turf/polygon-to-line': 5.1.5 + dev: true + + /@turf/boolean-disjoint@5.1.6: + resolution: {integrity: sha512-KHvUS6SBNYHBCLIJEJrg04pF5Oy+Fqn8V5G9U+9pti5vI9tyX7Ln2g7RSB7iJ1Cxsz8QAi6OukhXjEF2/8ZpGg==} + dependencies: + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/line-intersect': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/polygon-to-line': 5.1.5 + dev: true + + /@turf/boolean-equal@5.1.5: + resolution: {integrity: sha512-QEMbhDPV+J8PlRkMlVg6m5oSLaYUpOx2VUhDDekQ73FlpnhFBKRIlidhvHtS6CYnEw8d+/zA3h8Z18B4W4mq9Q==} + dependencies: + '@turf/clean-coords': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + geojson-equality: 0.1.6 + dev: true + + /@turf/boolean-overlap@5.1.5: + resolution: {integrity: sha512-lizojgU559KME0G705YAgWVa0B3/tsWNobMzOEWDx/1rABWTojCY4uxw2rFxpOsP++s8JJHrGWXRLh1PbdAvRQ==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/line-intersect': 5.1.5 + '@turf/line-overlap': 5.1.5 + '@turf/meta': 5.1.6 + geojson-equality: 0.1.6 + dev: true + + /@turf/boolean-parallel@5.1.5: + resolution: {integrity: sha512-eeuGgDhnas3nJ22A/DD8aiH0kg9dSzbQChIMAqYRPGg3pWNK41aGAbeh5z0GO5N/EVFX1+ga5a0vsPmiRgQB5g==} + dependencies: + '@turf/clean-coords': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/line-segment': 5.1.5 + '@turf/rhumb-bearing': 5.1.5 + dev: true + + /@turf/boolean-point-in-polygon@5.1.5: + resolution: {integrity: sha512-y+gbAhLmsAZH9uYhv+C68pu06mxsGIm3o7l0hzVkc/PXYdbkr+vKe7n7PfSN3xpVA3qoDLKLpCGOqeW8/ThaJA==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/boolean-point-in-polygon@6.5.0: + resolution: {integrity: sha512-DtSuVFB26SI+hj0SjrvXowGTUCHlgevPAIsukssW6BG5MlNSBQAo70wpICBNJL6RjukXg8d2eXaAWuD/CqL00A==} + dependencies: + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + dev: true + + /@turf/boolean-point-on-line@5.1.5: + resolution: {integrity: sha512-Zf4d28mckV2tYfLWf2iqxQ8eeLZqi2HGimM26mptf1OCEIwc1wfkKgLRRJXMu94Crvd/pJxjRAjoYGcGliP6Vg==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/boolean-within@5.1.5: + resolution: {integrity: sha512-CNAtrvm4HiUwV/vhpGhvJzfhV9CN7VhPC5y4tTfQicK82fYY6ifPz0iaNpUOmshU6+TAot/fsVQVgDJ4t7HXcA==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/boolean-point-on-line': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/buffer@5.1.5: + resolution: {integrity: sha512-U3LU0HF/JNFUNabpB5ArpNG6yPla7yR5XPrZvzZRH48vvbr/N0rkSRI0tJFRWTz7ntugVm9X0OD9Y382NTJRhA==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/center': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/projection': 5.1.5 + d3-geo: 1.7.1 + turf-jsts: 1.2.3 + dev: true + + /@turf/center-mean@5.1.5: + resolution: {integrity: sha512-XdkBXzFUuyCqu5EPlBwgkv8FLA8pIGBnt7xy5cxxhxKOYLMrKqwMPPHPA84TjeQpNti0gH0CVuOk2r1f/Pp8iQ==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/center-median@5.1.5: + resolution: {integrity: sha512-M+O6bSNsIDKZ4utk/YzSOIg6W0isjLVWud+TCLWyrDCWTSERlSJlhOaVE1y7cObhG8nYBHvmszqZyoAY6nufQw==} + dependencies: + '@turf/center-mean': 5.1.5 + '@turf/centroid': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/center-of-mass@5.1.5: + resolution: {integrity: sha512-UvI7q6GgW3afCVIDOyTRuLT54v9Xwv65Xudxh4FIT6w7HNU4KUBtTGnx0NuhODZcgvZgWVWVakhmIcHQTMjYYA==} + dependencies: + '@turf/centroid': 5.1.5 + '@turf/convex': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/center@5.1.5: + resolution: {integrity: sha512-Dy1TvAv2oHKFddZcWqlVsanxurfcZV1Mmb1E+7H7GRKI+fXZTfRjwCdbiZCbO/tPwxt8jWQHWdLHn8E9lecc3A==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/helpers': 5.1.5 + dev: true + + /@turf/centroid@5.1.5: + resolution: {integrity: sha512-0m9ZAZJB4YXLDxF2fWGqlE/g9Y68cebeWaRNOMN+e6Bti1fz0JKQuaEqJV+J8xOmODPHSMbZZ1SqSDVRgVHP2Q==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/circle@5.1.5: + resolution: {integrity: sha512-CNaEtvp38Q+TSFJHdzdl5iYNjBFZRluRTFikIuEcennSeMJD60nP0dMubP58TR/QQn541eNDUyED90V4KuOjyQ==} + dependencies: + '@turf/destination': 5.1.5 + '@turf/helpers': 5.1.5 + dev: true + + /@turf/clean-coords@5.1.5: + resolution: {integrity: sha512-xd/iSM0McVUxbu81KCKDqirCsYkKk3EAwpDjYI8vIQ+eKf/MLSdteRcm3PB7wo2y6JcYp4dMGv2cr9IP7V+dXQ==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/clone@5.1.5: + resolution: {integrity: sha512-//pITsQ8xUdcQ9pVb4JqXiSqG4dos5Q9N4sYFoWghX21tfOV2dhc5TGqYOhnHrQS7RiKQL1vQ48kIK34gQ5oRg==} + dependencies: + '@turf/helpers': 5.1.5 + dev: true + + /@turf/clone@6.5.0: + resolution: {integrity: sha512-mzVtTFj/QycXOn6ig+annKrM6ZlimreKYz6f/GSERytOpgzodbQyOgkfwru100O1KQhhjSudKK4DsQ0oyi9cTw==} + dependencies: + '@turf/helpers': 6.5.0 + dev: true + + /@turf/clusters-dbscan@5.1.5: + resolution: {integrity: sha512-X3qLLHJkwMuv+xdWQ08NtOc6BgeqCKKSAltyyAZ7iImE65f0C+sW024DfHSbTMsZVXBFst2Q6RQY8RVUf3QBeQ==} + dependencies: + '@turf/clone': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + density-clustering: 1.3.0 + dev: true + + /@turf/clusters-kmeans@5.1.5: + resolution: {integrity: sha512-W6raiv9+fRgmJxCvKrpSacbLXzh7beZUk0A1pjF82Fv3CFTrXAJbgAyIbdlmgXezYSXhOT5NMUugnbkUy2oBZw==} + dependencies: + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + skmeans: 0.9.7 + dev: true + + /@turf/clusters@5.1.5: + resolution: {integrity: sha512-+rQe+g66xfbIXz58tveXQCDdE9hzqRJtDVSw5xth92TvCcL4J60ZKN8mHNUSn1ZZvpUHtVPe4dYcbtk5bW8fXQ==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/collect@5.1.5: + resolution: {integrity: sha512-voFWu6EGPcNuIbAp43yvGf2Ip4/q8TTeWhOSJ2yDEHgOfbAwrNUwUJCclEjcUVsnc7ypKNrFn3/8bmR9tI0NQg==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/helpers': 5.1.5 + rbush: 2.0.2 + dev: true + + /@turf/combine@5.1.5: + resolution: {integrity: sha512-/RqmfCvduHquINVyNmzKOcZtZjfaEHMhghgmj8MYnzepN3ro+E2QXoaQGGrQ7nChAvGgWPAvN8EveVSc1MvzPg==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/concave@5.1.5: + resolution: {integrity: sha512-NvR5vmAunmgjEPjNzmvjLRvPcj7C6WuqCf+vu/aqyc4h2c1B/x399bDsSM64iFT+PYesFuoS1ZhJHWivXG8Y5g==} + dependencies: + '@turf/clone': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/tin': 5.1.5 + topojson-client: 3.1.0 + topojson-server: 3.0.1 + dev: true + + /@turf/convex@5.1.5: + resolution: {integrity: sha512-ZEk4kIAoYR/mjO3C8rMe2StgmwhdwmbxVvNxg3udeahe2m0ZzbfkRC4HiJAaBgfR4TLJUAEewynESReTPwASBQ==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + concaveman: 1.2.1 + dev: true + + /@turf/destination@5.1.5: + resolution: {integrity: sha512-EWwZnd4wxUO9d8UWzJt88jQlFf6W/6SE1930MMzzIR9o+RfqhrS/BL1eUDrg5I5drsymf6PZsK0j/V0q6jqkFQ==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/difference@5.1.5: + resolution: {integrity: sha512-hIjiUHS8WiDfnmADQrhh6QcXWc3zNtjIpPQ5g/2NZ3k1mjnOdmGBVObkSJG4WEUNqyj3PKlsZ8W9xnSu+lLF1Q==} + dependencies: + '@turf/area': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + turf-jsts: 1.2.3 + dev: true + + /@turf/dissolve@5.1.5: + resolution: {integrity: sha512-YcQgyp7pvhyZHCmbqqItVH6vHs43R9N0jzP/LnAG03oMiY4wves/BO1du6VDDbnJSXeRKf1afmY9tRGKYrm9ag==} + dependencies: + '@turf/boolean-overlap': 5.1.5 + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/line-intersect': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/union': 5.1.5 + geojson-rbush: 2.1.0 + get-closest: 0.0.4 + dev: true + + /@turf/distance@5.1.5: + resolution: {integrity: sha512-sYCAgYZ2MjNKMtx17EijHlK9qHwpA0MuuQWbR4P30LTCl52UlG/reBfV899wKyF3HuDL9ux78IbILwOfeQ4zgA==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/distance@6.5.0: + resolution: {integrity: sha512-xzykSLfoURec5qvQJcfifw/1mJa+5UwByZZ5TZ8iaqjGYN0vomhV9aiSLeYdUGtYRESZ+DYC/OzY+4RclZYgMg==} + dependencies: + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + dev: true + + /@turf/ellipse@5.1.5: + resolution: {integrity: sha512-oVTzEyDOi3d9isgB7Ah+YiOoUKB1eHMtMDXVl1oT+vC/T+6KR2aq+HjjbF11A0cjuh3VhjSWUZaS+2TYY0pu0w==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/rhumb-destination': 5.1.5 + '@turf/transform-rotate': 5.1.5 + dev: true + + /@turf/envelope@5.1.5: + resolution: {integrity: sha512-Mxl5A2euAxq3RZVN65/MVyaO91kzGU8MJXfegPdep6SN4bONDadEp0olwW5qSRf2U3cJ8Jppl089X6AeifD3IA==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/bbox-polygon': 5.1.5 + '@turf/helpers': 5.1.5 + dev: true + + /@turf/explode@5.1.5: + resolution: {integrity: sha512-v/hC9DB9RKRW9/ZjnKoQelIp08JNa5wew0889465s//tfgY8+JEGkSGMag2L2NnVARWmzI/vlLgMK36qwkyDIA==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/flatten@5.1.5: + resolution: {integrity: sha512-aagHz5tjHmOtb8eMb5fd10+HJwdlhkhsPql1vRXQNnpv0Q9xL/4SsbvXZ6lPqkRAjiZuy087mvaz+ERml76/jg==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/flip@5.1.5: + resolution: {integrity: sha512-7+IYM3QQAkV4co3wjEmM726/OkXqUCCHWWyIqrI9hiK+LR628qkoqP1hk6rQ4vZJrAYuvSlK+FZnr24OtgY0cw==} + dependencies: + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/great-circle@5.1.5: + resolution: {integrity: sha512-k6FWwlt+YCQoD5VS1NybQjriNL7apYHO+tm2HbIFQ85blPUX4IyLppHIFevfD/k+K2bJqhFCze8JNVMBwdrzVw==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/helpers@5.1.5: + resolution: {integrity: sha512-/lF+JR+qNDHZ8bF9d+Cp58nxtZWJ3sqFe6n3u3Vpj+/0cqkjk4nXKYBSY0azm+GIYB5mWKxUXvuP/m0ZnKj1bw==} + dev: true + + /@turf/helpers@6.5.0: + resolution: {integrity: sha512-VbI1dV5bLFzohYYdgqwikdMVpe7pJ9X3E+dlr425wa2/sMJqYDhTO++ec38/pcPvPE6oD9WEEeU3Xu3gza+VPw==} + dev: true + + /@turf/hex-grid@5.1.5: + resolution: {integrity: sha512-rwDL+DlUyxDNL1aVHIKKCmrt1131ZULF3irExYIO/um6/SwRzsBw+522/RcxD/mg/Shtrpozb6bz8aJJ/3RXHA==} + dependencies: + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/intersect': 5.1.6 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/interpolate@5.1.5: + resolution: {integrity: sha512-LfmvtIUWc3NVkqPkX6j3CAIjF7y1LAZqfDd+2Ii+0fN7XOOGMWcb1uiTTAb8zDQjhTsygcUYgaz6mMYDCWYKPg==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/centroid': 5.1.5 + '@turf/clone': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/hex-grid': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/point-grid': 5.1.5 + '@turf/square-grid': 5.1.5 + '@turf/triangle-grid': 5.1.5 + dev: true + + /@turf/intersect@5.1.6: + resolution: {integrity: sha512-KXyNv/GXdoGAOy03qZF53rgtXC2tNhF/4jLwTKiVRrBQH6kcEpipGStdJ+QkYIlarQPa8f7I9UlVAB19et4MfQ==} + dependencies: + '@turf/clean-coords': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/truncate': 5.1.5 + turf-jsts: 1.2.3 + dev: true + + /@turf/invariant@5.1.5: + resolution: {integrity: sha512-4elbC8GVQ8XxrnWLWpFFXTK3qnzIYzIVtSkJrY9eefA8WNZzwcwT3WGFY3xte4BB48o5oEjihjoJharWRis78w==} + dependencies: + '@turf/helpers': 5.1.5 + dev: true + + /@turf/invariant@6.5.0: + resolution: {integrity: sha512-Wv8PRNCtPD31UVbdJE/KVAWKe7l6US+lJItRR/HOEW3eh+U/JwRCSUl/KZ7bmjM/C+zLNoreM2TU6OoLACs4eg==} + dependencies: + '@turf/helpers': 6.5.0 + dev: true + + /@turf/isobands@5.1.5: + resolution: {integrity: sha512-0n3NPfDYQyqjOch00I4hVCCqjKn9Sm+a8qlWOKbkuhmGa9dCDzsu2bZL0ahT+LjwlS4c8/owQXqe6KE2GWqT1Q==} + dependencies: + '@turf/area': 5.1.5 + '@turf/bbox': 5.1.5 + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/explode': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/isolines@5.1.5: + resolution: {integrity: sha512-Ehn5pJmiq4hAn2+2jPB2rLt3iF8DDp8zciw9z2pAt5IGVRU/K+x3z4aYG5ra5vbFB/E4G3aHr/X4QPIb9LCJtA==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/kinks@5.1.5: + resolution: {integrity: sha512-G38sC8/+MYqQpVocT3XahhV42cqEAVJAZwUND9YOfKJZfjUn7FKmWhPURs5py95me48UuI0C0jLLAMzBkUc2nQ==} + dependencies: + '@turf/helpers': 5.1.5 + dev: true + + /@turf/length@5.1.5: + resolution: {integrity: sha512-0ryx68h512wCoNfwyksLdabxEfwkGNTPg61/QiY+QfGFUOUNhHbP+QimViFpwF5hyX7qmroaSHVclLUqyLGRbg==} + dependencies: + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/line-arc@5.1.5: + resolution: {integrity: sha512-Kz5RX/qRIHVrGNqF3BRlD3ACuuCr0G5lpaVyPjNvN+vA7Q4bEDyWIYeqm3DdTn7X2MXitpTNgr2uvX4WoUy4yA==} + dependencies: + '@turf/circle': 5.1.5 + '@turf/destination': 5.1.5 + '@turf/helpers': 5.1.5 + dev: true + + /@turf/line-chunk@5.1.5: + resolution: {integrity: sha512-mKvTUMahnb3EsYUMI8tQmygsliQkgQ1FZAY915zoTrm+WV246loa+84+h7i5d8W2O8gGJWuY7jQTpM7toTeL5w==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/length': 5.1.5 + '@turf/line-slice-along': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/line-intersect@5.1.5: + resolution: {integrity: sha512-9DajJbHhJauLI2qVMnqZ7SeFsinFroVICOSUheODk7j5teuwNABuZ2Z6WmKATzEsPkEJ1iVykqB+F9vGMVKB6g==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/line-segment': 5.1.5 + '@turf/meta': 5.1.6 + geojson-rbush: 2.1.0 + dev: true + + /@turf/line-offset@5.1.5: + resolution: {integrity: sha512-VccGDgFfBSiCTqrHdQgxD7Rs9lnJmDOJ5gqQRculKPsCNUyRFMYIZud7l2dTs83g66evfOwkZCrTxtSoBY3Jxg==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/line-overlap@5.1.5: + resolution: {integrity: sha512-hMz3XARXEbfGwLF9WXyErqQjzhZYMKvGQwlPGOoth+2o9Uga9mfWfevduJvozJAE1MKxtFttMjIXMzcShW3O8A==} + dependencies: + '@turf/boolean-point-on-line': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/line-segment': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/nearest-point-on-line': 5.1.5 + geojson-rbush: 2.1.0 + dev: true + + /@turf/line-segment@5.1.5: + resolution: {integrity: sha512-wIrRtWuLuLXhnSkqdVG1SDayTU0/CmZf+a+BBhEf0vFIsAedJnrY3a2cbCEvtfuk6ZsAbhOi7/kYiaR/F+rEzg==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/line-slice-along@5.1.5: + resolution: {integrity: sha512-yKvSDtULztLtlPIMowm9l8pS6XLAEpCPmrARZA0sIWFX8XrcSzISBaXZbiMMzg3nxQJMXfGIgWDk10B7+J8Tqw==} + dependencies: + '@turf/bearing': 5.1.5 + '@turf/destination': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + dev: true + + /@turf/line-slice@5.1.5: + resolution: {integrity: sha512-Fo+CuD+fj6T702BofHO+rgiXUgzCk0iO2JqMPtttMtgzfKkVTUOQoauMNS1LNNaG/7n/TfKGh5gRCEDRNaNwYA==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/nearest-point-on-line': 5.1.5 + dev: true + + /@turf/line-split@5.1.5: + resolution: {integrity: sha512-gtUUBwZL3hcSu5MpqHTl68hgAJBNHcr1APDj8E5o6iX5xFX+wvl4ohQXyMs5HOATCI8Iy83wLuggcY6maNw7LQ==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/line-intersect': 5.1.5 + '@turf/line-segment': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/nearest-point-on-line': 5.1.5 + '@turf/square': 5.1.5 + '@turf/truncate': 5.1.5 + geojson-rbush: 2.1.0 + dev: true + + /@turf/line-to-polygon@5.1.5: + resolution: {integrity: sha512-hGiDAPd6j986kZZLDgEAkVD7O6DmIqHQliBedspoKperPJOUJJzdzSnF6OAWSsxY+j8fWtQnIo5TTqdO/KfamA==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/mask@5.1.5: + resolution: {integrity: sha512-2eOuxA3ammZAGsjlsy/H7IpeJxjl3hrgkcKM6kTKRJGft4QyKwCxqQP7RN5j0zIYvAurgs9JOLe/dpd5sE5HXQ==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/union': 5.1.5 + rbush: 2.0.2 + dev: true + + /@turf/meta@5.1.6: + resolution: {integrity: sha512-lv+6LCgoc3LVitQZ4TScN/8a/fcctq8bIoxBTMJVq4aU8xoHeY1851Dq8MCU37EzbH33utkx8/jENaQP+aeElg==} + dependencies: + '@turf/helpers': 5.1.5 + dev: true + + /@turf/meta@6.5.0: + resolution: {integrity: sha512-RrArvtsV0vdsCBegoBtOalgdSOfkBrTJ07VkpiCnq/491W67hnMWmDu7e6Ztw0C3WldRYTXkg3SumfdzZxLBHA==} + dependencies: + '@turf/helpers': 6.5.0 + dev: true + + /@turf/midpoint@5.1.5: + resolution: {integrity: sha512-0pDQAKHyK/zxlvUx3XNxwvqftf4sV32QxnHfqSs4AXaODUGUbPhzAD7aXgDScBeUOVLwpAzFRQfitUvUMTGC6A==} + dependencies: + '@turf/bearing': 5.1.5 + '@turf/destination': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + dev: true + + /@turf/nearest-point-on-line@5.1.5: + resolution: {integrity: sha512-qT7BLTwToo8cq0oNoz921oLlRPJamyRg/rZgll+kNBadyDPmJI4W66riHcpM9RQcAJ6TPvDveIIBeGJH7iG88w==} + dependencies: + '@turf/bearing': 5.1.5 + '@turf/destination': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/line-intersect': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/nearest-point-to-line@5.1.6: + resolution: {integrity: sha512-ZSvDIEiHhifn/vNwLXZI/E8xmEz5yBPqfUR7BVHRZrB1cP7jLhKZvkbidjG//uW8Fr1Ulc+PFOXczLspIcx/lw==} + dependencies: + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + '@turf/meta': 6.5.0 + '@turf/point-to-line-distance': 5.1.6 + object-assign: 4.1.1 + dev: true + + /@turf/nearest-point-to-line@6.0.0: + resolution: {integrity: sha512-e6vU6+NWDCxJxoDD7qVEKoxK4U0ipnqdj3WNwwQ6bznAPsGtUItN017uDtxqjwLMLsXyCuTwuvI58rad0kz3ug==} + dependencies: + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + '@turf/meta': 6.5.0 + '@turf/point-to-line-distance': 6.0.0 + object-assign: 4.1.1 + dev: true + + /@turf/nearest-point@5.1.5: + resolution: {integrity: sha512-tZQXI7OE7keNKK4OvYOJ5gervCEuu2pJ6psu59QW9yhe2Di3Gl+HAdLvVa6RZ8s5Fndr3u0JWKsmxve3fCxc9g==} + dependencies: + '@turf/clone': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/planepoint@5.1.5: + resolution: {integrity: sha512-+Tp+SQ0Db2tqwLbxfXJPysT9IxcOHSMIin2dJb/j3Qn5+g0LRus6rczZl6dWNAIjqBPMawj/V/dZhMu6Q9O9wA==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/point-grid@5.1.5: + resolution: {integrity: sha512-4ibozguP9YJ297Q7i9e8/ypGSycvt1re2jrPXTxeuZ4/L/NE5B1nOBLG+tw121nMjD+S+v2RWOtqD+FZ3Ga+ew==} + dependencies: + '@turf/boolean-within': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/point-on-feature@5.1.5: + resolution: {integrity: sha512-NTcpe5xZjybRh0aTL+7td1cm0s49GGbAt5u8Cdec4W9ix2PsehRcLUbmQIQsODN2kiVyUSpnhECIpsyN5MjX7A==} + dependencies: + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/center': 5.1.5 + '@turf/explode': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/nearest-point': 5.1.5 + dev: true + + /@turf/point-to-line-distance@5.1.6: + resolution: {integrity: sha512-PE3hiTeeDEi4ZLPtI8XAzFYW9nHo1EVsZGm/4ZVV8jo39d3X1oLVHxY3e1PkCmWwRapXy4QLqvnTQ7nU4wspNw==} + dependencies: + '@turf/bearing': 6.5.0 + '@turf/distance': 6.5.0 + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + '@turf/meta': 6.5.0 + '@turf/projection': 6.5.0 + '@turf/rhumb-bearing': 6.5.0 + '@turf/rhumb-distance': 6.5.0 + dev: true + + /@turf/point-to-line-distance@6.0.0: + resolution: {integrity: sha512-2UuZFtn8MRfrqBHSqkrH/jm5q/VedyL7a4YC50Nd5FqXs5TgmAB7ms2igSbCkyaOtRypGhMl9fun3Hg5PIVRMQ==} + dependencies: + '@turf/bearing': 6.5.0 + '@turf/distance': 6.5.0 + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + '@turf/meta': 6.5.0 + '@turf/projection': 6.5.0 + '@turf/rhumb-bearing': 6.5.0 + '@turf/rhumb-distance': 6.5.0 + dev: true + + /@turf/points-within-polygon@5.1.5: + resolution: {integrity: sha512-nexe2AHVOY8wEBvs+CYSOp10NyOCkyZ1gkhIfsx0mzU8LPYBxD9ctjlKveheKh4AAldLcFupd/gSCBTKF1JS7A==} + dependencies: + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/polygon-tangents@5.1.5: + resolution: {integrity: sha512-uoZfKvFhl6rf0+CDWucru9fZ4mJB5Nsg37TS/7emrzjoVxXyOdxc/s1HFCjcKflMue7MjU/gT6AitJyrvdztDg==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/polygon-to-line@5.1.5: + resolution: {integrity: sha512-kVo0owPqyccy5+qZGvaxGvMsYkgueKE2OOgX2UV/HyrXF3uI3TomK1txjApqeFsLvwuSANxesvVbYLrYiIwvGw==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/polygonize@5.1.5: + resolution: {integrity: sha512-qzhtuzoOhldqZHm+ZPsWAs9nDpnkcDfsr+I0twmBF+wjAmo0HKiy9++sRQ4kEePpdwbMpF07D/NdZqYdmOJkGQ==} + dependencies: + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/envelope': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/projection@5.1.5: + resolution: {integrity: sha512-TWKJDFeEKQhI4Ce1+2PuOSDggn4cnMibqyUoCpIW+4KxUC1R88SE3/SYomqzwxMn00O09glHSycPkGD5JzHd8A==} + dependencies: + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/projection@6.5.0: + resolution: {integrity: sha512-/Pgh9mDvQWWu8HRxqpM+tKz8OzgauV+DiOcr3FCjD6ubDnrrmMJlsf6fFJmggw93mtVPrZRL6yyi9aYCQBOIvg==} + dependencies: + '@turf/clone': 6.5.0 + '@turf/helpers': 6.5.0 + '@turf/meta': 6.5.0 + dev: true + + /@turf/random@5.1.5: + resolution: {integrity: sha512-oitpBwEb6YXqoUkIAOVMK+vrTPxUi2rqITmtTa/FBHr6J8TDwMWq6bufE3Gmgjxsss50O2ITJunOksxrouWGDQ==} + dependencies: + '@turf/helpers': 5.1.5 + dev: true + + /@turf/rewind@5.1.5: + resolution: {integrity: sha512-Gdem7JXNu+G4hMllQHXRFRihJl3+pNl7qY+l4qhQFxq+hiU1cQoVFnyoleIqWKIrdK/i2YubaSwc3SCM7N5mMw==} + dependencies: + '@turf/boolean-clockwise': 5.1.5 + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/rhumb-bearing@5.1.5: + resolution: {integrity: sha512-zXTl2khjwf7mx2D1uPo5vgpGgP4sM2VrKDbJNKyulPu4TO4ELt8x7FsKyCBlRTzzQf284t/xnNcZOfUbkkd70g==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/rhumb-bearing@6.5.0: + resolution: {integrity: sha512-jMyqiMRK4hzREjQmnLXmkJ+VTNTx1ii8vuqRwJPcTlKbNWfjDz/5JqJlb5NaFDcdMpftWovkW5GevfnuzHnOYA==} + dependencies: + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + dev: true + + /@turf/rhumb-destination@5.1.5: + resolution: {integrity: sha512-FdDUCSRfRAfsRmUaWjc76Wk32QYFJ6ckmSt6Ls6nEczO6eg/RgH1atF8CIYwR5ifl0Sk1rQzKiOSbpCyvVwQtw==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/rhumb-distance@5.1.5: + resolution: {integrity: sha512-AGA/ky5/BJJZtzQqafy2GvJfcUXSzCCrPFp8sDRPSKBoUN4gMBHN15ijDWYYLFoWFFj0urcauVx7chQlHZ/Qfw==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/rhumb-distance@6.5.0: + resolution: {integrity: sha512-oKp8KFE8E4huC2Z1a1KNcFwjVOqa99isxNOwfo4g3SUABQ6NezjKDDrnvC4yI5YZ3/huDjULLBvhed45xdCrzg==} + dependencies: + '@turf/helpers': 6.5.0 + '@turf/invariant': 6.5.0 + dev: true + + /@turf/sample@5.1.5: + resolution: {integrity: sha512-EJE8yx+5x7rXejTzwBdOKpvT4tOCS0jwYJfycyTVDuLUSh2rETeYdjy7EeJbofnxm9CRPXqWQMPWIBKWxNTjow==} + dependencies: + '@turf/helpers': 5.1.5 + dev: true + + /@turf/sector@5.1.5: + resolution: {integrity: sha512-dnWVifL3xWTqPPs8mfbbV9muDimNJtxRk4ogrkOLEDQ9ZZ1ALQMtQdYrg7kI3iC+L+LscV37tl+E8bayWyX8YA==} + dependencies: + '@turf/circle': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/line-arc': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/shortest-path@5.1.5: + resolution: {integrity: sha512-ZGC8kSBj02GKWiI56Z5FNdrZ+fS0xyeOUNrPJWzudAlrv9wKGaRuWoIVRLGBu0j0OuO1HCwggic2c6WV/AhP0A==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/bbox-polygon': 5.1.5 + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/clean-coords': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/transform-scale': 5.1.5 + dev: true + + /@turf/simplify@5.1.5: + resolution: {integrity: sha512-IuBXEYdGSxbDOK3v949ajaPvs6NhjhTCTbKA6mSGuVbwGS7gzAuRiPSG4K/MvCVuQy3PKpkPcUGD+Uvt2Ov2PQ==} + dependencies: + '@turf/clean-coords': 5.1.5 + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/square-grid@5.1.5: + resolution: {integrity: sha512-/pusEL4FmOwNWLcZfIXUyqUe0fOdkfaLO4wLhDlg/ZL1jWr/wZjhVlMU0tQ27kVN6dJTvlzNc9e0JWNw6yt2eQ==} + dependencies: + '@turf/boolean-contains': 5.1.5 + '@turf/boolean-overlap': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/intersect': 5.1.6 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/square@5.1.5: + resolution: {integrity: sha512-GgP2le9ksoW6vsVef5wFkjmWQiLPTJvcjGXqmoGWT4oMwDpvTJVQ91RBLs8qQbI4KACCQevz94N69klk3ah30Q==} + dependencies: + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + dev: true + + /@turf/standard-deviational-ellipse@5.1.5: + resolution: {integrity: sha512-GOaxGKeeJAXV1H3Zz2fjQ5XeSbMKz1OkFRlTDBUipiAawe/9qTCF55L87I2ZPnO80B5BaaIT+AN2n0lMcAklzA==} + dependencies: + '@turf/center-mean': 5.1.5 + '@turf/ellipse': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/points-within-polygon': 5.1.5 + dev: true + + /@turf/tag@5.1.5: + resolution: {integrity: sha512-XI3QFpva6tEsRnzFe1tJGdAAWlzjnXZPfJ9EKShTxEW8ZgPzm92b2odjiSAt2KuQusK82ltNfdw5Frlna5xGYQ==} + dependencies: + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/tesselate@5.1.5: + resolution: {integrity: sha512-Rs/jAij26bcU4OzvFXkWDase1G3kSwyuuKZPFU0t7OmJu7eQJOR12WOZLGcVxd5oBlklo4xPE4EBQUqpQUsQgg==} + dependencies: + '@turf/helpers': 5.1.5 + earcut: 2.2.4 + dev: true + + /@turf/tin@5.1.5: + resolution: {integrity: sha512-lDyCTYKoThBIKmkBxBMupqEpFbvTDAYuZIs8qrWnmux2vntSb8OFGi7ZbGPC6apS2hdVwZZae3YB88Tp+Fg+xw==} + dependencies: + '@turf/helpers': 5.1.5 + dev: true + + /@turf/transform-rotate@5.1.5: + resolution: {integrity: sha512-3QKckeHKPXu5O5vEuT+nkszGDI6aknDD06ePb00+6H2oA7MZj7nj+fVQIJLs41MRb76IyKr4n5NvuKZU6idESA==} + dependencies: + '@turf/centroid': 5.1.5 + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/rhumb-bearing': 5.1.5 + '@turf/rhumb-destination': 5.1.5 + '@turf/rhumb-distance': 5.1.5 + dev: true + + /@turf/transform-scale@5.1.5: + resolution: {integrity: sha512-t1fCZX29ONA7DJiqCKA4YZy0+hCzhppWNOZhglBUv9vKHsWCFYZDUKfFInciaypUInsZyvm8eKxxixBVPdPGsw==} + dependencies: + '@turf/bbox': 5.1.5 + '@turf/center': 5.1.5 + '@turf/centroid': 5.1.5 + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/rhumb-bearing': 5.1.5 + '@turf/rhumb-destination': 5.1.5 + '@turf/rhumb-distance': 5.1.5 + dev: true + + /@turf/transform-translate@5.1.5: + resolution: {integrity: sha512-GdLFp7I7198oRQt311B8EjiqHupndeMSQ3Zclzki5L/niUrb1ptOIpo+mxSidSy03m+1Q5ylWlENroI1WBcQ3Q==} + dependencies: + '@turf/clone': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/rhumb-destination': 5.1.5 + dev: true + + /@turf/triangle-grid@5.1.5: + resolution: {integrity: sha512-jmCRcynI80xsVqd+0rv0YxP6mvZn4BAaJv8dwthg2T3WfHB9OD+rNUMohMuUY8HmI0zRT3s/Ypdy2Cdri9u/tw==} + dependencies: + '@turf/distance': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/intersect': 5.1.6 + '@turf/invariant': 5.1.5 + dev: true + + /@turf/truncate@5.1.5: + resolution: {integrity: sha512-WjWGsRE6o1vUqULGb/O7O1eK6B4Eu6R/RBZWnF0rH0Os6WVel6tHktkeJdlKwz9WElIEO12wDIu6uKd54t7DDQ==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + dev: true + + /@turf/turf@5.1.6: + resolution: {integrity: sha512-NIjkt5jAbOrom+56ELw9ERZF6qsdf1xAIHyC9/PkDMIOQAxe7FVe2HaqbQ+x88F0q5FaSX4dtpIEf08md6h5/A==} + dependencies: + '@turf/along': 5.1.5 + '@turf/area': 5.1.5 + '@turf/bbox': 5.1.5 + '@turf/bbox-clip': 5.1.5 + '@turf/bbox-polygon': 5.1.5 + '@turf/bearing': 5.1.5 + '@turf/bezier-spline': 5.1.5 + '@turf/boolean-clockwise': 5.1.5 + '@turf/boolean-contains': 5.1.5 + '@turf/boolean-crosses': 5.1.5 + '@turf/boolean-disjoint': 5.1.6 + '@turf/boolean-equal': 5.1.5 + '@turf/boolean-overlap': 5.1.5 + '@turf/boolean-parallel': 5.1.5 + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/boolean-point-on-line': 5.1.5 + '@turf/boolean-within': 5.1.5 + '@turf/buffer': 5.1.5 + '@turf/center': 5.1.5 + '@turf/center-mean': 5.1.5 + '@turf/center-median': 5.1.5 + '@turf/center-of-mass': 5.1.5 + '@turf/centroid': 5.1.5 + '@turf/circle': 5.1.5 + '@turf/clean-coords': 5.1.5 + '@turf/clone': 5.1.5 + '@turf/clusters': 5.1.5 + '@turf/clusters-dbscan': 5.1.5 + '@turf/clusters-kmeans': 5.1.5 + '@turf/collect': 5.1.5 + '@turf/combine': 5.1.5 + '@turf/concave': 5.1.5 + '@turf/convex': 5.1.5 + '@turf/destination': 5.1.5 + '@turf/difference': 5.1.5 + '@turf/dissolve': 5.1.5 + '@turf/distance': 5.1.5 + '@turf/ellipse': 5.1.5 + '@turf/envelope': 5.1.5 + '@turf/explode': 5.1.5 + '@turf/flatten': 5.1.5 + '@turf/flip': 5.1.5 + '@turf/great-circle': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/hex-grid': 5.1.5 + '@turf/interpolate': 5.1.5 + '@turf/intersect': 5.1.6 + '@turf/invariant': 5.1.5 + '@turf/isobands': 5.1.5 + '@turf/isolines': 5.1.5 + '@turf/kinks': 5.1.5 + '@turf/length': 5.1.5 + '@turf/line-arc': 5.1.5 + '@turf/line-chunk': 5.1.5 + '@turf/line-intersect': 5.1.5 + '@turf/line-offset': 5.1.5 + '@turf/line-overlap': 5.1.5 + '@turf/line-segment': 5.1.5 + '@turf/line-slice': 5.1.5 + '@turf/line-slice-along': 5.1.5 + '@turf/line-split': 5.1.5 + '@turf/line-to-polygon': 5.1.5 + '@turf/mask': 5.1.5 + '@turf/meta': 5.1.6 + '@turf/midpoint': 5.1.5 + '@turf/nearest-point': 5.1.5 + '@turf/nearest-point-on-line': 5.1.5 + '@turf/nearest-point-to-line': 5.1.6 + '@turf/planepoint': 5.1.5 + '@turf/point-grid': 5.1.5 + '@turf/point-on-feature': 5.1.5 + '@turf/point-to-line-distance': 5.1.6 + '@turf/points-within-polygon': 5.1.5 + '@turf/polygon-tangents': 5.1.5 + '@turf/polygon-to-line': 5.1.5 + '@turf/polygonize': 5.1.5 + '@turf/projection': 5.1.5 + '@turf/random': 5.1.5 + '@turf/rewind': 5.1.5 + '@turf/rhumb-bearing': 5.1.5 + '@turf/rhumb-destination': 5.1.5 + '@turf/rhumb-distance': 5.1.5 + '@turf/sample': 5.1.5 + '@turf/sector': 5.1.5 + '@turf/shortest-path': 5.1.5 + '@turf/simplify': 5.1.5 + '@turf/square': 5.1.5 + '@turf/square-grid': 5.1.5 + '@turf/standard-deviational-ellipse': 5.1.5 + '@turf/tag': 5.1.5 + '@turf/tesselate': 5.1.5 + '@turf/tin': 5.1.5 + '@turf/transform-rotate': 5.1.5 + '@turf/transform-scale': 5.1.5 + '@turf/transform-translate': 5.1.5 + '@turf/triangle-grid': 5.1.5 + '@turf/truncate': 5.1.5 + '@turf/union': 5.1.5 + '@turf/unkink-polygon': 5.1.5 + '@turf/voronoi': 5.1.5 + dev: true + + /@turf/union@5.1.5: + resolution: {integrity: sha512-wBy1ixxC68PpsTeEDebk/EfnbI1Za5dCyY7xFY9NMzrtVEOy0l0lQ5syOsaqY4Ire+dbsDM66p2GGxmefoyIEA==} + dependencies: + '@turf/helpers': 5.1.5 + turf-jsts: 1.2.3 + dev: true + + /@turf/unkink-polygon@5.1.5: + resolution: {integrity: sha512-lzSrgsfSuyxIc4pkE2qyM2dsHxR992e6oItoZAT8G58A2Ef4qc5gRocmXPWZakGx41fQobegSo7wlo4I49wyHg==} + dependencies: + '@turf/area': 5.1.5 + '@turf/boolean-point-in-polygon': 5.1.5 + '@turf/helpers': 5.1.5 + '@turf/meta': 5.1.6 + rbush: 2.0.2 + dev: true + + /@turf/voronoi@5.1.5: + resolution: {integrity: sha512-Ad0HZAyYjOpMIZfDGV+Q+30M9PQHIirTyn32kWyTjEI1O6uhL5NOYjzSha4Sr77xOls3hGzKOj+JET7eDtOvsg==} + dependencies: + '@turf/helpers': 5.1.5 + '@turf/invariant': 5.1.5 + d3-voronoi: 1.1.2 + dev: true + + /@types/accepts@1.3.5: + resolution: {integrity: sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/acorn@4.0.6: + resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + dependencies: + '@types/estree': 0.0.47 + dev: true + + /@types/babel__core@7.1.19: + resolution: {integrity: sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==} + dependencies: + '@babel/parser': 7.19.6 + '@babel/types': 7.19.4 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.18.2 + dev: true + + /@types/babel__generator@7.6.4: + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + dependencies: + '@babel/types': 7.19.4 + dev: true + + /@types/babel__template@7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.19.6 + '@babel/types': 7.19.4 + dev: true + + /@types/babel__traverse@7.18.2: + resolution: {integrity: sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==} + dependencies: + '@babel/types': 7.19.4 + dev: true + + /@types/bindings@1.5.1: + resolution: {integrity: sha512-8HzueDeoxGXdsJ0Ep7TOXHGN+woRTWa1bAds30r5we7PCC3P5zrSTRknePLn/KYAubgQv5t/1zkonnStHLCWOg==} + requiresBuild: true + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/body-parser@1.19.0: + resolution: {integrity: sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==} + dependencies: + '@types/connect': 3.4.35 + '@types/node': 14.18.29 + dev: true + + /@types/braces@3.0.1: + resolution: {integrity: sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==} + dev: true + + /@types/bson@4.0.5: + resolution: {integrity: sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/cacheable-request@6.0.2: + resolution: {integrity: sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==} + dependencies: + '@types/http-cache-semantics': 4.0.1 + '@types/keyv': 4.2.0 + '@types/node': 14.18.29 + '@types/responselike': 1.0.0 + dev: true + + /@types/connect@3.4.35: + resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/content-disposition@0.5.5: + resolution: {integrity: sha512-v6LCdKfK6BwcqMo+wYW05rLS12S0ZO0Fl4w1h4aaZMD7bqT3gVUns6FvLJKGZHQmYn3SX55JWGpziwJRwVgutA==} + dev: true + + /@types/cookies@0.7.7: + resolution: {integrity: sha512-h7BcvPUogWbKCzBR2lY4oqaZbO3jXZksexYJVFvkrFeLgbZjQkU4x8pRq6eg2MHXQhY0McQdqmmsxRWlVAHooA==} + dependencies: + '@types/connect': 3.4.35 + '@types/express': 4.17.14 + '@types/keygrip': 1.0.2 + '@types/node': 14.18.29 + dev: true + + /@types/cors@2.8.10: + resolution: {integrity: sha512-C7srjHiVG3Ey1nR6d511dtDkCEjxuN9W1HWAEjGq8kpcwmNM6JJkpC0xvabM7BXTG2wDq8Eu33iH9aQKa7IvLQ==} + dev: true + + /@types/debug@4.1.7: + resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + dependencies: + '@types/ms': 0.7.31 + dev: true + + /@types/estree-jsx@1.0.0: + resolution: {integrity: sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ==} + dependencies: + '@types/estree': 0.0.47 + dev: true + + /@types/estree@0.0.47: + resolution: {integrity: sha512-c5ciR06jK8u9BstrmJyO97m+klJrrhCf9u3rLu3DEAJBirxRqSCvDQoYKmxuYwQI5SZChAWu+tq9oVlGRuzPAg==} + requiresBuild: true + dev: true + + /@types/estree@1.0.0: + resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} + dev: true + + /@types/express-jwt@0.0.42: + resolution: {integrity: sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==} + dependencies: + '@types/express': 4.17.14 + '@types/express-unless': 2.0.1 + dev: true + + /@types/express-serve-static-core@4.17.31: + resolution: {integrity: sha512-DxMhY+NAsTwMMFHBTtJFNp5qiHKJ7TeqOo23zVEM9alT1Ml27Q3xcTH0xwxn7Q0BbMcVEJOs/7aQtUWupUQN3Q==} + dependencies: + '@types/node': 14.18.29 + '@types/qs': 6.9.7 + '@types/range-parser': 1.2.4 + dev: true + + /@types/express-unless@2.0.1: + resolution: {integrity: sha512-PJLiNw03EjkWDkQbhNjIXXDLObC3eMQhFASDV+WakFbT8eL7YdjlbV6MXd3Av5Lejq499d6pFuV1jyK+EHyG3Q==} + deprecated: This is a stub types definition. express-unless provides its own type definitions, so you do not need this installed. + dependencies: + express-unless: 2.1.2 + dev: true + + /@types/express@4.17.14: + resolution: {integrity: sha512-TEbt+vaPFQ+xpxFLFssxUDXj5cWCxZJjIcB7Yg0k0GMHGtgtQgpvx/MUQUeAkNbA9AAGrwkAsoeItdTgS7FMyg==} + dependencies: + '@types/body-parser': 1.19.0 + '@types/express-serve-static-core': 4.17.31 + '@types/qs': 6.9.7 + '@types/serve-static': 1.15.0 + dev: true + + /@types/fs-capacitor@2.0.0: + resolution: {integrity: sha512-FKVPOCFbhCvZxpVAMhdBdTfVfXUpsh15wFHgqOKxh9N9vzWZVuWCSijZ5T4U34XYNnuj2oduh6xcs1i+LPI+BQ==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/geojson@7946.0.10: + resolution: {integrity: sha512-Nmh0K3iWQJzniTuPRcJn5hxXkfB1T1pgB89SBig5PlJQU5yocazeu4jATJlaA0GYFKWMqDdvYemoSnF2pXgLVA==} + dev: true + + /@types/glob@7.2.0: + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + requiresBuild: true + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 14.18.29 + dev: true + + /@types/graceful-fs@4.1.5: + resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/hast@2.3.4: + resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /@types/http-assert@1.5.3: + resolution: {integrity: sha512-FyAOrDuQmBi8/or3ns4rwPno7/9tJTijVW6aQQjK02+kOQ8zmoNg2XJtAuQhvQcy1ASJq38wirX5//9J1EqoUA==} + dev: true + + /@types/http-cache-semantics@4.0.1: + resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} + dev: true + + /@types/http-errors@1.8.2: + resolution: {integrity: sha512-EqX+YQxINb+MeXaIqYDASb6U6FCHbWjkj4a1CKDBks3d/QiB2+PqBLyO72vLDgAO1wUI4O+9gweRcQK11bTL/w==} + dev: true + + /@types/istanbul-lib-coverage@2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/istanbul-lib-report@3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + dev: true + + /@types/istanbul-reports@3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/jsonwebtoken@8.5.9: + resolution: {integrity: sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/keygrip@1.0.2: + resolution: {integrity: sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw==} + dev: true + + /@types/keyv@3.1.4: + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/keyv@4.2.0: + resolution: {integrity: sha512-xoBtGl5R9jeKUhc8ZqeYaRDx04qqJ10yhhXYGmJ4Jr8qKpvMsDQQrNUvF/wUJ4klOtmJeJM+p2Xo3zp9uaC3tw==} + deprecated: This is a stub types definition. keyv provides its own type definitions, so you do not need this installed. + dependencies: + keyv: 4.5.0 + dev: true + + /@types/koa-compose@3.2.5: + resolution: {integrity: sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ==} + dependencies: + '@types/koa': 2.13.5 + dev: true + + /@types/koa@2.13.5: + resolution: {integrity: sha512-HSUOdzKz3by4fnqagwthW/1w/yJspTgppyyalPVbgZf8jQWvdIXcVW5h2DGtw4zYntOaeRGx49r1hxoPWrD4aA==} + dependencies: + '@types/accepts': 1.3.5 + '@types/content-disposition': 0.5.5 + '@types/cookies': 0.7.7 + '@types/http-assert': 1.5.3 + '@types/http-errors': 1.8.2 + '@types/keygrip': 1.0.2 + '@types/koa-compose': 3.2.5 + '@types/node': 14.18.29 + dev: true + + /@types/long@4.0.2: + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + dev: true + + /@types/mdast@3.0.10: + resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /@types/mdx@2.0.3: + resolution: {integrity: sha512-IgHxcT3RC8LzFLhKwP3gbMPeaK7BM9eBH46OdapPA7yvuIUJ8H6zHZV53J8hGZcTSnt95jANt+rTBNUUc22ACQ==} + dev: true + + /@types/micromatch@4.0.2: + resolution: {integrity: sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==} + requiresBuild: true + dependencies: + '@types/braces': 3.0.1 + dev: true + + /@types/mime@3.0.1: + resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + dev: true + + /@types/minimatch@5.1.2: + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + dev: true + + /@types/mongodb@3.6.20: + resolution: {integrity: sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==} + dependencies: + '@types/bson': 4.0.5 + '@types/node': 14.18.29 + dev: true + + /@types/ms@0.7.31: + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + dev: true + + /@types/node@10.17.60: + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + dev: true + + /@types/node@14.18.29: + resolution: {integrity: sha512-LhF+9fbIX4iPzhsRLpK5H7iPdvW8L4IwGciXQIOEcuF62+9nw/VQVsOViAOOGxY3OlOKGLFv0sWwJXdwQeTn6A==} + dev: true + + /@types/node@17.0.45: + resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} + dev: true + + /@types/prettier@2.7.1: + resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} + dev: true + + /@types/qs@6.9.7: + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + dev: true + + /@types/range-parser@1.2.4: + resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + dev: true + + /@types/rdfjs__namespace@2.0.0: + resolution: {integrity: sha512-bpVmmBrwg4plwfSNtwbwIYtZEpGFPWHTlfa1iftSY03+V+2wq+pfZxYkZwrhZwyh/Dxy5usIrVt04Rvigc4uXg==} + dependencies: + rdf-js: 4.0.2 + dev: true + + /@types/responselike@1.0.0: + resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/serve-static@1.15.0: + resolution: {integrity: sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg==} + dependencies: + '@types/mime': 3.0.1 + '@types/node': 14.18.29 + dev: true + + /@types/stack-utils@2.0.1: + resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + dev: true + + /@types/tough-cookie@4.0.2: + resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} + dev: true + + /@types/unist@2.0.6: + resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} + dev: true + + /@types/ws@7.4.7: + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /@types/yargs-parser@21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: true + + /@types/yargs@16.0.4: + resolution: {integrity: sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + + /@vercel/nft@0.22.1: + resolution: {integrity: sha512-lYYZIoxRurqDOSoVIdBicGnpUIpfyaS5qVjdPq+EfI285WqtZK3NK/dyCkiyBul+X2U2OEhRyeMdXPCHGJbohw==} + hasBin: true + requiresBuild: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.10 + acorn: 8.8.1 + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + node-gyp-build: 4.5.0 + resolve-from: 5.0.0 + rollup-pluginutils: 2.8.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@vue/compiler-sfc@2.7.13: + resolution: {integrity: sha512-zzu2rLRZlgIU+OT3Atbr7Y6PG+LW4wVQpPfNRrGDH3dM9PsrcVfa+1pKb8bW467bGM3aDOvAnsYLWVpYIv3GRg==} + dependencies: + '@babel/parser': 7.19.6 + postcss: 8.4.18 + source-map: 0.6.1 + dev: true + + /@webcomponents/template@1.5.0: + resolution: {integrity: sha512-DPQgBAedzjsFD7rgv7b6OKmpHq5VTBUCLmYfDiov2FC2C79QGaz+4iNmlVAem5iSicvN8DWTwU1kZ48XYLtuqg==} + dev: true + + /@wry/equality@0.1.11: + resolution: {integrity: sha512-mwEVBDUVODlsQQ5dfuLUS5/Tf7jqUKyhKYHmVi4fPB6bDMOfWvUPJmKgS1Z7Za/sOI3vzWt4+O7yCiL/70MogA==} + dependencies: + tslib: 1.14.1 + dev: true + + /@xmldom/xmldom@0.8.10: + resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} + engines: {node: '>=10.0.0'} + dev: true + + /@zazuko/node-fetch@2.6.6: + resolution: {integrity: sha512-mrEqq7BJyNBlK5oT7U1S0EfLbFPpVHLXQJswhrN8Mv/3BKmWIBtMBaphK8AXF7XEhgK9vzRs/f3AIG8oHlPdpg==} + engines: {node: 4.x || >=6.0.0} + dependencies: + whatwg-url: 5.0.0 + dev: true + + /@zazuko/rdf-vocabularies@2022.6.29: + resolution: {integrity: sha512-E1IyTK3WfeeB0LAPxtDapcBPB+uizhYFGBgjK0z9xMnGIeWWtWb59jpGxLTfVjHMbGbxeTm/HPAKLwtB1gX1xQ==} + hasBin: true + dependencies: + '@rdfjs/parser-n3': 1.1.4 + commander: 5.1.0 + pkg-dir: 5.0.0 + rdf-ext: 1.3.5 + readable-stream: 3.6.0 + string-to-stream: 3.0.1 + dev: true + + /@zazuko/rdf-vocabularies@2023.1.19: + resolution: {integrity: sha512-/vC/Ok8etIi4kflbOAoRr9JV95auJaUREV9lrWP3wDEMfhu8jVYogwi/OD1yA2pH6KIYPS2+z7LN1jxOe3G56g==} + hasBin: true + dependencies: + '@rdfjs/parser-n3': 1.1.4 + commander: 5.1.0 + pkg-dir: 5.0.0 + rdf-ext: 1.3.5 + readable-stream: 3.6.2 + string-to-stream: 3.0.1 + dev: true + + /@zeit/cosmosdb-query@0.7.2: + resolution: {integrity: sha512-DbJvahdaurKMyCCt0Ry4QlWpSXAMPK2b0FJcYZTNntB4VIsz9Bz0+aTTUYv0dzAJ+e6Qx5vKUaGGV3zeWkxxOw==} + requiresBuild: true + dependencies: + '@babel/generator': 7.6.2 + '@babel/traverse': 7.6.2 + '@turf/nearest-point-to-line': 6.0.0 + '@turf/point-to-line-distance': 6.0.0 + '@turf/turf': 5.1.6 + transitivePeerDependencies: + - supports-color + dev: true + + /Base64@1.1.0: + resolution: {integrity: sha512-qeacf8dvGpf+XAT27ESHMh7z84uRzj/ua2pQdJg483m3bEXv/kVFtDnMgvf70BQGqzbZhR9t6BmASzKvqfJf3Q==} + dev: true + + /JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + dev: true + + /JSV@4.0.2: + resolution: {integrity: sha512-ZJ6wx9xaKJ3yFUhq5/sk82PJMuUyLk277I8mQeyDgCTjGdjWJIvPfaU5LIXaMuaN2UO1X3kZH4+lgphublZUHw==} + dev: true + + /abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + dev: true + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: true + + /abstract-leveldown@6.2.3: + resolution: {integrity: sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==} + engines: {node: '>=6'} + dependencies: + buffer: 5.7.1 + immediate: 3.3.0 + level-concat-iterator: 2.0.1 + level-supports: 1.0.1 + xtend: 4.0.2 + dev: true + + /accept-language@3.0.18: + resolution: {integrity: sha512-sUofgqBPzgfcF20sPoBYGQ1IhQLt2LSkxTnlQSuLF3n5gPEqd5AimbvOvHEi0T1kLMiGVqPWzI5a9OteBRth3A==} + dependencies: + bcp47: 1.1.2 + stable: 0.1.8 + dev: true + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: true + + /acorn-globals@6.0.0: + resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + dev: true + + /acorn-jsx@5.3.2(acorn@8.8.1): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.8.1 + dev: true + + /acorn-node@1.8.2: + resolution: {integrity: sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A==} + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + xtend: 4.0.2 + dev: true + + /acorn-walk@7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn@8.8.1: + resolution: {integrity: sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /after@0.8.2: + resolution: {integrity: sha512-QbJ0NTQ/I9DI3uSJA4cbexiwQeRAfjPScqIbSjUDd9TOrcg6pTkdgziesOqxBMBzit8vFCTwrP27t13vFOORRA==} + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /agentkeepalive@4.2.1: + resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==} + engines: {node: '>= 8.0.0'} + requiresBuild: true + dependencies: + debug: 4.3.4 + depd: 1.1.2 + humanize-ms: 1.2.1 + transitivePeerDependencies: + - supports-color + dev: true + optional: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + optional: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /align-text@0.1.4: + resolution: {integrity: sha512-GrTZLRpmp6wIC2ztrWW9MjjTgSKccffgFagbNDOX95/dcjEcYZibYTeaOntySQLcdw1ztBoFkviiUvTMbb9MYg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + longest: 1.0.1 + repeat-string: 1.6.1 + dev: true + + /already@1.13.2: + resolution: {integrity: sha512-GU0ZqMhSetZeDlivqttmAmd2UpCbPSucziaDJcCN2NdOTedzaJTqZZwHHuGJvp0Us1wzQG0vSqFqax1SqgH8Aw==} + dependencies: + throat: 5.0.0 + dev: true + + /amdefine@1.0.1: + resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} + engines: {node: '>=0.4.2'} + dev: true + + /analytics-node@3.5.0(debug@4.3.4): + resolution: {integrity: sha512-XgQq6ejZHCehUSnZS4V7QJPLIP7S9OAWwQDYl4WTLtsRvc5fCxIwzK/yihzmIW51v9PnyBmrl9dMcqvwfOE8WA==} + engines: {node: '>=4'} + dependencies: + '@segment/loosely-validate-event': 2.0.0 + axios: 0.21.4(debug@4.3.4) + axios-retry: 3.3.1 + lodash.isstring: 4.0.1 + md5: 2.3.0 + ms: 2.1.3 + remove-trailing-slash: 0.1.1 + uuid: 3.4.0 + transitivePeerDependencies: + - debug + dev: true + + /ansi-align@2.0.0: + resolution: {integrity: sha512-TdlOggdA/zURfMYa7ABC66j+oqfMew58KpJMbUlH3bcZP1b+cBHIHDDn5uH9INsxrHBPjsqM0tDB4jPTF/vgJA==} + dependencies: + string-width: 2.1.1 + dev: true + + /ansi-escapes@3.2.0: + resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} + engines: {node: '>=4'} + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-green@0.1.1: + resolution: {integrity: sha512-WJ70OI4jCaMy52vGa/ypFSKFb/TrYNPaQ2xco5nUwE0C5H8piume/uAZNNdXXiMQ6DbRmiE7l8oNBHu05ZKkrw==} + engines: {node: '>=0.10.0'} + dependencies: + ansi-wrap: 0.1.0 + dev: true + + /ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + dev: true + + /ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /ansi-wrap@0.1.0: + resolution: {integrity: sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==} + engines: {node: '>=0.10.0'} + dev: true + + /any-base@1.1.0: + resolution: {integrity: sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg==} + dev: true + + /any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + dev: true + + /anymatch@2.0.0: + resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} + dependencies: + micromatch: 3.1.10 + normalize-path: 2.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /anymatch@3.1.2: + resolution: {integrity: sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /apollo-cache-control@0.15.0(graphql@14.7.0): + resolution: {integrity: sha512-U2uYvHZsWmR6s6CD5zlq3PepfbUAM8953CeVM2Y2QYMtJ8i4CYplEPbIWb3zTIXSPbIPeWGddM56pChI6Iz3zA==} + engines: {node: '>=6.0'} + deprecated: The functionality provided by the `apollo-cache-control` package is built in to `apollo-server-core` starting with Apollo Server 3. See https://www.apollographql.com/docs/apollo-server/migration/#cachecontrol for details. + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + apollo-server-env: 3.2.0 + apollo-server-plugin-base: 0.14.0(graphql@14.7.0) + graphql: 14.7.0 + transitivePeerDependencies: + - encoding + dev: true + + /apollo-datasource@0.10.0: + resolution: {integrity: sha512-wrLhuoM2MtA0KA0+3qyioe0H2FjAxjTvuFOlNCk6WberA887m0MQlWULZImCWTkKuN+zEAMerHfxN+F+W8+lBA==} + engines: {node: '>=6'} + deprecated: The `apollo-datasource` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + dependencies: + apollo-server-caching: 0.7.0 + apollo-server-env: 3.2.0 + transitivePeerDependencies: + - encoding + dev: true + + /apollo-graphql@0.9.7(graphql@14.7.0): + resolution: {integrity: sha512-bezL9ItUWUGHTm1bI/XzIgiiZbhXpsC7uxk4UxFPmcVJwJsDc3ayZ99oXxAaK+3Rbg/IoqrHckA6CwmkCsbaSA==} + engines: {node: '>=6'} + peerDependencies: + graphql: ^14.2.1 || ^15.0.0 + dependencies: + core-js-pure: 3.26.0 + graphql: 14.7.0 + lodash.sortby: 4.7.0 + sha.js: 2.4.11 + dev: true + + /apollo-link@1.2.14(graphql@14.7.0): + resolution: {integrity: sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==} + peerDependencies: + graphql: ^0.11.3 || ^0.12.3 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + apollo-utilities: 1.3.4(graphql@14.7.0) + graphql: 14.7.0 + ts-invariant: 0.4.4 + tslib: 1.14.1 + zen-observable-ts: 0.8.21 + dev: true + + /apollo-reporting-protobuf@0.8.0: + resolution: {integrity: sha512-B3XmnkH6Y458iV6OsA7AhfwvTgeZnFq9nPVjbxmLKnvfkEl8hYADtz724uPa0WeBiD7DSFcnLtqg9yGmCkBohg==} + deprecated: The `apollo-reporting-protobuf` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/usage-reporting-protobuf` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + dependencies: + '@apollo/protobufjs': 1.2.2 + dev: true + + /apollo-server-caching@0.7.0: + resolution: {integrity: sha512-MsVCuf/2FxuTFVhGLK13B+TZH9tBd2qkyoXKKILIiGcZ5CDUEBO14vIV63aNkMkS1xxvK2U4wBcuuNj/VH2Mkw==} + engines: {node: '>=6'} + deprecated: This package is part of the legacy caching implementation used by Apollo Server v2 and v3, and is no longer maintained. We recommend you switch to the newer Keyv-based implementation (which is compatible with all versions of Apollo Server). See https://www.apollographql.com/docs/apollo-server/v3/performance/cache-backends#legacy-caching-implementation for more details. + dependencies: + lru-cache: 6.0.0 + dev: true + + /apollo-server-core@2.26.1(graphql@14.7.0): + resolution: {integrity: sha512-YnO1YXhHOnCY7Q2SZ0uUtPq6SLCw+t2uI19l59mzWuCyZYdHrtSy3zUEU6pM3tR9vvUuRGkYIfMRlo/Q8a1U5g==} + engines: {node: '>=6'} + deprecated: The `apollo-server-core` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + '@apollographql/apollo-tools': 0.5.4(graphql@14.7.0) + '@apollographql/graphql-playground-html': 1.6.27 + '@apollographql/graphql-upload-8-fork': 8.1.4(graphql@14.7.0) + '@josephg/resolvable': 1.0.1 + '@types/ws': 7.4.7 + apollo-cache-control: 0.15.0(graphql@14.7.0) + apollo-datasource: 0.10.0 + apollo-graphql: 0.9.7(graphql@14.7.0) + apollo-reporting-protobuf: 0.8.0 + apollo-server-caching: 0.7.0 + apollo-server-env: 3.2.0 + apollo-server-errors: 2.5.0(graphql@14.7.0) + apollo-server-plugin-base: 0.14.0(graphql@14.7.0) + apollo-server-types: 0.10.0(graphql@14.7.0) + apollo-tracing: 0.16.0(graphql@14.7.0) + async-retry: 1.3.3 + fast-json-stable-stringify: 2.1.0 + graphql: 14.7.0 + graphql-extensions: 0.16.0(graphql@14.7.0) + graphql-tag: 2.12.6(graphql@14.7.0) + graphql-tools: 4.0.8(graphql@14.7.0) + loglevel: 1.8.0 + lru-cache: 6.0.0 + sha.js: 2.4.11 + subscriptions-transport-ws: 0.9.19(graphql@14.7.0) + uuid: 8.3.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + dev: true + + /apollo-server-env@3.2.0: + resolution: {integrity: sha512-V+kO5e6vUo2JwqV1/Ng71ZE3J6x1hCOC+nID2/++bCYl0/fPY9iLChbBNSgN/uoFcjhgmBchOv+m4o0Nie/TFQ==} + engines: {node: '>=6'} + deprecated: The `apollo-server-env` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/utils.fetcher` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + dependencies: + node-fetch: 2.6.12 + util.promisify: 1.1.1 + transitivePeerDependencies: + - encoding + dev: true + + /apollo-server-errors@2.5.0(graphql@14.7.0): + resolution: {integrity: sha512-lO5oTjgiC3vlVg2RKr3RiXIIQ5pGXBFxYGGUkKDhTud3jMIhs+gel8L8zsEjKaKxkjHhCQAA/bcEfYiKkGQIvA==} + engines: {node: '>=6'} + deprecated: The `apollo-server-errors` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + graphql: 14.7.0 + dev: true + + /apollo-server-express@2.26.1(graphql@14.7.0): + resolution: {integrity: sha512-eATTtlGhZFuo4KNRgaQ25jflUchI18oMd0vZyx0uIQ/CM0FPttO1noQ0fPAO6U0oSrxS8J9fCh8naJFDTUsZ0w==} + engines: {node: '>=6'} + deprecated: The `apollo-server-express` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + '@apollographql/graphql-playground-html': 1.6.27 + '@types/accepts': 1.3.5 + '@types/body-parser': 1.19.0 + '@types/cors': 2.8.10 + '@types/express': 4.17.14 + '@types/express-serve-static-core': 4.17.31 + accepts: 1.3.8 + apollo-server-core: 2.26.1(graphql@14.7.0) + apollo-server-types: 0.10.0(graphql@14.7.0) + body-parser: 1.20.1 + cors: 2.8.5 + express: 4.18.2 + graphql: 14.7.0 + graphql-subscriptions: 1.2.1(graphql@14.7.0) + graphql-tools: 4.0.8(graphql@14.7.0) + parseurl: 1.3.3 + subscriptions-transport-ws: 0.9.19(graphql@14.7.0) + type-is: 1.6.18 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /apollo-server-plugin-base@0.14.0(graphql@14.7.0): + resolution: {integrity: sha512-nTNSFuBhZURGjtWptdVqwemYUOdsvABj/GSKzeNvepiEubiv4N0rt4Gvy1inHDiMbo98wQTdF/7XohNcB9A77g==} + engines: {node: '>=6'} + deprecated: The `apollo-server-plugin-base` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + apollo-server-types: 0.10.0(graphql@14.7.0) + graphql: 14.7.0 + transitivePeerDependencies: + - encoding + dev: true + + /apollo-server-types@0.10.0(graphql@14.7.0): + resolution: {integrity: sha512-LsB3epw1X3Co/HGiKHCGtzWG35J59gG8Ypx0p22+wgdM9AVDm1ylsNGZy+osNIVJc1lUJf3nF5kZ90vA866K/w==} + engines: {node: '>=6'} + deprecated: The `apollo-server-types` package is part of Apollo Server v2 and v3, which are now deprecated (end-of-life October 22nd 2023). This package's functionality is now found in the `@apollo/server` package. See https://www.apollographql.com/docs/apollo-server/previous-versions/ for more details. + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + apollo-reporting-protobuf: 0.8.0 + apollo-server-caching: 0.7.0 + apollo-server-env: 3.2.0 + graphql: 14.7.0 + transitivePeerDependencies: + - encoding + dev: true + + /apollo-tracing@0.16.0(graphql@14.7.0): + resolution: {integrity: sha512-Oy8kTggB+fJ/hHXwHyMpuTl5KW7u1XetKFDErZVOobUKc2zjc/NgWiC/s7SGYZCgfLodBjvwfa6rMcvLkz7c0w==} + engines: {node: '>=4.0'} + deprecated: The `apollo-tracing` package is no longer part of Apollo Server 3. See https://www.apollographql.com/docs/apollo-server/migration/#tracing for details + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + apollo-server-env: 3.2.0 + apollo-server-plugin-base: 0.14.0(graphql@14.7.0) + graphql: 14.7.0 + transitivePeerDependencies: + - encoding + dev: true + + /apollo-utilities@1.3.4(graphql@14.7.0): + resolution: {integrity: sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==} + peerDependencies: + graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + '@wry/equality': 0.1.11 + fast-json-stable-stringify: 2.1.0 + graphql: 14.7.0 + ts-invariant: 0.4.4 + tslib: 1.14.1 + dev: true + + /aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: true + + /are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.0 + dev: true + + /are-we-there-yet@3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + requiresBuild: true + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.0 + dev: true + optional: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /argon2@0.27.2: + resolution: {integrity: sha512-evnzS/Q9rj6ahaaCJjLDoJo9ZuXHhVL2BrBz3wFHb5/i9zAJovBuIY+5t2En7tJjhFXs4O3rUZDeGZxBiDOLwQ==} + engines: {node: '>=10.0.0'} + requiresBuild: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.10 + '@phc/format': 1.0.0 + node-addon-api: 3.2.1 + opencollective-postinstall: 2.0.3 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argv@0.0.2: + resolution: {integrity: sha512-dEamhpPEwRUBpLNHeuCm/v+g0anFByHahxodVO/BbAarHVBBg2MccCwf9K+o1Pof+2btdnkJelYVUWjW/VrATw==} + engines: {node: '>=0.6.10'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + dev: true + + /arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + dev: true + + /arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + dev: true + + /arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + dev: true + + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: true + + /array-source@0.0.4: + resolution: {integrity: sha512-frNdc+zBn80vipY+GdcJkLEbMWj3xmzArYApmUGxoiV8uAu/ygcs9icPdsGdA26h0MkHUMW6EN2piIvVx+M5Mw==} + dev: true + + /array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + dev: true + + /array.prototype.reduce@1.0.4: + resolution: {integrity: sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + es-array-method-boxes-properly: 1.0.0 + is-string: 1.0.7 + dev: true + + /arraybuffer.slice@0.0.7: + resolution: {integrity: sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==} + dev: true + + /arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + dev: true + + /asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: true + + /asn1.js@5.4.1: + resolution: {integrity: sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==} + dependencies: + bn.js: 4.12.0 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + safer-buffer: 2.1.2 + dev: true + + /asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /assert-never@1.2.1: + resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} + dev: true + + /assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + dev: true + + /assert@1.5.0: + resolution: {integrity: sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==} + dependencies: + object-assign: 4.1.1 + util: 0.10.3 + dev: true + + /assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + dev: true + + /astring@1.8.4: + resolution: {integrity: sha512-97a+l2LBU3Op3bBQEff79i/E4jMD2ZLFD8rHx9B6mXyB2uQwhJQYfiDqUwtfjF4QA1F2qs//N6Cw8LetMbQjcw==} + hasBin: true + dev: true + + /async-array-reduce@0.2.1: + resolution: {integrity: sha512-/ywTADOcaEnwiAnOEi0UB/rAcIq5bTFfCV9euv3jLYFUMmy6KvKccTQUnLlp8Ensmfj43wHSmbGiPqjsZ6RhNA==} + engines: {node: '>=0.10.0'} + dev: true + + /async-each@1.0.3: + resolution: {integrity: sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==} + dev: true + + /async-limiter@1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + dev: true + + /async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + dependencies: + retry: 0.13.1 + dev: true + + /async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + dev: true + + /async@0.2.10: + resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} + dev: true + + /async@1.5.2: + resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} + dev: true + + /async@2.6.4: + resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} + dependencies: + lodash: 4.17.21 + dev: true + + /async@3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + + /atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + dev: true + + /audio-context-polyfill@1.0.0: + resolution: {integrity: sha512-Ex1jZc8e3AIiOBm8Tn0oS4yZ8aT5VCLygaov+fxJ4ymgUB2GPqW5DtQ8NBpR2dfvSR6RjWvMU8+nDwIE/he49w==} + dev: true + + /auth0@2.44.0(debug@4.3.4): + resolution: {integrity: sha512-TowzD2RbBVyhqW/qk0cqV5ibRc86r2gqqc+8CRdoV9/58hh3prjeSjaW+8CpnyVdBYqoCM0ItvbJnCjk/tsUig==} + engines: {node: '>=8.3.0'} + dependencies: + axios: 0.27.2(debug@4.3.4) + form-data: 3.0.1 + jsonwebtoken: 8.5.1 + jwks-rsa: 1.12.3 + lru-memoizer: 2.1.4 + rest-facade: 1.16.3 + retry: 0.13.1 + transitivePeerDependencies: + - debug + - superagent-proxy + - supports-color + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /aws-sdk@2.1240.0: + resolution: {integrity: sha512-WmZHnvka7SFKOwnGV0tDwjBPz5j9jJ7KU4BfvOZ/1y+hwcXsUY2JjKj9T7KKMjjG/L3m2H5b9JpS+r/gtcjnog==} + engines: {node: '>= 10.0.0'} + dependencies: + buffer: 4.9.2 + events: 1.1.1 + ieee754: 1.1.13 + jmespath: 0.16.0 + querystring: 0.2.0 + sax: 1.2.1 + url: 0.10.3 + util: 0.12.5 + uuid: 8.0.0 + xml2js: 0.4.19 + dev: true + + /aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + dev: true + + /aws4@1.11.0: + resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} + dev: true + + /axe-core@3.3.0: + resolution: {integrity: sha512-54XaTd2VB7A6iBnXMUG2LnBOI7aRbnrVxC5Tz+rVUwYl9MX/cIJc/Ll32YUoFIE/e9UKWMZoQenQu9dFrQyZCg==} + engines: {node: '>=4'} + dev: true + + /axios-retry@3.3.1: + resolution: {integrity: sha512-RohAUQTDxBSWLFEnoIG/6bvmy8l3TfpkclgStjl5MDCMBDgapAWCmr1r/9harQfWC8bzLC8job6UcL1A1Yc+/Q==} + dependencies: + '@babel/runtime': 7.19.4 + is-retry-allowed: 2.2.0 + dev: true + + /axios@0.21.4(debug@4.3.4): + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + dependencies: + follow-redirects: 1.15.2(debug@4.3.4) + transitivePeerDependencies: + - debug + dev: true + + /axios@0.26.1(debug@4.3.4): + resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} + dependencies: + follow-redirects: 1.15.2(debug@4.3.4) + transitivePeerDependencies: + - debug + dev: true + + /axios@0.27.2(debug@4.3.4): + resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} + dependencies: + follow-redirects: 1.15.2(debug@4.3.4) + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: true + + /azure-storage@2.10.7: + resolution: {integrity: sha512-4oeFGtn3Ziw/fGs/zkoIpKKtygnCVIcZwzJ7UQzKTxhkGQqVCByOFbYqMGYR3L+wOsunX9lNfD0jc51SQuKSSA==} + engines: {node: '>= 0.8.26'} + deprecated: 'Please note: newer packages @azure/storage-blob, @azure/storage-queue and @azure/storage-file are available as of November 2019 and @azure/data-tables is available as of June 2021. While the legacy azure-storage package will continue to receive critical bug fixes, we strongly encourage you to upgrade. Migration guide can be found: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/storage/MigrationGuide.md' + requiresBuild: true + dependencies: + browserify-mime: 1.2.9 + extend: 3.0.2 + json-edm-parser: 0.1.2 + json-schema: 0.4.0 + md5.js: 1.3.5 + readable-stream: 2.3.7 + request: 2.88.2 + underscore: 1.13.6 + uuid: 3.4.0 + validator: 13.7.0 + xml2js: 0.2.8 + xmlbuilder: 9.0.7 + dev: true + + /babel-jest@27.5.1(@babel/core@7.19.6): + resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + dependencies: + '@babel/core': 7.19.6 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/babel__core': 7.1.19 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 27.5.1(@babel/core@7.19.6) + chalk: 4.1.2 + graceful-fs: 4.2.10 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.19.0 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-jest-hoist@27.5.1: + resolution: {integrity: sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@babel/template': 7.18.10 + '@babel/types': 7.19.4 + '@types/babel__core': 7.1.19 + '@types/babel__traverse': 7.18.2 + dev: true + + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.19.6): + resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.19.6 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.19.6) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.19.6) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.19.6) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.19.6) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.19.6) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.19.6) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.19.6) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.19.6) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.19.6) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.19.6) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.19.6) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.19.6) + dev: true + + /babel-preset-jest@27.5.1(@babel/core@7.19.6): + resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.19.6 + babel-plugin-jest-hoist: 27.5.1 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.19.6) + dev: true + + /babel-walk@3.0.0-canary-5: + resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} + engines: {node: '>= 10.0.0'} + dependencies: + '@babel/types': 7.19.4 + dev: true + + /backo2@1.0.2: + resolution: {integrity: sha512-zj6Z6M7Eq+PBZ7PQxl5NT665MvJdAkzp0f60nAJ+sLaSCBPMwVak5ZegFbgVCzFcCJTKFoMizvM5Ld7+JrRJHA==} + dev: true + + /bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-arraybuffer@0.1.4: + resolution: {integrity: sha512-a1eIFi4R9ySrbiMuyTGx5e92uRH5tQY6kArNcFaKBUleIoLjdjBg7Zxm3Mqm3Kmkf27HLR/1fnxX9q8GQ7Iavg==} + engines: {node: '>= 0.6.0'} + dev: true + + /base64-js@0.0.2: + resolution: {integrity: sha512-Pj9L87dCdGcKlSqPVUjD+q96pbIx1zQQLb2CUiWURfjiBELv84YX+0nGnKmyT/9KkC7PQk7UN1w+Al8bBozaxQ==} + engines: {node: '>= 0.4'} + dev: true + + /base64-js@0.0.8: + resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} + engines: {node: '>= 0.4'} + dev: true + + /base64-js@1.0.2: + resolution: {integrity: sha512-ZXBDPMt/v/8fsIqn+Z5VwrhdR6jVka0bYobHdGia0Nxi7BJ9i/Uvml3AocHIBtIIBhZjBw5MR0aR4ROs/8+SNg==} + engines: {node: '>= 0.4'} + dev: true + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /base64id@2.0.0: + resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} + engines: {node: ^4.5.0 || >= 5.9} + dev: true + + /base64url@3.0.1: + resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==} + engines: {node: '>=6.0.0'} + dev: true + + /base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.0 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + dev: true + + /bcp47@1.1.2: + resolution: {integrity: sha512-JnkkL4GUpOvvanH9AZPX38CxhiLsXMBicBY2IAtqiVN8YulGDQybUydWA4W6yAMtw6iShtw+8HEF6cfrTHU+UQ==} + engines: {node: '>=0.10'} + dev: true + + /bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + dependencies: + tweetnacl: 0.14.5 + dev: true + + /bcrypt@5.1.0: + resolution: {integrity: sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q==} + engines: {node: '>= 10.0.0'} + requiresBuild: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.10 + node-addon-api: 5.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /bcryptjs@2.4.3: + resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} + dev: true + + /better-sqlite3@9.2.2: + resolution: {integrity: sha512-qwjWB46il0lsDkeB4rSRI96HyDQr8sxeu1MkBVLMrwusq1KRu4Bpt1TMI+8zIJkDUtZ3umjAkaEjIlokZKWCQw==} + requiresBuild: true + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.1 + dev: true + + /big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + dev: true + + /bignumber.js@9.0.0: + resolution: {integrity: sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A==} + dev: true + + /bignumber.js@9.1.0: + resolution: {integrity: sha512-4LwHK4nfDOraBCtst+wOWIHbu1vhvAPJK8g8nROd4iuc3PSEjWif/qwbkh8jwCJz6yDBvtU4KPynETgrfh7y3A==} + dev: true + + /binary-extensions@1.13.1: + resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} + engines: {node: '>=0.10.0'} + dev: true + + /binary-search-bounds@2.0.3: + resolution: {integrity: sha512-GMGnMG7owGQwTBNWdOnWvU6KC2k/lULWdbdXq95kxJHdTzeDa9x8QNwMXCv/7pfPGx9Zdi1nmCDZ0j+Tmk+vRg==} + dev: true + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: true + + /bl@1.2.3: + resolution: {integrity: sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==} + dependencies: + readable-stream: 2.3.7 + safe-buffer: 5.2.1 + dev: true + + /bl@2.2.1: + resolution: {integrity: sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==} + dependencies: + readable-stream: 2.3.7 + safe-buffer: 5.2.1 + dev: true + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.0 + dev: true + + /blob@0.0.5: + resolution: {integrity: sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==} + dev: true + + /bluebird@3.5.1: + resolution: {integrity: sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==} + dev: true + + /bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: true + + /bmp-js@0.1.0: + resolution: {integrity: sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw==} + dev: true + + /bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + dev: true + + /bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + dev: true + + /body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.4 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /bops@0.0.7: + resolution: {integrity: sha512-oF8JFj2vZoTTzbS4haaB/37vqoJbZXxPBWmNdFONu3dUBW+zp7JcoIIYYd1r+4/YwFM8QUSR1u4rrPbtcdHsRg==} + dependencies: + base64-js: 0.0.2 + to-utf8: 0.0.1 + dev: true + + /bops@1.0.0: + resolution: {integrity: sha512-vVai54aP4LqbM+KNB1giwMo9nHvlV7pc7+iUNHYDTQe6WWI9L/jeSPBC89kUz3xA8qD7sZLldHxOXip1npWbmw==} + dependencies: + base64-js: 1.0.2 + to-utf8: 0.0.1 + dev: true + + /boxen@1.3.0: + resolution: {integrity: sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==} + engines: {node: '>=4'} + dependencies: + ansi-align: 2.0.0 + camelcase: 4.1.0 + chalk: 2.4.2 + cli-boxes: 1.0.0 + string-width: 2.1.1 + term-size: 1.2.0 + widest-line: 2.0.1 + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /brfs@1.6.1: + resolution: {integrity: sha512-OfZpABRQQf+Xsmju8XE9bDjs+uU4vLREGolP7bDgcpsI17QREyZ4Bl+2KLxxx1kCgA0fAIhKQBaBYh+PEcCqYQ==} + hasBin: true + dependencies: + quote-stream: 1.0.2 + resolve: 1.22.1 + static-module: 2.2.5 + through2: 2.0.5 + dev: true + + /brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + dev: true + + /brotli@1.3.3: + resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} + dependencies: + base64-js: 1.5.1 + dev: true + + /browser-pack@6.1.0: + resolution: {integrity: sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==} + hasBin: true + dependencies: + JSONStream: 1.3.5 + combine-source-map: 0.8.0 + defined: 1.0.1 + safe-buffer: 5.2.1 + through2: 2.0.5 + umd: 3.0.3 + dev: true + + /browser-process-hrtime@1.0.0: + resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} + dev: true + + /browser-resolve@2.0.0: + resolution: {integrity: sha512-7sWsQlYL2rGLy2IWm8WL8DCTJvYLc/qlOnsakDac87SOoCd16WLsaAMdCiAqsTNHIe+SXfaqyxyo6THoWqs8WQ==} + dependencies: + resolve: 1.22.1 + dev: true + + /browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + dev: true + + /browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + dependencies: + cipher-base: 1.0.4 + des.js: 1.0.1 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /browserify-middleware@8.1.1: + resolution: {integrity: sha512-bHGQGZfncV92HmgIxr0PzY1fAIv4rBJx5rChG7veGl4aCLWu8lbRsLPYcKMbaI6jyimyqZv+RwuOZPDxvreNNw==} + requiresBuild: true + dependencies: + browserify: 16.5.2 + ms: 2.1.3 + prepare-response: 2.1.1 + promise: 7.3.1 + uglify-es: 3.3.9 + watchify: 3.11.1 + transitivePeerDependencies: + - supports-color + dev: true + + /browserify-mime@1.2.9: + resolution: {integrity: sha512-uz+ItyJXBLb6wgon1ELEiVowJBEsy03PUWGRQU7cxxx9S+DW2hujPp+DaMYEOClRPzsn7NB99NtJ6pGnt8y+CQ==} + dev: true + + /browserify-rsa@4.1.0: + resolution: {integrity: sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==} + dependencies: + bn.js: 5.2.1 + randombytes: 2.1.0 + dev: true + + /browserify-sign@4.2.1: + resolution: {integrity: sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==} + dependencies: + bn.js: 5.2.1 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.5.4 + inherits: 2.0.4 + parse-asn1: 5.1.6 + readable-stream: 3.6.0 + safe-buffer: 5.2.1 + dev: true + + /browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + dependencies: + pako: 1.0.11 + dev: true + + /browserify@16.5.2: + resolution: {integrity: sha512-TkOR1cQGdmXU9zW4YukWzWVSJwrxmNdADFbqbE3HFgQWe5wqZmOawqZ7J/8MPCwk/W8yY7Y0h+7mOtcZxLP23g==} + engines: {node: '>= 0.8'} + hasBin: true + dependencies: + JSONStream: 1.3.5 + assert: 1.5.0 + browser-pack: 6.1.0 + browser-resolve: 2.0.0 + browserify-zlib: 0.2.0 + buffer: 5.2.1 + cached-path-relative: 1.1.0 + concat-stream: 1.6.2 + console-browserify: 1.2.0 + constants-browserify: 1.0.0 + crypto-browserify: 3.12.0 + defined: 1.0.1 + deps-sort: 2.0.1 + domain-browser: 1.2.0 + duplexer2: 0.1.4 + events: 2.1.0 + glob: 7.2.3 + has: 1.0.3 + htmlescape: 1.1.1 + https-browserify: 1.0.0 + inherits: 2.0.4 + insert-module-globals: 7.2.1 + labeled-stream-splicer: 2.0.2 + mkdirp-classic: 0.5.3 + module-deps: 6.2.3 + os-browserify: 0.3.0 + parents: 1.0.1 + path-browserify: 0.0.1 + process: 0.11.10 + punycode: 1.4.1 + querystring-es3: 0.2.1 + read-only-stream: 2.0.0 + readable-stream: 2.3.7 + resolve: 1.22.1 + shasum: 1.0.2 + shell-quote: 1.7.4 + stream-browserify: 2.0.2 + stream-http: 3.2.0 + string_decoder: 1.3.0 + subarg: 1.0.0 + syntax-error: 1.4.0 + through2: 2.0.5 + timers-browserify: 1.4.2 + tty-browserify: 0.0.1 + url: 0.11.0 + util: 0.10.4 + vm-browserify: 1.1.2 + xtend: 4.0.2 + dev: true + + /browserslist@4.21.4: + resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001425 + electron-to-chromium: 1.4.284 + node-releases: 2.0.6 + update-browserslist-db: 1.0.10(browserslist@4.21.4) + dev: true + + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /bson@1.1.6: + resolution: {integrity: sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==} + engines: {node: '>=0.6.19'} + dev: true + + /buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: true + + /buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + dev: true + + /buffer-equal@0.0.1: + resolution: {integrity: sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA==} + engines: {node: '>=0.4.0'} + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer-writer@2.0.0: + resolution: {integrity: sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==} + engines: {node: '>=4'} + dev: true + + /buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + dev: true + + /buffer@4.9.2: + resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + isarray: 1.0.0 + dev: true + + /buffer@5.2.1: + resolution: {integrity: sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /builtin-status-codes@3.0.0: + resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + dev: true + + /bull@3.29.3: + resolution: {integrity: sha512-MOqV1dKLy1YQgP9m3lFolyMxaU+1+o4afzYYf0H4wNM+x/S0I1QPQfkgGlLiH00EyFrvSmeubeCYFP47rTfpjg==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + cron-parser: 2.18.0 + debuglog: 1.0.1 + get-port: 5.1.1 + ioredis: 4.28.5 + lodash: 4.17.21 + p-timeout: 3.2.0 + promise.prototype.finally: 3.1.3 + semver: 7.3.8 + util.promisify: 1.1.1 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + dev: true + + /bullmq@1.91.1: + resolution: {integrity: sha512-u7dat9I8ZwouZ651AMZkBSvB6NVUPpnAjd4iokd9DM41whqIBnDjuL11h7+kEjcpiDKj6E+wxZiER00FqirZQg==} + requiresBuild: true + dependencies: + cron-parser: 4.6.0 + get-port: 6.1.2 + glob: 8.0.3 + ioredis: 5.2.3 + lodash: 4.17.21 + msgpackr: 1.7.2 + semver: 7.3.8 + tslib: 2.4.0 + uuid: 9.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /busboy@0.3.1: + resolution: {integrity: sha512-y7tTxhGKXcyBxRKAni+awqx8uqaJKrSFSNFSeRG5CsWNdmy2BIK+6VGWEW7TZnIO/533mtMEA4rOevQV815YJw==} + engines: {node: '>=4.5.0'} + dependencies: + dicer: 0.3.0 + dev: true + + /byline@5.0.0: + resolution: {integrity: sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==} + engines: {node: '>=0.10.0'} + dev: true + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: true + + /cacache@15.3.0: + resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} + engines: {node: '>= 10'} + requiresBuild: true + dependencies: + '@npmcli/fs': 1.1.1 + '@npmcli/move-file': 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.2.3 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.3.4 + minipass-collect: 1.0.2 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1 + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.1.11 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + dev: true + optional: true + + /cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.0 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + dev: true + + /cache-content-type@1.0.1: + resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} + engines: {node: '>= 6.0.0'} + dependencies: + mime-types: 2.1.35 + ylru: 1.3.2 + dev: true + + /cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + dev: true + + /cacheable-request@2.1.4: + resolution: {integrity: sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==} + dependencies: + clone-response: 1.0.2 + get-stream: 3.0.0 + http-cache-semantics: 3.8.1 + keyv: 3.0.0 + lowercase-keys: 1.0.0 + normalize-url: 2.0.1 + responselike: 1.0.2 + dev: true + + /cacheable-request@7.0.2: + resolution: {integrity: sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==} + engines: {node: '>=8'} + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.0 + keyv: 4.5.0 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + dev: true + + /cached-path-relative@1.1.0: + resolution: {integrity: sha512-WF0LihfemtesFcJgO7xfOoOcnWzY/QHR4qeDqV44jPU3HTI54+LnfXK3SA27AVVGCdZFgjjFFaqUA9Jx7dMJZA==} + dev: true + + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.1.3 + dev: true + + /callback-stream@1.1.0: + resolution: {integrity: sha512-sAZ9kODla+mGACBZ1IpTCAisKoGnv6PykW7fPk1LrM+mMepE18Yz0515yoVcrZy7dQsTUp3uZLQ/9Sx1RnLoHw==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.7 + dev: true + + /callguard@2.0.0: + resolution: {integrity: sha512-I3nd+fuj20FK1qu00ImrbH+II+8ULS6ioYr9igqR1xyqySoqc3DiHEyUM0mkoAdKeLGg2CtGnO8R3VRQX5krpQ==} + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camaro@6.2.0: + resolution: {integrity: sha512-81zTKgZb2LnkZKtLbIqLqBzQ6stWSlWC3I/lZd5u4NJVljDgMcsZqn9zZ+Yij/yNyiVpko0EhOKdYa6YAbOWrA==} + engines: {node: '>= 12.0.0'} + requiresBuild: true + dependencies: + piscina: 3.2.0 + dev: true + + /camel-case@1.2.2: + resolution: {integrity: sha512-rUug78lL8mqStaLehmH2F0LxMJ2TM9fnPFxb+gFkgyUjUM/1o2wKTQtalypHnkb2cFwH/DENBw7YEAOYLgSMxQ==} + dependencies: + sentence-case: 1.1.3 + upper-case: 1.1.3 + dev: true + + /camelcase@1.2.1: + resolution: {integrity: sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==} + engines: {node: '>=0.10.0'} + dev: true + + /camelcase@2.1.1: + resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} + engines: {node: '>=0.10.0'} + dev: true + + /camelcase@4.1.0: + resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} + engines: {node: '>=4'} + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite@1.0.30001425: + resolution: {integrity: sha512-/pzFv0OmNG6W0ym80P3NtapU0QEiDS3VuYAZMGoLLqiC7f6FJFe1MjpQDREGApeenD9wloeytmVDj+JLXPC6qw==} + dev: true + + /canonical-json@0.0.4: + resolution: {integrity: sha512-2sW7x0m/P7dqEnO0O87U7RTVQAaa7MELcd+Jd9FA6CYgYtwJ1TlDWIYMD8nuMkH1KoThsJogqgLyklrt9d/Azw==} + dev: true + + /canonicalize@1.0.8: + resolution: {integrity: sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A==} + dev: true + + /canvas@2.11.2: + resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==} + engines: {node: '>=6'} + requiresBuild: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.10 + nan: 2.17.0 + simple-get: 3.1.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /capture-stack-trace@1.0.2: + resolution: {integrity: sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==} + engines: {node: '>=0.10.0'} + dev: true + + /caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + dev: true + + /ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + dev: true + + /center-align@0.1.3: + resolution: {integrity: sha512-Baz3aNe2gd2LP2qk5U+sDk/m4oSuwSDcBfayTCTBoWpfIGO5XFxPmjILQII4NGiZjD6DoDI6kf7gKaxkf7s3VQ==} + engines: {node: '>=0.10.0'} + dependencies: + align-text: 0.1.4 + lazy-cache: 1.0.4 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /change-case@2.3.1: + resolution: {integrity: sha512-3HE5jrTqqn9jeKzD0+yWi7FU4OMicLbwB57ph4bpwEn5jGi3hZug5WjZjnBD2RY7YyTKAAck86ACfShXUWJKLg==} + dependencies: + camel-case: 1.2.2 + constant-case: 1.1.2 + dot-case: 1.1.2 + is-lower-case: 1.1.3 + is-upper-case: 1.1.2 + lower-case: 1.1.4 + lower-case-first: 1.0.2 + param-case: 1.1.2 + pascal-case: 1.1.2 + path-case: 1.1.2 + sentence-case: 1.1.3 + snake-case: 1.1.2 + swap-case: 1.1.2 + title-case: 1.1.2 + upper-case: 1.1.3 + upper-case-first: 1.1.2 + dev: true + + /char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + dev: true + + /character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + dev: true + + /character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + dev: true + + /character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + dev: true + + /character-parser@2.2.0: + resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} + dependencies: + is-regex: 1.1.4 + dev: true + + /character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + dev: true + + /chardet@0.4.2: + resolution: {integrity: sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==} + dev: true + + /charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + dev: true + + /chokidar@2.1.8: + resolution: {integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==} + deprecated: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies + dependencies: + anymatch: 2.0.0 + async-each: 1.0.3 + braces: 2.3.2 + glob-parent: 3.1.0 + inherits: 2.0.4 + is-binary-path: 1.0.1 + is-glob: 4.0.3 + normalize-path: 3.0.0 + path-is-absolute: 1.0.1 + readdirp: 2.2.1 + upath: 1.2.0 + optionalDependencies: + fsevents: 1.2.13 + transitivePeerDependencies: + - supports-color + dev: true + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: true + + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: true + + /chrome-launcher@0.10.7: + resolution: {integrity: sha512-IoQLp64s2n8OQuvKZwt77CscVj3UlV2Dj7yZtd1EBMld9mSdGcsGy9fN5hd/r4vJuWZR09it78n1+A17gB+AIQ==} + dependencies: + '@types/node': 14.18.29 + is-wsl: 1.1.0 + lighthouse-logger: 1.3.0 + mkdirp: 0.5.1 + rimraf: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: true + + /chrome-launcher@0.11.2: + resolution: {integrity: sha512-jx0kJDCXdB2ARcDMwNCtrf04oY1Up4rOmVu+fqJ5MTPOOIG8EhRcEU9NZfXZc6dMw9FU8o1r21PNp8V2M0zQ+g==} + dependencies: + '@types/node': 14.18.29 + is-wsl: 2.2.0 + lighthouse-logger: 1.3.0 + mkdirp: 0.5.1 + rimraf: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: true + + /chrome-remote-interface@0.25.7: + resolution: {integrity: sha512-6zI6LbR2IiGmduFZededaerEr9hHXabxT/L+fRrdq65a0CfyLMzpq0BKuZiqN0Upqcacsb6q2POj7fmobwBsEA==} + engines: {node: '>=4'} + hasBin: true + dependencies: + commander: 2.11.0 + ws: 3.3.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + + /chromeless@1.5.2: + resolution: {integrity: sha512-lxQHERZOP1aD+8Uvj+P4xM72e4aNous5igOvs+w6gRrcOZ6oIuYaSTJWMuhnTSgQzhg0APsAsIQq+a+k/2Yvow==} + engines: {node: '>= 6.10.0'} + requiresBuild: true + dependencies: + aws-sdk: 2.1240.0 + bluebird: 3.7.2 + chrome-launcher: 0.10.7 + chrome-remote-interface: 0.25.7 + cuid: 2.1.8 + form-data: 2.5.1 + got: 8.3.2 + mqtt: 2.18.9 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /ci-info@1.6.0: + resolution: {integrity: sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==} + dev: true + + /ci-info@3.5.0: + resolution: {integrity: sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==} + dev: true + + /cipher-base@1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /cjs-module-lexer@1.2.2: + resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} + dev: true + + /class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + dev: true + + /classnames@2.3.2: + resolution: {integrity: sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw==} + dev: true + + /cldrjs@0.5.5: + resolution: {integrity: sha512-KDwzwbmLIPfCgd8JERVDpQKrUUM1U4KpFJJg2IROv89rF172lLufoJnqJ/Wea6fXL5bO6WjuLMzY8V52UWPvkA==} + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + requiresBuild: true + dev: true + optional: true + + /cli-boxes@1.0.0: + resolution: {integrity: sha512-3Fo5wu8Ytle8q9iCzS4D2MWVL2X7JVWRiS1BnXbTFDhS9c/REkM9vd1AmabsoZoY5/dGi5TT9iKL8Kb6DeBRQg==} + engines: {node: '>=0.10.0'} + dev: true + + /cli-cursor@2.1.0: + resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} + engines: {node: '>=4'} + dependencies: + restore-cursor: 2.0.0 + dev: true + + /cli-width@2.2.1: + resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} + dev: true + + /cliui@2.1.0: + resolution: {integrity: sha512-GIOYRizG+TGoc7Wgc1LiOTLare95R3mzKgoln+Q/lE4ceiYH19gUpl0l0Ffq4lJDEf3FxujMe6IBfOCs7pfqNA==} + dependencies: + center-align: 0.1.3 + right-align: 0.1.3 + wordwrap: 0.0.2 + dev: true + + /cliui@3.2.0: + resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + wrap-ansi: 2.1.0 + dev: true + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: true + + /cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + dev: true + + /clone-response@1.0.2: + resolution: {integrity: sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==} + dependencies: + mimic-response: 1.0.1 + dev: true + + /clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + dependencies: + mimic-response: 1.0.1 + dev: true + + /clone-stats@0.0.1: + resolution: {integrity: sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==} + dev: true + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: true + + /clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + dev: true + + /clownface@1.5.1: + resolution: {integrity: sha512-Ko8N/UFsnhEGmPlyE1bUFhbRhVgDbxqlIjcqxtLysc4dWaY0A7iCdg3savhAxs7Lheb7FCygIyRh7ADYZWVIng==} + dependencies: + '@rdfjs/data-model': 1.3.4 + '@rdfjs/namespace': 1.1.0 + dev: true + + /cls-bluebird@2.1.0: + resolution: {integrity: sha512-XVb0RPmHQyy35Tz9z34gvtUcBKUK8A/1xkGCyeFc9B0C7Zr5SysgFaswRVdwI5NEMcO+3JKlIDGIOgERSn9NdA==} + dependencies: + is-bluebird: 1.0.2 + shimmer: 1.2.1 + dev: true + + /cluster-key-slot@1.1.1: + resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==} + engines: {node: '>=0.10.0'} + dev: true + + /co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: true + + /code-block-writer@11.0.3: + resolution: {integrity: sha512-NiujjUFB4SwScJq2bwbYUtXbZhBSlY6vYzm++3Q6oC+U+injTqfPYFK8wS9COOmb2lueqp0ZRB4nK1VYeHgNyw==} + dev: true + + /code-point-at@1.1.0: + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} + engines: {node: '>=0.10.0'} + dev: true + + /codecov@3.8.3: + resolution: {integrity: sha512-Y8Hw+V3HgR7V71xWH2vQ9lyS358CbGCldWlJFR0JirqoGtOoas3R3/OclRTvgUYFK29mmJICDPauVKmpqbwhOA==} + engines: {node: '>=4.0'} + deprecated: https://about.codecov.io/blog/codecov-uploader-deprecation-plan/ + hasBin: true + requiresBuild: true + dependencies: + argv: 0.0.2 + ignore-walk: 3.0.4 + js-yaml: 3.14.1 + teeny-request: 7.1.1 + urlgrey: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /coffee-script@1.12.7: + resolution: {integrity: sha512-fLeEhqwymYat/MpTPUjSKHVYYl0ec2mOyALEMLmzr5i1isuG+6jfI2j2d5oBO3VIzgUXgBVIcOT9uH1TFxBckw==} + engines: {node: '>=0.8.0'} + deprecated: CoffeeScript on NPM has moved to "coffeescript" (no hyphen) + hasBin: true + dev: true + + /collect-v8-coverage@1.0.1: + resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} + dev: true + + /collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + dev: true + + /color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: true + + /color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + dev: true + + /combine-source-map@0.8.0: + resolution: {integrity: sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==} + dependencies: + convert-source-map: 1.1.3 + inline-source-map: 0.6.2 + lodash.memoize: 3.0.4 + source-map: 0.5.7 + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + dev: true + + /commander@2.11.0: + resolution: {integrity: sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==} + dev: true + + /commander@2.13.0: + resolution: {integrity: sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==} + dev: true + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander@5.1.0: + resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==} + engines: {node: '>= 6'} + dev: true + + /commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: true + + /commist@1.1.0: + resolution: {integrity: sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==} + dependencies: + leven: 2.1.0 + minimist: 1.2.7 + dev: true + + /component-bind@1.0.0: + resolution: {integrity: sha512-WZveuKPeKAG9qY+FkYDeADzdHyTYdIboXS59ixDeRJL5ZhxpqUnxSOwop4FQjMsiYm3/Or8cegVbpAHNA7pHxw==} + dev: true + + /component-emitter@1.2.1: + resolution: {integrity: sha512-jPatnhd33viNplKjqXKRkGU345p263OIWzDL2wH3LGIGp5Kojo+uXizHmOADRvhGFFTnJqX3jBAKP6vvmSDKcA==} + dev: true + + /component-emitter@1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + dev: true + + /component-inherit@0.0.3: + resolution: {integrity: sha512-w+LhYREhatpVqTESyGFg3NlP6Iu0kEKUHETY9GoZP/pQyW4mHFZuFWRUCIqVPZ36ueVLtoOEZaAqbCF2RDndaA==} + dev: true + + /component-type@1.2.1: + resolution: {integrity: sha512-Kgy+2+Uwr75vAi6ChWXgHuLvd+QLD7ssgpaRq2zCvt80ptvAfMc/hijcJxXkBa2wMlEZcJvC2H8Ubo+A9ATHIg==} + dev: true + + /compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + requiresBuild: true + dependencies: + mime-db: 1.52.0 + dev: true + optional: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.7 + typedarray: 0.0.6 + dev: true + + /concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.0 + typedarray: 0.0.6 + dev: true + + /concaveman@1.2.1: + resolution: {integrity: sha512-PwZYKaM/ckQSa8peP5JpVr7IMJ4Nn/MHIaWUjP4be+KoZ7Botgs8seAZGpmaOM+UZXawcdYRao/px9ycrCihHw==} + dependencies: + point-in-polygon: 1.1.0 + rbush: 3.0.1 + robust-predicates: 2.0.4 + tinyqueue: 2.0.3 + dev: true + + /configstore@3.1.5: + resolution: {integrity: sha512-nlOhI4+fdzoK5xmJ+NY+1gZK56bwEaWZr8fYuXohZ9Vkc1o3a4T/R3M+yE/w7x/ZVJ1zF8c+oaOvF0dztdUgmA==} + engines: {node: '>=4'} + dependencies: + dot-prop: 4.2.1 + graceful-fs: 4.2.10 + make-dir: 1.3.0 + unique-string: 1.0.0 + write-file-atomic: 2.4.3 + xdg-basedir: 3.0.0 + dev: true + + /configstore@5.0.1: + resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + dot-prop: 5.3.0 + graceful-fs: 4.2.10 + make-dir: 3.1.0 + unique-string: 2.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 4.0.0 + dev: true + optional: true + + /connection-parse@0.0.7: + resolution: {integrity: sha512-bTTG28diWg7R7/+qE5NZumwPbCiJOT8uPdZYu674brDjBWQctbaQbYlDKhalS+4i5HxIx+G8dZsnBHKzWpp01A==} + dev: true + + /console-browserify@1.2.0: + resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} + dev: true + + /console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: true + + /consolidate@0.15.1(pug@3.0.2)(react-dom@16.14.0)(react@16.14.0)(swig@1.4.2)(underscore@1.13.6): + resolution: {integrity: sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==} + engines: {node: '>= 0.10.0'} + deprecated: Please upgrade to consolidate v1.0.0+ as it has been modernized with several long-awaited fixes implemented. Maintenance is supported by Forward Email at https://forwardemail.net ; follow/watch https://github.com/ladjs/consolidate for updates and release changelog + peerDependencies: + arc-templates: ^0.5.3 + atpl: '>=0.7.6' + babel-core: ^6.26.3 + bracket-template: ^1.1.5 + coffee-script: ^1.12.7 + dot: ^1.1.3 + dust: ^0.3.0 + dustjs-helpers: ^1.7.4 + dustjs-linkedin: ^2.7.5 + eco: ^1.1.0-rc-3 + ect: ^0.5.9 + ejs: ^3.1.5 + haml-coffee: ^1.14.1 + hamlet: ^0.3.3 + hamljs: ^0.6.2 + handlebars: ^4.7.6 + hogan.js: ^3.0.2 + htmling: ^0.0.8 + jade: ^1.11.0 + jazz: ^0.0.18 + jqtpl: ~1.1.0 + just: ^0.1.8 + liquid-node: ^3.0.1 + liquor: ^0.0.5 + lodash: ^4.17.20 + marko: ^3.14.4 + mote: ^0.2.0 + mustache: ^3.0.0 + nunjucks: ^3.2.2 + plates: ~0.4.11 + pug: ^3.0.0 + qejs: ^3.0.5 + ractive: ^1.3.12 + razor-tmpl: ^1.3.1 + react: ^16.13.1 + react-dom: ^16.13.1 + slm: ^2.0.0 + squirrelly: ^5.1.0 + swig: ^1.4.2 + swig-templates: ^2.0.3 + teacup: ^2.0.0 + templayed: '>=0.2.3' + then-jade: '*' + then-pug: '*' + tinyliquid: ^0.2.34 + toffee: ^0.3.6 + twig: ^1.15.2 + twing: ^5.0.2 + underscore: ^1.11.0 + vash: ^0.13.0 + velocityjs: ^2.0.1 + walrus: ^0.10.1 + whiskers: ^0.4.0 + peerDependenciesMeta: + arc-templates: + optional: true + atpl: + optional: true + babel-core: + optional: true + bracket-template: + optional: true + coffee-script: + optional: true + dot: + optional: true + dust: + optional: true + dustjs-helpers: + optional: true + dustjs-linkedin: + optional: true + eco: + optional: true + ect: + optional: true + ejs: + optional: true + haml-coffee: + optional: true + hamlet: + optional: true + hamljs: + optional: true + handlebars: + optional: true + hogan.js: + optional: true + htmling: + optional: true + jade: + optional: true + jazz: + optional: true + jqtpl: + optional: true + just: + optional: true + liquid-node: + optional: true + liquor: + optional: true + lodash: + optional: true + marko: + optional: true + mote: + optional: true + mustache: + optional: true + nunjucks: + optional: true + plates: + optional: true + pug: + optional: true + qejs: + optional: true + ractive: + optional: true + razor-tmpl: + optional: true + react: + optional: true + react-dom: + optional: true + slm: + optional: true + squirrelly: + optional: true + swig: + optional: true + swig-templates: + optional: true + teacup: + optional: true + templayed: + optional: true + then-jade: + optional: true + then-pug: + optional: true + tinyliquid: + optional: true + toffee: + optional: true + twig: + optional: true + twing: + optional: true + underscore: + optional: true + vash: + optional: true + velocityjs: + optional: true + walrus: + optional: true + whiskers: + optional: true + dependencies: + bluebird: 3.7.2 + pug: 3.0.2 + react: 16.14.0 + react-dom: 16.14.0(react@16.14.0) + swig: 1.4.2 + underscore: 1.13.6 + dev: true + + /constant-case@1.1.2: + resolution: {integrity: sha512-FQ/HuOuSnX6nIF8OnofRWj+KnOpGAHXQpOKHmsL1sAnuLwu6r5mHGK+mJc0SkHkbmNfcU/SauqXLTEOL1JQfJA==} + dependencies: + snake-case: 1.1.2 + upper-case: 1.1.3 + dev: true + + /constantinople@4.0.1: + resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} + dependencies: + '@babel/parser': 7.19.6 + '@babel/types': 7.19.4 + dev: true + + /constants-browserify@1.0.0: + resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} + dev: true + + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /content-type@1.0.4: + resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} + engines: {node: '>= 0.6'} + dev: true + + /convert-source-map@1.1.3: + resolution: {integrity: sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==} + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: true + + /cookie@0.3.1: + resolution: {integrity: sha512-+IJOX0OqlHCszo2mBUq+SrEbCj6w7Kpffqx60zYbPTFaO4+yYgRjHwcZNpWvaTylDHaV7PPmBHzSecZiMhtPgw==} + engines: {node: '>= 0.6'} + dev: true + + /cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + dev: true + + /cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: true + + /cookiejar@2.1.3: + resolution: {integrity: sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==} + dev: true + + /cookies@0.8.0: + resolution: {integrity: sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + keygrip: 1.1.0 + dev: true + + /copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + dev: true + + /copy@0.3.2: + resolution: {integrity: sha512-drDFuUZctIuvSuvL9dOF/v5GxrwB1Q8eMIRlYONC0lSMEq+L2xabXP3jme8cQFdDO8cgP8JsuYhQg7JtTwezmg==} + engines: {node: '>=0.10.0'} + hasBin: true + requiresBuild: true + dependencies: + async-each: 1.0.3 + bluebird: 3.7.2 + extend-shallow: 2.0.1 + file-contents: 0.3.2 + glob-parent: 2.0.0 + graceful-fs: 4.2.10 + has-glob: 0.1.1 + is-absolute: 0.2.6 + lazy-cache: 2.0.2 + log-ok: 0.1.1 + matched: 0.4.4 + mkdirp: 0.5.6 + resolve-dir: 0.1.1 + to-file: 0.2.0 + dev: true + + /core-js-pure@3.26.0: + resolution: {integrity: sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==} + requiresBuild: true + dev: true + + /core-js@2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + requiresBuild: true + dev: true + + /core-js@3.6.5: + resolution: {integrity: sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + requiresBuild: true + dev: true + + /core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + dev: true + + /cowsay@1.5.0: + resolution: {integrity: sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA==} + engines: {node: '>= 4'} + hasBin: true + requiresBuild: true + dependencies: + get-stdin: 8.0.0 + string-width: 2.1.1 + strip-final-newline: 2.0.0 + yargs: 15.4.1 + dev: true + + /create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.4 + dev: true + + /create-error-class@3.0.2: + resolution: {integrity: sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==} + engines: {node: '>=0.10.0'} + dependencies: + capture-stack-trace: 1.0.2 + dev: true + + /create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + dev: true + + /create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /cron-parser@2.18.0: + resolution: {integrity: sha512-s4odpheTyydAbTBQepsqd2rNWGa2iV3cyo8g7zbI2QQYGLVsfbhmwukayS1XHppe02Oy1fg7mg6xoaraVJeEcg==} + engines: {node: '>=0.8'} + dependencies: + is-nan: 1.3.2 + moment-timezone: 0.5.38 + dev: true + + /cron-parser@4.6.0: + resolution: {integrity: sha512-guZNLMGUgg6z4+eGhmHGw7ft+v6OQeuHzd1gcLxCo9Yg/qoxmG3nindp2/uwGCLizEisf2H0ptqeVXeoCpP6FA==} + engines: {node: '>=12.0.0'} + dependencies: + luxon: 3.0.4 + dev: true + + /cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + dependencies: + node-fetch: 2.6.12 + transitivePeerDependencies: + - encoding + dev: true + + /cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /cross-spawn@6.0.5: + resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} + engines: {node: '>=4.8'} + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.1 + shebang-command: 1.2.0 + which: 1.3.1 + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + dev: true + + /crypto-browserify@3.12.0: + resolution: {integrity: sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==} + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.1 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + inherits: 2.0.4 + pbkdf2: 3.1.2 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + dev: true + + /crypto-js@3.3.0: + resolution: {integrity: sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==} + dev: true + + /crypto-random-string@1.0.0: + resolution: {integrity: sha512-GsVpkFPlycH7/fRR7Dhcmnoii54gV1nz7y4CWyeFS14N+JVBBhY+r8amRHE4BwSYal7BPTDp8isvAlCxyFt3Hg==} + engines: {node: '>=4'} + dev: true + + /crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + requiresBuild: true + dev: true + optional: true + + /cson-parser@1.3.5: + resolution: {integrity: sha512-Pchz4dDkyafUL4V3xBuP9Os8Hu9VU96R+MxuTKh7NR+D866UiWrhBiSLbfuvwApEaJzpXhXTr3iPe4lFtXLzcQ==} + dependencies: + coffee-script: 1.12.7 + dev: true + + /css-selector-parser@1.4.1: + resolution: {integrity: sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==} + dev: true + + /cssfilter@0.0.10: + resolution: {integrity: sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==} + dev: true + + /cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + dev: true + + /cssom@0.4.4: + resolution: {integrity: sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==} + dev: true + + /cssstyle@1.2.1: + resolution: {integrity: sha512-7DYm8qe+gPx/h77QlCyFmX80+fGaE/6A/Ekl0zaszYOubvySO2saYFdQ78P29D0UsULxFKCetDGNaNRUdSF+2A==} + dependencies: + cssom: 0.3.8 + dev: true + + /cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + dependencies: + cssom: 0.3.8 + dev: true + + /csstype@3.1.1: + resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + dev: true + + /cuid@2.1.8: + resolution: {integrity: sha512-xiEMER6E7TlTPnDxrM4eRiC6TRgjNX9xzEZ5U/Se2YJKr7Mq4pJn/2XEHjl3STcSh96GmkHPcBXLES8M29wyyg==} + deprecated: Cuid and other k-sortable and non-cryptographic ids (Ulid, ObjectId, KSUID, all UUIDs) are all insecure. Use @paralleldrive/cuid2 instead. + dev: true + + /current-script-polyfill@1.0.0: + resolution: {integrity: sha512-qv8s+G47V6Hq+g2kRE5th+ASzzrL7b6l+tap1DHKK25ZQJv3yIFhH96XaQ7NGL+zRW3t/RDbweJf/dJDe5Z5KA==} + dev: true + + /d3-array@1.2.4: + resolution: {integrity: sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==} + dev: true + + /d3-geo@1.7.1: + resolution: {integrity: sha512-O4AempWAr+P5qbk2bC2FuN/sDW4z+dN2wDf9QV3bxQt4M5HfOEeXLgJ/UKQW0+o1Dj8BE+L5kiDbdWUMjsmQpw==} + dependencies: + d3-array: 1.2.4 + dev: true + + /d3-voronoi@1.1.2: + resolution: {integrity: sha512-RhGS1u2vavcO7ay7ZNAPo4xeDh/VYeGof3x5ZLJBQgYhLegxr3s5IykvWmJ94FTU6mcbtp4sloqZ54mP6R4Utw==} + dev: true + + /d@0.1.1: + resolution: {integrity: sha512-0SdM9V9pd/OXJHoWmTfNPTAeD+lw6ZqHg+isPyBFuJsZLSE0Ygg1cYZ/0l6DrKQXMOqGOu1oWupMoOfoRfMZrQ==} + dependencies: + es5-ext: 0.10.62 + dev: true + + /d@1.0.1: + resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} + dependencies: + es5-ext: 0.10.62 + type: 1.2.0 + dev: true + + /dash-ast@1.0.0: + resolution: {integrity: sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==} + dev: true + + /dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + dev: true + + /data-urls@2.0.0: + resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} + engines: {node: '>=10'} + dependencies: + abab: 2.0.6 + whatwg-mimetype: 2.3.0 + whatwg-url: 8.7.0 + dev: true + + /dayjs@1.11.6: + resolution: {integrity: sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==} + dev: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug@3.1.0: + resolution: {integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug@4.1.1: + resolution: {integrity: sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==} + deprecated: Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797) + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /debuglog@1.0.1: + resolution: {integrity: sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + dev: true + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: true + + /decimal.js@10.4.2: + resolution: {integrity: sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==} + dev: true + + /decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + dependencies: + character-entities: 2.0.2 + dev: true + + /decode-uri-component@0.2.0: + resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} + engines: {node: '>=0.10'} + dev: true + + /decompress-response@3.3.0: + resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} + engines: {node: '>=4'} + dependencies: + mimic-response: 1.0.1 + dev: true + + /decompress-response@4.2.1: + resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==} + engines: {node: '>=8'} + dependencies: + mimic-response: 2.1.0 + dev: true + + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: true + + /dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + dev: true + + /deep-equal@1.0.1: + resolution: {integrity: sha512-bHtC0iYvWhyaTzvV3CZgPeZQqCOBGyGsVV7v4eevpdkLHfiSrXUdBG+qAuSz4RI70sszvjQ1QSZ98An1yNwpSw==} + dev: true + + /deep-equal@1.1.1: + resolution: {integrity: sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==} + dependencies: + is-arguments: 1.1.1 + is-date-object: 1.0.5 + is-regex: 1.1.4 + object-is: 1.1.5 + object-keys: 1.1.1 + regexp.prototype.flags: 1.4.3 + dev: true + + /deep-equal@2.0.5: + resolution: {integrity: sha512-nPiRgmbAtm1a3JsnLCf6/SLfXcjyN5v8L1TXzdCmHrXJ4hx+gW/w1YCcn7z8gJtSiDArZCgYtbao3QqLm/N1Sw==} + dependencies: + call-bind: 1.0.2 + es-get-iterator: 1.1.2 + get-intrinsic: 1.1.3 + is-arguments: 1.1.1 + is-date-object: 1.0.5 + is-regex: 1.1.4 + isarray: 2.0.5 + object-is: 1.1.5 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.4.3 + side-channel: 1.0.4 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.8 + dev: true + + /deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deepmerge@3.3.0: + resolution: {integrity: sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA==} + engines: {node: '>=0.10.0'} + dev: true + + /deepmerge@4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + dev: true + + /defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + dev: true + + /define-properties@1.1.4: + resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 0.1.6 + dev: true + + /define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 1.0.2 + dev: true + + /define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 1.0.2 + isobject: 3.0.1 + dev: true + + /defined@1.0.1: + resolution: {integrity: sha512-hsBd2qSVCRE+5PmNdHt1uzyrFu5d3RwmFDKzyNZMFq/EwDNJF7Ee5+D5oEKF0hU6LhtoUF1macFvOe4AskQC1Q==} + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + + /delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: true + + /denque@1.5.1: + resolution: {integrity: sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==} + engines: {node: '>=0.10'} + dev: true + + /denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + dev: true + + /density-clustering@1.3.0: + resolution: {integrity: sha512-icpmBubVTwLnsaor9qH/4tG5+7+f61VcqMN3V3pm9sxxSCt2Jcs0zWOgwZW9ARJYaKD3FumIgHiMOcIMRRAzFQ==} + dev: true + + /depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + dev: true + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: true + + /deprecated-decorator@0.1.6: + resolution: {integrity: sha512-MHidOOnCHGlZDKsI21+mbIIhf4Fff+hhCTB7gtVg4uoIqjcrTZc5v6M+GS2zVI0sV7PqK415rb8XaOSQsQkHOw==} + dev: true + + /deps-sort@2.0.1: + resolution: {integrity: sha512-1orqXQr5po+3KI6kQb9A4jnXT1PBwggGl2d7Sq2xsnOeI9GPcE/tGcF9UiSZtZBM7MukY4cAh7MemS6tZYipfw==} + hasBin: true + dependencies: + JSONStream: 1.3.5 + shasum-object: 1.0.0 + subarg: 1.0.0 + through2: 2.0.5 + dev: true + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /des.js@1.0.1: + resolution: {integrity: sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: true + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: true + + /details-element-polyfill@2.4.0: + resolution: {integrity: sha512-jnZ/m0+b1gz3EcooitqL7oDEkKHEro659dt8bWB/T/HjiILucoQhHvvi5MEOAIFJXxxO+rIYJ/t3qCgfUOSU5g==} + dev: true + + /detect-libc@2.0.1: + resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} + engines: {node: '>=8'} + dev: true + + /detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /detective@5.2.1: + resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} + engines: {node: '>=0.8.0'} + hasBin: true + dependencies: + acorn-node: 1.8.2 + defined: 1.0.1 + minimist: 1.2.7 + dev: true + + /dfa@1.2.0: + resolution: {integrity: sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q==} + dev: true + + /dicer@0.3.0: + resolution: {integrity: sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==} + engines: {node: '>=4.5.0'} + dependencies: + streamsearch: 0.1.2 + dev: true + + /dicer@0.3.1: + resolution: {integrity: sha512-ObioMtXnmjYs3aRtpIJt9rgQSPCIhKVkFPip+E9GUDyWl8N435znUxK/JfNwGZJ2wnn5JKQ7Ly3vOK5Q5dylGA==} + engines: {node: '>=10.0.0'} + dependencies: + streamsearch: 1.1.0 + dev: true + + /diff-sequences@27.5.1: + resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dev: true + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /diff@5.1.0: + resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} + engines: {node: '>=0.3.1'} + dev: true + + /diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + dependencies: + bn.js: 4.12.0 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + dev: true + + /doctypes@1.1.0: + resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} + dev: true + + /dom-storage@2.1.0: + resolution: {integrity: sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q==} + dev: true + + /dom-walk@0.1.2: + resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} + dev: true + + /domain-browser@1.2.0: + resolution: {integrity: sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==} + engines: {node: '>=0.4', npm: '>=1.2'} + dev: true + + /domexception@2.0.1: + resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} + engines: {node: '>=8'} + dependencies: + webidl-conversions: 5.0.0 + dev: true + + /dot-case@1.1.2: + resolution: {integrity: sha512-NzEIt12UjECXi6JZ/R/nBey6EE1qCN0yUTEFaPIaKW0AcOEwlKqujtcJVbtSfLNnj3CDoXLQyli79vAaqohyvw==} + dependencies: + sentence-case: 1.1.3 + dev: true + + /dot-prop@4.2.1: + resolution: {integrity: sha512-l0p4+mIuJIua0mhxGoh4a+iNL9bmeK5DvnSVQa6T0OhrVmaEa1XScX5Etc673FePCJOArq/4Pa2cLGODUWTPOQ==} + engines: {node: '>=4'} + dependencies: + is-obj: 1.0.1 + dev: true + + /dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + is-obj: 2.0.0 + dev: true + optional: true + + /dottie@2.0.2: + resolution: {integrity: sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==} + dev: true + + /duplex@1.0.0: + resolution: {integrity: sha512-6Urdl3FU6TU6TAbd9b46YsvYhxqWvuuvlDL1VaP4DJb9E1jbU9Y5E6KUIXt7+0CUgKhPveZ495kqVAzm/uynyg==} + dev: true + + /duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + dependencies: + readable-stream: 2.3.7 + dev: true + + /duplexer3@0.1.5: + resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} + dev: true + + /duplexer@0.0.4: + resolution: {integrity: sha512-nO0WWuIDTde3CWK/8IPpG50dyhUilgpsqzYSIP+w20Yh+4iDgb/2Gs75QItcp0Hmx/JtxtTXBalj+LSTD1VemA==} + dev: true + + /duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 2.3.7 + stream-shift: 1.0.1 + dev: true + + /duplexify@4.1.2: + resolution: {integrity: sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 3.6.0 + stream-shift: 1.0.1 + dev: true + + /earcut@2.2.4: + resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} + dev: true + + /ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: true + + /ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: true + + /ejs@2.7.4: + resolution: {integrity: sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dev: true + + /ejs@3.1.8: + resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.8.5 + dev: true + + /electron-to-chromium@1.4.284: + resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} + dev: true + + /elliptic@6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: true + + /emissary@1.3.3: + resolution: {integrity: sha512-pD6FWNBSlEOzSJDCTcSGVLgNnGw5fnCvvGMdQ/TN43efeXZ/QTq8+hZoK3OOEXPRNjMmSJmeOnEJh+bWT5O8rQ==} + dependencies: + es6-weak-map: 0.1.4 + mixto: 1.0.0 + property-accessors: 1.1.3 + underscore-plus: 1.7.0 + dev: true + + /emittery@0.8.1: + resolution: {integrity: sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==} + engines: {node: '>=10'} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: true + + /encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + requiresBuild: true + dependencies: + iconv-lite: 0.6.3 + dev: true + optional: true + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: true + + /engine.io-client@3.5.3: + resolution: {integrity: sha512-qsgyc/CEhJ6cgMUwxRRtOndGVhIu5hpL5tR4umSpmX/MvkFoIxUTM7oFMDQumHNzlNLwSVy6qhstFPoWTf7dOw==} + dependencies: + component-emitter: 1.3.0 + component-inherit: 0.0.3 + debug: 3.1.0 + engine.io-parser: 2.2.1 + has-cors: 1.1.0 + indexof: 0.0.1 + parseqs: 0.0.6 + parseuri: 0.0.6 + ws: 7.4.6 + xmlhttprequest-ssl: 1.6.3 + yeast: 0.1.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /engine.io-parser@2.2.1: + resolution: {integrity: sha512-x+dN/fBH8Ro8TFwJ+rkB2AmuVw9Yu2mockR/p3W8f8YtExwFgDvBDi0GWyb4ZLkpahtDGZgtr3zLovanJghPqg==} + dependencies: + after: 0.8.2 + arraybuffer.slice: 0.0.7 + base64-arraybuffer: 0.1.4 + blob: 0.0.5 + has-binary2: 1.0.3 + dev: true + + /engine.io@3.6.0: + resolution: {integrity: sha512-Kc8fo5bbg8F4a2f3HPHTEpGyq/IRIQpyeHu3H1ThR14XDD7VrLcsGBo16HUpahgp8YkHJDaU5gNxJZbuGcuueg==} + engines: {node: '>=8.0.0'} + dependencies: + accepts: 1.3.8 + base64id: 2.0.0 + cookie: 0.4.2 + debug: 4.1.1 + engine.io-parser: 2.2.1 + ws: 7.4.6 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /ent@2.2.0: + resolution: {integrity: sha512-GHrMyVZQWvTIdDtpiEXdHZnFQKzeO09apj8Cbl4pKWy4i0Oprcq17usfDt5aO63swf0JOeMWjWQE/LzgSRuWpA==} + dev: true + + /env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + requiresBuild: true + dev: true + optional: true + + /err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + requiresBuild: true + dev: true + optional: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + dependencies: + stackframe: 1.3.4 + dev: true + + /es-abstract@1.20.4: + resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + es-to-primitive: 1.2.1 + function-bind: 1.1.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.1.3 + get-symbol-description: 1.0.0 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-symbols: 1.0.3 + internal-slot: 1.0.3 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-weakref: 1.0.2 + object-inspect: 1.12.2 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.4.3 + safe-regex-test: 1.0.0 + string.prototype.trimend: 1.0.5 + string.prototype.trimstart: 1.0.5 + unbox-primitive: 1.0.2 + dev: true + + /es-array-method-boxes-properly@1.0.0: + resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} + dev: true + + /es-get-iterator@1.1.2: + resolution: {integrity: sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.2 + is-set: 2.0.2 + is-string: 1.0.7 + isarray: 2.0.5 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /es5-ext@0.10.62: + resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} + engines: {node: '>=0.10'} + requiresBuild: true + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.3 + next-tick: 1.1.0 + dev: true + + /es6-iterator@0.1.3: + resolution: {integrity: sha512-6TOmbFM6OPWkTe+bQ3ZuUkvqcWUjAnYjKUCLdbvRsAUz2Pr+fYIibwNXNkLNtIK9PPFbNMZZddaRNkyJhlGJhA==} + dependencies: + d: 0.1.1 + es5-ext: 0.10.62 + es6-symbol: 2.0.1 + dev: true + + /es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-symbol: 3.1.3 + dev: true + + /es6-map@0.1.5: + resolution: {integrity: sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-iterator: 2.0.3 + es6-set: 0.1.6 + es6-symbol: 3.1.3 + event-emitter: 0.3.5 + dev: true + + /es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + dev: true + + /es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + dependencies: + es6-promise: 4.2.8 + dev: true + + /es6-set@0.1.6: + resolution: {integrity: sha512-TE3LgGLDIBX332jq3ypv6bcOpkLO0AslAQo7p2VqX/1N46YNsvIWgvjojjSEnWEGWMhr1qUbYeTSir5J6mFHOw==} + engines: {node: '>=0.12'} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + es6-iterator: 2.0.3 + es6-symbol: 3.1.3 + event-emitter: 0.3.5 + type: 2.7.2 + dev: true + + /es6-symbol@2.0.1: + resolution: {integrity: sha512-wjobO4zO8726HVU7mI2OA/B6QszqwHJuKab7gKHVx+uRfVVYGcWJkCIFxV2Madqb9/RUSrhJ/r6hPfG7FsWtow==} + dependencies: + d: 0.1.1 + es5-ext: 0.10.62 + dev: true + + /es6-symbol@3.1.3: + resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} + dependencies: + d: 1.0.1 + ext: 1.7.0 + dev: true + + /es6-weak-map@0.1.4: + resolution: {integrity: sha512-P+N5Cd2TXeb7G59euFiM7snORspgbInS29Nbf3KNO2JQp/DyhvMCDWd58nsVAXwYJ6W3Bx7qDdy6QQ3PCJ7jKQ==} + dependencies: + d: 0.1.1 + es5-ext: 0.10.62 + es6-iterator: 0.1.3 + es6-symbol: 2.0.1 + dev: true + + /esbuild-android-64@0.15.12: + resolution: {integrity: sha512-MJKXwvPY9g0rGps0+U65HlTsM1wUs9lbjt5CU19RESqycGFDRijMDQsh68MtbzkqWSRdEtiKS1mtPzKneaAI0Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-android-arm64@0.15.12: + resolution: {integrity: sha512-Hc9SEcZbIMhhLcvhr1DH+lrrec9SFTiRzfJ7EGSBZiiw994gfkVV6vG0sLWqQQ6DD7V4+OggB+Hn0IRUdDUqvA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-64@0.15.12: + resolution: {integrity: sha512-qkmqrTVYPFiePt5qFjP8w/S+GIUMbt6k8qmiPraECUWfPptaPJUGkCKrWEfYFRWB7bY23FV95rhvPyh/KARP8Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-arm64@0.15.12: + resolution: {integrity: sha512-z4zPX02tQ41kcXMyN3c/GfZpIjKoI/BzHrdKUwhC/Ki5BAhWv59A9M8H+iqaRbwpzYrYidTybBwiZAIWCLJAkw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-64@0.15.12: + resolution: {integrity: sha512-XFL7gKMCKXLDiAiBjhLG0XECliXaRLTZh6hsyzqUqPUf/PY4C6EJDTKIeqqPKXaVJ8+fzNek88285krSz1QECw==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-arm64@0.15.12: + resolution: {integrity: sha512-jwEIu5UCUk6TjiG1X+KQnCGISI+ILnXzIzt9yDVrhjug2fkYzlLbl0K43q96Q3KB66v6N1UFF0r5Ks4Xo7i72g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-32@0.15.12: + resolution: {integrity: sha512-uSQuSEyF1kVzGzuIr4XM+v7TPKxHjBnLcwv2yPyCz8riV8VUCnO/C4BF3w5dHiVpCd5Z1cebBtZJNlC4anWpwA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-64@0.15.12: + resolution: {integrity: sha512-QcgCKb7zfJxqT9o5z9ZUeGH1k8N6iX1Y7VNsEi5F9+HzN1OIx7ESxtQXDN9jbeUSPiRH1n9cw6gFT3H4qbdvcA==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm64@0.15.12: + resolution: {integrity: sha512-HtNq5xm8fUpZKwWKS2/YGwSfTF+339L4aIA8yphNKYJckd5hVdhfdl6GM2P3HwLSCORS++++7++//ApEwXEuAQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm@0.15.12: + resolution: {integrity: sha512-Wf7T0aNylGcLu7hBnzMvsTfEXdEdJY/hY3u36Vla21aY66xR0MS5I1Hw8nVquXjTN0A6fk/vnr32tkC/C2lb0A==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-mips64le@0.15.12: + resolution: {integrity: sha512-Qol3+AvivngUZkTVFgLpb0H6DT+N5/zM3V1YgTkryPYFeUvuT5JFNDR3ZiS6LxhyF8EE+fiNtzwlPqMDqVcc6A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-ppc64le@0.15.12: + resolution: {integrity: sha512-4D8qUCo+CFKaR0cGXtGyVsOI7w7k93Qxb3KFXWr75An0DHamYzq8lt7TNZKoOq/Gh8c40/aKaxvcZnTgQ0TJNg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-riscv64@0.15.12: + resolution: {integrity: sha512-G9w6NcuuCI6TUUxe6ka0enjZHDnSVK8bO+1qDhMOCtl7Tr78CcZilJj8SGLN00zO5iIlwNRZKHjdMpfFgNn1VA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-s390x@0.15.12: + resolution: {integrity: sha512-Lt6BDnuXbXeqSlVuuUM5z18GkJAZf3ERskGZbAWjrQoi9xbEIsj/hEzVnSAFLtkfLuy2DE4RwTcX02tZFunXww==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-netbsd-64@0.15.12: + resolution: {integrity: sha512-jlUxCiHO1dsqoURZDQts+HK100o0hXfi4t54MNRMCAqKGAV33JCVvMplLAa2FwviSojT/5ZG5HUfG3gstwAG8w==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-openbsd-64@0.15.12: + resolution: {integrity: sha512-1o1uAfRTMIWNOmpf8v7iudND0L6zRBYSH45sofCZywrcf7NcZA+c7aFsS1YryU+yN7aRppTqdUK1PgbZVaB1Dw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-sunos-64@0.15.12: + resolution: {integrity: sha512-nkl251DpoWoBO9Eq9aFdoIt2yYmp4I3kvQjba3jFKlMXuqQ9A4q+JaqdkCouG3DHgAGnzshzaGu6xofGcXyPXg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-32@0.15.12: + resolution: {integrity: sha512-WlGeBZHgPC00O08luIp5B2SP4cNCp/PcS+3Pcg31kdcJPopHxLkdCXtadLU9J82LCfw4TVls21A6lilQ9mzHrw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-64@0.15.12: + resolution: {integrity: sha512-VActO3WnWZSN//xjSfbiGOSyC+wkZtI8I4KlgrTo5oHJM6z3MZZBCuFaZHd8hzf/W9KPhF0lY8OqlmWC9HO5AA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-arm64@0.15.12: + resolution: {integrity: sha512-Of3MIacva1OK/m4zCNIvBfz8VVROBmQT+gRX6pFTLPngFYcj6TFH/12VveAqq1k9VB2l28EoVMNMUCcmsfwyuA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild@0.15.12: + resolution: {integrity: sha512-PcT+/wyDqJQsRVhaE9uX/Oq4XLrFh0ce/bs2TJh4CSaw9xuvI+xFrH2nAYOADbhQjUgAhNWC5LKoUsakm4dxng==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.15.12 + '@esbuild/linux-loong64': 0.15.12 + esbuild-android-64: 0.15.12 + esbuild-android-arm64: 0.15.12 + esbuild-darwin-64: 0.15.12 + esbuild-darwin-arm64: 0.15.12 + esbuild-freebsd-64: 0.15.12 + esbuild-freebsd-arm64: 0.15.12 + esbuild-linux-32: 0.15.12 + esbuild-linux-64: 0.15.12 + esbuild-linux-arm: 0.15.12 + esbuild-linux-arm64: 0.15.12 + esbuild-linux-mips64le: 0.15.12 + esbuild-linux-ppc64le: 0.15.12 + esbuild-linux-riscv64: 0.15.12 + esbuild-linux-s390x: 0.15.12 + esbuild-netbsd-64: 0.15.12 + esbuild-openbsd-64: 0.15.12 + esbuild-sunos-64: 0.15.12 + esbuild-windows-32: 0.15.12 + esbuild-windows-64: 0.15.12 + esbuild-windows-arm64: 0.15.12 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + dev: true + + /escodegen@1.14.3: + resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} + engines: {node: '>=4.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /escodegen@1.9.1: + resolution: {integrity: sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==} + engines: {node: '>=4.0'} + hasBin: true + dependencies: + esprima: 3.1.3 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /escodegen@2.0.0: + resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /esm@3.2.25: + resolution: {integrity: sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==} + engines: {node: '>=6'} + requiresBuild: true + dev: true + + /esprima@3.1.3: + resolution: {integrity: sha512-AWwVMNxwhN8+NIPQzAQZCm7RkLC4RbM3B1OobMuyp3i+w73X57KCKaVIxaRZb+DYCojq7rspo+fmuQfAboyhFg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-util-attach-comments@2.1.0: + resolution: {integrity: sha512-rJz6I4L0GaXYtHpoMScgDIwM0/Vwbu5shbMeER596rB2D1EWF6+Gj0e0UKzJPZrpoOc87+Q2kgVFHfjAymIqmw==} + dependencies: + '@types/estree': 1.0.0 + dev: true + + /estree-util-build-jsx@2.2.2: + resolution: {integrity: sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==} + dependencies: + '@types/estree-jsx': 1.0.0 + estree-util-is-identifier-name: 2.0.1 + estree-walker: 3.0.2 + dev: true + + /estree-util-is-identifier-name@2.0.1: + resolution: {integrity: sha512-rxZj1GkQhY4x1j/CSnybK9cGuMFQYFPLq0iNyopqf14aOVLFtMv7Esika+ObJWPWiOHuMOAHz3YkWoLYYRnzWQ==} + dev: true + + /estree-util-to-js@1.1.0: + resolution: {integrity: sha512-490lbfCcpLk+ofK6HCgqDfYs4KAfq6QVvDw3+Bm1YoKRgiOjKiKYGAVQE1uwh7zVxBgWhqp4FDtp5SqunpUk1A==} + dependencies: + '@types/estree-jsx': 1.0.0 + astring: 1.8.4 + source-map: 0.7.4 + dev: true + + /estree-util-visit@1.2.0: + resolution: {integrity: sha512-wdsoqhWueuJKsh5hqLw3j8lwFqNStm92VcwtAOAny8g/KS/l5Y8RISjR4k5W6skCj3Nirag/WUCMS0Nfy3sgsg==} + dependencies: + '@types/estree-jsx': 1.0.0 + '@types/unist': 2.0.6 + dev: true + + /estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /estree-walker@3.0.2: + resolution: {integrity: sha512-C03BvXCQIH/po+PNPONx/zSM9ziPr9weX8xNhYb/IJtdJ9z+L4z9VKPTB+UTHdmhnIopA2kc419ueyVyHVktwA==} + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: true + + /event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + dependencies: + d: 1.0.1 + es5-ext: 0.10.62 + dev: true + + /event-kit@2.5.3: + resolution: {integrity: sha512-b7Qi1JNzY4BfAYfnIRanLk0DOD1gdkWHT4GISIn8Q2tAf3LpU8SP2CMwWaq40imYoKWbtN4ZhbSRxvsnikooZQ==} + dev: true + + /event-source-polyfill@1.0.31: + resolution: {integrity: sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==} + dev: true + + /event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: true + + /eventemitter-asyncresource@1.0.0: + resolution: {integrity: sha512-39F7TBIV0G7gTelxwbEqnwhp90eqCPON1k0NwNfwhgKn4Co4ybUbj2pECcXT0B3ztRKZ7Pw1JujUUgmQJHcVAQ==} + dev: true + + /eventemitter2@5.0.1: + resolution: {integrity: sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==} + dev: true + + /eventemitter3@3.1.2: + resolution: {integrity: sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==} + dev: true + + /events@1.1.1: + resolution: {integrity: sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==} + engines: {node: '>=0.4.x'} + dev: true + + /events@2.1.0: + resolution: {integrity: sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==} + engines: {node: '>=0.4.x'} + dev: true + + /evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + dev: true + + /execa@0.7.0: + resolution: {integrity: sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==} + engines: {node: '>=4'} + dependencies: + cross-spawn: 5.1.0 + get-stream: 3.0.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + dev: true + + /execa@1.0.0: + resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} + engines: {node: '>=6'} + dependencies: + cross-spawn: 6.0.5 + get-stream: 4.1.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + dev: true + + /execa@4.1.0: + resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /exif-parser@0.1.12: + resolution: {integrity: sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw==} + dev: true + + /exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + dev: true + + /expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + dev: true + + /expand-tilde@1.2.2: + resolution: {integrity: sha512-rtmc+cjLZqnu9dSYosX9EWmSJhTwpACgJQTfj4hgg2JjOD/6SIQalZrt4a3aQeh++oNxkazcaxrhPUj6+g5G/Q==} + engines: {node: '>=0.10.0'} + dependencies: + os-homedir: 1.0.2 + dev: true + + /expect@27.5.1: + resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + jest-get-type: 27.5.1 + jest-matcher-utils: 27.5.1 + jest-message-util: 27.5.1 + dev: true + + /express-unless@2.1.2: + resolution: {integrity: sha512-6ZK8+2mCUQwPFZCslGL0F55n6iiVgGw3nBuGT9wnSno7eD2w7KbDo2M7exFGgJZ/DL81xXEbEWy1gqRZRWhUBg==} + dev: true + + /express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.4 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + dependencies: + type: 2.7.2 + dev: true + + /extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + dependencies: + is-extendable: 0.1.1 + dev: true + + /extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + dev: true + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + + /external-editor@2.2.0: + resolution: {integrity: sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==} + engines: {node: '>=0.12'} + dependencies: + chardet: 0.4.2 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + + /extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /extract-zip@1.7.0: + resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} + hasBin: true + dependencies: + concat-stream: 1.6.2 + debug: 2.6.9 + mkdirp: 0.5.6 + yauzl: 2.10.0 + transitivePeerDependencies: + - supports-color + dev: true + + /extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + dev: true + + /eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + dev: true + + /falafel@2.2.5: + resolution: {integrity: sha512-HuC1qF9iTnHDnML9YZAdCDQwT0yKl/U55K4XSUXqGAA2GLoafFgWRqdAbhWJxXaYD4pyoVxAJ8wH670jMpI9DQ==} + engines: {node: '>=0.4.0'} + dependencies: + acorn: 7.4.1 + isarray: 2.0.5 + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob@3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + dev: true + + /fast-text-encoding@1.0.6: + resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} + dev: true + + /fast-url-parser@1.1.3: + resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==} + dependencies: + punycode: 1.4.1 + dev: true + + /fastq@1.13.0: + resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} + dependencies: + reusify: 1.0.4 + dev: true + + /faye-websocket@0.11.3: + resolution: {integrity: sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==} + engines: {node: '>=0.8.0'} + dependencies: + websocket-driver: 0.7.4 + dev: true + + /faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + dependencies: + websocket-driver: 0.7.4 + dev: true + + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + dev: true + + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + dev: true + + /fetch-h2@2.5.1: + resolution: {integrity: sha512-U+LQ+fHwF6TMg82A88wjljC5L174eoJfrc+0g4e7JWqL7U0w0QAoOkPDCGkO9KGH9BY55s4n45gLGOtlTAoqmw==} + engines: {node: '>=10.4'} + requiresBuild: true + dependencies: + '@types/tough-cookie': 4.0.2 + already: 1.13.2 + callguard: 2.0.0 + get-stream: 6.0.1 + through2: 4.0.2 + to-arraybuffer: 1.0.1 + tough-cookie: 4.1.2 + dev: true + + /figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /file-contents@0.2.4: + resolution: {integrity: sha512-PEz7U6YlXr+dvWCtW63DUY1LUTHOVs1rv4s1/I/39dpvvidQqMSTY6JklazQS60MMoI/ztpo5kMlpdvGagvLbA==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + file-stat: 0.1.3 + graceful-fs: 4.2.10 + is-buffer: 1.1.6 + is-utf8: 0.2.1 + lazy-cache: 0.2.7 + through2: 2.0.5 + dev: true + + /file-contents@0.3.2: + resolution: {integrity: sha512-7xaJjA+9eTve2l1FzoagBX26tICgaTwLPAY9vi/FDutEUKNeBR4YYvvQ8bgxuYJb09edaAQoEGIa6Juim88dpQ==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 0.2.5 + extend-shallow: 2.0.1 + file-stat: 0.2.3 + fs-exists-sync: 0.1.0 + graceful-fs: 4.2.10 + is-buffer: 1.1.6 + isobject: 2.1.0 + lazy-cache: 2.0.2 + strip-bom-buffer: 0.1.1 + strip-bom-string: 0.1.2 + through2: 2.0.5 + vinyl: 1.2.0 + dev: true + + /file-source@0.6.1: + resolution: {integrity: sha512-1R1KneL7eTXmXfKxC10V/9NeGOdbsAXJ+lQ//fvvcHUgtaZcZDWNJNblxAoVOyV1cj45pOtUrR3vZTBwqcW8XA==} + dependencies: + stream-source: 0.3.5 + dev: true + + /file-stat@0.1.3: + resolution: {integrity: sha512-f72m4132aOd5DVtREdDX8I0Dd7Zf/3PiUYYvn4BFCxfsLqj6r8joBZzrRlfvsNvxhADw+jpEa0AnWPII9H0Fbg==} + engines: {node: '>=0.10.0'} + dependencies: + graceful-fs: 4.2.10 + lazy-cache: 0.2.7 + through2: 2.0.5 + dev: true + + /file-stat@0.2.3: + resolution: {integrity: sha512-wjHoKZzas90Jl1XOBfLnNGc5gl9JTm7sTceuoO4P3OdadlCz1ELrOxYmiamqLJP4S8+phD7wzW8S1oBj+8vnBQ==} + engines: {node: '>=0.10.0'} + dependencies: + fs-exists-sync: 0.1.0 + graceful-fs: 4.2.10 + lazy-cache: 2.0.2 + through2: 2.0.5 + dev: true + + /file-type@9.0.0: + resolution: {integrity: sha512-Qe/5NJrgIOlwijpq3B7BEpzPFcgzggOTagZmkXQY4LA6bsXKTUstK7Wp12lEJ/mLKTpvIZxmIuRcLYWT6ov9lw==} + engines: {node: '>=6'} + dev: true + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: true + + /filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + dependencies: + minimatch: 5.1.0 + dev: true + + /fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /firebase-admin@9.12.0(@firebase/app-compat@0.2.15)(@firebase/app-types@0.9.0): + resolution: {integrity: sha512-AtA7OH5RbIFGoc0gZOQgaYC6cdjdhZv4w3XgWoupkPKO1HY+0GzixOuXDa75kFeoVyhIyo4PkLg/GAC1dC1P6w==} + engines: {node: '>=10.13.0'} + dependencies: + '@firebase/database-compat': 0.1.8(@firebase/app-compat@0.2.15)(@firebase/app-types@0.9.0) + '@firebase/database-types': 0.7.3 + '@types/node': 14.18.29 + dicer: 0.3.1 + jsonwebtoken: 8.5.1 + jwks-rsa: 2.1.5 + node-forge: 0.10.0 + optionalDependencies: + '@google-cloud/firestore': 4.15.1 + '@google-cloud/storage': 5.20.5 + transitivePeerDependencies: + - '@firebase/app-compat' + - '@firebase/app-types' + - encoding + - supports-color + dev: true + + /firebase@7.24.0: + resolution: {integrity: sha512-j6jIyGFFBlwWAmrlUg9HyQ/x+YpsPkc/TTkbTyeLwwAJrpAmmEHNPT6O9xtAnMV4g7d3RqLL/u9//aZlbY4rQA==} + engines: {node: ^8.13.0 || >=10.10.0} + requiresBuild: true + dependencies: + '@firebase/analytics': 0.6.0(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/app': 0.6.11 + '@firebase/app-types': 0.6.1 + '@firebase/auth': 0.15.0(@firebase/app-types@0.6.1)(@firebase/app@0.6.11)(@firebase/util@0.3.2) + '@firebase/database': 0.6.13(@firebase/app-types@0.6.1) + '@firebase/firestore': 1.18.0(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/functions': 0.5.1(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/installations': 0.4.17(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/messaging': 0.7.1(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/performance': 0.4.2(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/polyfill': 0.3.36 + '@firebase/remote-config': 0.1.28(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/storage': 0.3.43(@firebase/app-types@0.6.1)(@firebase/app@0.6.11) + '@firebase/util': 0.3.2 + dev: true + + /first-mate-select-grammar@1.0.3: + resolution: {integrity: sha512-OTGt//jDdzPAzny8hpxhg6SHpkeFhOAj26egYqusY78twKk9vpyMBqIVtm6TE2Q7ccM0p21gnNFadIUbyDFmJQ==} + dependencies: + lodash: 4.17.21 + dev: true + + /first-mate@7.4.3: + resolution: {integrity: sha512-PtZUpaPmcV5KV4Rw5TfwczEnExN+X1o3Q/G82E4iRJ0tW91fm3Yi7pa5t4cBH8r3D6EyoBKvfpG2jKE+TZ0/nw==} + dependencies: + emissary: 1.3.3 + event-kit: 2.5.3 + fs-plus: 3.1.1 + grim: 2.0.3 + oniguruma: 7.2.3 + season: 6.0.2 + underscore-plus: 1.7.0 + dev: true + + /fluent-ffmpeg@2.1.2: + resolution: {integrity: sha512-IZTB4kq5GK0DPp7sGQ0q/BWurGHffRtQQwVkiqDgeO6wYJLLV5ZhgNOQ65loZxxuPMKZKZcICCUnaGtlxBiR0Q==} + engines: {node: '>=0.8.0'} + requiresBuild: true + dependencies: + async: 3.2.4 + which: 1.3.1 + dev: true + + /follow-redirects@1.15.2(debug@4.3.4): + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dependencies: + debug: 4.3.4 + dev: true + + /fontkit@1.9.0: + resolution: {integrity: sha512-HkW/8Lrk8jl18kzQHvAw9aTHe1cqsyx5sDnxncx652+CIfhawokEPkeM3BoIC+z/Xv7a0yMr0f3pRRwhGH455g==} + dependencies: + '@swc/helpers': 0.3.17 + brotli: 1.3.3 + clone: 2.1.2 + deep-equal: 2.0.5 + dfa: 1.2.0 + restructure: 2.0.1 + tiny-inflate: 1.0.3 + unicode-properties: 1.4.1 + unicode-trie: 2.0.0 + dev: true + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + dev: true + + /forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + dev: true + + /form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /form-data@2.5.1: + resolution: {integrity: sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /form-data@3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /formidable@1.2.6: + resolution: {integrity: sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==} + deprecated: 'Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau' + dev: true + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: true + + /fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + dependencies: + map-cache: 0.2.2 + dev: true + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: true + + /from2-string@1.1.0: + resolution: {integrity: sha512-m8vCh+KnXXXBtfF2VUbiYlQ+nczLcntB0BrtNgpmLkHylhObe9WF1b2LZjBBzrZzA6P4mkEla6ZYQoOUTG8cYA==} + dependencies: + from2: 2.3.0 + dev: true + + /from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.7 + dev: true + + /fs-capacitor@2.0.4: + resolution: {integrity: sha512-8S4f4WsCryNw2mJJchi46YgB6CR5Ze+4L1h8ewl9tEpL4SJ3ZO+c/bS4BWhB8bK+O3TMqhuZarTitd0S0eh2pA==} + engines: {node: '>=8.5'} + dev: true + + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: true + + /fs-exists-sync@0.1.0: + resolution: {integrity: sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==} + engines: {node: '>=0.10.0'} + dev: true + + /fs-extra@1.0.0: + resolution: {integrity: sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==} + dependencies: + graceful-fs: 4.2.10 + jsonfile: 2.4.0 + klaw: 1.3.1 + dev: true + + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.10 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + dev: true + + /fs-plus@3.1.1: + resolution: {integrity: sha512-Se2PJdOWXqos1qVTkvqqjb0CSnfBnwwD+pq+z4ksT+e97mEShod/hrNg0TRCCsXPbJzcIq+NuzQhigunMWMJUA==} + dependencies: + async: 1.5.2 + mkdirp: 0.5.6 + rimraf: 2.7.1 + underscore-plus: 1.7.0 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: The v1 package contains DANGEROUS / INSECURE binaries. Upgrade to safe fsevents v2 + requiresBuild: true + dependencies: + bindings: 1.5.0 + nan: 2.17.0 + dev: true + optional: true + + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name@1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + functions-have-names: 1.2.3 + dev: true + + /functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: true + + /gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + requiresBuild: true + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: true + optional: true + + /gaxios@2.3.4: + resolution: {integrity: sha512-US8UMj8C5pRnao3Zykc4AAVr+cffoNKRTg9Rsf2GiuZCW69vgJj38VK2PzlPuQU73FZ/nTk9/Av6/JGcE1N9vA==} + engines: {node: '>=8.10.0'} + dependencies: + abort-controller: 3.0.0 + extend: 3.0.2 + https-proxy-agent: 5.0.1 + is-stream: 2.0.1 + node-fetch: 2.6.12 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /gaxios@4.3.3: + resolution: {integrity: sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + abort-controller: 3.0.0 + extend: 3.0.2 + https-proxy-agent: 5.0.1 + is-stream: 2.0.1 + node-fetch: 2.6.12 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /gcp-metadata@3.5.0: + resolution: {integrity: sha512-ZQf+DLZ5aKcRpLzYUyBS3yo3N0JSa82lNDO8rj3nMSlovLcz2riKFBsYgDzeXcv75oo5eqB2lx+B14UvPoCRnA==} + engines: {node: '>=8.10.0'} + dependencies: + gaxios: 2.3.4 + json-bigint: 0.3.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /gcp-metadata@4.3.1: + resolution: {integrity: sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + gaxios: 4.3.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /geo-tz@7.0.3: + resolution: {integrity: sha512-Hy+OCidh+HQKvJBtb9B1eQ2CVYA5V9pQt2rdaM1zGIu7jwcHuQoa+HsZK+G4w4U5xRWQLI4iekOHuuSe+jVvVA==} + engines: {node: '>=12'} + requiresBuild: true + dependencies: + '@turf/boolean-point-in-polygon': 6.5.0 + '@turf/helpers': 6.5.0 + geobuf: 3.0.2 + pbf: 3.2.1 + dev: true + + /geobuf@3.0.2: + resolution: {integrity: sha512-ASgKwEAQQRnyNFHNvpd5uAwstbVYmiTW0Caw3fBb509tNTqXyAAPMyFs5NNihsLZhLxU1j/kjFhkhLWA9djuVg==} + hasBin: true + dependencies: + concat-stream: 2.0.0 + pbf: 3.2.1 + shapefile: 0.6.6 + dev: true + + /geojson-equality@0.1.6: + resolution: {integrity: sha512-TqG8YbqizP3EfwP5Uw4aLu6pKkg6JQK9uq/XZ1lXQntvTHD1BBKJWhNpJ2M0ax6TuWMP3oyx6Oq7FCIfznrgpQ==} + dependencies: + deep-equal: 1.1.1 + dev: true + + /geojson-rbush@2.1.0: + resolution: {integrity: sha512-9HvLGhmAJBYkYYDdPlCrlfkKGwNW3PapiS0xPekdJLobkZE4rjtduKJXsO7+kUr97SsUlz4VtMcPuSIbjjJaQg==} + dependencies: + '@turf/helpers': 6.5.0 + '@turf/meta': 6.5.0 + rbush: 3.0.1 + dev: true + + /get-assigned-identifiers@1.2.0: + resolution: {integrity: sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==} + dev: true + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: true + + /get-closest@0.0.4: + resolution: {integrity: sha512-oMgZYUtnPMZB6XieXiUADpRIc5kfD+RPfpiYe9aIlEYGIcOx2mTGgKmUkctlLof/ANleypqOJRhQypbrh33DkA==} + dev: true + + /get-intrinsic@1.1.3: + resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-symbols: 1.0.3 + dev: true + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} + dev: true + + /get-port@6.1.2: + resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + + /get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + dev: true + + /get-stream@3.0.0: + resolution: {integrity: sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==} + engines: {node: '>=4'} + dev: true + + /get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + dependencies: + pump: 3.0.0 + dev: true + + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + dev: true + + /get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + dev: true + + /getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + dependencies: + assert-plus: 1.0.0 + dev: true + + /github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + dev: true + + /glob-parent@2.0.0: + resolution: {integrity: sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==} + dependencies: + is-glob: 2.0.1 + dev: true + + /glob-parent@3.1.0: + resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} + dependencies: + is-glob: 3.1.0 + path-dirname: 1.0.2 + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-stream@6.1.0: + resolution: {integrity: sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==} + engines: {node: '>= 0.10'} + dependencies: + extend: 3.0.2 + glob: 7.2.3 + glob-parent: 3.1.0 + is-negated-glob: 1.0.0 + ordered-read-streams: 1.0.1 + pumpify: 1.5.1 + readable-stream: 2.3.7 + remove-trailing-separator: 1.1.0 + to-absolute-glob: 2.0.2 + unique-stream: 2.3.1 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob@8.0.3: + resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.0 + once: 1.4.0 + dev: true + + /global-dirs@0.1.1: + resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} + engines: {node: '>=4'} + dependencies: + ini: 1.3.8 + dev: true + + /global-modules@0.2.3: + resolution: {integrity: sha512-JeXuCbvYzYXcwE6acL9V2bAOeSIGl4dD+iwLY9iUx2VBJJ80R18HCn+JCwHM9Oegdfya3lEkGCdaRkSyc10hDA==} + engines: {node: '>=0.10.0'} + dependencies: + global-prefix: 0.1.5 + is-windows: 0.2.0 + dev: true + + /global-prefix@0.1.5: + resolution: {integrity: sha512-gOPiyxcD9dJGCEArAhF4Hd0BAqvAe/JzERP7tYumE4yIkmIedPUVXcJFWbV3/p/ovIIvKjkrTk+f1UVkq7vvbw==} + engines: {node: '>=0.10.0'} + dependencies: + homedir-polyfill: 1.0.3 + ini: 1.3.8 + is-windows: 0.2.0 + which: 1.3.1 + dev: true + + /global@4.4.0: + resolution: {integrity: sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==} + dependencies: + min-document: 2.19.0 + process: 0.11.10 + dev: true + + /globalize@1.7.0: + resolution: {integrity: sha512-faR46vTIbFCeAemyuc9E6/d7Wrx9k2ae2L60UhakztFg6VuE42gENVJNuPFtt7Sdjrk9m2w8+py7Jj+JTNy59w==} + dependencies: + cldrjs: 0.5.5 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /google-auth-library@5.10.1: + resolution: {integrity: sha512-rOlaok5vlpV9rSiUu5EpR0vVpc+PhN62oF4RyX/6++DG1VsaulAFEMlDYBLjJDDPI6OcNOCGAKy9UVB/3NIDXg==} + engines: {node: '>=8.10.0'} + dependencies: + arrify: 2.0.1 + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + fast-text-encoding: 1.0.6 + gaxios: 2.3.4 + gcp-metadata: 3.5.0 + gtoken: 4.1.4 + jws: 4.0.0 + lru-cache: 5.1.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /google-auth-library@7.14.1: + resolution: {integrity: sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==} + engines: {node: '>=10'} + dependencies: + arrify: 2.0.1 + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + fast-text-encoding: 1.0.6 + gaxios: 4.3.3 + gcp-metadata: 4.3.1 + gtoken: 5.3.2 + jws: 4.0.0 + lru-cache: 6.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /google-gax@2.30.5: + resolution: {integrity: sha512-Jey13YrAN2hfpozHzbtrwEfEHdStJh1GwaQ2+Akh1k0Tv/EuNVSuBtHZoKSBm5wBMvNsxTsEIZ/152NrYyZgxQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@grpc/grpc-js': 1.6.12 + '@grpc/proto-loader': 0.6.13 + '@types/long': 4.0.2 + abort-controller: 3.0.0 + duplexify: 4.1.2 + fast-text-encoding: 1.0.6 + google-auth-library: 7.14.1 + is-stream-ended: 0.1.4 + node-fetch: 2.6.12 + object-hash: 3.0.0 + proto3-json-serializer: 0.1.9 + protobufjs: 6.11.3 + retry-request: 4.2.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /google-p12-pem@2.0.5: + resolution: {integrity: sha512-7RLkxwSsMsYh9wQ5Vb2zRtkAHvqPvfoMGag+nugl1noYO7gf0844Yr9TIFA5NEBMAeVt2Z+Imu7CQMp3oNatzQ==} + engines: {node: '>=8.10.0'} + hasBin: true + dependencies: + node-forge: 0.10.0 + dev: true + + /google-p12-pem@3.1.4: + resolution: {integrity: sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==} + engines: {node: '>=10'} + hasBin: true + requiresBuild: true + dependencies: + node-forge: 1.3.1 + dev: true + + /got@11.8.5: + resolution: {integrity: sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==} + engines: {node: '>=10.19.0'} + requiresBuild: true + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.2 + '@types/responselike': 1.0.0 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.2 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + dev: true + + /got@6.7.1: + resolution: {integrity: sha512-Y/K3EDuiQN9rTZhBvPRWMLXIKdeD1Rj0nzunfoi0Yyn5WBEbzxXKU9Ub2X41oZBagVWOBU3MuDonFMgPWQFnwg==} + engines: {node: '>=4'} + dependencies: + '@types/keyv': 3.1.4 + '@types/responselike': 1.0.0 + create-error-class: 3.0.2 + duplexer3: 0.1.5 + get-stream: 3.0.0 + is-redirect: 1.0.0 + is-retry-allowed: 1.2.0 + is-stream: 1.1.0 + lowercase-keys: 1.0.1 + safe-buffer: 5.2.1 + timed-out: 4.0.1 + unzip-response: 2.0.1 + url-parse-lax: 1.0.0 + dev: true + + /got@8.3.2: + resolution: {integrity: sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==} + engines: {node: '>=4'} + dependencies: + '@sindresorhus/is': 0.7.0 + '@types/keyv': 3.1.4 + '@types/responselike': 1.0.0 + cacheable-request: 2.1.4 + decompress-response: 3.3.0 + duplexer3: 0.1.5 + get-stream: 3.0.0 + into-stream: 3.1.0 + is-retry-allowed: 1.2.0 + isurl: 1.0.0 + lowercase-keys: 1.0.1 + mimic-response: 1.0.1 + p-cancelable: 0.4.1 + p-timeout: 2.0.1 + pify: 3.0.0 + safe-buffer: 5.2.1 + timed-out: 4.0.1 + url-parse-lax: 3.0.0 + url-to-options: 1.0.1 + dev: true + + /graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /graphql-extensions@0.16.0(graphql@14.7.0): + resolution: {integrity: sha512-rZQc/USoEIw437BGRUwoHoLPR1LA791Ltj6axONqgKIyyx2sqIO3YT9kTbB/eIUdJBrCozp4KuUeZ09xKeQDxg==} + engines: {node: '>=6.0'} + deprecated: 'The `graphql-extensions` API has been removed from Apollo Server 3. Use the plugin API instead: https://www.apollographql.com/docs/apollo-server/integrations/plugins/' + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + '@apollographql/apollo-tools': 0.5.4(graphql@14.7.0) + apollo-server-env: 3.2.0 + apollo-server-types: 0.10.0(graphql@14.7.0) + graphql: 14.7.0 + transitivePeerDependencies: + - encoding + dev: true + + /graphql-subscriptions@1.2.1(graphql@14.7.0): + resolution: {integrity: sha512-95yD/tKi24q8xYa7Q9rhQN16AYj5wPbrb8tmHGM3WRc9EBmWrG/0kkMl+tQG8wcEuE9ibR4zyOM31p5Sdr2v4g==} + peerDependencies: + graphql: ^0.10.5 || ^0.11.3 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + graphql: 14.7.0 + iterall: 1.3.0 + dev: true + + /graphql-tag@2.12.6(graphql@14.7.0): + resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} + engines: {node: '>=10'} + peerDependencies: + graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + dependencies: + graphql: 14.7.0 + tslib: 2.4.0 + dev: true + + /graphql-tools@4.0.8(graphql@14.7.0): + resolution: {integrity: sha512-MW+ioleBrwhRjalKjYaLQbr+920pHBgy9vM/n47sswtns8+96sRn5M/G+J1eu7IMeKWiN/9p6tmwCHU7552VJg==} + deprecated: |- + This package has been deprecated and now it only exports makeExecutableSchema. + And it will no longer receive updates. + We recommend you to migrate to scoped packages such as @graphql-tools/schema, @graphql-tools/utils and etc. + Check out https://www.graphql-tools.com to learn what package you should use instead + peerDependencies: + graphql: ^0.13.0 || ^14.0.0 || ^15.0.0 + dependencies: + apollo-link: 1.2.14(graphql@14.7.0) + apollo-utilities: 1.3.4(graphql@14.7.0) + deprecated-decorator: 0.1.6 + graphql: 14.7.0 + iterall: 1.3.0 + uuid: 3.4.0 + dev: true + + /graphql@14.7.0: + resolution: {integrity: sha512-l0xWZpoPKpppFzMfvVyFmp9vLN7w/ZZJPefUicMCepfJeQ8sMcztloGYY9DfjVPo6tIUDzU5Hw3MUbIjj9AVVA==} + engines: {node: '>= 6.x'} + requiresBuild: true + dependencies: + iterall: 1.3.0 + dev: true + + /grim@2.0.3: + resolution: {integrity: sha512-FM20Ump11qYLK9k9DbL8yzVpy+YBieya1JG15OeH8s+KbHq8kL4SdwRtURwIUHniSxb24EoBUpwKfFjGNVi4/Q==} + dependencies: + event-kit: 2.5.3 + dev: true + + /gtoken@4.1.4: + resolution: {integrity: sha512-VxirzD0SWoFUo5p8RDP8Jt2AGyOmyYcT/pOUgDKJCK+iSw0TMqwrVfY37RXTNmoKwrzmDHSk0GMT9FsgVmnVSA==} + engines: {node: '>=8.10.0'} + dependencies: + gaxios: 2.3.4 + google-p12-pem: 2.0.5 + jws: 4.0.0 + mime: 2.6.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /gtoken@5.3.2: + resolution: {integrity: sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + gaxios: 4.3.3 + google-p12-pem: 3.1.4 + jws: 4.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + dev: true + + /har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-binary2@1.0.3: + resolution: {integrity: sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==} + dependencies: + isarray: 2.0.1 + dev: true + + /has-cors@1.1.0: + resolution: {integrity: sha512-g5VNKdkFuUuVCP9gYfDJHjK2nqdQJ7aDLTnycnc2+RvsOQbuLdF5pm7vuE5J76SEBIQjs4kQY/BWq74JUmjbXA==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-glob@0.1.1: + resolution: {integrity: sha512-WMHzb7oCwDcMDngWy0b+viLjED8zvSi5d4/YdBetADHX/rLH+noJaRTytuyN6thTxxM7lK+FloogQHHdOOR+7g==} + engines: {node: '>=0.10.0'} + dependencies: + is-glob: 2.0.1 + dev: true + + /has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.1.3 + dev: true + + /has-symbol-support-x@1.4.2: + resolution: {integrity: sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-to-string-tag-x@1.4.1: + resolution: {integrity: sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==} + dependencies: + has-symbol-support-x: 1.4.2 + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: true + + /has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + dev: true + + /has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + dev: true + + /has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + dev: true + + /has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + dev: true + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.0 + safe-buffer: 5.2.1 + dev: true + + /hash-stream-validation@0.2.4: + resolution: {integrity: sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==} + requiresBuild: true + dev: true + optional: true + + /hash-sum@2.0.0: + resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} + dev: true + + /hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + dev: true + + /hasha@2.2.0: + resolution: {integrity: sha512-jZ38TU/EBiGKrmyTNNZgnvCZHNowiRI4+w/I9noMlekHTZH3KyGgvJLmhSgykeAQ9j2SYPDosM0Bg3wHfzibAQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-stream: 1.1.0 + pinkie-promise: 2.0.1 + dev: true + + /hashring@3.2.0: + resolution: {integrity: sha512-xCMovURClsQZ+TR30icCZj+34Fq1hs0y6YCASD6ZqdRfYRybb5Iadws2WS+w09mGM/kf9xyA5FCdJQGcgcraSA==} + dependencies: + connection-parse: 0.0.7 + simple-lru-cache: 0.0.2 + dev: true + + /hast-util-to-estree@2.2.1: + resolution: {integrity: sha512-kiGD9WIW3gRKK8Gao3n1f+ahUeTMeJUJILnIT2QNrPigDNdH7rJxzhEbh81UajGeAdAHFecT1a+fLVOCTq9B4Q==} + dependencies: + '@types/estree': 1.0.0 + '@types/estree-jsx': 1.0.0 + '@types/hast': 2.3.4 + '@types/unist': 2.0.6 + comma-separated-tokens: 2.0.3 + estree-util-attach-comments: 2.1.0 + estree-util-is-identifier-name: 2.0.1 + hast-util-whitespace: 2.0.1 + mdast-util-mdx-expression: 1.3.1 + mdast-util-mdxjs-esm: 1.3.0 + property-information: 6.2.0 + space-separated-tokens: 2.0.2 + style-to-object: 0.4.1 + unist-util-position: 4.0.3 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /hast-util-whitespace@2.0.1: + resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} + dev: true + + /hdr-histogram-js@2.0.3: + resolution: {integrity: sha512-Hkn78wwzWHNCp2uarhzQ2SGFLU3JY8SBDDd3TAABK4fc30wm+MuPOrg5QVFVfkKOQd6Bfz3ukJEI+q9sXEkK1g==} + dependencies: + '@assemblyscript/loader': 0.10.1 + base64-js: 1.5.1 + pako: 1.0.11 + dev: true + + /hdr-histogram-percentiles-obj@3.0.0: + resolution: {integrity: sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw==} + dev: true + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + + /help-me@1.1.0: + resolution: {integrity: sha512-P/IZ8yOMne3SCTHbVY429NZ67B/2bVQlcYGZh2iPPbdLrEQ/qY5aGChn0YTDmt7Sb4IKRI51fypItav+lNl76w==} + dependencies: + callback-stream: 1.1.0 + glob-stream: 6.1.0 + through2: 2.0.5 + xtend: 4.0.2 + dev: true + + /highlights@3.1.6: + resolution: {integrity: sha512-WvFo8DzI+DnFWPckWjdK5Sne4ucAaNI4guikzAE5k0qhJE7JX2Px7OOolwVJJQmi7YkJDbubWVAxT3SjMUJWcw==} + hasBin: true + requiresBuild: true + dependencies: + first-mate: 7.4.3 + first-mate-select-grammar: 1.0.3 + fs-plus: 3.1.1 + once: 1.4.0 + season: 6.0.2 + underscore-plus: 1.7.0 + yargs: 17.6.0 + dev: true + + /hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + dev: true + + /homedir-polyfill@1.0.3: + resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} + engines: {node: '>=0.10.0'} + dependencies: + parse-passwd: 1.0.0 + dev: true + + /hot-shots@9.3.0: + resolution: {integrity: sha512-e4tgWptiBvlIMnAX0ORe+dNEt0HznD+T2ckzXDUwCBsU7uWr2mwq5UtoT+Df5r9hD5S/DuP8rTxJUQvqAFSFKA==} + engines: {node: '>=6.0.0'} + requiresBuild: true + optionalDependencies: + unix-dgram: 2.0.6 + dev: true + + /html-encoding-sniffer@2.0.1: + resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==} + engines: {node: '>=10'} + dependencies: + whatwg-encoding: 1.0.5 + dev: true + + /html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + dev: true + + /html5shiv@3.7.3: + resolution: {integrity: sha512-SZwGvLGNtgp8GbgFX7oXEp8OR1aBt5LliX6dG0kdD1kl3KhMonN0QcSa/A3TsTgFewaGCbIryQunjayWDXzxmw==} + dev: true + + /htmlescape@1.1.1: + resolution: {integrity: sha512-eVcrzgbR4tim7c7soKQKtxa/kQM4TzjnlU83rcZ9bHU6t31ehfV7SktN6McWgwPWg+JYMA/O3qpGxBvFq1z2Jg==} + engines: {node: '>=0.10'} + dev: true + + /http-assert@1.5.0: + resolution: {integrity: sha512-uPpH7OKX4H25hBmU6G1jWNaqJGpTXxey+YOUizJUAgu0AjLUeC8D73hTrhvDS5D+GJN1DN1+hhc/eF/wpxtp0w==} + engines: {node: '>= 0.8'} + dependencies: + deep-equal: 1.0.1 + http-errors: 1.8.1 + dev: true + + /http-cache-semantics@3.8.1: + resolution: {integrity: sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w==} + dev: true + + /http-cache-semantics@4.1.0: + resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} + dev: true + + /http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 1.5.0 + toidentifier: 1.0.1 + dev: true + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: true + + /http-link-header@0.8.0: + resolution: {integrity: sha512-qsh/wKe1Mk1vtYEFr+LpQBFWTO1gxZQBdii2D0Umj+IUQ23r5sT088Rhpq4XzpSyIpaX7vwjB8Rrtx8u9JTg+Q==} + dev: true + + /http-parser-js@0.5.8: + resolution: {integrity: sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==} + dev: true + + /http-proxy-agent@4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + requiresBuild: true + dependencies: + '@tootallnate/once': 2.0.0 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + optional: true + + /http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.17.0 + dev: true + + /http-status@1.5.3: + resolution: {integrity: sha512-jCClqdnnwigYslmtfb28vPplOgoiZ0siP2Z8C5Ua+3UKbx410v+c+jT+jh1bbI4TvcEySuX0vd/CfFZFbDkJeQ==} + engines: {node: '>= 0.4.0'} + dev: true + + /http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + dev: true + + /httpntlm@1.6.1: + resolution: {integrity: sha512-Tcz3Ct9efvNqw3QdTl3h6IgRRlIQxwKkJELN/aAIGnzi2xvb3pDHdnMs8BrxWLV6OoT4DlVyhzSVhFt/tk0lIw==} + engines: {node: '>=0.8.0'} + dependencies: + httpreq: 0.5.2 + underscore: 1.7.0 + dev: true + + /httpreq@0.5.2: + resolution: {integrity: sha512-2Jm+x9WkExDOeFRrdBCBSpLPT5SokTcRHkunV3pjKmX/cx6av8zQ0WtHUMDrYb6O4hBFzNU6sxJEypvRUVYKnw==} + engines: {node: '>= 6.15.1'} + dev: true + + /https-browserify@1.0.0: + resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} + dev: true + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + requiresBuild: true + dependencies: + ms: 2.1.3 + dev: true + optional: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /idb@3.0.2: + resolution: {integrity: sha512-+FLa/0sTXqyux0o6C+i2lOR0VoS60LU/jzUo5xjfY6+7sEEgy4Gz1O7yFBXvjd7N0NyIGWIRg8DcQSLEG+VSPw==} + dev: true + + /idb@7.1.1: + resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} + dev: true + + /ieee754@1.1.13: + resolution: {integrity: sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==} + dev: true + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /ignore-walk@3.0.4: + resolution: {integrity: sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==} + dependencies: + minimatch: 3.1.2 + dev: true + + /image-ssim@0.2.0: + resolution: {integrity: sha512-W7+sO6/yhxy83L0G7xR8YAc5Z5QFtYEXXRV6EaE8tuYBZJnA3gVgp3q7X7muhLZVodeb9UfvjSbwt9VJwjIYAg==} + dev: true + + /immediate@3.3.0: + resolution: {integrity: sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==} + dev: true + + /import-lazy@2.1.0: + resolution: {integrity: sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==} + engines: {node: '>=4'} + dev: true + + /import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + requiresBuild: true + dev: true + optional: true + + /indexof@0.0.1: + resolution: {integrity: sha512-i0G7hLJ1z0DE8dsqJa2rycj9dBmNKgXBvotXtZYXakU9oivfB9Uj2ZBC27qqef2U58/ZLwalxa1X/RDCdkHtVg==} + dev: true + + /infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + requiresBuild: true + dev: true + optional: true + + /inflection@1.12.0: + resolution: {integrity: sha512-lRy4DxuIFWXlJU7ed8UiTJOSTqStqYdEb4CEbtXfNbkdj3nH1L+reUWiE10VWcJS2yR7tge8Z74pJjtBjNwj0w==} + engines: {'0': node >= 0.4.0} + dev: true + + /inflection@1.13.4: + resolution: {integrity: sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==} + engines: {'0': node >= 0.4.0} + dev: true + + /inflection@1.2.7: + resolution: {integrity: sha512-0baJIGEJm8RVuFZ390oImj8Q0i57nZvH/gRKjLbatW2JYEnphm+IGTuHCRw5PN59nAtrrQrT83q0tnebEznz7Q==} + engines: {'0': node >= 0.4.0} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.1: + resolution: {integrity: sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==} + dev: true + + /inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + dev: true + + /inline-source-map@0.6.2: + resolution: {integrity: sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==} + dependencies: + source-map: 0.5.7 + dev: true + + /inline-style-parser@0.1.1: + resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + dev: true + + /inquirer@3.3.0: + resolution: {integrity: sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==} + dependencies: + ansi-escapes: 3.2.0 + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-width: 2.2.1 + external-editor: 2.2.0 + figures: 2.0.0 + lodash: 4.17.21 + mute-stream: 0.0.7 + run-async: 2.4.1 + rx-lite: 4.0.8 + rx-lite-aggregates: 4.0.8 + string-width: 2.1.1 + strip-ansi: 4.0.0 + through: 2.3.8 + dev: true + + /insert-module-globals@7.2.1: + resolution: {integrity: sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg==} + hasBin: true + dependencies: + JSONStream: 1.3.5 + acorn-node: 1.8.2 + combine-source-map: 0.8.0 + concat-stream: 1.6.2 + is-buffer: 1.1.6 + path-is-absolute: 1.0.1 + process: 0.11.10 + through2: 2.0.5 + undeclared-identifiers: 1.1.3 + xtend: 4.0.2 + dev: true + + /internal-slot@1.0.3: + resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.1.3 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /intl-messageformat-parser@1.8.1: + resolution: {integrity: sha512-IMSCKVf0USrM/959vj3xac7s8f87sc+80Y/ipBzdKy4ifBv5Gsj2tZ41EAaURVg01QU71fYr77uA8Meh6kELbg==} + deprecated: We've written a new parser that's 6x faster and is backwards compatible. Please use @formatjs/icu-messageformat-parser + dev: true + + /intl-messageformat@4.4.0: + resolution: {integrity: sha512-z+Bj2rS3LZSYU4+sNitdHrwnBhr0wO80ZJSW8EzKDBowwUe3Q/UsvgCGjrwa+HPzoGCLEb9HAjfJgo4j2Sac8w==} + dependencies: + intl-messageformat-parser: 1.8.1 + dev: true + + /intl-pluralrules@1.3.1: + resolution: {integrity: sha512-sNYPls1Q4fyN0EGLFVJ7TIuaMWln01LupLozfIBt69rHK0DHehghMSz6ejfnSklgRddnyQSEaQPIU6d9TCKH3w==} + dev: true + + /intl@1.2.5: + resolution: {integrity: sha512-rK0KcPHeBFBcqsErKSpvZnrOmWOj+EmDkyJ57e90YWaQNqbcivcqmKDlHEeNprDWOsKzPsh1BfSpPQdDvclHVw==} + dev: true + + /into-stream@3.1.0: + resolution: {integrity: sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==} + engines: {node: '>=4'} + dependencies: + from2: 2.3.0 + p-is-promise: 1.1.0 + dev: true + + /invert-kv@1.0.0: + resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} + engines: {node: '>=0.10.0'} + dev: true + + /invert-kv@2.0.0: + resolution: {integrity: sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==} + engines: {node: '>=4'} + dev: true + + /invert-kv@3.0.1: + resolution: {integrity: sha512-CYdFeFexxhv/Bcny+Q0BfOV+ltRlJcd4BBZBYFX/O0u4npJrgZtIcjokegtiSMAvlMTJ+Koq0GBCc//3bueQxw==} + engines: {node: '>=8'} + dev: true + + /ioredis@4.28.5: + resolution: {integrity: sha512-3GYo0GJtLqgNXj4YhrisLaNNvWSNwSS2wS4OELGfGxH8I69+XfNdnmV1AyN+ZqMh0i7eX+SWjrwFKDBDgfBC1A==} + engines: {node: '>=6'} + dependencies: + cluster-key-slot: 1.1.1 + debug: 4.3.4 + denque: 1.5.1 + lodash.defaults: 4.2.0 + lodash.flatten: 4.4.0 + lodash.isarguments: 3.1.0 + p-map: 2.1.0 + redis-commands: 1.7.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /ioredis@5.2.3: + resolution: {integrity: sha512-gQNcMF23/NpvjCaa1b5YycUyQJ9rBNH2xP94LWinNpodMWVUPP5Ai/xXANn/SM7gfIvI62B5CCvZxhg5pOgyMw==} + engines: {node: '>=12.22.0'} + dependencies: + '@ioredis/commands': 1.2.0 + cluster-key-slot: 1.1.1 + debug: 4.3.4 + denque: 2.1.0 + lodash.defaults: 4.2.0 + lodash.isarguments: 3.1.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /ip-regex@2.1.0: + resolution: {integrity: sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==} + engines: {node: '>=4'} + dev: true + + /ip@2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + requiresBuild: true + dev: true + optional: true + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: true + + /is-absolute@0.2.6: + resolution: {integrity: sha512-7Kr05z5LkcOpoMvxHN1PC11WbPabdNFmMYYo0eZvWu3BfVS0T03yoqYDczoCBx17xqk2x1XAZrcKiFVL88jxlQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-relative: 0.2.1 + is-windows: 0.2.0 + dev: true + + /is-absolute@1.0.0: + resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} + engines: {node: '>=0.10.0'} + dependencies: + is-relative: 1.0.0 + is-windows: 1.0.2 + dev: true + + /is-accessor-descriptor@0.1.6: + resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-accessor-descriptor@1.0.0: + resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 6.0.3 + dev: true + + /is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + dev: true + + /is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + dev: true + + /is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path@1.0.1: + resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} + engines: {node: '>=0.10.0'} + dependencies: + binary-extensions: 1.13.1 + dev: true + + /is-bluebird@1.0.2: + resolution: {integrity: sha512-PDRu1vVip5dGQg5tfn2qVCCyxbBYu5MhYUJwSfL/RoGBI97n1fxvilVazxzptZW0gcmsMH17H4EVZZI5E/RSeA==} + engines: {node: '>=0.10.0'} + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + dev: true + + /is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-ci@1.2.1: + resolution: {integrity: sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==} + hasBin: true + dependencies: + ci-info: 1.6.0 + dev: true + + /is-core-module@2.11.0: + resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + dependencies: + has: 1.0.3 + dev: true + + /is-data-descriptor@0.1.4: + resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-data-descriptor@1.0.0: + resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 6.0.3 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + dev: true + + /is-descriptor@0.1.6: + resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} + engines: {node: '>=0.10.0'} + dependencies: + is-accessor-descriptor: 0.1.6 + is-data-descriptor: 0.1.4 + kind-of: 5.1.0 + dev: true + + /is-descriptor@1.0.2: + resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} + engines: {node: '>=0.10.0'} + dependencies: + is-accessor-descriptor: 1.0.0 + is-data-descriptor: 1.0.0 + kind-of: 6.0.3 + dev: true + + /is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + + /is-expression@4.0.0: + resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} + dependencies: + acorn: 7.4.1 + object-assign: 4.1.1 + dev: true + + /is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + dev: true + + /is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + dependencies: + is-plain-object: 2.0.4 + dev: true + + /is-extglob@1.0.0: + resolution: {integrity: sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==} + engines: {node: '>=0.10.0'} + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@1.0.0: + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} + engines: {node: '>=0.10.0'} + dependencies: + number-is-nan: 1.0.1 + dev: true + + /is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-function@1.0.2: + resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} + dev: true + + /is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + dev: true + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-glob@2.0.1: + resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 1.0.0 + dev: true + + /is-glob@3.1.0: + resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + dev: true + + /is-installed-globally@0.1.0: + resolution: {integrity: sha512-ERNhMg+i/XgDwPIPF3u24qpajVreaiSuvpb1Uu0jugw7KKcxGyCX8cgp8P5fwTmAuXku6beDHHECdKArjlg7tw==} + engines: {node: '>=4'} + dependencies: + global-dirs: 0.1.1 + is-path-inside: 1.0.1 + dev: true + + /is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + requiresBuild: true + dev: true + optional: true + + /is-lower-case@1.1.3: + resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==} + dependencies: + lower-case: 1.1.4 + dev: true + + /is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + + /is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + dev: true + + /is-negated-glob@1.0.0: + resolution: {integrity: sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==} + engines: {node: '>=0.10.0'} + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-npm@1.0.0: + resolution: {integrity: sha512-9r39FIr3d+KD9SbX0sfMsHzb5PP3uimOiwr3YupUaUFG4W0l1U57Rx3utpttV7qz5U3jmrO5auUa04LU9pyHsg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + requiresBuild: true + dev: true + optional: true + + /is-object@1.0.2: + resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} + dev: true + + /is-path-inside@1.0.1: + resolution: {integrity: sha512-qhsCR/Esx4U4hg/9I19OVUAJkGWtjRYHMRgUMZE2TDdj+Ag+kttZanLupfddNyglzz50cUlmWzUaI37GDfNx/g==} + engines: {node: '>=0.10.0'} + dependencies: + path-is-inside: 1.0.2 + dev: true + + /is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + dev: true + + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + dev: true + + /is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: true + + /is-redirect@1.0.0: + resolution: {integrity: sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==} + engines: {node: '>=0.10.0'} + dev: true + + /is-reference@3.0.1: + resolution: {integrity: sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==} + dependencies: + '@types/estree': 0.0.47 + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-relative@0.2.1: + resolution: {integrity: sha512-9AMzjRmLqcue629b4ezEVSK6kJsYJlUIhMcygmYORUgwUNJiavHcC3HkaGx0XYpyVKQSOqFbMEZmW42cY87sYw==} + engines: {node: '>=0.10.0'} + dependencies: + is-unc-path: 0.1.2 + dev: true + + /is-relative@1.0.0: + resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} + engines: {node: '>=0.10.0'} + dependencies: + is-unc-path: 1.0.0 + dev: true + + /is-retry-allowed@1.2.0: + resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-retry-allowed@2.2.0: + resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} + engines: {node: '>=10'} + dev: true + + /is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-stream-ended@0.1.4: + resolution: {integrity: sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==} + dev: true + + /is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.9: + resolution: {integrity: sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-abstract: 1.20.4 + for-each: 0.3.3 + has-tostringtag: 1.0.0 + dev: true + + /is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + dev: true + + /is-unc-path@0.1.2: + resolution: {integrity: sha512-HhLc5VDMH4pu3oMtIuunz/DFQUIoR561kMME3U3Afhj8b7vH085vkIkemrz1kLXCEIuoMAmO3yVmafWdSbGW8w==} + engines: {node: '>=0.10.0'} + dependencies: + unc-path-regex: 0.1.2 + dev: true + + /is-unc-path@1.0.0: + resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} + engines: {node: '>=0.10.0'} + dependencies: + unc-path-regex: 0.1.2 + dev: true + + /is-upper-case@1.1.2: + resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==} + dependencies: + upper-case: 1.1.3 + dev: true + + /is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + dev: true + + /is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + dev: true + + /is-valid-glob@0.3.0: + resolution: {integrity: sha512-CvG8EtJZ8FyzVOGPzrDorzyN65W1Ld8BVnqshRCah6pFIsprGx3dKgFtjLn/Vw9kGqR4OlR84U7yhT9ZVTyWIQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + dev: true + + /is-windows@0.2.0: + resolution: {integrity: sha512-n67eJYmXbniZB7RF4I/FTjK1s6RPOCTxhYrVYLRaCt3lF0mpWZPKr3T2LSZAqyjQsxR2qMmGYXXzK0YWwcPM1Q==} + engines: {node: '>=0.10.0'} + dev: true + + /is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /is-wsl@1.1.0: + resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} + engines: {node: '>=4'} + dev: true + + /is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + + /is2@2.0.1: + resolution: {integrity: sha512-+WaJvnaA7aJySz2q/8sLjMb2Mw14KTplHmSwcSpZ/fWJPkUmqw3YTzSWbPJ7OAwRvdYTWF2Wg+yYJ1AdP5Z8CA==} + engines: {node: '>=v0.10.0'} + dependencies: + deep-is: 0.1.4 + ip-regex: 2.1.0 + is-url: 1.2.4 + dev: true + + /is@3.3.0: + resolution: {integrity: sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==} + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isarray@2.0.1: + resolution: {integrity: sha512-c2cu3UxbI+b6kR3fy0nRnAhodsvR9dx7U5+znCOzdj6IfP3upFURTr0Xl5BlQZNKZjEtxrmVyfSdeE3O57smoQ==} + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isemail@3.2.0: + resolution: {integrity: sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==} + engines: {node: '>=4.0.0'} + dependencies: + punycode: 2.1.1 + dev: true + + /iserror@0.0.2: + resolution: {integrity: sha512-oKGGrFVaWwETimP3SiWwjDeY27ovZoyZPHtxblC4hCq9fXxed/jasx+ATWFFjCVSRZng8VTMsN1nDnGo6zMBSw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + dependencies: + isarray: 1.0.0 + dev: true + + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + + /isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + requiresBuild: true + dependencies: + node-fetch: 2.6.12 + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding + dev: true + + /isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + dev: true + + /istanbul-lib-coverage@3.2.0: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.19.6 + '@babel/parser': 7.19.6 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-lib-report@3.0.0: + resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} + engines: {node: '>=8'} + dependencies: + istanbul-lib-coverage: 3.2.0 + make-dir: 3.1.0 + supports-color: 7.2.0 + dev: true + + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.0 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + + /istanbul-reports@3.1.5: + resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} + engines: {node: '>=8'} + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.0 + dev: true + + /isurl@1.0.0: + resolution: {integrity: sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==} + engines: {node: '>= 4'} + dependencies: + has-to-string-tag-x: 1.4.1 + is-object: 1.0.2 + dev: true + + /iterall@1.3.0: + resolution: {integrity: sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg==} + dev: true + + /jackpot@0.0.6: + resolution: {integrity: sha512-rbWXX+A9ooq03/dfavLg9OXQ8YB57Wa7PY5c4LfU3CgFpwEhhl3WyXTQVurkaT7zBM5I9SSOaiLyJ4I0DQmC0g==} + dependencies: + retry: 0.6.0 + dev: true + + /jake@10.8.5: + resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + async: 3.2.4 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + dev: true + + /jayson@2.1.2: + resolution: {integrity: sha512-2GejcQnEV35KYTXoBvzALIDdO/1oyEIoJHBnaJFhJhcurv0x2JqUXQW6xlDUhcNOpN9t+d2w+JGA6vOphb+5mg==} + hasBin: true + dependencies: + '@types/node': 10.17.60 + JSONStream: 1.3.5 + commander: 2.20.3 + es6-promisify: 5.0.0 + eyes: 0.1.8 + json-stringify-safe: 5.0.1 + lodash: 4.17.21 + uuid: 3.4.0 + dev: true + + /jest-changed-files@27.5.1: + resolution: {integrity: sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + execa: 5.1.1 + throat: 6.0.1 + dev: true + + /jest-circus@27.5.1: + resolution: {integrity: sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + expect: 27.5.1 + is-generator-fn: 2.1.0 + jest-each: 27.5.1 + jest-matcher-utils: 27.5.1 + jest-message-util: 27.5.1 + jest-runtime: 27.5.1 + jest-snapshot: 27.5.1 + jest-util: 27.5.1 + pretty-format: 27.5.1 + slash: 3.0.0 + stack-utils: 2.0.5 + throat: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-cli@27.5.1(canvas@2.11.2)(ts-node@10.9.1): + resolution: {integrity: sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 27.5.1(canvas@2.11.2)(ts-node@10.9.1) + '@jest/test-result': 27.5.1 + '@jest/types': 27.5.1 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.10 + import-local: 3.1.0 + jest-config: 27.5.1(canvas@2.11.2)(ts-node@10.9.1) + jest-util: 27.5.1 + jest-validate: 27.5.1 + prompts: 2.4.2 + yargs: 16.2.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /jest-config@27.5.1(canvas@2.11.2)(ts-node@10.9.1): + resolution: {integrity: sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + ts-node: '>=9.0.0' + peerDependenciesMeta: + ts-node: + optional: true + dependencies: + '@babel/core': 7.19.6 + '@jest/test-sequencer': 27.5.1 + '@jest/types': 27.5.1 + babel-jest: 27.5.1(@babel/core@7.19.6) + chalk: 4.1.2 + ci-info: 3.5.0 + deepmerge: 4.2.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 27.5.1 + jest-environment-jsdom: 27.5.1(canvas@2.11.2) + jest-environment-node: 27.5.1 + jest-get-type: 27.5.1 + jest-jasmine2: 27.5.1 + jest-regex-util: 27.5.1 + jest-resolve: 27.5.1 + jest-runner: 27.5.1(canvas@2.11.2) + jest-util: 27.5.1 + jest-validate: 27.5.1 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 27.5.1 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.1(@types/node@14.18.29)(typescript@4.8.4) + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-diff@27.5.1: + resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + chalk: 4.1.2 + diff-sequences: 27.5.1 + jest-get-type: 27.5.1 + pretty-format: 27.5.1 + dev: true + + /jest-docblock@27.5.1: + resolution: {integrity: sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + detect-newline: 3.1.0 + dev: true + + /jest-each@27.5.1: + resolution: {integrity: sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + chalk: 4.1.2 + jest-get-type: 27.5.1 + jest-util: 27.5.1 + pretty-format: 27.5.1 + dev: true + + /jest-environment-jsdom@27.5.1(canvas@2.11.2): + resolution: {integrity: sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.5.1 + '@jest/fake-timers': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + jest-mock: 27.5.1 + jest-util: 27.5.1 + jsdom: 16.7.0(canvas@2.11.2) + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-environment-node@27.5.1: + resolution: {integrity: sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.5.1 + '@jest/fake-timers': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + jest-mock: 27.5.1 + jest-util: 27.5.1 + dev: true + + /jest-get-type@27.5.1: + resolution: {integrity: sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dev: true + + /jest-haste-map@27.5.1: + resolution: {integrity: sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + '@types/graceful-fs': 4.1.5 + '@types/node': 14.18.29 + anymatch: 3.1.2 + fb-watchman: 2.0.2 + graceful-fs: 4.2.10 + jest-regex-util: 27.5.1 + jest-serializer: 27.5.1 + jest-util: 27.5.1 + jest-worker: 27.5.1 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /jest-jasmine2@27.5.1: + resolution: {integrity: sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.5.1 + '@jest/source-map': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + chalk: 4.1.2 + co: 4.6.0 + expect: 27.5.1 + is-generator-fn: 2.1.0 + jest-each: 27.5.1 + jest-matcher-utils: 27.5.1 + jest-message-util: 27.5.1 + jest-runtime: 27.5.1 + jest-snapshot: 27.5.1 + jest-util: 27.5.1 + pretty-format: 27.5.1 + throat: 6.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-leak-detector@27.5.1: + resolution: {integrity: sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + jest-get-type: 27.5.1 + pretty-format: 27.5.1 + dev: true + + /jest-matcher-utils@27.5.1: + resolution: {integrity: sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + chalk: 4.1.2 + jest-diff: 27.5.1 + jest-get-type: 27.5.1 + pretty-format: 27.5.1 + dev: true + + /jest-message-util@27.5.1: + resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@babel/code-frame': 7.18.6 + '@jest/types': 27.5.1 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + pretty-format: 27.5.1 + slash: 3.0.0 + stack-utils: 2.0.5 + dev: true + + /jest-mock@27.5.1: + resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + dev: true + + /jest-pnp-resolver@1.2.2(jest-resolve@27.5.1): + resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + dependencies: + jest-resolve: 27.5.1 + dev: true + + /jest-regex-util@27.5.1: + resolution: {integrity: sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dev: true + + /jest-resolve-dependencies@27.5.1: + resolution: {integrity: sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + jest-regex-util: 27.5.1 + jest-snapshot: 27.5.1 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-resolve@27.5.1: + resolution: {integrity: sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + jest-haste-map: 27.5.1 + jest-pnp-resolver: 1.2.2(jest-resolve@27.5.1) + jest-util: 27.5.1 + jest-validate: 27.5.1 + resolve: 1.22.1 + resolve.exports: 1.1.0 + slash: 3.0.0 + dev: true + + /jest-runner@27.5.1(canvas@2.11.2): + resolution: {integrity: sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/console': 27.5.1 + '@jest/environment': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + chalk: 4.1.2 + emittery: 0.8.1 + graceful-fs: 4.2.10 + jest-docblock: 27.5.1 + jest-environment-jsdom: 27.5.1(canvas@2.11.2) + jest-environment-node: 27.5.1 + jest-haste-map: 27.5.1 + jest-leak-detector: 27.5.1 + jest-message-util: 27.5.1 + jest-resolve: 27.5.1 + jest-runtime: 27.5.1 + jest-util: 27.5.1 + jest-worker: 27.5.1 + source-map-support: 0.5.21 + throat: 6.0.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /jest-runtime@27.5.1: + resolution: {integrity: sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/environment': 27.5.1 + '@jest/fake-timers': 27.5.1 + '@jest/globals': 27.5.1 + '@jest/source-map': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + chalk: 4.1.2 + cjs-module-lexer: 1.2.2 + collect-v8-coverage: 1.0.1 + execa: 5.1.1 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-haste-map: 27.5.1 + jest-message-util: 27.5.1 + jest-mock: 27.5.1 + jest-regex-util: 27.5.1 + jest-resolve: 27.5.1 + jest-snapshot: 27.5.1 + jest-util: 27.5.1 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-serializer@27.5.1: + resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@types/node': 14.18.29 + graceful-fs: 4.2.10 + dev: true + + /jest-snapshot@27.5.1: + resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@babel/core': 7.19.6 + '@babel/generator': 7.19.6 + '@babel/plugin-syntax-typescript': 7.18.6(@babel/core@7.19.6) + '@babel/traverse': 7.19.6 + '@babel/types': 7.19.4 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/babel__traverse': 7.18.2 + '@types/prettier': 2.7.1 + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.19.6) + chalk: 4.1.2 + expect: 27.5.1 + graceful-fs: 4.2.10 + jest-diff: 27.5.1 + jest-get-type: 27.5.1 + jest-haste-map: 27.5.1 + jest-matcher-utils: 27.5.1 + jest-message-util: 27.5.1 + jest-util: 27.5.1 + natural-compare: 1.4.0 + pretty-format: 27.5.1 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color + dev: true + + /jest-util@27.5.1: + resolution: {integrity: sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + chalk: 4.1.2 + ci-info: 3.5.0 + graceful-fs: 4.2.10 + picomatch: 2.3.1 + dev: true + + /jest-validate@27.5.1: + resolution: {integrity: sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 27.5.1 + leven: 3.1.0 + pretty-format: 27.5.1 + dev: true + + /jest-watcher@27.5.1: + resolution: {integrity: sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/test-result': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 14.18.29 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + jest-util: 27.5.1 + string-length: 4.0.2 + dev: true + + /jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 14.18.29 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jest@27.5.1(canvas@2.11.2)(ts-node@10.9.1): + resolution: {integrity: sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + dependencies: + '@jest/core': 27.5.1(canvas@2.11.2)(ts-node@10.9.1) + import-local: 3.1.0 + jest-cli: 27.5.1(canvas@2.11.2)(ts-node@10.9.1) + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + dev: true + + /jimp@0.6.8: + resolution: {integrity: sha512-F7emeG7Hp61IM8VFbNvWENLTuHe0ghizWPuP4JS9ujx2r5mCVYEd/zdaz6M2M42ZdN41blxPajLWl9FXo7Mr2Q==} + requiresBuild: true + dependencies: + '@jimp/custom': 0.6.8 + '@jimp/plugins': 0.6.8(@jimp/custom@0.6.8) + '@jimp/types': 0.6.8(@jimp/custom@0.6.8) + core-js: 2.6.12 + regenerator-runtime: 0.13.10 + dev: true + + /jmespath@0.16.0: + resolution: {integrity: sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==} + engines: {node: '>= 0.6.0'} + dev: true + + /join-component@1.1.0: + resolution: {integrity: sha512-bF7vcQxbODoGK1imE2P9GS9aw4zD0Sd+Hni68IMZLj7zRnquH7dXUmMw9hDI5S/Jzt7q+IyTXN0rSg2GI0IKhQ==} + dev: true + + /jose@2.0.6: + resolution: {integrity: sha512-FVoPY7SflDodE4lknJmbAHSUjLCzE2H1F6MS0RYKMQ8SR+lNccpMf8R4eqkNYyyUjR5qZReOzZo5C5YiHOCjjg==} + engines: {node: '>=10.13.0 < 13 || >=13.7.0'} + dependencies: + '@panva/asn1.js': 1.0.0 + dev: true + + /jpeg-js@0.1.2: + resolution: {integrity: sha512-CiRVjMKBUp6VYtGwzRjrdnro41yMwKGOWdP9ATXqmixdz2n7KHNwdqthTYSSbOKj/Ha79Gct1sA8ZQpse55TYA==} + dev: true + + /jpeg-js@0.3.7: + resolution: {integrity: sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==} + dev: true + + /js-library-detector@5.9.0: + resolution: {integrity: sha512-0wYHRVJv8uVsylJhfQQaH2vOBYGehyZyJbtaHuchoTP3Mb6hqYvrA0hoMQ1ZhARLHzHJMbMc/nCr4D3pTNSCgw==} + dev: true + + /js-polyfills@0.1.43: + resolution: {integrity: sha512-wWCJcw7uMA12uk7qcqZlIQy9nj+Evh1wVUmn5MOlJ7GPC8HT5PLjB9Uiqjw9ldAbbOuNOWJ6ENb7NwU6qqf48g==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + dev: true + + /js-stringify@1.0.2: + resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js2xmlparser@3.0.0: + resolution: {integrity: sha512-CSOkdn0/GhRFwxnipmhXfqJ+FG6+wkWBi46kKSsPx6+j65176ZiQcrCYpg6K8x3iLbO4k3zScBnZ7I/L80dAtw==} + dependencies: + xmlcreate: 1.0.2 + dev: true + + /js2xmlparser@4.0.2: + resolution: {integrity: sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==} + dependencies: + xmlcreate: 2.0.4 + dev: true + + /jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + dev: true + + /jsdom@16.7.0(canvas@2.11.2): + resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==} + engines: {node: '>=10'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + dependencies: + abab: 2.0.6 + acorn: 8.8.1 + acorn-globals: 6.0.0 + canvas: 2.11.2 + cssom: 0.4.4 + cssstyle: 2.3.0 + data-urls: 2.0.0 + decimal.js: 10.4.2 + domexception: 2.0.1 + escodegen: 2.0.0 + form-data: 3.0.1 + html-encoding-sniffer: 2.0.1 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.2 + parse5: 6.0.1 + saxes: 5.0.1 + symbol-tree: 3.2.4 + tough-cookie: 4.1.2 + w3c-hr-time: 1.0.2 + w3c-xmlserializer: 2.0.0 + webidl-conversions: 6.1.0 + whatwg-encoding: 1.0.5 + whatwg-mimetype: 2.3.0 + whatwg-url: 8.7.0 + ws: 7.5.9 + xml-name-validator: 3.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /json-bigint@0.3.1: + resolution: {integrity: sha512-DGWnSzmusIreWlEupsUelHrhwmPPE+FiQvg+drKfk2p+bdEYa5mp4PJ8JsCWqae0M2jQNb0HPvnwvf1qOTThzQ==} + dependencies: + bignumber.js: 9.1.0 + dev: true + + /json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + requiresBuild: true + dependencies: + bignumber.js: 9.1.0 + dev: true + + /json-buffer@2.0.11: + resolution: {integrity: sha512-Wu4/hxSZX7Krzjor+sZHWaRau6Be4WQHlrkl3v8cmxRBBewF2TotlgHUedKQJyFiUyFxnK/ZlRYnR9UNVZ7pkg==} + dev: true + + /json-buffer@3.0.0: + resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-edm-parser@0.1.2: + resolution: {integrity: sha512-J1U9mk6lf8dPULcaMwALXB6yel3cJyyhk9Z8FQ4sMwiazNwjaUhegIcpZyZFNMvLRtnXwh+TkCjX9uYUObBBYA==} + dependencies: + jsonparse: 1.2.0 + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json-stable-stringify@0.0.1: + resolution: {integrity: sha512-nKtD/Qxm7tWdZqJoldEC7fF0S41v0mWbeaXG3637stOWfyGxTgWTYE2wtfKmjzpvxv2MA2xzxsXOIiwUpkX6Qw==} + dependencies: + jsonify: 0.0.1 + dev: true + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true + + /json3@3.3.3: + resolution: {integrity: sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==} + dev: true + + /json5@1.0.1: + resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} + hasBin: true + dependencies: + minimist: 1.2.7 + dev: true + + /json5@2.2.1: + resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonfile@2.4.0: + resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} + optionalDependencies: + graceful-fs: 4.2.10 + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.10 + dev: true + + /jsonify@0.0.1: + resolution: {integrity: sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==} + dev: true + + /jsonld@1.8.1: + resolution: {integrity: sha512-f0rusl5v8aPKS3jApT5fhYsdTC/JpyK1PoJ+ZtYYtZXoyb1J0Z///mJqLwrfL/g4NueFSqPymDYIi1CcSk7b8Q==} + engines: {node: '>=6'} + dependencies: + canonicalize: 1.0.8 + rdf-canonize: 1.2.0 + request: 2.88.2 + semver: 5.7.1 + xmldom: 0.1.19 + dev: true + + /jsonlint-mod@1.7.6: + resolution: {integrity: sha512-oGuk6E1ehmIpw0w9ttgb2KsDQQgGXBzZczREW8OfxEm9eCQYL9/LCexSnh++0z3AiYGcXpBgqDSx9AAgzl/Bvg==} + engines: {node: '>= 0.6'} + hasBin: true + dependencies: + JSV: 4.0.2 + chalk: 2.4.2 + underscore: 1.13.6 + dev: true + + /jsonparse@1.2.0: + resolution: {integrity: sha512-LkDEYtKnPFI9hQ/IURETe6F1dUH80cbRkaF6RaViSwoSNPwaxQpi6TgJGvJKyLQ2/9pQW+XCxK3hBoR44RAjkg==} + engines: {'0': node >= 0.2.0} + dev: true + + /jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + dev: true + + /jsonstream2@3.0.0: + resolution: {integrity: sha512-8ngq2XB8NjYrpe3+Xtl9lFJl6RoV2dNT4I7iyaHwxUpTBwsj0AlAR7epGfeYVP0z4Z7KxMoSxRgJWrd2jmBT/Q==} + engines: {node: '>=5.10.0'} + hasBin: true + dependencies: + jsonparse: 1.3.1 + through2: 3.0.2 + type-component: 0.0.1 + dev: true + + /jsonwebtoken@8.5.1: + resolution: {integrity: sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==} + engines: {node: '>=4', npm: '>=1.4.28'} + dependencies: + jws: 3.2.2 + lodash.includes: 4.3.0 + lodash.isboolean: 3.0.3 + lodash.isinteger: 4.0.4 + lodash.isnumber: 3.0.3 + lodash.isplainobject: 4.0.6 + lodash.isstring: 4.0.1 + lodash.once: 4.1.1 + ms: 2.1.3 + semver: 5.7.1 + dev: true + + /jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: true + + /jstransformer@1.0.0: + resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} + dependencies: + is-promise: 2.2.2 + promise: 7.3.1 + dev: true + + /jugglingdb@2.0.1: + resolution: {integrity: sha512-KZxp+ypI2yyFYWG94mX9xWuwLBkZdJHE8OFmCbwlprtRDNWi5hoJaKxAjF+zVmwItWpiGUCcLremAaI22vpqtA==} + engines: {'0': node >= 0.6} + requiresBuild: true + dependencies: + inflection: 1.2.7 + when: 3.7.3 + dev: true + + /jwa@1.4.1: + resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==} + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: true + + /jwa@2.0.0: + resolution: {integrity: sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==} + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + dev: true + + /jwks-rsa@1.12.3: + resolution: {integrity: sha512-cFipFDeYYaO9FhhYJcZWX/IyZgc0+g316rcHnDpT2dNRNIE/lMOmWKKqp09TkJoYlNFzrEVODsR4GgXJMgWhnA==} + dependencies: + '@types/express-jwt': 0.0.42 + axios: 0.21.4(debug@4.3.4) + debug: 4.3.4 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + jsonwebtoken: 8.5.1 + limiter: 1.1.5 + lru-memoizer: 2.1.4 + ms: 2.1.3 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jwks-rsa@2.1.5: + resolution: {integrity: sha512-IODtn1SwEm7n6GQZnQLY0oxKDrMh7n/jRH1MzE8mlxWMrh2NnMyOsXTebu8vJ1qCpmuTJcL4DdiE0E4h8jnwsA==} + engines: {node: '>=10 < 13 || >=14'} + dependencies: + '@types/express': 4.17.14 + '@types/jsonwebtoken': 8.5.9 + debug: 4.3.4 + jose: 2.0.6 + limiter: 1.1.5 + lru-memoizer: 2.1.4 + transitivePeerDependencies: + - supports-color + dev: true + + /jws@3.2.2: + resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==} + dependencies: + jwa: 1.4.1 + safe-buffer: 5.2.1 + dev: true + + /jws@4.0.0: + resolution: {integrity: sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==} + dependencies: + jwa: 2.0.0 + safe-buffer: 5.2.1 + dev: true + + /kareem@2.3.2: + resolution: {integrity: sha512-STHz9P7X2L4Kwn72fA4rGyqyXdmrMSdxqHx9IXon/FXluXieaFA6KJ2upcHAHxQPQ0LeM/OjLrhFxifHewOALQ==} + dev: true + + /kew@0.7.0: + resolution: {integrity: sha512-IG6nm0+QtAMdXt9KvbgbGdvY50RSrw+U4sGZg+KlrSKPJEwVE5JVoI3d7RWfSMdBQneRheeAOj3lIjX5VL/9RQ==} + dev: true + + /keygrip@1.1.0: + resolution: {integrity: sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==} + engines: {node: '>= 0.6'} + dependencies: + tsscmp: 1.0.6 + dev: true + + /keyv@3.0.0: + resolution: {integrity: sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==} + dependencies: + json-buffer: 3.0.0 + dev: true + + /keyv@4.5.0: + resolution: {integrity: sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + dev: true + + /kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + dev: true + + /kind-of@5.1.0: + resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} + engines: {node: '>=0.10.0'} + dev: true + + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /klaw@1.3.1: + resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} + optionalDependencies: + graceful-fs: 4.2.10 + dev: true + + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /koa-compose@4.1.0: + resolution: {integrity: sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==} + dev: true + + /koa-convert@2.0.0: + resolution: {integrity: sha512-asOvN6bFlSnxewce2e/DK3p4tltyfC4VM7ZwuTuepI7dEQVcvpyFuBcEARu1+Hxg8DIwytce2n7jrZtRlPrARA==} + engines: {node: '>= 10'} + dependencies: + co: 4.6.0 + koa-compose: 4.1.0 + dev: true + + /koa@2.13.4: + resolution: {integrity: sha512-43zkIKubNbnrULWlHdN5h1g3SEKXOEzoAlRsHOTFpnlDu8JlAOZSMJBLULusuXRequboiwJcj5vtYXKB3k7+2g==} + engines: {node: ^4.8.4 || ^6.10.1 || ^7.10.1 || >= 8.1.4} + requiresBuild: true + dependencies: + accepts: 1.3.8 + cache-content-type: 1.0.1 + content-disposition: 0.5.4 + content-type: 1.0.4 + cookies: 0.8.0 + debug: 4.3.4 + delegates: 1.0.0 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + fresh: 0.5.2 + http-assert: 1.5.0 + http-errors: 1.8.1 + is-generator-function: 1.0.10 + koa-compose: 4.1.0 + koa-convert: 2.0.0 + on-finished: 2.4.1 + only: 0.0.2 + parseurl: 1.3.3 + statuses: 1.5.0 + type-is: 1.6.18 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /labeled-stream-splicer@2.0.2: + resolution: {integrity: sha512-Ca4LSXFFZUjPScRaqOcFxneA0VpKZr4MMYCljyQr4LIewTLb3Y0IUTIsnBBsVubIeEfxeSZpSjSsRM8APEQaAw==} + dependencies: + inherits: 2.0.4 + stream-splicer: 2.0.1 + dev: true + + /latest-version@3.1.0: + resolution: {integrity: sha512-Be1YRHWWlZaSsrz2U+VInk+tO0EwLIyV+23RhWLINJYwg/UIikxjlj3MhH37/6/EDCAusjajvMkMMUXRaMWl/w==} + engines: {node: '>=4'} + dependencies: + package-json: 4.0.1 + dev: true + + /lazy-cache@0.2.7: + resolution: {integrity: sha512-gkX52wvU/R8DVMMt78ATVPFMJqfW8FPz1GZ1sVHBVQHmu/WvhIWE4cE1GBzhJNFicDeYhnwp6Rl35BcAIM3YOQ==} + engines: {node: '>=0.10.0'} + dev: true + + /lazy-cache@1.0.4: + resolution: {integrity: sha512-RE2g0b5VGZsOCFOCgP7omTRYFqydmZkBwl5oNnQ1lDYC57uyO9KqNnNVxT7COSHTxrRCWVcAVOcbjk+tvh/rgQ==} + engines: {node: '>=0.10.0'} + dev: true + + /lazy-cache@2.0.2: + resolution: {integrity: sha512-7vp2Acd2+Kz4XkzxGxaB1FWOi8KjWIWsgdfD5MCb86DWvlLqhRPM+d6Pro3iNEL5VT9mstz5hKAlcd+QR6H3aA==} + engines: {node: '>=0.10.0'} + dependencies: + set-getter: 0.1.1 + dev: true + + /lcid@1.0.0: + resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} + engines: {node: '>=0.10.0'} + dependencies: + invert-kv: 1.0.0 + dev: true + + /lcid@2.0.0: + resolution: {integrity: sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==} + engines: {node: '>=6'} + dependencies: + invert-kv: 2.0.0 + dev: true + + /lcid@3.1.1: + resolution: {integrity: sha512-M6T051+5QCGLBQb8id3hdvIW8+zeFV2FyBGFS9IEK5H9Wt4MueD4bW1eWikpHgZp+5xR3l5c8pZUkQsIA0BFZg==} + engines: {node: '>=8'} + dependencies: + invert-kv: 3.0.1 + dev: true + + /level-concat-iterator@2.0.1: + resolution: {integrity: sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==} + engines: {node: '>=6'} + dev: true + + /level-supports@1.0.1: + resolution: {integrity: sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==} + engines: {node: '>=6'} + dependencies: + xtend: 4.0.2 + dev: true + + /leveldown@5.6.0: + resolution: {integrity: sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==} + engines: {node: '>=8.6.0'} + requiresBuild: true + dependencies: + abstract-leveldown: 6.2.3 + napi-macros: 2.0.0 + node-gyp-build: 4.1.1 + dev: true + + /leven@2.1.0: + resolution: {integrity: sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==} + engines: {node: '>=0.10.0'} + dev: true + + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + dev: true + + /lighthouse-logger@1.3.0: + resolution: {integrity: sha512-BbqAKApLb9ywUli+0a+PcV04SyJ/N1q/8qgCNe6U97KbPCS1BTksEuHFLYdvc8DltuhfxIUBqDZsC0bBGtl3lA==} + dependencies: + debug: 2.6.9 + marky: 1.2.5 + transitivePeerDependencies: + - supports-color + dev: true + + /lighthouse@5.6.0: + resolution: {integrity: sha512-PQYeK6/P0p/JxP/zq8yfcPmuep/aeib5ykROTgzDHejMiuzYdD6k6MaSCv0ncwK+lj+Ld67Az+66rHqiPKHc6g==} + engines: {node: '>=10.13'} + hasBin: true + requiresBuild: true + dependencies: + axe-core: 3.3.0 + chrome-launcher: 0.11.2 + configstore: 3.1.5 + cssstyle: 1.2.1 + details-element-polyfill: 2.4.0 + http-link-header: 0.8.0 + inquirer: 3.3.0 + intl: 1.2.5 + intl-messageformat: 4.4.0 + intl-pluralrules: 1.3.1 + jpeg-js: 0.1.2 + js-library-detector: 5.9.0 + jsonld: 1.8.1 + jsonlint-mod: 1.7.6 + lighthouse-logger: 1.3.0 + lodash.isequal: 4.5.0 + lodash.set: 4.3.2 + lookup-closest-locale: 6.0.4 + metaviewport-parser: 0.2.0 + mkdirp: 0.5.1 + open: 6.4.0 + parse-cache-control: 1.0.1 + raven: 2.6.4 + rimraf: 2.7.1 + robots-parser: 2.4.0 + semver: 5.7.1 + speedline-core: 1.4.2 + third-party-web: 0.11.1 + update-notifier: 2.5.0 + ws: 3.3.2 + yargs: 3.32.0 + yargs-parser: 7.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /limiter@1.1.5: + resolution: {integrity: sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==} + dev: true + + /linebreak@0.3.0: + resolution: {integrity: sha512-zt8pzlM3oq4moDN8U5mP1SbZ44yKV6dXCu44Ez6iTXmxUl8/jRFWeho2SDqL5YDBv0TBKPgU/XGovZwnXAKlOQ==} + dependencies: + base64-js: 0.0.8 + brfs: 1.6.1 + unicode-trie: 0.3.1 + dev: true + + /lineclip@1.1.5: + resolution: {integrity: sha512-KlA/wRSjpKl7tS9iRUdlG72oQ7qZ1IlVbVgHwoO10TBR/4gQ86uhKow6nlzMAJJhjCWKto8OeoAzzIzKSmN25A==} + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /load-bmfont@1.4.1: + resolution: {integrity: sha512-8UyQoYmdRDy81Brz6aLAUhfZLwr5zV0L3taTQ4hju7m6biuwiWiJXjPhBJxbUQJA8PrkvJ/7Enqmwk2sM14soA==} + dependencies: + buffer-equal: 0.0.1 + mime: 1.6.0 + parse-bmfont-ascii: 1.0.6 + parse-bmfont-binary: 1.0.6 + parse-bmfont-xml: 1.1.4 + phin: 2.9.3 + xhr: 2.6.0 + xtend: 4.0.2 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash._reinterpolate@3.0.0: + resolution: {integrity: sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==} + dev: true + + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: true + + /lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + dev: true + + /lodash.defaults@4.2.0: + resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} + dev: true + + /lodash.flatten@4.4.0: + resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} + dev: true + + /lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + dev: true + + /lodash.includes@4.3.0: + resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==} + dev: true + + /lodash.isarguments@3.1.0: + resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==} + dev: true + + /lodash.isboolean@3.0.3: + resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==} + dev: true + + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + dev: true + + /lodash.isinteger@4.0.4: + resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==} + dev: true + + /lodash.isnumber@3.0.3: + resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==} + dev: true + + /lodash.isplainobject@4.0.6: + resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==} + dev: true + + /lodash.isstring@4.0.1: + resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==} + dev: true + + /lodash.memoize@3.0.4: + resolution: {integrity: sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==} + dev: true + + /lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + dev: true + + /lodash.set@4.3.2: + resolution: {integrity: sha512-4hNPN5jlm/N/HLMCO43v8BXKq9Z7QdAGc/VGrRD61w8gN9g/6jF9A4L1pbUgBLCffi0w9VsXfTOij5x8iTyFvg==} + dev: true + + /lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + + /lodash.template@4.5.0: + resolution: {integrity: sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==} + dependencies: + lodash._reinterpolate: 3.0.0 + lodash.templatesettings: 4.2.0 + dev: true + + /lodash.templatesettings@4.2.0: + resolution: {integrity: sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==} + dependencies: + lodash._reinterpolate: 3.0.0 + dev: true + + /lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-ok@0.1.1: + resolution: {integrity: sha512-cc8VrkS6C+9TFuYAwuHpshrcrGRAv7d0tUJ0GdM72ZBlKXtlgjUZF84O+OhQUdiVHoF7U/nVxwpjOdwUJ8d3Vg==} + engines: {node: '>=0.10.0'} + dependencies: + ansi-green: 0.1.1 + success-symbol: 0.1.0 + dev: true + + /loglevel@1.8.0: + resolution: {integrity: sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA==} + engines: {node: '>= 0.6.0'} + dev: true + + /long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + dev: true + + /long@5.2.0: + resolution: {integrity: sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w==} + dev: true + + /longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + dev: true + + /longest@1.0.1: + resolution: {integrity: sha512-k+yt5n3l48JU4k8ftnKG6V7u32wyH2NfKzeMto9F/QRE0amxy/LayxwlvjjkZEIzqR+19IrtFO8p5kB9QaYUFg==} + engines: {node: '>=0.10.0'} + dev: true + + /lookup-closest-locale@6.0.4: + resolution: {integrity: sha512-bWoFbSGe6f1GvMGzj17LrwMX4FhDXDwZyH04ySVCPbtOJADcSRguZNKewoJ3Ful/MOxD/wRHvFPadk/kYZUbuQ==} + dev: true + + /loopback-connector-remote@3.4.1: + resolution: {integrity: sha512-O22X2Gcq8YzZF9DvRjOCyktQlASw1/22i/zzqxJHNKSQA5aQYeTB0w5FttOiKxcw6Q/jzL476hUvUE/NaZVZ1Q==} + engines: {node: '>=6'} + dependencies: + loopback-datasource-juggler: 3.36.1 + strong-remoting: 3.17.0 + transitivePeerDependencies: + - supports-color + dev: true + + /loopback-connector@4.11.1: + resolution: {integrity: sha512-EA31zur3xIhP4UW+P2rWEcSbqpk4jPddpTBZSSw8KCszM7T0/Pe4HvEmG0MndAWJctRPtrwKDEu/8rWuMDLf+A==} + engines: {node: '>=8.9'} + dependencies: + async: 3.2.4 + bluebird: 3.7.2 + debug: 4.3.4 + msgpack5: 4.5.1 + strong-globalize: 5.1.0 + uuid: 7.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /loopback-datasource-juggler@3.36.1: + resolution: {integrity: sha512-6eop3qxFyN3AkPBPUte2DHcsW1DopJwXXA20x3vwYsBSo4hLSv4gIeXo0+yqdQoXpHfbKRB9cv1hHEHAQSiWUA==} + engines: {node: '>=8'} + dependencies: + async: 2.6.4 + bluebird: 3.7.2 + debug: 3.1.0 + depd: 1.1.2 + inflection: 1.13.4 + lodash: 4.17.21 + loopback-connector: 4.11.1 + minimatch: 3.1.2 + qs: 6.11.0 + shortid: 2.2.16 + strong-globalize: 4.1.3 + traverse: 0.6.7 + uuid: 3.4.0 + transitivePeerDependencies: + - supports-color + dev: true + + /loopback-datatype-geopoint@1.0.0: + resolution: {integrity: sha512-MqcEBXl/x4YC/hm/5ZRFBZGI9RCqHdy8zrv3jGHiE4cOnSdKVdranG+zEs8Xv7Z2sy/rV6qY3wsr7gBNcC9Kmw==} + engines: {node: '>=4'} + dev: true + + /loopback-filters@1.1.1: + resolution: {integrity: sha512-p0qSzuuX7eATe5Bxy+RqCj3vSfSFfdCtqyf3yuC+DpchMvgal33XlhEi2UmywyK/Ym28oVnZxxWmfrwFMzSwLQ==} + engines: {node: '>=4.0.0'} + dependencies: + debug: 3.1.0 + transitivePeerDependencies: + - supports-color + dev: true + + /loopback-phase@3.4.0: + resolution: {integrity: sha512-FHtCOXO9IpaGkg/dw3lBQc2EmEtUx6LXZ0th5vkL1+jwDQVh6kdfvVk7wqVfZsskdOZz3j34rGWEP8qWx9JF0A==} + engines: {node: '>=8.9'} + dependencies: + async: 2.6.4 + debug: 3.1.0 + strong-globalize: 4.1.3 + transitivePeerDependencies: + - supports-color + dev: true + + /loopback@3.28.0: + resolution: {integrity: sha512-txYAc2vUn2imOKqcxnRFTm7fLx6+dbZ+V/wfAME0kyOJVyuV56H8RPpHl9/LTpKyNYQuoedGYrl9bwSavXgKoQ==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + async: 2.6.4 + bcryptjs: 2.4.3 + bluebird: 3.7.2 + body-parser: 1.20.1 + canonical-json: 0.0.4 + debug: 2.6.9 + depd: 1.1.2 + ejs: 2.7.4 + express: 4.18.2 + inflection: 1.13.4 + isemail: 3.2.0 + loopback-connector-remote: 3.4.1 + loopback-datasource-juggler: 3.36.1 + loopback-filters: 1.1.1 + loopback-phase: 3.4.0 + nodemailer: 6.8.0 + nodemailer-direct-transport: 3.3.2 + nodemailer-stub-transport: 1.1.0 + serve-favicon: 2.5.0 + stable: 0.1.8 + strong-globalize: 4.1.3 + strong-remoting: 3.17.0 + uid2: 0.0.3 + underscore.string: 3.3.6 + transitivePeerDependencies: + - supports-color + dev: true + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /lower-case-first@1.0.2: + resolution: {integrity: sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==} + dependencies: + lower-case: 1.1.4 + dev: true + + /lower-case@1.1.4: + resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} + dev: true + + /lowercase-keys@1.0.0: + resolution: {integrity: sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==} + engines: {node: '>=0.10.0'} + dev: true + + /lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + dev: true + + /lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + dev: true + + /lru-cache@4.0.2: + resolution: {integrity: sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==} + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + dev: true + + /lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /lru-memoizer@2.1.4: + resolution: {integrity: sha512-IXAq50s4qwrOBrXJklY+KhgZF+5y98PDaNo0gi/v2KQBFLyWr+JyFvijZXkGKjQj/h9c0OwoE+JZbwUXce76hQ==} + dependencies: + lodash.clonedeep: 4.5.0 + lru-cache: 4.0.2 + dev: true + + /lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + dev: true + + /luxon@3.0.4: + resolution: {integrity: sha512-aV48rGUwP/Vydn8HT+5cdr26YYQiUZ42NM6ToMoaGKwYfWbfLeRkEu1wXWMHBZT6+KyLfcbbtVcoQFCbbPjKlw==} + engines: {node: '>=12'} + dev: true + + /magic-string@0.22.5: + resolution: {integrity: sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==} + dependencies: + vlq: 0.2.3 + dev: true + + /mailgun@0.5.0: + resolution: {integrity: sha512-g0qrj4RP7l3S6+9Fb7x0nTmRoR+oB1rm68iEuSg3IKJir67b9RE5kfsNyK3ZenVgDCLRCdtaheDiybjkSYeZRA==} + requiresBuild: true + dev: true + + /make-dir@1.3.0: + resolution: {integrity: sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==} + engines: {node: '>=4'} + dependencies: + pify: 3.0.0 + dev: true + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /make-fetch-happen@9.1.0: + resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} + engines: {node: '>= 10'} + requiresBuild: true + dependencies: + agentkeepalive: 4.2.1 + cacache: 15.3.0 + http-cache-semantics: 4.1.0 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 6.0.0 + minipass: 3.3.4 + minipass-collect: 1.0.2 + minipass-fetch: 1.4.1 + minipass-flush: 1.0.5 + minipass-pipeline: 1.2.4 + negotiator: 0.6.3 + promise-retry: 2.0.1 + socks-proxy-agent: 6.2.1 + ssri: 8.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + dev: true + optional: true + + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + + /map-age-cleaner@0.1.3: + resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} + engines: {node: '>=6'} + dependencies: + p-defer: 1.0.0 + dev: true + + /map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + dev: true + + /map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + dependencies: + object-visit: 1.0.1 + dev: true + + /mariadb@2.5.6: + resolution: {integrity: sha512-zBx7loYY5GzLl8Y6AKxGXfY9DUYIIdGrmEORPOK9FEu0pg5ZLBKCGJuucHwKADxTBxKY7eM4rxndqxRcnMZKIw==} + engines: {node: '>= 10.13'} + requiresBuild: true + dependencies: + '@types/geojson': 7946.0.10 + '@types/node': 17.0.45 + denque: 2.1.0 + iconv-lite: 0.6.3 + long: 5.2.0 + moment-timezone: 0.5.38 + please-upgrade-node: 3.2.0 + dev: true + + /markdown-extensions@1.1.1: + resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} + engines: {node: '>=0.10.0'} + dev: true + + /marky@1.2.5: + resolution: {integrity: sha512-q9JtQJKjpsVxCRVgQ+WapguSbKC3SQ5HEzFGPAJMStgh3QjCawp00UKv3MTTAArTmGmmPUvllHZoNbZ3gs0I+Q==} + dev: true + + /matched@0.4.4: + resolution: {integrity: sha512-zpasnbB5vQkvb0nfcKV0zEoGgMtV7atlWR1Vk3E8tEKh6EicMseKtVV+5vc+zsZwvDlcNMKlKK/CVOEeAalYRQ==} + engines: {node: '>= 0.12.0'} + dependencies: + arr-union: 3.1.0 + async-array-reduce: 0.2.1 + extend-shallow: 2.0.1 + fs-exists-sync: 0.1.0 + glob: 7.2.3 + has-glob: 0.1.1 + is-valid-glob: 0.3.0 + lazy-cache: 2.0.2 + resolve-dir: 0.1.1 + dev: true + + /md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /md5@2.3.0: + resolution: {integrity: sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==} + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + is-buffer: 1.1.6 + dev: true + + /mdast-util-definitions@5.1.1: + resolution: {integrity: sha512-rQ+Gv7mHttxHOBx2dkF4HWTg+EE+UR78ptQWDylzPKaQuVGdG4HIoY3SrS/pCp80nZ04greFvXbVFHT+uf0JVQ==} + dependencies: + '@types/mdast': 3.0.10 + '@types/unist': 2.0.6 + unist-util-visit: 4.1.1 + dev: true + + /mdast-util-from-markdown@1.2.0: + resolution: {integrity: sha512-iZJyyvKD1+K7QX1b5jXdE7Sc5dtoTry1vzV28UZZe8Z1xVnB/czKntJ7ZAkG0tANqRnBF6p3p7GpU1y19DTf2Q==} + dependencies: + '@types/mdast': 3.0.10 + '@types/unist': 2.0.6 + decode-named-character-reference: 1.0.2 + mdast-util-to-string: 3.1.0 + micromark: 3.1.0 + micromark-util-decode-numeric-character-reference: 1.0.0 + micromark-util-decode-string: 1.0.2 + micromark-util-normalize-identifier: 1.0.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + unist-util-stringify-position: 3.0.2 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-mdx-expression@1.3.1: + resolution: {integrity: sha512-TTb6cKyTA1RD+1su1iStZ5PAv3rFfOUKcoU5EstUpv/IZo63uDX03R8+jXjMEhcobXnNOiG6/ccekvVl4eV1zQ==} + dependencies: + '@types/estree-jsx': 1.0.0 + '@types/hast': 2.3.4 + '@types/mdast': 3.0.10 + mdast-util-from-markdown: 1.2.0 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-mdx-jsx@2.1.0: + resolution: {integrity: sha512-KzgzfWMhdteDkrY4mQtyvTU5bc/W4ppxhe9SzelO6QUUiwLAM+Et2Dnjjprik74a336kHdo0zKm7Tp+n6FFeRg==} + dependencies: + '@types/estree-jsx': 1.0.0 + '@types/hast': 2.3.4 + '@types/mdast': 3.0.10 + ccount: 2.0.1 + mdast-util-to-markdown: 1.5.0 + parse-entities: 4.0.0 + stringify-entities: 4.0.3 + unist-util-remove-position: 4.0.1 + unist-util-stringify-position: 3.0.2 + vfile-message: 3.1.2 + dev: true + + /mdast-util-mdx@2.0.0: + resolution: {integrity: sha512-M09lW0CcBT1VrJUaF/PYxemxxHa7SLDHdSn94Q9FhxjCQfuW7nMAWKWimTmA3OyDMSTH981NN1csW1X+HPSluw==} + dependencies: + mdast-util-mdx-expression: 1.3.1 + mdast-util-mdx-jsx: 2.1.0 + mdast-util-mdxjs-esm: 1.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-mdxjs-esm@1.3.0: + resolution: {integrity: sha512-7N5ihsOkAEGjFotIX9p/YPdl4TqUoMxL4ajNz7PbT89BqsdWJuBC9rvgt6wpbwTZqWWR0jKWqQbwsOWDBUZv4g==} + dependencies: + '@types/estree-jsx': 1.0.0 + '@types/hast': 2.3.4 + '@types/mdast': 3.0.10 + mdast-util-from-markdown: 1.2.0 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-phrasing@3.0.0: + resolution: {integrity: sha512-S+QYsDRLkGi8U7o5JF1agKa/sdP+CNGXXLqC17pdTVL8FHHgQEiwFGa9yE5aYtUxNiFGYoaDy9V1kC85Sz86Gg==} + dependencies: + '@types/mdast': 3.0.10 + unist-util-is: 5.1.1 + dev: true + + /mdast-util-to-hast@12.2.5: + resolution: {integrity: sha512-EFNhT35ZR/VZ85/EedDdCNTq0oFM+NM/+qBomVGQ0+Lcg0nhI8xIwmdCzNMlVlCJNXRprpobtKP/IUh8cfz6zQ==} + dependencies: + '@types/hast': 2.3.4 + '@types/mdast': 3.0.10 + mdast-util-definitions: 5.1.1 + micromark-util-sanitize-uri: 1.1.0 + trim-lines: 3.0.1 + unist-builder: 3.0.0 + unist-util-generated: 2.0.0 + unist-util-position: 4.0.3 + unist-util-visit: 4.1.1 + dev: true + + /mdast-util-to-markdown@1.5.0: + resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} + dependencies: + '@types/mdast': 3.0.10 + '@types/unist': 2.0.6 + longest-streak: 3.1.0 + mdast-util-phrasing: 3.0.0 + mdast-util-to-string: 3.1.0 + micromark-util-decode-string: 1.0.2 + unist-util-visit: 4.1.1 + zwitch: 2.0.4 + dev: true + + /mdast-util-to-string@3.1.0: + resolution: {integrity: sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA==} + dev: true + + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: true + + /mem@4.3.0: + resolution: {integrity: sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==} + engines: {node: '>=6'} + dependencies: + map-age-cleaner: 0.1.3 + mimic-fn: 2.1.0 + p-is-promise: 2.1.0 + dev: true + + /mem@5.1.1: + resolution: {integrity: sha512-qvwipnozMohxLXG1pOqoLiZKNkC4r4qqRucSoDwXowsNGDSULiqFTRUF05vcZWnwJSG22qTsynQhxbaMtnX9gw==} + engines: {node: '>=8'} + dependencies: + map-age-cleaner: 0.1.3 + mimic-fn: 2.1.0 + p-is-promise: 2.1.0 + dev: true + + /memcached@2.2.2: + resolution: {integrity: sha512-lHwUmqkT9WdUUgRsAvquO4xsKXYaBd644Orz31tuth+w/BIfFNuJMWwsG7sa7H3XXytaNfPTZ5R/yOG3d9zJMA==} + requiresBuild: true + dependencies: + hashring: 3.2.0 + jackpot: 0.0.6 + dev: true + + /memory-pager@1.5.0: + resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==} + dev: true + + /merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + dev: true + + /merge-source-map@1.0.4: + resolution: {integrity: sha512-PGSmS0kfnTnMJCzJ16BLLCEe6oeYCamKFFdQKshi4BmM6FUwipjVOcBFGxqtQtirtAG4iZvHlqST9CpZKqlRjA==} + dependencies: + source-map: 0.5.7 + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /metaviewport-parser@0.2.0: + resolution: {integrity: sha512-qL5NtY18LGs7lvZCkj3ep2H4Pes9rIiSLZRUyfDdvVw7pWFA0eLwmqaIxApD74RGvUrNEtk9e5Wt1rT+VlCvGw==} + dev: true + + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: true + + /micromark-core-commonmark@1.0.6: + resolution: {integrity: sha512-K+PkJTxqjFfSNkfAhp4GB+cZPfQd6dxtTXnf+RjZOV7T4EEXnvgzOcnp+eSTmpGk9d1S9sL6/lqrgSNn/s0HZA==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-factory-destination: 1.0.0 + micromark-factory-label: 1.0.2 + micromark-factory-space: 1.0.0 + micromark-factory-title: 1.0.2 + micromark-factory-whitespace: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-chunked: 1.0.0 + micromark-util-classify-character: 1.0.0 + micromark-util-html-tag-name: 1.1.0 + micromark-util-normalize-identifier: 1.0.0 + micromark-util-resolve-all: 1.0.0 + micromark-util-subtokenize: 1.0.2 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: true + + /micromark-extension-mdx-expression@1.0.3: + resolution: {integrity: sha512-TjYtjEMszWze51NJCZmhv7MEBcgYRgb3tJeMAJ+HQCAaZHHRBaDCccqQzGizR/H4ODefP44wRTgOn2vE5I6nZA==} + dependencies: + micromark-factory-mdx-expression: 1.0.6 + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-events-to-acorn: 1.2.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: true + + /micromark-extension-mdx-jsx@1.0.3: + resolution: {integrity: sha512-VfA369RdqUISF0qGgv2FfV7gGjHDfn9+Qfiv5hEwpyr1xscRj/CiVRkU7rywGFCO7JwJ5L0e7CJz60lY52+qOA==} + dependencies: + '@types/acorn': 4.0.6 + estree-util-is-identifier-name: 2.0.1 + micromark-factory-mdx-expression: 1.0.6 + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + vfile-message: 3.1.2 + dev: true + + /micromark-extension-mdx-md@1.0.0: + resolution: {integrity: sha512-xaRAMoSkKdqZXDAoSgp20Azm0aRQKGOl0RrS81yGu8Hr/JhMsBmfs4wR7m9kgVUIO36cMUQjNyiyDKPrsv8gOw==} + dependencies: + micromark-util-types: 1.0.2 + dev: true + + /micromark-extension-mdxjs-esm@1.0.3: + resolution: {integrity: sha512-2N13ol4KMoxb85rdDwTAC6uzs8lMX0zeqpcyx7FhS7PxXomOnLactu8WI8iBNXW8AVyea3KIJd/1CKnUmwrK9A==} + dependencies: + micromark-core-commonmark: 1.0.6 + micromark-util-character: 1.1.0 + micromark-util-events-to-acorn: 1.2.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + unist-util-position-from-estree: 1.1.1 + uvu: 0.5.6 + vfile-message: 3.1.2 + dev: true + + /micromark-extension-mdxjs@1.0.0: + resolution: {integrity: sha512-TZZRZgeHvtgm+IhtgC2+uDMR7h8eTKF0QUX9YsgoL9+bADBpBY6SiLvWqnBlLbCEevITmTqmEuY3FoxMKVs1rQ==} + dependencies: + acorn: 8.8.1 + acorn-jsx: 5.3.2(acorn@8.8.1) + micromark-extension-mdx-expression: 1.0.3 + micromark-extension-mdx-jsx: 1.0.3 + micromark-extension-mdx-md: 1.0.0 + micromark-extension-mdxjs-esm: 1.0.3 + micromark-util-combine-extensions: 1.0.0 + micromark-util-types: 1.0.2 + dev: true + + /micromark-factory-destination@1.0.0: + resolution: {integrity: sha512-eUBA7Rs1/xtTVun9TmV3gjfPz2wEwgK5R5xcbIM5ZYAtvGF6JkyaDsj0agx8urXnO31tEO6Ug83iVH3tdedLnw==} + dependencies: + micromark-util-character: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + dev: true + + /micromark-factory-label@1.0.2: + resolution: {integrity: sha512-CTIwxlOnU7dEshXDQ+dsr2n+yxpP0+fn271pu0bwDIS8uqfFcumXpj5mLn3hSC8iw2MUr6Gx8EcKng1dD7i6hg==} + dependencies: + micromark-util-character: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: true + + /micromark-factory-mdx-expression@1.0.6: + resolution: {integrity: sha512-WRQIc78FV7KrCfjsEf/sETopbYjElh3xAmNpLkd1ODPqxEngP42eVRGbiPEQWpRV27LzqW+XVTvQAMIIRLPnNA==} + dependencies: + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-events-to-acorn: 1.2.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + unist-util-position-from-estree: 1.1.1 + uvu: 0.5.6 + vfile-message: 3.1.2 + dev: true + + /micromark-factory-space@1.0.0: + resolution: {integrity: sha512-qUmqs4kj9a5yBnk3JMLyjtWYN6Mzfcx8uJfi5XAveBniDevmZasdGBba5b4QsvRcAkmvGo5ACmSUmyGiKTLZew==} + dependencies: + micromark-util-character: 1.1.0 + micromark-util-types: 1.0.2 + dev: true + + /micromark-factory-title@1.0.2: + resolution: {integrity: sha512-zily+Nr4yFqgMGRKLpTVsNl5L4PMu485fGFDOQJQBl2NFpjGte1e86zC0da93wf97jrc4+2G2GQudFMHn3IX+A==} + dependencies: + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: true + + /micromark-factory-whitespace@1.0.0: + resolution: {integrity: sha512-Qx7uEyahU1lt1RnsECBiuEbfr9INjQTGa6Err+gF3g0Tx4YEviPbqqGKNv/NrBaE7dVHdn1bVZKM/n5I/Bak7A==} + dependencies: + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + dev: true + + /micromark-util-character@1.1.0: + resolution: {integrity: sha512-agJ5B3unGNJ9rJvADMJ5ZiYjBRyDpzKAOk01Kpi1TKhlT1APx3XZk6eN7RtSz1erbWHC2L8T3xLZ81wdtGRZzg==} + dependencies: + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + dev: true + + /micromark-util-chunked@1.0.0: + resolution: {integrity: sha512-5e8xTis5tEZKgesfbQMKRCyzvffRRUX+lK/y+DvsMFdabAicPkkZV6gO+FEWi9RfuKKoxxPwNL+dFF0SMImc1g==} + dependencies: + micromark-util-symbol: 1.0.1 + dev: true + + /micromark-util-classify-character@1.0.0: + resolution: {integrity: sha512-F8oW2KKrQRb3vS5ud5HIqBVkCqQi224Nm55o5wYLzY/9PwHGXC01tr3d7+TqHHz6zrKQ72Okwtvm/xQm6OVNZA==} + dependencies: + micromark-util-character: 1.1.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + dev: true + + /micromark-util-combine-extensions@1.0.0: + resolution: {integrity: sha512-J8H058vFBdo/6+AsjHp2NF7AJ02SZtWaVUjsayNFeAiydTxUwViQPxN0Hf8dp4FmCQi0UUFovFsEyRSUmFH3MA==} + dependencies: + micromark-util-chunked: 1.0.0 + micromark-util-types: 1.0.2 + dev: true + + /micromark-util-decode-numeric-character-reference@1.0.0: + resolution: {integrity: sha512-OzO9AI5VUtrTD7KSdagf4MWgHMtET17Ua1fIpXTpuhclCqD8egFWo85GxSGvxgkGS74bEahvtM0WP0HjvV0e4w==} + dependencies: + micromark-util-symbol: 1.0.1 + dev: true + + /micromark-util-decode-string@1.0.2: + resolution: {integrity: sha512-DLT5Ho02qr6QWVNYbRZ3RYOSSWWFuH3tJexd3dgN1odEuPNxCngTCXJum7+ViRAd9BbdxCvMToPOD/IvVhzG6Q==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 1.1.0 + micromark-util-decode-numeric-character-reference: 1.0.0 + micromark-util-symbol: 1.0.1 + dev: true + + /micromark-util-encode@1.0.1: + resolution: {integrity: sha512-U2s5YdnAYexjKDel31SVMPbfi+eF8y1U4pfiRW/Y8EFVCy/vgxk/2wWTxzcqE71LHtCuCzlBDRU2a5CQ5j+mQA==} + dev: true + + /micromark-util-events-to-acorn@1.2.0: + resolution: {integrity: sha512-WWp3bf7xT9MppNuw3yPjpnOxa8cj5ACivEzXJKu0WwnjBYfzaBvIAT9KfeyI0Qkll+bfQtfftSwdgTH6QhTOKw==} + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.0 + estree-util-visit: 1.2.0 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + vfile-location: 4.0.1 + vfile-message: 3.1.2 + dev: true + + /micromark-util-html-tag-name@1.1.0: + resolution: {integrity: sha512-BKlClMmYROy9UiV03SwNmckkjn8QHVaWkqoAqzivabvdGcwNGMMMH/5szAnywmsTBUzDsU57/mFi0sp4BQO6dA==} + dev: true + + /micromark-util-normalize-identifier@1.0.0: + resolution: {integrity: sha512-yg+zrL14bBTFrQ7n35CmByWUTFsgst5JhA4gJYoty4Dqzj4Z4Fr/DHekSS5aLfH9bdlfnSvKAWsAgJhIbogyBg==} + dependencies: + micromark-util-symbol: 1.0.1 + dev: true + + /micromark-util-resolve-all@1.0.0: + resolution: {integrity: sha512-CB/AGk98u50k42kvgaMM94wzBqozSzDDaonKU7P7jwQIuH2RU0TeBqGYJz2WY1UdihhjweivStrJ2JdkdEmcfw==} + dependencies: + micromark-util-types: 1.0.2 + dev: true + + /micromark-util-sanitize-uri@1.1.0: + resolution: {integrity: sha512-RoxtuSCX6sUNtxhbmsEFQfWzs8VN7cTctmBPvYivo98xb/kDEoTCtJQX5wyzIYEmk/lvNFTat4hL8oW0KndFpg==} + dependencies: + micromark-util-character: 1.1.0 + micromark-util-encode: 1.0.1 + micromark-util-symbol: 1.0.1 + dev: true + + /micromark-util-subtokenize@1.0.2: + resolution: {integrity: sha512-d90uqCnXp/cy4G881Ub4psE57Sf8YD0pim9QdjCRNjfas2M1u6Lbt+XZK9gnHL2XFhnozZiEdCa9CNfXSfQ6xA==} + dependencies: + micromark-util-chunked: 1.0.0 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + dev: true + + /micromark-util-symbol@1.0.1: + resolution: {integrity: sha512-oKDEMK2u5qqAptasDAwWDXq0tG9AssVwAx3E9bBF3t/shRIGsWIRG+cGafs2p/SnDSOecnt6hZPCE2o6lHfFmQ==} + dev: true + + /micromark-util-types@1.0.2: + resolution: {integrity: sha512-DCfg/T8fcrhrRKTPjRrw/5LLvdGV7BHySf/1LOZx7TzWZdYRjogNtyNq885z3nNallwr3QUKARjqvHqX1/7t+w==} + dev: true + + /micromark@3.1.0: + resolution: {integrity: sha512-6Mj0yHLdUZjHnOPgr5xfWIMqMWS12zDN6iws9SLuSz76W8jTtAv24MN4/CL7gJrl5vtxGInkkqDv/JIoRsQOvA==} + dependencies: + '@types/debug': 4.1.7 + debug: 4.3.4 + decode-named-character-reference: 1.0.2 + micromark-core-commonmark: 1.0.6 + micromark-factory-space: 1.0.0 + micromark-util-character: 1.1.0 + micromark-util-chunked: 1.0.0 + micromark-util-combine-extensions: 1.0.0 + micromark-util-decode-numeric-character-reference: 1.0.0 + micromark-util-encode: 1.0.1 + micromark-util-normalize-identifier: 1.0.0 + micromark-util-resolve-all: 1.0.0 + micromark-util-sanitize-uri: 1.1.0 + micromark-util-subtokenize: 1.0.2 + micromark-util-symbol: 1.0.1 + micromark-util-types: 1.0.2 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + dev: true + + /micromatch@3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + dev: true + + /mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + dev: true + + /mimic-response@2.1.0: + resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==} + engines: {node: '>=8'} + dev: true + + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: true + + /min-document@2.19.0: + resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} + dependencies: + dom-walk: 0.1.2 + dev: true + + /minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + dev: true + + /minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@5.1.0: + resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@0.0.10: + resolution: {integrity: sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==} + dev: true + + /minimist@0.0.8: + resolution: {integrity: sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==} + dev: true + + /minimist@1.2.7: + resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + dev: true + + /minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + requiresBuild: true + dependencies: + minipass: 3.3.4 + dev: true + optional: true + + /minipass-fetch@1.4.1: + resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + minipass: 3.3.4 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + dev: true + optional: true + + /minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + requiresBuild: true + dependencies: + minipass: 3.3.4 + dev: true + optional: true + + /minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + minipass: 3.3.4 + dev: true + optional: true + + /minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + minipass: 3.3.4 + dev: true + optional: true + + /minipass@3.3.4: + resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.4 + yallist: 4.0.0 + dev: true + + /mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + dev: true + + /mixto@1.0.0: + resolution: {integrity: sha512-g2Kg8O3ww9RbWuPnAgTsAhe+aBwVXoo/lhYyDKTYPiLKdJofAr97O8zTFzW5UfiJUoeJbmXLmcjDAF7/Egwi8Q==} + dev: true + + /mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: true + + /mkdirp@0.5.1: + resolution: {integrity: sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==} + deprecated: Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.) + hasBin: true + dependencies: + minimist: 0.0.8 + dev: true + + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.7 + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /mnemonist@0.32.0: + resolution: {integrity: sha512-WMVGPpT8guWwnsnw+WibOvInBnPfXFG+9SD+mg2+YgPEuW9Gdz9D2MEi05ko6RG1ui0RHljc+yYAvOHQn3GbbQ==} + dependencies: + obliterator: 1.6.1 + dev: true + + /module-deps@6.2.3: + resolution: {integrity: sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA==} + engines: {node: '>= 0.8.0'} + hasBin: true + dependencies: + JSONStream: 1.3.5 + browser-resolve: 2.0.0 + cached-path-relative: 1.1.0 + concat-stream: 1.6.2 + defined: 1.0.1 + detective: 5.2.1 + duplexer2: 0.1.4 + inherits: 2.0.4 + parents: 1.0.1 + readable-stream: 2.3.7 + resolve: 1.22.1 + stream-combiner2: 1.1.1 + subarg: 1.0.0 + through2: 2.0.5 + xtend: 4.0.2 + dev: true + + /moment-timezone@0.5.38: + resolution: {integrity: sha512-nMIrzGah4+oYZPflDvLZUgoVUO4fvAqHstvG3xAUnMolWncuAiLDWNnJZj6EwJGMGfb1ZcuTFE6GI3hNOVWI/Q==} + dependencies: + moment: 2.29.4 + dev: true + + /moment@2.29.4: + resolution: {integrity: sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==} + dev: true + + /mongodb@3.7.3: + resolution: {integrity: sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw==} + engines: {node: '>=4'} + peerDependencies: + aws4: '*' + bson-ext: '*' + kerberos: '*' + mongodb-client-encryption: '*' + mongodb-extjson: '*' + snappy: '*' + peerDependenciesMeta: + aws4: + optional: true + bson-ext: + optional: true + kerberos: + optional: true + mongodb-client-encryption: + optional: true + mongodb-extjson: + optional: true + snappy: + optional: true + dependencies: + bl: 2.2.1 + bson: 1.1.6 + denque: 1.5.1 + optional-require: 1.1.8 + safe-buffer: 5.2.1 + optionalDependencies: + saslprep: 1.0.3 + dev: true + + /mongoose-legacy-pluralize@1.0.2(mongoose@5.13.15): + resolution: {integrity: sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ==} + peerDependencies: + mongoose: '*' + dependencies: + mongoose: 5.13.15 + dev: true + + /mongoose@5.13.15: + resolution: {integrity: sha512-cxp1Gbb8yUWkaEbajdhspSaKzAvsIvOtRlYD87GN/P2QEUhpd6bIvebi36T6M0tIVAMauNaK9SPA055N3PwF8Q==} + engines: {node: '>=4.0.0'} + requiresBuild: true + dependencies: + '@types/bson': 4.0.5 + '@types/mongodb': 3.6.20 + bson: 1.1.6 + kareem: 2.3.2 + mongodb: 3.7.3 + mongoose-legacy-pluralize: 1.0.2(mongoose@5.13.15) + mpath: 0.8.4 + mquery: 3.2.5 + ms: 2.1.2 + optional-require: 1.0.3 + regexp-clone: 1.0.0 + safe-buffer: 5.2.1 + sift: 13.5.2 + sliced: 1.0.1 + transitivePeerDependencies: + - aws4 + - bson-ext + - kerberos + - mongodb-client-encryption + - mongodb-extjson + - snappy + - supports-color + dev: true + + /mpath@0.8.4: + resolution: {integrity: sha512-DTxNZomBcTWlrMW76jy1wvV37X/cNNxPW1y2Jzd4DZkAaC5ZGsm8bfGfNOthcDuRJujXLqiuS6o3Tpy0JEoh7g==} + engines: {node: '>=4.0.0'} + dev: true + + /mqtt-packet@5.6.1: + resolution: {integrity: sha512-eaF9rO2uFrIYEHomJxziuKTDkbWW5psLBaIGCazQSKqYsTaB3n4SpvJ1PexKaDBiPnMLPIFWBIiTYT3IfEJfww==} + dependencies: + bl: 1.2.3 + inherits: 2.0.4 + process-nextick-args: 2.0.1 + safe-buffer: 5.2.1 + dev: true + + /mqtt@2.18.9: + resolution: {integrity: sha512-ufywki8VAQ8YAERiunbj77TnXgaeVYVlyebnj4o9vhPUQFRjo+d3oUf0rft8kWi7YPYf4O8rkwPkeFc7ndWESg==} + engines: {node: '>=4.0.0'} + hasBin: true + dependencies: + commist: 1.1.0 + concat-stream: 1.6.2 + duplexify: 4.1.2 + end-of-stream: 1.4.4 + es6-map: 0.1.5 + help-me: 1.1.0 + inherits: 2.0.4 + minimist: 1.2.7 + mqtt-packet: 5.6.1 + pump: 3.0.0 + readable-stream: 2.3.7 + reinterval: 1.1.0 + split2: 2.2.0 + websocket-stream: 5.2.0 + xtend: 4.0.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + + /mquery@3.2.5: + resolution: {integrity: sha512-VjOKHHgU84wij7IUoZzFRU07IAxd5kWJaDmyUzQlbjHjyoeK5TNeeo8ZsFDtTYnSgpW6n/nMNIHvE3u8Lbrf4A==} + engines: {node: '>=4.0.0'} + dependencies: + bluebird: 3.5.1 + debug: 3.1.0 + regexp-clone: 1.0.0 + safe-buffer: 5.1.2 + sliced: 1.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms@2.1.1: + resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /msgpack-js@0.3.0: + resolution: {integrity: sha512-dBIO+q0IAtZMeTn8K1gr0NuM0OvXEV97NwFsJQKzJ/qkQI9d5MN7Vc++TAUkIxaoIMJyIgMByOAwoJO2wdYDrA==} + dependencies: + bops: 0.0.7 + dev: true + + /msgpack-stream@0.0.13: + resolution: {integrity: sha512-Wh+t8IJrHPzSjph4wKJhenKG8vvtT0RDebLf1k1RSuRNOJ7caLFvwDnkyiihhZ5QJJmSg0KpjvqtDj9FvvWHWg==} + dependencies: + bops: 1.0.0 + msgpack-js: 0.3.0 + through: 2.3.4 + dev: true + + /msgpack5@4.5.1: + resolution: {integrity: sha512-zC1vkcliryc4JGlL6OfpHumSYUHWFGimSI+OgfRCjTFLmKA2/foR9rMTOhWiqfOrfxJOctrpWPvrppf8XynJxw==} + dependencies: + bl: 2.2.1 + inherits: 2.0.4 + readable-stream: 2.3.7 + safe-buffer: 5.2.1 + dev: true + + /msgpackr-extract@2.2.0: + resolution: {integrity: sha512-0YcvWSv7ZOGl9Od6Y5iJ3XnPww8O7WLcpYMDwX+PAA/uXLDtyw94PJv9GLQV/nnp3cWlDhMoyKZIQLrx33sWog==} + hasBin: true + requiresBuild: true + dependencies: + node-gyp-build-optional-packages: 5.0.3 + optionalDependencies: + '@msgpackr-extract/msgpackr-extract-darwin-arm64': 2.2.0 + '@msgpackr-extract/msgpackr-extract-darwin-x64': 2.2.0 + '@msgpackr-extract/msgpackr-extract-linux-arm': 2.2.0 + '@msgpackr-extract/msgpackr-extract-linux-arm64': 2.2.0 + '@msgpackr-extract/msgpackr-extract-linux-x64': 2.2.0 + '@msgpackr-extract/msgpackr-extract-win32-x64': 2.2.0 + dev: true + optional: true + + /msgpackr@1.7.2: + resolution: {integrity: sha512-mWScyHTtG6TjivXX9vfIy2nBtRupaiAj0HQ2mtmpmYujAmqZmaaEVPaSZ1NKLMvicaMLFzEaMk0ManxMRg8rMQ==} + optionalDependencies: + msgpackr-extract: 2.2.0 + dev: true + + /mutationobserver-shim@0.3.7: + resolution: {integrity: sha512-oRIDTyZQU96nAiz2AQyngwx1e89iApl2hN5AOYwyxLUB47UYsU3Wv9lJWqH5y/QdiYkc5HQLi23ZNB3fELdHcQ==} + dev: true + + /mute-stream@0.0.7: + resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} + dev: true + + /mux-demux@3.7.9: + resolution: {integrity: sha512-zf+kqfl+e/U+0MSqJwUg+Wzbyxucf8YK6Sxyzy94gzS6ichxcEV2mUpXD7hPhCTKAVpX6s00ihYbJC/aH8gxwA==} + dependencies: + duplex: 1.0.0 + json-buffer: 2.0.11 + msgpack-stream: 0.0.13 + stream-combiner: 0.0.2 + stream-serializer: 1.1.2 + through: 2.3.8 + xtend: 1.0.3 + dev: true + + /mysql@2.18.1: + resolution: {integrity: sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig==} + engines: {node: '>= 0.6'} + requiresBuild: true + dependencies: + bignumber.js: 9.0.0 + readable-stream: 2.3.7 + safe-buffer: 5.1.2 + sqlstring: 2.3.1 + dev: true + + /n3@1.16.2: + resolution: {integrity: sha512-5vYa2HuNEJ+a26FEs4FGgfFLgaPOODaZpJlc7FS0eUjDumc4uK0cvx216PjKXBkLzmAsSqGgQPwqztcLLvwDsw==} + engines: {node: '>=8.0'} + dependencies: + queue-microtask: 1.2.3 + readable-stream: 3.6.0 + dev: true + + /nan@2.17.0: + resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==} + dev: true + + /nanoid@2.1.11: + resolution: {integrity: sha512-s/snB+WGm6uwi0WjsZdaVcuf3KJXlfGl2LcxgwkEwJF0D/BWzVWAZW/XY4bFaiR7s0Jk3FPvlnepg1H1b1UwlA==} + dev: true + + /nanoid@3.3.4: + resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /napi-build-utils@1.0.2: + resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} + dev: true + + /napi-macros@2.0.0: + resolution: {integrity: sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: true + + /next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + dev: true + + /nice-napi@1.0.2: + resolution: {integrity: sha512-px/KnJAJZf5RuBGcfD+Sp2pAKq0ytz8j+1NehvgIGFkvtvFrDM3T8E4x/JJODXK9WZow8RRGrbA9QQ3hs+pDhA==} + os: ['!win32'] + requiresBuild: true + dependencies: + node-addon-api: 3.2.1 + node-gyp-build: 4.5.0 + dev: true + optional: true + + /nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + dev: true + + /node-abi@3.28.0: + resolution: {integrity: sha512-fRlDb4I0eLcQeUvGq7IY3xHrSb0c9ummdvDSYWfT9+LKP+3jCKw/tKoqaM7r1BAoiAC6GtwyjaGnOz6B3OtF+A==} + engines: {node: '>=10'} + dependencies: + semver: 7.3.8 + dev: true + + /node-addon-api@3.2.1: + resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + dev: true + + /node-addon-api@4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + dev: true + + /node-addon-api@5.0.0: + resolution: {integrity: sha512-CvkDw2OEnme7ybCykJpVcKH+uAOLV2qLqiyla128dN9TkEWfrYmxG6C2boDe5KcNQqZF3orkqzGgOMvZ/JNekA==} + dev: true + + /node-fetch@2.6.1: + resolution: {integrity: sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==} + engines: {node: 4.x || >=6.0.0} + dev: true + + /node-fetch@2.6.12: + resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-forge@0.10.0: + resolution: {integrity: sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==} + engines: {node: '>= 6.0.0'} + dev: true + + /node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + requiresBuild: true + dev: true + + /node-gyp-build-optional-packages@5.0.3: + resolution: {integrity: sha512-k75jcVzk5wnnc/FMxsf4udAoTEUv2jY3ycfdSd3yWu6Cnd1oee6/CfZJApyscA4FJOmdoixWwiwOyf16RzD5JA==} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /node-gyp-build@4.1.1: + resolution: {integrity: sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==} + hasBin: true + dev: true + + /node-gyp-build@4.5.0: + resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} + hasBin: true + dev: true + + /node-gyp@8.4.1: + resolution: {integrity: sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==} + engines: {node: '>= 10.12.0'} + hasBin: true + requiresBuild: true + dependencies: + env-paths: 2.2.1 + glob: 7.2.3 + graceful-fs: 4.2.10 + make-fetch-happen: 9.1.0 + nopt: 5.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.3.8 + tar: 6.1.11 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + dev: true + optional: true + + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + + /node-releases@2.0.6: + resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} + dev: true + + /nodeify-fetch@2.2.2: + resolution: {integrity: sha512-4b1Jysy9RGyya0wJpseTQyxUgSbx6kw9ocHTY0OFRXWlxa2Uy5PrSo/P/nwoUn59rBR9YKty2kd7g4LKXmsZVA==} + dependencies: + '@zazuko/node-fetch': 2.6.6 + concat-stream: 1.6.2 + cross-fetch: 3.1.8 + readable-error: 1.0.0 + readable-stream: 3.6.2 + transitivePeerDependencies: + - encoding + dev: true + + /nodemailer-direct-transport@3.3.2: + resolution: {integrity: sha512-vEMLWdUZP9NpbeabM8VTiB3Ar1R0ixASp/6DdKX372LK4USKB4Lq12/WCp69k/+kWk4RiCWWEGo57CcsXOs/bw==} + dependencies: + nodemailer-shared: 1.1.0 + smtp-connection: 2.12.0 + dev: true + + /nodemailer-fetch@1.6.0: + resolution: {integrity: sha512-P7S5CEVGAmDrrpn351aXOLYs1R/7fD5NamfMCHyi6WIkbjS2eeZUB/TkuvpOQr0bvRZicVqo59+8wbhR3yrJbQ==} + dev: true + + /nodemailer-shared@1.1.0: + resolution: {integrity: sha512-68xW5LSyPWv8R0GLm6veAvm7E+XFXkVgvE3FW0FGxNMMZqMkPFeGDVALfR1DPdSfcoO36PnW7q5AAOgFImEZGg==} + dependencies: + nodemailer-fetch: 1.6.0 + dev: true + + /nodemailer-stub-transport@1.1.0: + resolution: {integrity: sha512-4fwl2f+647IIyuNuf6wuEMqK4oEU9FMJSYme8kPckVSr1rXIXcmI6BNcIWO+1cAK8XeexYKxYoFztam0jAwjkA==} + dev: true + + /nodemailer@6.8.0: + resolution: {integrity: sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ==} + engines: {node: '>=6.0.0'} + dev: true + + /nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + dependencies: + remove-trailing-separator: 1.1.0 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-url@2.0.1: + resolution: {integrity: sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==} + engines: {node: '>=4'} + dependencies: + prepend-http: 2.0.0 + query-string: 5.1.1 + sort-keys: 2.0.0 + dev: true + + /normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + dev: true + + /notate@1.1.2: + resolution: {integrity: sha512-87c1SbFP7TvHk1gdc1ZRTk+0wr+1VbKC6Nm3cW7xqHjEyU0eY27fOHjJnWmxFkgSkQF/kaLj9PfvtUh13GjHMQ==} + dev: true + + /npm-run-path@2.0.2: + resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} + engines: {node: '>=4'} + dependencies: + path-key: 2.0.1 + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /npm@6.14.17: + resolution: {integrity: sha512-CxEDn1ydVRPDl4tHrlnq+WevYAhv4GF2AEHzJKQ4prZDZ96IS3Uo6t0Sy6O9kB6XzqkI+J00WfYCqqk0p6IJ1Q==} + engines: {node: 6 >=6.2.0 || 8 || >=9.3.0} + hasBin: true + requiresBuild: true + dev: true + bundledDependencies: + - abbrev + - ansicolors + - ansistyles + - aproba + - archy + - bin-links + - bluebird + - byte-size + - cacache + - call-limit + - chownr + - ci-info + - cli-columns + - cli-table3 + - cmd-shim + - columnify + - config-chain + - debuglog + - detect-indent + - detect-newline + - dezalgo + - editor + - figgy-pudding + - find-npm-prefix + - fs-vacuum + - fs-write-stream-atomic + - gentle-fs + - glob + - graceful-fs + - has-unicode + - hosted-git-info + - iferr + - imurmurhash + - infer-owner + - inflight + - inherits + - ini + - init-package-json + - is-cidr + - json-parse-better-errors + - JSONStream + - lazy-property + - libcipm + - libnpm + - libnpmaccess + - libnpmhook + - libnpmorg + - libnpmsearch + - libnpmteam + - libnpx + - lock-verify + - lockfile + - lodash._baseindexof + - lodash._baseuniq + - lodash._bindcallback + - lodash._cacheindexof + - lodash._createcache + - lodash._getnative + - lodash.clonedeep + - lodash.restparam + - lodash.union + - lodash.uniq + - lodash.without + - lru-cache + - meant + - mississippi + - mkdirp + - move-concurrently + - node-gyp + - nopt + - normalize-package-data + - npm-audit-report + - npm-cache-filename + - npm-install-checks + - npm-lifecycle + - npm-package-arg + - npm-packlist + - npm-pick-manifest + - npm-profile + - npm-registry-fetch + - npm-user-validate + - npmlog + - once + - opener + - osenv + - pacote + - path-is-inside + - promise-inflight + - qrcode-terminal + - query-string + - qw + - read-cmd-shim + - read-installed + - read-package-json + - read-package-tree + - read + - readable-stream + - readdir-scoped-modules + - request + - retry + - rimraf + - safe-buffer + - semver + - sha + - slide + - sorted-object + - sorted-union-stream + - ssri + - stringify-package + - tar + - text-table + - tiny-relative-date + - uid-number + - umask + - unique-filename + - unpipe + - update-notifier + - uuid + - validate-npm-package-license + - validate-npm-package-name + - which + - worker-farm + - write-file-atomic + + /npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: true + + /npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + requiresBuild: true + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + dev: true + optional: true + + /number-is-nan@1.0.1: + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} + engines: {node: '>=0.10.0'} + dev: true + + /nwsapi@2.2.2: + resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} + dev: true + + /oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + dev: true + + /oauth@0.9.15: + resolution: {integrity: sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA==} + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + dev: true + + /object-hash@3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: true + + /object-inspect@1.12.2: + resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} + dev: true + + /object-inspect@1.4.1: + resolution: {integrity: sha512-wqdhLpfCUbEsoEwl3FXwGyv8ief1k/1aUdIPCqVnupM6e8l63BEJdiF/0swtn04/8p05tG/T0FrpTlfwvljOdw==} + dev: true + + /object-is@1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object-path@0.11.8: + resolution: {integrity: sha512-YJjNZrlXJFM42wTBn6zgOJVar9KFJvzx6sTWDte8sWZF//cnjl0BxHNpfZx+ZffXX63A9q0b1zsFiBX4g4X5KA==} + engines: {node: '>= 10.12.0'} + dev: true + + /object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.getownpropertydescriptors@2.1.4: + resolution: {integrity: sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==} + engines: {node: '>= 0.8'} + dependencies: + array.prototype.reduce: 1.0.4 + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /obliterator@1.6.1: + resolution: {integrity: sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==} + dev: true + + /omggif@1.0.10: + resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==} + dev: true + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@2.0.1: + resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} + engines: {node: '>=4'} + dependencies: + mimic-fn: 1.2.0 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /oniguruma@7.2.3: + resolution: {integrity: sha512-PZZcE0yfg8Q1IvaJImh21RUTHl8ep0zwwyoE912KqlWVrsGByjjj29sdACcD1BFyX2bLkfuOJeP+POzAGVWtbA==} + requiresBuild: true + dependencies: + nan: 2.17.0 + dev: true + + /only@0.0.2: + resolution: {integrity: sha512-Fvw+Jemq5fjjyWz6CpKx6w9s7xxqo3+JCyM0WXWeCSOboZ8ABkyvP8ID4CZuChA/wxSx+XSJmdOm8rGVyJ1hdQ==} + dev: true + + /open@6.4.0: + resolution: {integrity: sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==} + engines: {node: '>=8'} + dependencies: + is-wsl: 1.1.0 + dev: true + + /opencollective-postinstall@2.0.3: + resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==} + hasBin: true + dev: true + + /optimist@0.6.1: + resolution: {integrity: sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==} + dependencies: + minimist: 0.0.10 + wordwrap: 0.0.3 + dev: true + + /optional-require@1.0.3: + resolution: {integrity: sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==} + engines: {node: '>=4'} + dev: true + + /optional-require@1.1.8: + resolution: {integrity: sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==} + engines: {node: '>=4'} + dependencies: + require-at: 1.0.6 + dev: true + + /optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.3 + dev: true + + /options@0.0.6: + resolution: {integrity: sha512-bOj3L1ypm++N+n7CEbbe473A414AB7z+amKYshRb//iuL3MpdDCLhPnw6aVTdKB9g5ZRVHIEp8eUln6L2NUStg==} + engines: {node: '>=0.4.0'} + dev: true + + /oracledb@4.2.0: + resolution: {integrity: sha512-07ZylNcUB9wknsiRa7dNqDWgGK3loP8eNWuoCjsiCOZ19PA1g8QLu+0gah7ty82VXl/MOQYFCMl5OpjD9Aqjcw==} + engines: {node: '>=8.16'} + deprecated: Update to node-oracledb 5 + requiresBuild: true + dev: false + optional: true + + /ordered-read-streams@1.0.1: + resolution: {integrity: sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==} + dependencies: + readable-stream: 2.3.7 + dev: true + + /os-browserify@0.3.0: + resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} + dev: true + + /os-homedir@1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + dev: true + + /os-locale@1.4.0: + resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} + engines: {node: '>=0.10.0'} + dependencies: + lcid: 1.0.0 + dev: true + + /os-locale@3.1.0: + resolution: {integrity: sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==} + engines: {node: '>=6'} + dependencies: + execa: 1.0.0 + lcid: 2.0.0 + mem: 4.3.0 + dev: true + + /os-locale@5.0.0: + resolution: {integrity: sha512-tqZcNEDAIZKBEPnHPlVDvKrp7NzgLi7jRmhKiUoa2NUmhl13FtkAGLUVR+ZsYvApBQdBfYm43A4tXXQ4IrYLBA==} + engines: {node: '>=10'} + dependencies: + execa: 4.1.0 + lcid: 3.1.1 + mem: 5.1.1 + dev: true + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /outpipe@1.1.1: + resolution: {integrity: sha512-BnNY/RwnDrkmQdUa9U+OfN/Y7AWmKuUPCCd+hbRclZnnANvYpO72zp/a6Q4n829hPbdqEac31XCcsvlEvb+rtA==} + dependencies: + shell-quote: 1.7.4 + dev: true + + /p-cancelable@0.4.1: + resolution: {integrity: sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==} + engines: {node: '>=4'} + dev: true + + /p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + dev: true + + /p-defer@1.0.0: + resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} + engines: {node: '>=4'} + dev: true + + /p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + dev: true + + /p-is-promise@1.1.0: + resolution: {integrity: sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==} + engines: {node: '>=4'} + dev: true + + /p-is-promise@2.1.0: + resolution: {integrity: sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==} + engines: {node: '>=6'} + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + dev: true + + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + aggregate-error: 3.1.0 + dev: true + optional: true + + /p-timeout@2.0.1: + resolution: {integrity: sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==} + engines: {node: '>=4'} + dependencies: + p-finally: 1.0.0 + dev: true + + /p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + dependencies: + p-finally: 1.0.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /package-json@4.0.1: + resolution: {integrity: sha512-q/R5GrMek0vzgoomq6rm9OX+3PQve8sLwTirmK30YB3Cu0Bbt9OX9M/SIUnroN5BGJkzwGsFwDaRGD9EwBOlCA==} + engines: {node: '>=4'} + dependencies: + got: 6.7.1 + registry-auth-token: 3.4.0 + registry-url: 3.1.0 + semver: 5.7.1 + dev: true + + /packet-reader@1.0.0: + resolution: {integrity: sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==} + dev: true + + /pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + dev: true + + /pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + dev: true + + /param-case@1.1.2: + resolution: {integrity: sha512-gksk6zeZQxwBm1AHsKh+XDFsTGf1LvdZSkkpSIkfDtzW+EQj/P2PBgNb3Cs0Y9Xxqmbciv2JZe3fWU6Xbher+Q==} + dependencies: + sentence-case: 1.1.3 + dev: true + + /paraphrase@1.8.0: + resolution: {integrity: sha512-447jeY7a82JcPtJht+rEEnlSeKFmaZezMpkeQTtWB88n8PtJew/HIGHhmvjxi2QfSiRECeIJ6XkZ9U8w0neCZg==} + requiresBuild: true + dependencies: + notate: 1.1.2 + dev: true + + /parents@1.0.1: + resolution: {integrity: sha512-mXKF3xkoUt5td2DoxpLmtOmZvko9VfFpwRwkKDHSNvgmpLAeBo18YDhcPbBzJq+QLCHMbGOfzia2cX4U+0v9Mg==} + dependencies: + path-platform: 0.11.15 + dev: true + + /parse-asn1@5.1.6: + resolution: {integrity: sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==} + dependencies: + asn1.js: 5.4.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + pbkdf2: 3.1.2 + safe-buffer: 5.2.1 + dev: true + + /parse-bmfont-ascii@1.0.6: + resolution: {integrity: sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA==} + dev: true + + /parse-bmfont-binary@1.0.6: + resolution: {integrity: sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA==} + dev: true + + /parse-bmfont-xml@1.1.4: + resolution: {integrity: sha512-bjnliEOmGv3y1aMEfREMBJ9tfL3WR0i0CKPj61DnSLaoxWR3nLrsQrEbCId/8rF4NyRF0cCqisSVXyQYWM+mCQ==} + dependencies: + xml-parse-from-string: 1.0.1 + xml2js: 0.4.23 + dev: true + + /parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + dev: true + + /parse-entities@4.0.0: + resolution: {integrity: sha512-5nk9Fn03x3rEhGaX1FU6IDwG/k+GxLXlFAkgrbM1asuAFl3BhdQWvASaIsmwWypRNcZKHPYnIuOSfIWEyEQnPQ==} + dependencies: + '@types/unist': 2.0.6 + character-entities: 2.0.2 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.0.2 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + dev: true + + /parse-headers@2.0.5: + resolution: {integrity: sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==} + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.18.6 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parse-numeric-range@1.3.0: + resolution: {integrity: sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==} + dev: true + + /parse-passwd@1.0.0: + resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} + engines: {node: '>=0.10.0'} + dev: true + + /parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + dependencies: + parse5: 6.0.1 + dev: true + + /parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + dev: true + + /parseqs@0.0.6: + resolution: {integrity: sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==} + dev: true + + /parseuri@0.0.6: + resolution: {integrity: sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==} + dev: true + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: true + + /pascal-case@1.1.2: + resolution: {integrity: sha512-QWlbdQHdKWlcyTEuv/M0noJtlCa7qTmg5QFAqhx5X9xjAfCU1kXucL+rcOmd2HliESuRLIOz8521RAW/yhuQog==} + dependencies: + camel-case: 1.2.2 + upper-case-first: 1.1.2 + dev: true + + /pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + dev: true + + /passport-google-oauth1@1.0.0: + resolution: {integrity: sha512-qpCEhuflJgYrdg5zZIpAq/K3gTqa1CtHjbubsEsidIdpBPLkEVq6tB1I8kBNcH89RdSiYbnKpCBXAZXX/dtx1Q==} + dependencies: + passport-oauth1: 1.2.0 + dev: true + + /passport-google-oauth20@2.0.0: + resolution: {integrity: sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ==} + engines: {node: '>= 0.4.0'} + dependencies: + passport-oauth2: 1.6.1 + dev: true + + /passport-google-oauth@2.0.0: + resolution: {integrity: sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA==} + engines: {node: '>= 0.4.0'} + requiresBuild: true + dependencies: + passport-google-oauth1: 1.0.0 + passport-google-oauth20: 2.0.0 + dev: true + + /passport-oauth1@1.2.0: + resolution: {integrity: sha512-Sv2YWodC6jN12M/OXwmR4BIXeeIHjjbwYTQw4kS6tHK4zYzSEpxBgSJJnknBjICA5cj0ju3FSnG1XmHgIhYnLg==} + engines: {node: '>= 0.4.0'} + dependencies: + oauth: 0.9.15 + passport-strategy: 1.0.0 + utils-merge: 1.0.1 + dev: true + + /passport-oauth2@1.6.1: + resolution: {integrity: sha512-ZbV43Hq9d/SBSYQ22GOiglFsjsD1YY/qdiptA+8ej+9C1dL1TVB+mBE5kDH/D4AJo50+2i8f4bx0vg4/yDDZCQ==} + engines: {node: '>= 0.4.0'} + dependencies: + base64url: 3.0.1 + oauth: 0.9.15 + passport-strategy: 1.0.0 + uid2: 0.0.4 + utils-merge: 1.0.1 + dev: true + + /passport-strategy@1.0.0: + resolution: {integrity: sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==} + engines: {node: '>= 0.4.0'} + dev: true + + /passport-trakt@1.0.4: + resolution: {integrity: sha512-XTmscUdrSEk4jYC+XQoybShbpNepaYigJLAlAd5wNS6HlCB+p+lT14+hvOuuUeNRwUI259+kVgVKXZjc3Asgeg==} + engines: {node: '>= 0.4.0'} + requiresBuild: true + dependencies: + passport-oauth2: 1.6.1 + pkginfo: 0.3.1 + dev: true + + /passport@0.4.1: + resolution: {integrity: sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==} + engines: {node: '>= 0.4.0'} + requiresBuild: true + dependencies: + passport-strategy: 1.0.0 + pause: 0.0.1 + dev: true + + /path-browserify@0.0.1: + resolution: {integrity: sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==} + dev: true + + /path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: true + + /path-case@1.1.2: + resolution: {integrity: sha512-2snAGA6xVRqTuTPa40bn0iEpYtVK6gEqeyS/63dqpm5pGlesOv6EmRcnB9Rr6eAnAC2Wqlbz0tqgJZryttxhxg==} + dependencies: + sentence-case: 1.1.3 + dev: true + + /path-dirname@1.0.2: + resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + dev: true + + /path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-platform@0.11.15: + resolution: {integrity: sha512-Y30dB6rab1A/nfEKsZxmr01nUotHX0c/ZiIAsCTatEe1CmS5Pm5He7fZ195bPT7RdquoaL8lLxFCMQi/bS7IJg==} + engines: {node: '>= 0.8.0'} + dev: true + + /path-source@0.1.3: + resolution: {integrity: sha512-dWRHm5mIw5kw0cs3QZLNmpUWty48f5+5v9nWD2dw3Y0Hf+s01Ag8iJEWV0Sm0kocE8kK27DrIowha03e1YR+Qw==} + dependencies: + array-source: 0.0.4 + file-source: 0.6.1 + dev: true + + /path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + dev: true + + /pause@0.0.1: + resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} + dev: true + + /pbf@3.2.1: + resolution: {integrity: sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==} + hasBin: true + dependencies: + ieee754: 1.2.1 + resolve-protobuf-schema: 2.1.0 + dev: true + + /pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + dev: true + + /pdf2json@2.1.0: + resolution: {integrity: sha512-mXF9AIgnvq1DP/ZM2R28tAfxP2wKZHYa2DjV0R1KCwcqSzm5Iqh1XQq9rdfAt6dp2DuPP0VHZIaCALc2v1cL5A==} + engines: {node: '>=14.18.0', npm: '>=6.14.15'} + deprecated: v2.1.0 is deprecated, use v3.x.x instead + hasBin: true + requiresBuild: true + dependencies: + '@xmldom/xmldom': 0.8.10 + dev: true + bundledDependencies: + - '@xmldom/xmldom' + + /pdfkit@0.10.0: + resolution: {integrity: sha512-mRJ6iuDzpIQ4ftKp5GvijLXNVRK86xjnyIPBraYSPrUPubNqWM5/oYmc7FZKUWz3wusRTj3PLR9HJ1X5ooqfsg==} + requiresBuild: true + dependencies: + crypto-js: 3.3.0 + fontkit: 1.9.0 + linebreak: 0.3.0 + png-js: 1.0.0 + dev: true + + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: true + + /performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: true + + /periscopic@3.0.4: + resolution: {integrity: sha512-SFx68DxCv0Iyo6APZuw/AKewkkThGwssmU0QWtTlvov3VAtPX+QJ4CadwSaz8nrT5jPIuxdvJWB4PnD2KNDxQg==} + dependencies: + estree-walker: 3.0.2 + is-reference: 3.0.1 + dev: true + + /pg-connection-string@0.1.3: + resolution: {integrity: sha512-i0NV/CrSkFTaiOQs9AGy3tq0dkSjtTd4d7DfsjeDVZAA4aIHInwfFEmriNYGGJUfZ5x6IAC/QddoUpUJjQAi0w==} + dev: true + + /pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + dev: true + + /pg-packet-stream@1.1.0: + resolution: {integrity: sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg==} + dev: true + + /pg-pool@2.0.10(pg@7.18.2): + resolution: {integrity: sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg==} + peerDependencies: + pg: '>5.0' + dependencies: + pg: 7.18.2 + dev: true + + /pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + dev: true + + /pg@7.18.2: + resolution: {integrity: sha512-Mvt0dGYMwvEADNKy5PMQGlzPudKcKKzJds/VbOeZJpb6f/pI3mmoXX0JksPgI3l3JPP/2Apq7F36O63J7mgveA==} + engines: {node: '>= 4.5.0'} + requiresBuild: true + dependencies: + buffer-writer: 2.0.0 + packet-reader: 1.0.0 + pg-connection-string: 0.1.3 + pg-packet-stream: 1.1.0 + pg-pool: 2.0.10(pg@7.18.2) + pg-types: 2.2.0 + pgpass: 1.0.5 + semver: 4.3.2 + dev: true + + /pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + dependencies: + split2: 4.1.0 + dev: true + + /phantomjs-prebuilt@2.1.16: + resolution: {integrity: sha512-PIiRzBhW85xco2fuj41FmsyuYHKjKuXWmhjy3A/Y+CMpN/63TV+s9uzfVhsUwFe0G77xWtHBG8xmXf5BqEUEuQ==} + deprecated: this package is now deprecated + hasBin: true + requiresBuild: true + dependencies: + es6-promise: 4.2.8 + extract-zip: 1.7.0 + fs-extra: 1.0.0 + hasha: 2.2.0 + kew: 0.7.0 + progress: 1.1.8 + request: 2.88.2 + request-progress: 2.0.1 + which: 1.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /phin@2.9.3: + resolution: {integrity: sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /picturefill@3.0.3: + resolution: {integrity: sha512-JDdx+3i4fs2pkqwWZJgGEM2vFWsq+01YsQFT9CKPGuv2Q0xSdrQZoxi9XwyNARTgxiOdgoAwWQRluLRe/JQX2g==} + engines: {node: '>= 0.8.0'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + dev: true + + /pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + dev: true + + /pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + dependencies: + pinkie: 2.0.4 + dev: true + + /pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + dev: true + + /pirates@4.0.5: + resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} + engines: {node: '>= 6'} + dev: true + + /piscina@3.2.0: + resolution: {integrity: sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA==} + dependencies: + eventemitter-asyncresource: 1.0.0 + hdr-histogram-js: 2.0.3 + hdr-histogram-percentiles-obj: 3.0.0 + optionalDependencies: + nice-napi: 1.0.2 + dev: true + + /pixelmatch@4.0.2: + resolution: {integrity: sha512-J8B6xqiO37sU/gkcMglv6h5Jbd9xNER7aHzpfRdNmV4IbQBzBpe4l9XmbG+xPF/znacgu2jfEw+wHffaq/YkXA==} + hasBin: true + dependencies: + pngjs: 3.4.0 + dev: true + + /pixelmatch@5.3.0: + resolution: {integrity: sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==} + hasBin: true + requiresBuild: true + dependencies: + pngjs: 6.0.0 + dev: true + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /pkg-dir@5.0.0: + resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} + engines: {node: '>=10'} + dependencies: + find-up: 5.0.0 + dev: true + + /pkginfo@0.3.1: + resolution: {integrity: sha512-yO5feByMzAp96LtP58wvPKSbaKAi/1C4kV9XpTctr6EepnP6F33RBNOiVrdz9BrPA98U2BMFsTNHo44TWcbQ2A==} + engines: {node: '>= 0.4.0'} + dev: true + + /playwright-core@1.27.1: + resolution: {integrity: sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==} + engines: {node: '>=14'} + hasBin: true + requiresBuild: true + dev: true + + /please-upgrade-node@3.2.0: + resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} + dependencies: + semver-compare: 1.0.0 + dev: true + + /png-js@1.0.0: + resolution: {integrity: sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g==} + dev: true + + /pngjs@3.4.0: + resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} + engines: {node: '>=4.0.0'} + dev: true + + /pngjs@6.0.0: + resolution: {integrity: sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==} + engines: {node: '>=12.13.0'} + dev: true + + /point-in-polygon@1.1.0: + resolution: {integrity: sha512-3ojrFwjnnw8Q9242TzgXuTD+eKiutbzyslcq1ydfu82Db2y+Ogbmyrkpv0Hgj31qwT3lbS9+QAAO/pIQM35XRw==} + dev: true + + /polyfill-library@3.93.0: + resolution: {integrity: sha512-Sv4A4hUK5/s95EqUtOnbZawQj2o9aVsnZbIQ6pCg400I0Ip4mWNLyDhpXwj78WV6OWvGhh4LBNjm5G43c1R5TA==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + '@financial-times/polyfill-useragent-normaliser': 1.10.2 + '@formatjs/intl-pluralrules': 1.5.9 + '@formatjs/intl-relativetimeformat': 3.1.0 + '@webcomponents/template': 1.5.0 + Base64: 1.1.0 + abort-controller: 3.0.0 + audio-context-polyfill: 1.0.0 + current-script-polyfill: 1.0.0 + diff: 4.0.2 + event-source-polyfill: 1.0.31 + from2-string: 1.1.0 + glob: 7.2.3 + graceful-fs: 4.2.10 + html5shiv: 3.7.3 + intl: 1.2.5 + js-polyfills: 0.1.43 + json3: 3.3.3 + merge2: 1.4.1 + mkdirp: 0.5.6 + mnemonist: 0.32.0 + mutationobserver-shim: 0.3.7 + picturefill: 3.0.3 + resize-observer-polyfill: 1.5.1 + rimraf: 3.0.2 + smoothscroll-polyfill: 0.4.4 + spdx-licenses: 1.0.0 + stream-cache: 0.0.2 + stream-from-promise: 1.0.0 + stream-to-string: 1.2.0 + toposort: 2.0.2 + uglify-js: 2.8.29 + unorm: 1.6.0 + usertiming: 0.1.8 + web-animations-js: 2.3.2 + whatwg-fetch: 3.6.2 + wicg-inert: 3.1.2 + yaku: 0.19.3 + transitivePeerDependencies: + - supports-color + dev: true + + /pop-iterate@1.0.1: + resolution: {integrity: sha512-HRCx4+KJE30JhX84wBN4+vja9bNfysxg1y28l0DuJmkoaICiv2ZSilKddbS48pq50P8d2erAhqDLbp47yv3MbQ==} + dev: true + + /posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + dev: true + + /postcss@8.4.18: + resolution: {integrity: sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.4 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + dev: true + + /postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + dev: true + + /postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + dev: true + + /postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + dependencies: + xtend: 4.0.2 + dev: true + + /prebuild-install@7.1.1: + resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + detect-libc: 2.0.1 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.7 + mkdirp-classic: 0.5.3 + napi-build-utils: 1.0.2 + node-abi: 3.28.0 + pump: 3.0.0 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + dev: true + + /prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + dev: true + + /prepare-response@2.1.1: + resolution: {integrity: sha512-WwQJDGRqIOsUqPV13TwEV+7c0u1rBGM5hs2JKSHJsRfaX1Lwqt7w1/FT5euUTP3b04tdhnWHq6JNPM7EWTbVPA==} + dependencies: + mime: 2.6.0 + ms: 2.1.3 + promise: 8.3.0 + dev: true + + /prepend-http@1.0.4: + resolution: {integrity: sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==} + engines: {node: '>=0.10.0'} + dev: true + + /prepend-http@2.0.0: + resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} + engines: {node: '>=4'} + dev: true + + /pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + dev: true + + /priorityqueuejs@1.0.0: + resolution: {integrity: sha512-lg++21mreCEOuGWTbO5DnJKAdxfjrdN0S9ysoW9SzdSJvbkWpkaDdpG/cdsPCsEnoLUwmd9m3WcZhngW7yKA2g==} + dev: true + + /prismjs@1.29.0: + resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==} + engines: {node: '>=6'} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: true + + /progress@1.1.8: + resolution: {integrity: sha512-UdA8mJ4weIkUBO224tIarHzuHs4HuYiJvsuGT7j/SPQiUJVjYvNDBIPa0hAorduOfjGohB/qHWRa/lrrWX/mXw==} + engines: {node: '>=0.4.0'} + dev: true + + /promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + requiresBuild: true + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + dev: true + optional: true + + /promise-polyfill@1.1.6: + resolution: {integrity: sha512-7rrONfyLkDEc7OJ5QBkqa4KI4EBhCd340xRuIUPGCfu13znS+vx+VDdrT9ODAJHlXm7w4lbxN3DRjyv58EuzDg==} + dev: true + + /promise-polyfill@8.1.3: + resolution: {integrity: sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==} + dev: true + + /promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + dev: true + optional: true + + /promise-the-world@1.0.1: + resolution: {integrity: sha512-eAXctcYU0ksq9YT5LT0N3e8yvdEAp0aYuzIiaJo9CpZwga45i08MW05GMXZIow7N05d1o4EBoR5hjkb7jhzqKg==} + dev: true + + /promise.prototype.finally@3.1.3: + resolution: {integrity: sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /promise@7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + dependencies: + asap: 2.0.6 + dev: true + + /promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + dependencies: + asap: 2.0.6 + dev: true + + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /property-accessors@1.1.3: + resolution: {integrity: sha512-WQTVW7rn+k6wq8FyYVM15afyoB2loEdeIzd/o7+HEA5hMZcxvRf4Khie0fBM9wLP3EJotKhiH15kY7Dd4gc57g==} + dependencies: + es6-weak-map: 0.1.4 + mixto: 1.0.0 + dev: true + + /property-information@6.2.0: + resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==} + dev: true + + /proto3-json-serializer@0.1.9: + resolution: {integrity: sha512-A60IisqvnuI45qNRygJjrnNjX2TMdQGMY+57tR3nul3ZgO2zXkR9OGR8AXxJhkqx84g0FTnrfi3D5fWMSdANdQ==} + dependencies: + protobufjs: 6.11.3 + dev: true + + /protobufjs@6.11.3: + resolution: {integrity: sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==} + hasBin: true + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + '@types/node': 14.18.29 + long: 4.0.0 + dev: true + + /protobufjs@7.1.2: + resolution: {integrity: sha512-4ZPTPkXCdel3+L81yw3dG6+Kq3umdWKh7Dc7GW/CpNk4SX3hK58iPCWeCyhVTDrbkNeKrYNZ7EojM5WDaEWTLQ==} + engines: {node: '>=12.0.0'} + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 14.18.29 + long: 5.2.0 + dev: true + + /protocol-buffers-schema@3.6.0: + resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==} + dev: true + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: true + + /pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + dev: true + + /psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + dev: true + + /public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + dependencies: + bn.js: 4.12.0 + browserify-rsa: 4.1.0 + create-hash: 1.2.0 + parse-asn1: 5.1.6 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + dev: true + + /pug-attrs@3.0.0: + resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} + dependencies: + constantinople: 4.0.1 + js-stringify: 1.0.2 + pug-runtime: 3.0.1 + dev: true + + /pug-code-gen@3.0.2: + resolution: {integrity: sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==} + dependencies: + constantinople: 4.0.1 + doctypes: 1.1.0 + js-stringify: 1.0.2 + pug-attrs: 3.0.0 + pug-error: 2.0.0 + pug-runtime: 3.0.1 + void-elements: 3.1.0 + with: 7.0.2 + dev: true + + /pug-error@2.0.0: + resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==} + dev: true + + /pug-filters@4.0.0: + resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==} + dependencies: + constantinople: 4.0.1 + jstransformer: 1.0.0 + pug-error: 2.0.0 + pug-walk: 2.0.0 + resolve: 1.22.1 + dev: true + + /pug-lexer@5.0.1: + resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==} + dependencies: + character-parser: 2.2.0 + is-expression: 4.0.0 + pug-error: 2.0.0 + dev: true + + /pug-linker@4.0.0: + resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==} + dependencies: + pug-error: 2.0.0 + pug-walk: 2.0.0 + dev: true + + /pug-load@3.0.0: + resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==} + dependencies: + object-assign: 4.1.1 + pug-walk: 2.0.0 + dev: true + + /pug-parser@6.0.0: + resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==} + dependencies: + pug-error: 2.0.0 + token-stream: 1.0.0 + dev: true + + /pug-runtime@3.0.1: + resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==} + dev: true + + /pug-strip-comments@2.0.0: + resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==} + dependencies: + pug-error: 2.0.0 + dev: true + + /pug-walk@2.0.0: + resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==} + dev: true + + /pug@3.0.2: + resolution: {integrity: sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==} + requiresBuild: true + dependencies: + pug-code-gen: 3.0.2 + pug-filters: 4.0.0 + pug-lexer: 5.0.1 + pug-linker: 4.0.0 + pug-load: 3.0.0 + pug-parser: 6.0.0 + pug-runtime: 3.0.1 + pug-strip-comments: 2.0.0 + dev: true + + /pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + dev: true + + /pumpify@2.0.1: + resolution: {integrity: sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==} + requiresBuild: true + dependencies: + duplexify: 4.1.2 + inherits: 2.0.4 + pump: 3.0.0 + dev: true + optional: true + + /punycode@1.3.2: + resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} + dev: true + + /punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + dev: true + + /punycode@2.1.1: + resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} + engines: {node: '>=6'} + dev: true + + /q@2.0.3: + resolution: {integrity: sha512-gv6vLGcmAOg96/fgo3d9tvA4dJNZL3fMyBqVRrGxQ+Q/o4k9QzbJ3NQF9cOO/71wRodoXhaPgphvMFU68qVAJQ==} + dependencies: + asap: 2.0.6 + pop-iterate: 1.0.1 + weak-map: 1.0.8 + dev: true + + /qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + dev: true + + /query-string@5.1.1: + resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} + engines: {node: '>=0.10.0'} + dependencies: + decode-uri-component: 0.2.0 + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + dev: true + + /querystring-es3@0.2.1: + resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} + engines: {node: '>=0.4.x'} + dev: true + + /querystring@0.2.0: + resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} + engines: {node: '>=0.4.x'} + deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. + dev: true + + /querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: true + + /quickselect@1.1.1: + resolution: {integrity: sha512-qN0Gqdw4c4KGPsBOQafj6yj/PA6c/L63f6CaZ/DCF/xF4Esu3jVmKLUDYxghFx8Kb/O7y9tI7x2RjTSXwdK1iQ==} + dev: true + + /quickselect@2.0.0: + resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==} + dev: true + + /quote-stream@1.0.2: + resolution: {integrity: sha512-kKr2uQ2AokadPjvTyKJQad9xELbZwYzWlNfI3Uz2j/ib5u6H9lDP7fUUR//rMycd0gv4Z5P1qXMfXR8YpIxrjQ==} + hasBin: true + dependencies: + buffer-equal: 0.0.1 + minimist: 1.2.7 + through2: 2.0.5 + dev: true + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + dev: true + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: true + + /raven@2.6.4: + resolution: {integrity: sha512-6PQdfC4+DQSFncowthLf+B6Hr0JpPsFBgTVYTAOq7tCmx/kR4SXbeawtPch20+3QfUcQDoJBLjWW1ybvZ4kXTw==} + engines: {node: '>= 4.0.0'} + deprecated: Please upgrade to @sentry/node. See the migration guide https://bit.ly/3ybOlo7 + hasBin: true + dependencies: + cookie: 0.3.1 + md5: 2.3.0 + stack-trace: 0.0.10 + timed-out: 4.0.1 + uuid: 3.3.2 + dev: true + + /raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: true + + /rbush@2.0.2: + resolution: {integrity: sha512-XBOuALcTm+O/H8G90b6pzu6nX6v2zCKiFG4BJho8a+bY6AER6t8uQUZdi5bomQc0AprCWhEGa7ncAbbRap0bRA==} + dependencies: + quickselect: 1.1.1 + dev: true + + /rbush@3.0.1: + resolution: {integrity: sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==} + dependencies: + quickselect: 2.0.0 + dev: true + + /rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.7 + strip-json-comments: 2.0.1 + dev: true + + /rdf-canonize@1.2.0: + resolution: {integrity: sha512-MQdcRDz4+82nUrEb3hNQangBDpmep15uMmnWclGi/1KS0bNVc8oHpoNI0PFLHZsvwgwRzH31bO1JAScqUAstvw==} + engines: {node: '>=6'} + dependencies: + node-forge: 0.10.0 + semver: 6.3.0 + dev: true + + /rdf-ext@1.3.5: + resolution: {integrity: sha512-LS/waItwp5aGY9Ay7y147HxWLIaSvw4r172S995aGwVkvg0KwUA0NY8w61p/LoFdQ4V6mzxQdVoRN6x/6OaK0w==} + dependencies: + '@rdfjs/data-model': 1.3.4 + '@rdfjs/dataset': 1.1.1 + '@rdfjs/to-ntriples': 1.0.2 + rdf-normalize: 1.0.0 + readable-stream: 3.6.0 + dev: true + + /rdf-js@4.0.2: + resolution: {integrity: sha512-ApvlFa/WsQh8LpPK/6hctQwG06Z9ztQQGWVtrcrf9L6+sejHNXLPOqL+w7q3hF+iL0C4sv3AX1PUtGkLNzyZ0Q==} + dependencies: + '@rdfjs/types': 1.1.0 + dev: true + + /rdf-normalize@1.0.0: + resolution: {integrity: sha512-1ocjoxovKc4+AyS4Tgtroay5R33yrtM2kQnAGvVaB0iGSRggukHxMJW0y8xTR7TwKZabS+7oMSQNMdbu/qTtCQ==} + dev: true + + /rdf-transform-triple-to-quad@1.0.2: + resolution: {integrity: sha512-cr8wgJcj+SvPLichNhWhUTyXHcoD1EVgajVmvbtwYbMRw479KAaW03TTviQaJAUqgcWzIzkrWLtWkrY2FgwryQ==} + dependencies: + '@rdfjs/data-model': 1.3.4 + readable-stream: 3.6.2 + dev: true + + /react-dom@16.14.0(react@16.14.0): + resolution: {integrity: sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==} + peerDependencies: + react: ^16.14.0 + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + prop-types: 15.8.1 + react: 16.14.0 + scheduler: 0.19.1 + dev: true + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /react@16.14.0: + resolution: {integrity: sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==} + engines: {node: '>=0.10.0'} + requiresBuild: true + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + prop-types: 15.8.1 + dev: true + + /read-only-stream@2.0.0: + resolution: {integrity: sha512-3ALe0bjBVZtkdWKIcThYpQCLbBMd/+Tbh2CDSrAIDO3UsZ4Xs+tnyjv2MjCOMMgBG+AsUOeuP1cgtY1INISc8w==} + dependencies: + readable-stream: 2.3.7 + dev: true + + /readable-error@1.0.0: + resolution: {integrity: sha512-CLnInu5bUphmFiZ3pD/BC6+Cg4/BzK6ZMvWfd0b2QMzYo159Z/f/nVFQ9L5IeMrqUxy0EFsp3XJ+BRfLfY13IQ==} + dependencies: + readable-stream: 2.3.8 + dev: true + + /readable-stream@2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@3.6.0: + resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readable-to-readable@0.1.3: + resolution: {integrity: sha512-G+0kz01xJM/uTuItKcqC73cifW8S6CZ7tp77NLN87lE5mrSU+GC8geoSAlfmp0NocmXckQ7W8s8ns73HYsIA3w==} + dependencies: + readable-stream: 3.6.0 + dev: true + + /readdirp@2.2.1: + resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} + engines: {node: '>=0.10'} + dependencies: + graceful-fs: 4.2.10 + micromatch: 3.1.10 + readable-stream: 2.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /redis-commands@1.7.0: + resolution: {integrity: sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ==} + dev: true + + /redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + dev: true + + /redis-parser@3.0.0: + resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} + engines: {node: '>=4'} + dependencies: + redis-errors: 1.2.0 + dev: true + + /redis@3.1.2: + resolution: {integrity: sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + denque: 1.5.1 + redis-commands: 1.7.0 + redis-errors: 1.2.0 + redis-parser: 3.0.0 + dev: true + + /regenerator-runtime@0.13.10: + resolution: {integrity: sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==} + dev: true + + /regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + dev: true + + /regexp-clone@1.0.0: + resolution: {integrity: sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw==} + dev: true + + /regexp.prototype.flags@1.4.3: + resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + functions-have-names: 1.2.3 + dev: true + + /registry-auth-token@3.4.0: + resolution: {integrity: sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==} + dependencies: + rc: 1.2.8 + safe-buffer: 5.2.1 + dev: true + + /registry-url@3.1.0: + resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} + engines: {node: '>=0.10.0'} + dependencies: + rc: 1.2.8 + dev: true + + /reinterval@1.1.0: + resolution: {integrity: sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==} + dev: true + + /remark-mdx@2.2.1: + resolution: {integrity: sha512-R9wcN+/THRXTKyRBp6Npo/mcbGA2iT3N4G8qUqLA5pOEg7kBidHv8K2hHidCMYZ6DXmwK18umu0K4cicgA2PPQ==} + dependencies: + mdast-util-mdx: 2.0.0 + micromark-extension-mdxjs: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /remark-parse@10.0.1: + resolution: {integrity: sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw==} + requiresBuild: true + dependencies: + '@types/mdast': 3.0.10 + mdast-util-from-markdown: 1.2.0 + unified: 10.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /remark-prism@1.3.6(canvas@2.11.2): + resolution: {integrity: sha512-yYSXJ2MEK2DeD9UKDKFkQPcVqRx6aX2FYD1kE27ScogpZ/BBO8MoOO6gf/AKqfXvKGnP51wqvDEBmPseypgaug==} + dependencies: + classnames: 2.3.2 + css-selector-parser: 1.4.1 + escape-html: 1.0.3 + jsdom: 16.7.0(canvas@2.11.2) + parse-numeric-range: 1.3.0 + parse5: 6.0.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + prismjs: 1.29.0 + unist-util-map: 2.0.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + dev: true + + /remark-rehype@10.1.0: + resolution: {integrity: sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==} + dependencies: + '@types/hast': 2.3.4 + '@types/mdast': 3.0.10 + mdast-util-to-hast: 12.2.5 + unified: 10.1.2 + dev: true + + /remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + dev: true + + /remove-trailing-slash@0.1.1: + resolution: {integrity: sha512-o4S4Qh6L2jpnCy83ysZDau+VORNvnFw07CKSAymkd6ICNVEPisMyzlc00KlvvicsxKck94SEwhDnMNdICzO+tA==} + dev: true + + /repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + dev: true + + /repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + dev: true + + /replace-ext@0.0.1: + resolution: {integrity: sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==} + engines: {node: '>= 0.4'} + dev: true + + /request-progress@2.0.1: + resolution: {integrity: sha512-dxdraeZVUNEn9AvLrxkgB2k6buTlym71dJk1fk4v8j3Ou3RKNm07BcgbHdj2lLgYGfqX71F+awb1MR+tWPFJzA==} + dependencies: + throttleit: 1.0.0 + dev: true + + /request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + dependencies: + aws-sign2: 0.7.0 + aws4: 1.11.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + dev: true + + /require-at@1.0.6: + resolution: {integrity: sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==} + engines: {node: '>=4'} + dev: true + + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: true + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: true + + /requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + dev: true + + /resize-observer-polyfill@1.5.1: + resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} + dev: true + + /resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + dev: true + + /resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + dependencies: + resolve-from: 5.0.0 + dev: true + + /resolve-dir@0.1.1: + resolution: {integrity: sha512-QxMPqI6le2u0dCLyiGzgy92kjkkL6zO0XyvHzjdTNH3zM6e5Hz3BwG6+aEyNgiQ5Xz6PwTwgQEj3U50dByPKIA==} + engines: {node: '>=0.10.0'} + dependencies: + expand-tilde: 1.2.2 + global-modules: 0.2.3 + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve-protobuf-schema@2.1.0: + resolution: {integrity: sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==} + dependencies: + protocol-buffers-schema: 3.6.0 + dev: true + + /resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + dev: true + + /resolve.exports@1.1.0: + resolution: {integrity: sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==} + engines: {node: '>=10'} + dev: true + + /resolve@1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.11.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /responselike@1.0.2: + resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} + dependencies: + lowercase-keys: 1.0.1 + dev: true + + /responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + dependencies: + lowercase-keys: 2.0.0 + dev: true + + /rest-facade@1.16.3: + resolution: {integrity: sha512-9BQTPLiwg23XZwcWi0ys1wTizfc//0b2G3U6vBWcgqh56ozs2K6CD+Jw4DYcw3AqdPQN7jj8nzRUcUXFVGzb0Q==} + peerDependencies: + superagent-proxy: ^3.0.0 + peerDependenciesMeta: + superagent-proxy: + optional: true + dependencies: + change-case: 2.3.1 + deepmerge: 3.3.0 + lodash.get: 4.4.2 + superagent: 5.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /restore-cursor@2.0.0: + resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} + engines: {node: '>=4'} + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + dev: true + + /restructure@2.0.1: + resolution: {integrity: sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg==} + dev: true + + /ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + dev: true + + /retry-as-promised@3.2.0: + resolution: {integrity: sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==} + dependencies: + any-promise: 1.3.0 + dev: true + + /retry-request@4.2.2: + resolution: {integrity: sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==} + engines: {node: '>=8.10.0'} + dependencies: + debug: 4.3.4 + extend: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + requiresBuild: true + dev: true + optional: true + + /retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + dev: true + + /retry@0.6.0: + resolution: {integrity: sha512-RgncoxLF1GqwAzTZs/K2YpZkWrdIYbXsmesdomi+iPilSzjUyr/wzNIuteoTVaWokzdwZIJ9NHRNQa/RUiOB2g==} + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /right-align@0.1.3: + resolution: {integrity: sha512-yqINtL/G7vs2v+dFIZmFUDbnVyFUJFKd6gK22Kgo6R4jfJGFtisKyncWDDULgjfqf4ASQuIQyjJ7XZ+3aWpsAg==} + engines: {node: '>=0.10.0'} + dependencies: + align-text: 0.1.4 + dev: true + + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + dev: true + + /robots-parser@2.4.0: + resolution: {integrity: sha512-oO8f2SI04dJk3pbj2KOMJ4G6QfPAgqcGmrYGmansIcpRewIPT2ljWEt5I+ip6EgiyaLo+RXkkUWw74M25HDkMA==} + dev: true + + /robust-predicates@2.0.4: + resolution: {integrity: sha512-l4NwboJM74Ilm4VKfbAtFeGq7aEjWL+5kVFcmgFA2MrdnQWx9iE/tUGvxY5HyMI7o/WpSIUFLbC5fbeaHgSCYg==} + dev: true + + /rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + dependencies: + estree-walker: 0.6.1 + dev: true + + /rootpath@0.1.2: + resolution: {integrity: sha512-R3wLbuAYejpxQjL/SjXo1Cjv4wcJECnMRT/FlcCfTwCBhaji9rWaRCoVEQ1SPiTJ4kKK+yh+bZLAV7SCafoDDw==} + dev: true + + /run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rx-lite-aggregates@4.0.8: + resolution: {integrity: sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==} + dependencies: + rx-lite: 4.0.8 + dev: true + + /rx-lite@4.0.8: + resolution: {integrity: sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==} + dev: true + + /rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + requiresBuild: true + dependencies: + tslib: 1.14.1 + dev: true + + /sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + dependencies: + mri: 1.2.0 + dev: true + + /safe-buffer@5.1.1: + resolution: {integrity: sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==} + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-identifier@0.4.2: + resolution: {integrity: sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w==} + dev: true + + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + is-regex: 1.1.4 + dev: true + + /safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + dependencies: + ret: 0.1.15 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /saslprep@1.0.3: + resolution: {integrity: sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==} + engines: {node: '>=6'} + requiresBuild: true + dependencies: + sparse-bitfield: 3.0.3 + dev: true + + /sax@0.5.8: + resolution: {integrity: sha512-c0YL9VcSfcdH3F1Qij9qpYJFpKFKMXNOkLWFssBL3RuF7ZS8oZhllR2rWlCRjDTJsfq3R6wbSsaRU6o0rkEdNw==} + dev: true + + /sax@1.2.1: + resolution: {integrity: sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==} + dev: true + + /sax@1.2.4: + resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + dev: true + + /saxes@5.0.1: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} + engines: {node: '>=10'} + dependencies: + xmlchars: 2.2.0 + dev: true + + /scheduler@0.19.1: + resolution: {integrity: sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + dev: true + + /scmp@2.1.0: + resolution: {integrity: sha512-o/mRQGk9Rcer/jEEw/yw4mwo3EU/NvYvp577/Btqrym9Qy5/MdWGBqipbALgd2lrdWTJ5/gqDusxfnQBxOxT2Q==} + dev: true + + /season@6.0.2: + resolution: {integrity: sha512-5eq1ZKvsIUTkefE/R6PhJyiDDaalPjmdhUPVMuOFh4Yz2n5pBl1COkzNlxQyI8BXEBEIu1nJeJqJPVD0c3vycQ==} + hasBin: true + dependencies: + cson-parser: 1.3.5 + fs-plus: 3.1.1 + yargs: 3.32.0 + dev: true + + /semaphore@1.0.5: + resolution: {integrity: sha512-15WnK4TxpOk33fL0UoDnJ5myIWwJiodIZHtPRBoSxcaADt1Tm7kxEERd8n0vsw6OWsXwCCeROjSKU9MqfHaS1A==} + engines: {node: '>=0.8.0'} + dev: true + + /semver-compare@1.0.0: + resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} + dev: true + + /semver-diff@2.1.0: + resolution: {integrity: sha512-gL8F8L4ORwsS0+iQ34yCYv///jsOq0ZL7WP55d1HnJ32o7tyFYEFQZQA22mrLIacZdU6xecaBBZ+uEiffGNyXw==} + engines: {node: '>=0.10.0'} + dependencies: + semver: 5.7.1 + dev: true + + /semver@4.3.2: + resolution: {integrity: sha512-VyFUffiBx8hABJ9HYSTXLRwyZtdDHMzMtFmID1aiNAD2BZppBmJm0Hqw3p2jkgxP9BNt1pQ9RnC49P0EcXf6cA==} + hasBin: true + dev: true + + /semver@5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + dev: true + + /semver@6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver@7.3.8: + resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /sentence-case@1.1.3: + resolution: {integrity: sha512-laa/UDTPXsrQnoN/Kc8ZO7gTeEjMsuPiDgUCk9N0iINRZvqAMCTXjGl8+tD27op1eF/JHbdUlEUmovDh6AX7sA==} + dependencies: + lower-case: 1.1.4 + dev: true + + /separate-stream@1.0.1: + resolution: {integrity: sha512-UKFCzmddW2akOq40YdGehllv5gu6AD3y6nGSVuZuwI1kify2CiW7Zwsxx4ioaNLxx4LZaZMkcjdICHtSxpEpaA==} + dependencies: + readable-stream: 3.6.2 + dev: true + + /sequelize-pool@2.3.0: + resolution: {integrity: sha512-Ibz08vnXvkZ8LJTiUOxRcj1Ckdn7qafNZ2t59jYHMX1VIebTAOYefWdRYFt6z6+hy52WGthAHAoLc9hvk3onqA==} + engines: {node: '>= 6.0.0'} + dev: true + + /sequelize@5.22.5: + resolution: {integrity: sha512-ySIHof18sJbeVG4zjEvsDL490cd9S14/IhkCrZR/g0C/FPlZq1AzEJVeSAo++9/sgJH2eERltAIGqYQNgVqX/A==} + engines: {node: '>=6.0.0'} + deprecated: 'Please update to v6 or higher! A migration guide can be found here: https://sequelize.org/v6/manual/upgrade-to-v6.html' + requiresBuild: true + dependencies: + bluebird: 3.7.2 + cls-bluebird: 2.1.0 + debug: 4.3.4 + dottie: 2.0.2 + inflection: 1.12.0 + lodash: 4.17.21 + moment: 2.29.4 + moment-timezone: 0.5.38 + retry-as-promised: 3.2.0 + semver: 6.3.0 + sequelize-pool: 2.3.0 + toposort-class: 1.0.1 + uuid: 8.3.2 + validator: 13.7.0 + wkx: 0.4.8 + transitivePeerDependencies: + - supports-color + dev: true + + /serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serve-favicon@2.5.0: + resolution: {integrity: sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==} + engines: {node: '>= 0.8.0'} + dependencies: + etag: 1.8.1 + fresh: 0.5.2 + ms: 2.1.1 + parseurl: 1.3.3 + safe-buffer: 5.1.1 + dev: true + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /set-getter@0.1.1: + resolution: {integrity: sha512-9sVWOy+gthr+0G9DzqqLaYNA7+5OKkSmcqjL9cBpDEaZrr3ShQlyX2cZ/O/ozE41oxn/Tt0LGEM/w4Rub3A3gw==} + engines: {node: '>=0.10.0'} + dependencies: + to-object-path: 0.3.0 + dev: true + + /set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + dev: true + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: true + + /sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + dev: true + + /shallow-copy@0.0.1: + resolution: {integrity: sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw==} + dev: true + + /shapefile@0.6.6: + resolution: {integrity: sha512-rLGSWeK2ufzCVx05wYd+xrWnOOdSV7xNUW5/XFgx3Bc02hBkpMlrd2F1dDII7/jhWzv0MSyBFh5uJIy9hLdfuw==} + hasBin: true + dependencies: + array-source: 0.0.4 + commander: 2.20.3 + path-source: 0.1.3 + slice-source: 0.4.1 + stream-source: 0.3.5 + text-encoding: 0.6.4 + dev: true + + /sharp@0.30.7: + resolution: {integrity: sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig==} + engines: {node: '>=12.13.0'} + requiresBuild: true + dependencies: + color: 4.2.3 + detect-libc: 2.0.1 + node-addon-api: 5.0.0 + prebuild-install: 7.1.1 + semver: 7.3.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + dev: true + + /shasum-object@1.0.0: + resolution: {integrity: sha512-Iqo5rp/3xVi6M4YheapzZhhGPVs0yZwHj7wvwQ1B9z8H6zk+FEnI7y3Teq7qwnekfEhu8WmG2z0z4iWZaxLWVg==} + dependencies: + fast-safe-stringify: 2.1.1 + dev: true + + /shasum@1.0.2: + resolution: {integrity: sha512-UTzHm/+AzKfO9RgPgRpDIuMSNie1ubXRaljjlhFMNGYoG7z+rm9AHLPMf70R7887xboDH9Q+5YQbWKObFHEAtw==} + dependencies: + json-stable-stringify: 0.0.1 + sha.js: 2.4.11 + dev: true + + /shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + dependencies: + shebang-regex: 1.0.0 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /shell-quote@1.7.4: + resolution: {integrity: sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw==} + dev: true + + /shimmer@1.2.1: + resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} + dev: true + + /shortid@2.2.16: + resolution: {integrity: sha512-Ugt+GIZqvGXCIItnsL+lvFJOiN7RYqlGy7QE41O3YC1xbNSeDGIRO7xg2JJXIAj1cAGnOeC1r7/T9pgrtQbv4g==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + dependencies: + nanoid: 2.1.11 + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.1.3 + object-inspect: 1.12.2 + dev: true + + /sift@13.5.2: + resolution: {integrity: sha512-+gxdEOMA2J+AI+fVsCqeNn7Tgx3M9ZN9jdi95939l1IJ8cZsqS8sqpJyOkic2SJk+1+98Uwryt/gL6XDaV+UZA==} + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + dev: true + + /simple-get@3.1.1: + resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==} + dependencies: + decompress-response: 4.2.1 + once: 1.4.0 + simple-concat: 1.0.1 + dev: true + + /simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + dev: true + + /simple-lru-cache@0.0.2: + resolution: {integrity: sha512-uEv/AFO0ADI7d99OHDmh1QfYzQk/izT1vCmu/riQfh7qjBVUUgRT87E5s5h7CxWCA/+YoZerykpEthzVrW3LIw==} + dev: true + + /simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + dependencies: + is-arrayish: 0.3.2 + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /skmeans@0.9.7: + resolution: {integrity: sha512-hNj1/oZ7ygsfmPZ7ZfN5MUBRoGg1gtpnImuJBgLO0ljQ67DtJuiQaiYdS4lUA6s0KCwnPhGivtC/WRwIZLkHyg==} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /slice-source@0.4.1: + resolution: {integrity: sha512-YiuPbxpCj4hD9Qs06hGAz/OZhQ0eDuALN0lRWJez0eD/RevzKqGdUx1IOMUnXgpr+sXZLq3g8ERwbAH0bCb8vg==} + dev: true + + /sliced@1.0.1: + resolution: {integrity: sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==} + dev: true + + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + requiresBuild: true + dev: true + optional: true + + /smoothscroll-polyfill@0.4.4: + resolution: {integrity: sha512-TK5ZA9U5RqCwMpfoMq/l1mrH0JAR7y7KRvOBx0n2869aLxch+gT9GhN3yUfjiw+d/DiF1mKo14+hd62JyMmoBg==} + dev: true + + /smtp-connection@2.12.0: + resolution: {integrity: sha512-UP5jK4s5SGcUcqPN4U9ingqKt9mXYSKa52YhqxPuMecAnUOsVJpOmtgGaOm1urUBJZlzDt1M9WhZZkgbhxQlvg==} + dependencies: + httpntlm: 1.6.1 + nodemailer-shared: 1.1.0 + dev: true + + /snake-case@1.1.2: + resolution: {integrity: sha512-oapUKC+qulnUIN+/O7Tbl2msi9PQvJeivGN9RNbygxzI2EOY0gA96i8BJLYnGUWSLGcYtyW4YYqnGTZEySU/gg==} + dependencies: + sentence-case: 1.1.3 + dev: true + + /snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + dev: true + + /snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /socket.io-adapter@1.1.2: + resolution: {integrity: sha512-WzZRUj1kUjrTIrUKpZLEzFZ1OLj5FwLlAFQs9kuZJzJi5DKdU7FsWc36SNmA8iDOtwBQyT8FkrriRM8vXLYz8g==} + dev: true + + /socket.io-client@2.5.0: + resolution: {integrity: sha512-lOO9clmdgssDykiOmVQQitwBAF3I6mYcQAo7hQ7AM6Ny5X7fp8hIJ3HcQs3Rjz4SoggoxA1OgrQyY8EgTbcPYw==} + dependencies: + backo2: 1.0.2 + component-bind: 1.0.0 + component-emitter: 1.3.0 + debug: 3.1.0 + engine.io-client: 3.5.3 + has-binary2: 1.0.3 + indexof: 0.0.1 + parseqs: 0.0.6 + parseuri: 0.0.6 + socket.io-parser: 3.3.2 + to-array: 0.1.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /socket.io-parser@3.3.2: + resolution: {integrity: sha512-FJvDBuOALxdCI9qwRrO/Rfp9yfndRtc1jSgVgV8FDraihmSP/MLGD5PEuJrNfjALvcQ+vMDM/33AWOYP/JSjDg==} + dependencies: + component-emitter: 1.3.0 + debug: 3.1.0 + isarray: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /socket.io-parser@3.4.1: + resolution: {integrity: sha512-11hMgzL+WCLWf1uFtHSNvliI++tcRUWdoeYuwIl+Axvwy9z2gQM+7nJyN3STj1tLj5JyIUH8/gpDGxzAlDdi0A==} + dependencies: + component-emitter: 1.2.1 + debug: 4.1.1 + isarray: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /socket.io@2.5.0: + resolution: {integrity: sha512-gGunfS0od3VpwDBpGwVkzSZx6Aqo9uOcf1afJj2cKnKFAoyl16fvhpsUhmUFd4Ldbvl5JvRQed6eQw6oQp6n8w==} + requiresBuild: true + dependencies: + debug: 4.1.1 + engine.io: 3.6.0 + has-binary2: 1.0.3 + socket.io-adapter: 1.1.2 + socket.io-client: 2.5.0 + socket.io-parser: 3.4.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /socks-proxy-agent@6.2.1: + resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==} + engines: {node: '>= 10'} + requiresBuild: true + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: true + optional: true + + /socks@2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + requiresBuild: true + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: true + optional: true + + /sort-keys@2.0.0: + resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} + engines: {node: '>=4'} + dependencies: + is-plain-obj: 1.1.0 + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.0 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + dev: true + + /source-map@0.1.34: + resolution: {integrity: sha512-yfCwDj0vR9RTwt3pEzglgb3ZgmcXHt6DjG3bjJvzPwTL+5zDQ2MhmSzAcTy0GTiQuCiriSWXvWM1/NhKdXuoQA==} + engines: {node: '>=0.8.0'} + dependencies: + amdefine: 1.0.1 + dev: true + + /source-map@0.5.6: + resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true + + /space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + dev: true + + /sparql-http-client@2.4.2: + resolution: {integrity: sha512-b7KBjs3BEJVQJAbWeaTx4EdBSOU1L0KfWLVgnkeRyBUoSTI8F1kTHuX7wzme/+UlfCS2zYsKGdpma5DwdaVRBQ==} + dependencies: + '@rdfjs/data-model': 1.3.4 + '@rdfjs/parser-n3': 1.1.4 + '@rdfjs/to-ntriples': 1.0.2 + get-stream: 5.2.0 + jsonstream2: 3.0.0 + lodash: 4.17.21 + nodeify-fetch: 2.2.2 + promise-the-world: 1.0.1 + rdf-transform-triple-to-quad: 1.0.2 + readable-stream: 3.6.2 + separate-stream: 1.0.1 + transitivePeerDependencies: + - encoding + dev: true + + /sparse-bitfield@3.0.3: + resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==} + dependencies: + memory-pager: 1.5.0 + dev: true + + /spdx-licenses@1.0.0: + resolution: {integrity: sha512-BmeFZRYH9XXf56omx0LuiG+gBXRqwmrKsOtcsGTJh8tw9U0cgRKTrOnyDpP1uvI1AVEkoRKYaAvR902ByotFOw==} + dependencies: + debug: 4.1.1 + is2: 2.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /speedline-core@1.4.2: + resolution: {integrity: sha512-9/5CApkKKl6bS6jJ2D0DQllwz/1xq3cyJCR6DLgAQnkj5djCuq8NbflEdD2TI01p8qzS9qaKjzxM9cHT11ezmg==} + engines: {node: '>=5.0'} + dependencies: + '@types/node': 14.18.29 + image-ssim: 0.2.0 + jpeg-js: 0.1.2 + dev: true + + /split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + dev: true + + /split2@2.2.0: + resolution: {integrity: sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==} + dependencies: + through2: 2.0.5 + dev: true + + /split2@4.1.0: + resolution: {integrity: sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==} + engines: {node: '>= 10.x'} + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /sprintf-js@1.1.2: + resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==} + dev: true + + /sqlite3@5.1.2: + resolution: {integrity: sha512-D0Reg6pRWAFXFUnZKsszCI67tthFD8fGPewRddDCX6w4cYwz3MbvuwRICbL+YQjBAh9zbw+lJ/V9oC8nG5j6eg==} + requiresBuild: true + peerDependenciesMeta: + node-gyp: + optional: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.10 + node-addon-api: 4.3.0 + tar: 6.1.11 + optionalDependencies: + node-gyp: 8.4.1 + transitivePeerDependencies: + - bluebird + - encoding + - supports-color + dev: true + + /sqlstring@2.3.1: + resolution: {integrity: sha512-ooAzh/7dxIG5+uDik1z/Rd1vli0+38izZhGzSa34FwR7IbelPWCCKSNIl8jlL/F7ERvy8CB2jNeM1E9i9mXMAQ==} + engines: {node: '>= 0.6'} + dev: true + + /sse@0.0.8: + resolution: {integrity: sha512-cviG7JH31TUhZeaEVhac3zTzA+2FwA7qvHziAHpb7mC7RNVJ/RbHN+6LIGsS2ugP4o2H15DWmrSMK+91CboIcg==} + engines: {node: '>=0.4.0'} + dependencies: + options: 0.0.6 + dev: true + + /sshpk@1.17.0: + resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + dev: true + + /ssri@8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + requiresBuild: true + dependencies: + minipass: 3.3.4 + dev: true + optional: true + + /stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + dev: true + + /stack-generator@2.0.10: + resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} + dependencies: + stackframe: 1.3.4 + dev: true + + /stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + dev: true + + /stack-utils@2.0.5: + resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==} + engines: {node: '>=10'} + dependencies: + escape-string-regexp: 2.0.0 + dev: true + + /stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + dev: true + + /standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + dev: true + + /static-eval@2.1.0: + resolution: {integrity: sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw==} + dependencies: + escodegen: 1.14.3 + dev: true + + /static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + dev: true + + /static-module@2.2.5: + resolution: {integrity: sha512-D8vv82E/Kpmz3TXHKG8PPsCPg+RAX6cbCOyvjM6x04qZtQ47EtJFVwRsdov3n5d6/6ynrOY9XB4JkaZwB2xoRQ==} + dependencies: + concat-stream: 1.6.2 + convert-source-map: 1.9.0 + duplexer2: 0.1.4 + escodegen: 1.9.1 + falafel: 2.2.5 + has: 1.0.3 + magic-string: 0.22.5 + merge-source-map: 1.0.4 + object-inspect: 1.4.1 + quote-stream: 1.0.2 + readable-stream: 2.3.7 + shallow-copy: 0.0.1 + static-eval: 2.1.0 + through2: 2.0.5 + dev: true + + /statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + dev: true + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: true + + /stream-browserify@2.0.2: + resolution: {integrity: sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.7 + dev: true + + /stream-cache@0.0.2: + resolution: {integrity: sha512-FsMTiRi4aXOcbL3M2lh7yAOWqM7kfVWQfkJ6kelrhdKNpJJVm0IebICQ2LURsbC5w9XfPSRwd9DkfqDHR9OP3g==} + dev: true + + /stream-combiner2@1.1.1: + resolution: {integrity: sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==} + dependencies: + duplexer2: 0.1.4 + readable-stream: 2.3.7 + dev: true + + /stream-combiner@0.0.2: + resolution: {integrity: sha512-Z2D5hPQapscuHNqiyUgjnF1sxG/9CB7gs1a9vcS2/OvMiFwmm6EZw9IjbU34l5mPXS62RidpoBdyB83E0GXHLw==} + dependencies: + duplexer: 0.0.4 + dev: true + + /stream-events@1.0.5: + resolution: {integrity: sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==} + dependencies: + stubs: 3.0.0 + dev: true + + /stream-from-promise@1.0.0: + resolution: {integrity: sha512-j84KLkudt+gr8KJ21RB02btPLx61uGbrLnewsWz6QKmsz8/c4ZFqXw6mJh5+G4oRN7DgDxdbjPxnpySpg1mUig==} + engines: {node: '>=0.10.0'} + dev: true + + /stream-http@2.8.3: + resolution: {integrity: sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==} + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 2.3.7 + to-arraybuffer: 1.0.1 + xtend: 4.0.2 + dev: true + + /stream-http@3.2.0: + resolution: {integrity: sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==} + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 3.6.0 + xtend: 4.0.2 + dev: true + + /stream-serializer@1.1.2: + resolution: {integrity: sha512-I/GbDmZwBLn4/gpW4gOwt+jc/cVXt0kQwLOBuY/YLIACfwAnK88qzvSHyyu1+YgoALrWTgbnAVRRirVjGUCTBg==} + dev: true + + /stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + dev: true + + /stream-source@0.3.5: + resolution: {integrity: sha512-ZuEDP9sgjiAwUVoDModftG0JtYiLUV8K4ljYD1VyUMRWtbVf92474o4kuuul43iZ8t/hRuiDAx1dIJSvirrK/g==} + dev: true + + /stream-splicer@2.0.1: + resolution: {integrity: sha512-Xizh4/NPuYSyAXyT7g8IvdJ9HJpxIGL9PjyhtywCZvvP0OPIdqyrr4dMikeuvY8xahpdKEBlBTySe583totajg==} + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.7 + dev: true + + /stream-to-string@1.2.0: + resolution: {integrity: sha512-8drZlFIKBHSMdX9GCWv8V9AAWnQcTqw0iAI6/GC7UJ0H0SwKeFKjOoZfGY1tOU00GGU7FYZQoJ/ZCUEoXhD7yQ==} + dependencies: + promise-polyfill: 1.1.6 + dev: true + + /streamsearch@0.1.2: + resolution: {integrity: sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==} + engines: {node: '>=0.8.0'} + dev: true + + /streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + dev: true + + /strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + dev: true + + /string-format-obj@1.1.1: + resolution: {integrity: sha512-Mm+sROy+pHJmx0P/0Bs1uxIX6UhGJGj6xDGQZ5zh9v/SZRmLGevp+p0VJxV7lirrkAmQ2mvva/gHKpnF/pTb+Q==} + dev: true + + /string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + dev: true + + /string-to-stream@3.0.1: + resolution: {integrity: sha512-Hl092MV3USJuUCC6mfl9sPzGloA3K5VwdIeJjYIkXY/8K+mUvaeEabWJgArp+xXrsWxCajeT2pc4axbVhIZJyg==} + dependencies: + readable-stream: 3.6.0 + dev: true + + /string-width@1.0.2: + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} + engines: {node: '>=0.10.0'} + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + dev: true + + /string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string.prototype.trimend@1.0.5: + resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /string.prototype.trimstart@1.0.5: + resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + es-abstract: 1.20.4 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /stringify-entities@4.0.3: + resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + dev: true + + /strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + dependencies: + ansi-regex: 2.1.1 + dev: true + + /strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + dependencies: + ansi-regex: 3.0.1 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom-buffer@0.1.1: + resolution: {integrity: sha512-dbIOX/cOLFgLH/2ofd7n78uPD3uPkXyt3P1IgaVoGiPYEdOnb7D1mawyhOTXyYWva1kCuRxJY5FkMsVKYlZRRg==} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + is-utf8: 0.2.1 + dev: true + + /strip-bom-string@0.1.2: + resolution: {integrity: sha512-3DgNqQFTfOwWgxn3cXsa6h/WRgFa7dVb6/7YqwfJlBpLSSQbiU1VhaBNRKmtLI59CHjc9awLp9yGJREu7AnaMQ==} + engines: {node: '>=0.10.0'} + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + dev: true + + /strip-eof@1.0.0: + resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} + engines: {node: '>=0.10.0'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /stripe@7.63.1: + resolution: {integrity: sha512-W6R2CzMF87DeWVtxrAD8E9As62VIu2M9Ece+YKVw2P4oOBgvj5M2F2xH8R5VMmnDtmx4RJtg8PIJ4DmijpLU6g==} + engines: {node: ^6 || ^8.1 || >=10.*} + requiresBuild: true + dependencies: + qs: 6.11.0 + dev: true + + /strong-error-handler@3.5.0: + resolution: {integrity: sha512-PCMOf6RYni7wMD3ytGN/TBIJdKZ/EfgItgE8tVrJNGVAf2X39L7I0r/tlDyn+1G9qfVCZL0mSeutljpkOpBy1Q==} + engines: {node: '>=10'} + dependencies: + '@types/express': 4.17.14 + accepts: 1.3.8 + debug: 4.3.4 + ejs: 3.1.8 + fast-safe-stringify: 2.1.1 + http-status: 1.5.3 + js2xmlparser: 4.0.2 + strong-globalize: 6.0.5 + transitivePeerDependencies: + - supports-color + dev: true + + /strong-error-handler@4.0.0: + resolution: {integrity: sha512-Ki59WSOfSEod6IkDUB4uf9+DwkCLQRbEdYqen167I/zyPps9x9gS+UzhLZOcer58RA6iFmoGg/+CN/x5d+Cv3Q==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + '@types/express': 4.17.14 + accepts: 1.3.8 + debug: 4.3.4 + ejs: 3.1.8 + fast-safe-stringify: 2.1.1 + http-status: 1.5.3 + js2xmlparser: 4.0.2 + strong-globalize: 6.0.5 + transitivePeerDependencies: + - supports-color + dev: true + + /strong-globalize@4.1.3: + resolution: {integrity: sha512-SJegV7w5D4AodEspZJtJ7rls3fmi+Zc0PdyJCqBsg4RN9B8TC80/uAI2fikC+s1Jp9FLvr2vDX8f0Fqc62M4OA==} + engines: {node: '>=6'} + dependencies: + accept-language: 3.0.18 + debug: 4.3.4 + globalize: 1.7.0 + lodash: 4.17.21 + md5: 2.3.0 + mkdirp: 0.5.6 + os-locale: 3.1.0 + yamljs: 0.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /strong-globalize@5.1.0: + resolution: {integrity: sha512-9cooAb6kNMDFmTDybkkch1x7b+LuzZNva8oIr+MxXnvx9jcvw4/4DTSXPc53mG68G0Q9YOTYZkhDkWe/DiJ1Qg==} + engines: {node: '>=8.9'} + dependencies: + accept-language: 3.0.18 + debug: 4.3.4 + globalize: 1.7.0 + lodash: 4.17.21 + md5: 2.3.0 + mkdirp: 0.5.6 + os-locale: 5.0.0 + yamljs: 0.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /strong-globalize@6.0.5: + resolution: {integrity: sha512-7nfUli41TieV9/TSc0N62ve5Q4nfrpy/T0nNNy6TyD3vst79QWmeylCyd3q1gDxh8dqGEtabLNCdPQP1Iuvecw==} + engines: {node: '>=10'} + dependencies: + accept-language: 3.0.18 + debug: 4.3.4 + globalize: 1.7.0 + lodash: 4.17.21 + md5: 2.3.0 + mkdirp: 1.0.4 + os-locale: 5.0.0 + yamljs: 0.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /strong-remoting@3.17.0: + resolution: {integrity: sha512-MfDyLxmoSizuxBE5C8S2A9nPmy4sQquoZNs6NtbSEmaX2OFKlvb/AhTKU9An+Xuee1RRQHEIun8Q/nO+Lp/H6g==} + engines: {node: '>=8'} + dependencies: + async: 3.2.4 + body-parser: 1.20.1 + debug: 4.3.4 + depd: 2.0.0 + escape-string-regexp: 2.0.0 + eventemitter2: 5.0.1 + express: 4.18.2 + inflection: 1.13.4 + jayson: 2.1.2 + js2xmlparser: 3.0.0 + loopback-datatype-geopoint: 1.0.0 + loopback-phase: 3.4.0 + mux-demux: 3.7.9 + qs: 6.11.0 + request: 2.88.2 + sse: 0.0.8 + strong-error-handler: 3.5.0 + strong-globalize: 5.1.0 + traverse: 0.6.7 + xml2js: 0.4.23 + transitivePeerDependencies: + - supports-color + dev: true + + /stubs@3.0.0: + resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} + dev: true + + /style-to-object@0.4.1: + resolution: {integrity: sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==} + dependencies: + inline-style-parser: 0.1.1 + dev: true + + /subarg@1.0.0: + resolution: {integrity: sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==} + dependencies: + minimist: 1.2.7 + dev: true + + /subscriptions-transport-ws@0.9.19(graphql@14.7.0): + resolution: {integrity: sha512-dxdemxFFB0ppCLg10FTtRqH/31FNRL1y1BQv8209MK5I4CwALb7iihQg+7p65lFcIl8MHatINWBLOqpgU4Kyyw==} + deprecated: The `subscriptions-transport-ws` package is no longer maintained. We recommend you use `graphql-ws` instead. For help migrating Apollo software to `graphql-ws`, see https://www.apollographql.com/docs/apollo-server/data/subscriptions/#switching-from-subscriptions-transport-ws For general help using `graphql-ws`, see https://github.com/enisdenjo/graphql-ws/blob/master/README.md + peerDependencies: + graphql: '>=0.10.0' + dependencies: + backo2: 1.0.2 + eventemitter3: 3.1.2 + graphql: 14.7.0 + iterall: 1.3.0 + symbol-observable: 1.2.0 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + + /success-symbol@0.1.0: + resolution: {integrity: sha512-7S6uOTxPklNGxOSbDIg4KlVLBQw1UiGVyfCUYgYxrZUKRblUkmGj7r8xlfQoFudvqLv6Ap5gd76/IIFfI9JG2A==} + engines: {node: '>=0.10.0'} + dev: true + + /superagent@5.3.1: + resolution: {integrity: sha512-wjJ/MoTid2/RuGCOFtlacyGNxN9QLMgcpYLDQlWFIhhdJ93kNscFonGvrpAHSCVjRVj++DGCglocF7Aej1KHvQ==} + engines: {node: '>= 7.0.0'} + deprecated: Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at . + dependencies: + component-emitter: 1.3.0 + cookiejar: 2.1.3 + debug: 4.3.4 + fast-safe-stringify: 2.1.1 + form-data: 3.0.1 + formidable: 1.2.6 + methods: 1.1.2 + mime: 2.6.0 + qs: 6.11.0 + readable-stream: 3.6.0 + semver: 7.3.8 + transitivePeerDependencies: + - supports-color + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-hyperlinks@2.3.0: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /swap-case@1.1.2: + resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} + dependencies: + lower-case: 1.1.4 + upper-case: 1.1.3 + dev: true + + /swig@1.4.2: + resolution: {integrity: sha512-23eN2Cmm6XmSc9j//g7J/PlYBdm60eznA/snxYZLVpoy4diL2wzCqEsf6ThVwRhhYIngwSNSztvIdrdH9sTCGA==} + engines: {node: '>=0.10.0'} + deprecated: This package is no longer maintained + hasBin: true + requiresBuild: true + dependencies: + optimist: 0.6.1 + uglify-js: 2.4.24 + dev: true + + /symbol-observable@1.2.0: + resolution: {integrity: sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==} + engines: {node: '>=0.10.0'} + dev: true + + /symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + dev: true + + /syntax-error@1.4.0: + resolution: {integrity: sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==} + dependencies: + acorn-node: 1.8.2 + dev: true + + /tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: true + + /tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.0 + dev: true + + /tar@6.1.11: + resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} + engines: {node: '>= 10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 3.3.4 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: true + + /teeny-request@6.0.3: + resolution: {integrity: sha512-TZG/dfd2r6yeji19es1cUIwAlVD8y+/svB1kAC2Y0bjEyysrfbO8EZvJBRwIE6WkwmUoB7uvWLwTIhJbMXZ1Dw==} + dependencies: + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + node-fetch: 2.6.12 + stream-events: 1.0.5 + uuid: 7.0.3 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /teeny-request@7.1.1: + resolution: {integrity: sha512-iwY6rkW5DDGq8hE2YgNQlKbptYpY5Nn2xecjQiNjOXWbKzPGUfmeUBCSQbbr306d7Z7U2N0TPl+/SwYRfua1Dg==} + engines: {node: '>=10'} + dependencies: + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + node-fetch: 2.6.12 + stream-events: 1.0.5 + uuid: 8.3.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /teeny-request@7.2.0: + resolution: {integrity: sha512-SyY0pek1zWsi0LRVAALem+avzMLc33MKW/JLLakdP4s9+D7+jHcy5x6P+h94g2QNZsAqQNfX5lsbd3WSeJXrrw==} + engines: {node: '>=10'} + requiresBuild: true + dependencies: + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + node-fetch: 2.6.12 + stream-events: 1.0.5 + uuid: 8.3.2 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + optional: true + + /term-size@1.2.0: + resolution: {integrity: sha512-7dPUZQGy/+m3/wjVz3ZW5dobSoD/02NxJpoXUX0WIyjfVS3l0c+b/+9phIDFA7FHzkYtwtMFgeGZ/Y8jVTeqQQ==} + engines: {node: '>=4'} + dependencies: + execa: 0.7.0 + dev: true + + /terminal-link@2.1.1: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} + engines: {node: '>=8'} + dependencies: + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.3.0 + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /text-encoding@0.6.4: + resolution: {integrity: sha512-hJnc6Qg3dWoOMkqP53F0dzRIgtmsAge09kxUIqGrEUS4qr5rWLckGYaQAVr+opBrIMRErGgy6f5aPnyPpyGRfg==} + deprecated: no longer maintained + dev: true + + /third-party-web@0.11.1: + resolution: {integrity: sha512-PBS478cWhvCM8seuloomV5lGHvu2qMOCj8gq8wKOApdfAaGh9l2rYZkdsBDaQyQg/6plov3uodc6sZ/3c1lu/g==} + dev: true + + /throat@5.0.0: + resolution: {integrity: sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==} + dev: true + + /throat@6.0.1: + resolution: {integrity: sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==} + dev: true + + /throttleit@1.0.0: + resolution: {integrity: sha512-rkTVqu6IjfQ/6+uNuuc3sZek4CEYxTJom3IktzgdSxcZqdARuebbA/f4QmAxMQIxqq9ZLEUkSYqvuk1I6VKq4g==} + dev: true + + /through2-filter@3.0.0: + resolution: {integrity: sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==} + dependencies: + through2: 2.0.5 + xtend: 4.0.2 + dev: true + + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.7 + xtend: 4.0.2 + dev: true + + /through2@3.0.2: + resolution: {integrity: sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==} + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + dependencies: + readable-stream: 3.6.0 + dev: true + + /through@2.3.4: + resolution: {integrity: sha512-DwbmSAcABsMazNkLOJJSLRC3gfh4cPxUxJCn9npmvbcI6undhgoJ2ShvEOgZrW8BH62Gyr9jKboGbfFcmY5VsQ==} + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /timed-out@4.0.1: + resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} + engines: {node: '>=0.10.0'} + dev: true + + /timers-browserify@1.4.2: + resolution: {integrity: sha512-PIxwAupJZiYU4JmVZYwXp9FKsHMXb5h0ZEFyuXTAn8WLHOlcij+FEcbrvDsom1o5dr1YggEtFbECvGCW2sT53Q==} + engines: {node: '>=0.6.0'} + dependencies: + process: 0.11.10 + dev: true + + /timm@1.7.1: + resolution: {integrity: sha512-IjZc9KIotudix8bMaBW6QvMuq64BrJWFs1+4V0lXwWGQZwH+LnX87doAYhem4caOEusRP9/g6jVDQmZ8XOk1nw==} + dev: true + + /tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + dev: true + + /tiny-json-http@7.4.2: + resolution: {integrity: sha512-+3ns4PfQTLaF69zGASkAfDoOEVmwYTXSDrU6VR93h317uFOW7evFzKa7Ih9JzPHiYSee3lUXHLAGhws2wFSexQ==} + requiresBuild: true + dev: true + + /tinycolor2@1.4.2: + resolution: {integrity: sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==} + dev: true + + /tinyqueue@2.0.3: + resolution: {integrity: sha512-ppJZNDuKGgxzkHihX8v9v9G5f+18gzaTfrukGrq6ueg0lmH4nqVnA2IPG0AEH3jKEk2GRJCUhDoqpoiw3PHLBA==} + dev: true + + /title-case@1.1.2: + resolution: {integrity: sha512-xYbo5Um5MBgn24xJSK+x5hZ8ehuGXTVhgx32KJCThHRHwpyIb1lmABi1DH5VvN9E7rNEquPjz//rF/tZQd7mjQ==} + dependencies: + sentence-case: 1.1.3 + upper-case: 1.1.3 + dev: true + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: true + + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + + /to-absolute-glob@2.0.2: + resolution: {integrity: sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==} + engines: {node: '>=0.10.0'} + dependencies: + is-absolute: 1.0.0 + is-negated-glob: 1.0.0 + dev: true + + /to-array@0.1.4: + resolution: {integrity: sha512-LhVdShQD/4Mk4zXNroIQZJC+Ap3zgLcDuwEdcmLv9CCO73NWockQDwyUnW/m8VX/EElfL6FcYx7EeutN4HJA6A==} + dev: true + + /to-arraybuffer@1.0.1: + resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /to-file@0.2.0: + resolution: {integrity: sha512-xLyYVRKJQTwy2tKMOLD0M0yL+YSZVgMAzkaY9hh7GhzgBBHSIWARDkgPx8krPPm0mW5CgoIFsQEdKRFOyIRdqg==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 0.2.5 + extend-shallow: 2.0.1 + file-contents: 0.2.4 + glob-parent: 2.0.0 + is-valid-glob: 0.3.0 + isobject: 2.1.0 + lazy-cache: 2.0.2 + vinyl: 1.2.0 + dev: true + + /to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + dev: true + + /to-utf8@0.0.1: + resolution: {integrity: sha512-zks18/TWT1iHO3v0vFp5qLKOG27m67ycq/Y7a7cTiRuUNlc4gf3HGnkRgMv0NyhnfTamtkYBJl+YeD1/j07gBQ==} + dev: true + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: true + + /token-stream@1.0.0: + resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} + dev: true + + /topojson-client@3.1.0: + resolution: {integrity: sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==} + hasBin: true + dependencies: + commander: 2.20.3 + dev: true + + /topojson-server@3.0.1: + resolution: {integrity: sha512-/VS9j/ffKr2XAOjlZ9CgyyeLmgJ9dMwq6Y0YEON8O7p/tGGk+dCWnrE03zEdu7i4L7YsFZLEPZPzCvcB7lEEXw==} + hasBin: true + dependencies: + commander: 2.20.3 + dev: true + + /toposort-class@1.0.1: + resolution: {integrity: sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==} + dev: true + + /toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + dev: true + + /tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + dependencies: + psl: 1.9.0 + punycode: 2.1.1 + dev: true + + /tough-cookie@4.1.2: + resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==} + engines: {node: '>=6'} + dependencies: + psl: 1.9.0 + punycode: 2.1.1 + universalify: 0.2.0 + url-parse: 1.5.10 + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + + /tr46@2.1.0: + resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==} + engines: {node: '>=8'} + dependencies: + punycode: 2.1.1 + dev: true + + /traverse@0.6.7: + resolution: {integrity: sha512-/y956gpUo9ZNCb99YjxG7OaslxZWHfCHAUUfshwqOXmxUIvqLjVO581BT+gM59+QV9tFe6/CGG53tsA1Y7RSdg==} + dev: true + + /trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + dev: true + + /trough@2.1.0: + resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} + dev: true + + /ts-invariant@0.4.4: + resolution: {integrity: sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==} + dependencies: + tslib: 1.14.1 + dev: true + + /ts-morph@15.1.0: + resolution: {integrity: sha512-RBsGE2sDzUXFTnv8Ba22QfeuKbgvAGJFuTN7HfmIRUkgT/NaVLfDM/8OFm2NlFkGlWEXdpW5OaFIp1jvqdDuOg==} + requiresBuild: true + dependencies: + '@ts-morph/common': 0.16.0 + code-block-writer: 11.0.3 + dev: true + + /ts-node@10.9.1(@types/node@14.18.29)(typescript@4.8.4): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.3 + '@types/node': 14.18.29 + acorn: 8.8.1 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.8.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /tsconfig-paths@3.14.1: + resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} + requiresBuild: true + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.1 + minimist: 1.2.7 + strip-bom: 3.0.0 + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: true + + /tslib@2.6.1: + resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==} + dev: true + + /tsscmp@1.0.6: + resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} + engines: {node: '>=0.6.x'} + dev: true + + /tty-browserify@0.0.1: + resolution: {integrity: sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==} + dev: true + + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /tunnel@0.0.5: + resolution: {integrity: sha512-gj5sdqherx4VZKMcBA4vewER7zdK25Td+z1npBqpbDys4eJrLx+SlYjJvq1bDXs2irkuJM5pf8ktaEQVipkrbA==} + engines: {node: '>=0.6.11 <=0.7.0 || >=0.7.3'} + dev: true + + /turf-jsts@1.2.3: + resolution: {integrity: sha512-Ja03QIJlPuHt4IQ2FfGex4F4JAr8m3jpaHbFbQrgwr7s7L6U8ocrHiF3J1+wf9jzhGKxvDeaCAnGDot8OjGFyA==} + dev: true + + /tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + dev: true + + /twilio@3.83.0(debug@4.3.4): + resolution: {integrity: sha512-tiJ4NdTIppUR/Vb0vSfGp4wYa1Higv72EXleaGj/ZB40knG1BuWAjMIV3adkq2gKCq9SHsBqCdfAha6yQXipQw==} + engines: {node: '>=6.0'} + dependencies: + axios: 0.26.1(debug@4.3.4) + dayjs: 1.11.6 + https-proxy-agent: 5.0.1 + jsonwebtoken: 8.5.1 + lodash: 4.17.21 + q: 2.0.3 + qs: 6.11.0 + rootpath: 0.1.2 + scmp: 2.1.0 + url-parse: 1.5.10 + xmlbuilder: 13.0.2 + transitivePeerDependencies: + - debug + - supports-color + dev: true + + /type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + dev: true + + /type-component@0.0.1: + resolution: {integrity: sha512-mDZRBQS2yZkwRQKfjJvQ8UIYJeBNNWCq+HBNstl9N5s9jZ4dkVYXEGkVPsSCEh5Ld4JM1kmrZTzjnrqSAIQ7dw==} + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + dev: true + + /type@1.2.0: + resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} + dev: true + + /type@2.7.2: + resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} + dev: true + + /typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + requiresBuild: true + dependencies: + is-typedarray: 1.0.0 + dev: true + + /typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + dev: true + + /typescript@4.8.4: + resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} + engines: {node: '>=4.2.0'} + hasBin: true + requiresBuild: true + dev: true + + /uglify-es@3.3.9: + resolution: {integrity: sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==} + engines: {node: '>=0.8.0'} + deprecated: support for ECMAScript is superseded by `uglify-js` as of v3.13.0 + hasBin: true + dependencies: + commander: 2.13.0 + source-map: 0.6.1 + dev: true + + /uglify-js@2.4.24: + resolution: {integrity: sha512-tktIjwackfZLd893KGJmXc1hrRHH1vH9Po3xFh1XBjjeGAnN02xJ3SuoA+n1L29/ZaCA18KzCFlckS+vfPugiA==} + engines: {node: '>=0.4.0'} + hasBin: true + dependencies: + async: 0.2.10 + source-map: 0.1.34 + uglify-to-browserify: 1.0.2 + yargs: 3.5.4 + dev: true + + /uglify-js@2.8.29: + resolution: {integrity: sha512-qLq/4y2pjcU3vhlhseXGGJ7VbFO4pBANu0kwl8VCa9KEI0V8VfZIx2Fy3w01iSTA/pGwKZSmu/+I4etLNDdt5w==} + engines: {node: '>=0.8.0'} + hasBin: true + dependencies: + source-map: 0.5.7 + yargs: 3.10.0 + optionalDependencies: + uglify-to-browserify: 1.0.2 + dev: true + + /uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + engines: {node: '>=0.8.0'} + hasBin: true + requiresBuild: true + dev: true + + /uglify-to-browserify@1.0.2: + resolution: {integrity: sha512-vb2s1lYx2xBtUgy+ta+b2J/GLVUR+wmpINwHePmPRhOsIVCG2wDzKJ0n14GslH1BifsqVzSOwQhRaCAsZ/nI4Q==} + dev: true + + /uid2@0.0.3: + resolution: {integrity: sha512-5gSP1liv10Gjp8cMEnFd6shzkL/D6W1uhXSFNCxDC+YI8+L8wkCYCbJ7n77Ezb4wE/xzMogecE+DtamEe9PZjg==} + dev: true + + /uid2@0.0.4: + resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==} + dev: true + + /ultron@1.1.1: + resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==} + dev: true + + /umd@3.0.3: + resolution: {integrity: sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==} + hasBin: true + dev: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /unc-path-regex@0.1.2: + resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} + engines: {node: '>=0.10.0'} + dev: true + + /undeclared-identifiers@1.1.3: + resolution: {integrity: sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==} + hasBin: true + dependencies: + acorn-node: 1.8.2 + dash-ast: 1.0.0 + get-assigned-identifiers: 1.2.0 + simple-concat: 1.0.1 + xtend: 4.0.2 + dev: true + + /underscore-plus@1.7.0: + resolution: {integrity: sha512-A3BEzkeicFLnr+U/Q3EyWwJAQPbA19mtZZ4h+lLq3ttm9kn8WC4R3YpuJZEXmWdLjYP47Zc8aLZm9kwdv+zzvA==} + dependencies: + underscore: 1.13.6 + dev: true + + /underscore.string@3.3.6: + resolution: {integrity: sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==} + dependencies: + sprintf-js: 1.1.2 + util-deprecate: 1.0.2 + dev: true + + /underscore@1.13.6: + resolution: {integrity: sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==} + dev: true + + /underscore@1.7.0: + resolution: {integrity: sha512-cp0oQQyZhUM1kpJDLdGO1jPZHgS/MpzoWYfe9+CM2h/QGDZlqwT2T3YGukuBdaNJ/CAPoeyAZRRHz8JFo176vA==} + dev: true + + /unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + dev: true + + /unicode-properties@1.4.1: + resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} + dependencies: + base64-js: 1.5.1 + unicode-trie: 2.0.0 + dev: true + + /unicode-trie@0.3.1: + resolution: {integrity: sha512-WgVuO0M2jDl7hVfbPgXv2LUrD81HM0bQj/bvLGiw6fJ4Zo8nNFnDrA0/hU2Te/wz6pjxCm5cxJwtLjo2eyV51Q==} + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + dev: true + + /unicode-trie@2.0.0: + resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} + dependencies: + pako: 0.2.9 + tiny-inflate: 1.0.3 + dev: true + + /unified@10.1.2: + resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + dependencies: + '@types/unist': 2.0.6 + bail: 2.0.2 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 4.1.0 + trough: 2.1.0 + vfile: 5.3.5 + dev: true + + /union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + dev: true + + /unique-filename@1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + requiresBuild: true + dependencies: + unique-slug: 2.0.2 + dev: true + optional: true + + /unique-slug@2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + requiresBuild: true + dependencies: + imurmurhash: 0.1.4 + dev: true + optional: true + + /unique-stream@2.3.1: + resolution: {integrity: sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==} + dependencies: + json-stable-stringify-without-jsonify: 1.0.1 + through2-filter: 3.0.0 + dev: true + + /unique-string@1.0.0: + resolution: {integrity: sha512-ODgiYu03y5g76A1I9Gt0/chLCzQjvzDy7DsZGsLOE/1MrF6wriEskSncj1+/C58Xk/kPZDppSctDybCwOSaGAg==} + engines: {node: '>=4'} + dependencies: + crypto-random-string: 1.0.0 + dev: true + + /unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + requiresBuild: true + dependencies: + crypto-random-string: 2.0.0 + dev: true + optional: true + + /unist-builder@3.0.0: + resolution: {integrity: sha512-GFxmfEAa0vi9i5sd0R2kcrI9ks0r82NasRq5QHh2ysGngrc6GiqD5CDf1FjPenY4vApmFASBIIlk/jj5J5YbmQ==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-generated@2.0.0: + resolution: {integrity: sha512-TiWE6DVtVe7Ye2QxOVW9kqybs6cZexNwTwSMVgkfjEReqy/xwGpAXb99OxktoWwmL+Z+Epb0Dn8/GNDYP1wnUw==} + dev: true + + /unist-util-is@5.1.1: + resolution: {integrity: sha512-F5CZ68eYzuSvJjGhCLPL3cYx45IxkqXSetCcRgUXtbcm50X2L9oOWQlfUfDdAf+6Pd27YDblBfdtmsThXmwpbQ==} + dev: true + + /unist-util-map@2.0.1: + resolution: {integrity: sha512-VdNvk4BQUUU9Rgr8iUOvclHa/iN9O+6Dt66FKij8l9OVezGG37gGWCPU5KSax1R2degqXFvl3kWTkvzL79e9tQ==} + dependencies: + '@types/mdast': 3.0.10 + object-assign: 4.1.1 + dev: true + + /unist-util-position-from-estree@1.1.1: + resolution: {integrity: sha512-xtoY50b5+7IH8tFbkw64gisG9tMSpxDjhX9TmaJJae/XuxQ9R/Kc8Nv1eOsf43Gt4KV/LkriMy9mptDr7XLcaw==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-position@4.0.3: + resolution: {integrity: sha512-p/5EMGIa1qwbXjA+QgcBXaPWjSnZfQ2Sc3yBEEfgPwsEmJd8Qh+DSk3LGnmOM4S1bY2C0AjmMnB8RuEYxpPwXQ==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-remove-position@4.0.1: + resolution: {integrity: sha512-0yDkppiIhDlPrfHELgB+NLQD5mfjup3a8UYclHruTJWmY74je8g+CIFr79x5f6AkmzSwlvKLbs63hC0meOMowQ==} + dependencies: + '@types/unist': 2.0.6 + unist-util-visit: 4.1.1 + dev: true + + /unist-util-stringify-position@3.0.2: + resolution: {integrity: sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-visit-parents@5.1.1: + resolution: {integrity: sha512-gks4baapT/kNRaWxuGkl5BIhoanZo7sC/cUT/JToSRNL1dYoXRFl75d++NkjYk4TAu2uv2Px+l8guMajogeuiw==} + dependencies: + '@types/unist': 2.0.6 + unist-util-is: 5.1.1 + dev: true + + /unist-util-visit@4.1.1: + resolution: {integrity: sha512-n9KN3WV9k4h1DxYR1LoajgN93wpEi/7ZplVe02IoB4gH5ctI1AaF2670BLHQYbwj+pY83gFtyeySFiyMHJklrg==} + dependencies: + '@types/unist': 2.0.6 + unist-util-is: 5.1.1 + unist-util-visit-parents: 5.1.1 + dev: true + + /universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + dev: true + + /universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /unix-dgram@2.0.6: + resolution: {integrity: sha512-AURroAsb73BZ6CdAyMrTk/hYKNj3DuYYEuOaB8bYMOHGKupRNScw90Q5C71tWJc3uE7dIeXRyuwN0xLLq3vDTg==} + engines: {node: '>=0.10.48'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + nan: 2.17.0 + dev: true + optional: true + + /unorm@1.6.0: + resolution: {integrity: sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==} + engines: {node: '>= 0.4.0'} + dev: true + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: true + + /unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + dev: true + + /unzip-response@2.0.1: + resolution: {integrity: sha512-N0XH6lqDtFH84JxptQoZYmloF4nzrQqqrAymNj+/gW60AO2AZgOcf4O/nUXJcYfyQkqvMo9lSupBZmmgvuVXlw==} + engines: {node: '>=4'} + dev: true + + /upath@1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + dev: true + + /update-browserslist-db@1.0.10(browserslist@4.21.4): + resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.4 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /update-notifier@2.5.0: + resolution: {integrity: sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==} + engines: {node: '>=4'} + dependencies: + boxen: 1.3.0 + chalk: 2.4.2 + configstore: 3.1.5 + import-lazy: 2.1.0 + is-ci: 1.2.1 + is-installed-globally: 0.1.0 + is-npm: 1.0.0 + latest-version: 3.1.0 + semver-diff: 2.1.0 + xdg-basedir: 3.0.0 + dev: true + + /upper-case-first@1.1.2: + resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==} + dependencies: + upper-case: 1.1.3 + dev: true + + /upper-case@1.1.3: + resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==} + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.1.1 + dev: true + + /urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + dev: true + + /url-parse-lax@1.0.0: + resolution: {integrity: sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==} + engines: {node: '>=0.10.0'} + dependencies: + prepend-http: 1.0.4 + dev: true + + /url-parse-lax@3.0.0: + resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} + engines: {node: '>=4'} + dependencies: + prepend-http: 2.0.0 + dev: true + + /url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + + /url-to-options@1.0.1: + resolution: {integrity: sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==} + engines: {node: '>= 4'} + dev: true + + /url@0.10.3: + resolution: {integrity: sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==} + dependencies: + punycode: 1.3.2 + querystring: 0.2.0 + dev: true + + /url@0.11.0: + resolution: {integrity: sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==} + dependencies: + punycode: 1.3.2 + querystring: 0.2.0 + dev: true + + /urlgrey@1.0.0: + resolution: {integrity: sha512-hJfIzMPJmI9IlLkby8QrsCykQ+SXDeO2W5Q9QTW3QpqZVTx4a/K7p8/5q+/isD8vsbVaFgql/gvAoQCRQ2Cb5w==} + dependencies: + fast-url-parser: 1.1.3 + dev: true + + /use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + dev: true + + /usertiming@0.1.8: + resolution: {integrity: sha512-0P7EsAN6Fx/VWFuYaleB1EZZ2UNT8n+lQ1Kdhggo1ZX1vau0Sd6ti3HvKAUWT/2HIXYcgKDUd3XtUrdYdR62MQ==} + dev: true + + /utif@2.0.1: + resolution: {integrity: sha512-Z/S1fNKCicQTf375lIP9G8Sa1H/phcysstNrrSdZKj1f9g58J4NMgb5IgiEZN9/nLMPDwF0W7hdOe9Qq2IYoLg==} + dependencies: + pako: 1.0.11 + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /util.promisify@1.1.1: + resolution: {integrity: sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.1.4 + for-each: 0.3.3 + has-symbols: 1.0.3 + object.getownpropertydescriptors: 2.1.4 + dev: true + + /util@0.10.3: + resolution: {integrity: sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==} + dependencies: + inherits: 2.0.1 + dev: true + + /util@0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + dependencies: + inherits: 2.0.3 + dev: true + + /util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.9 + which-typed-array: 1.1.8 + dev: true + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: true + + /uuid@3.3.2: + resolution: {integrity: sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: true + + /uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + dev: true + + /uuid@7.0.3: + resolution: {integrity: sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==} + hasBin: true + dev: true + + /uuid@8.0.0: + resolution: {integrity: sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==} + hasBin: true + dev: true + + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: true + + /uuid@9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + dev: true + + /uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + dequal: 2.0.3 + diff: 5.1.0 + kleur: 4.1.5 + sade: 1.8.1 + dev: true + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /v8-to-istanbul@8.1.1: + resolution: {integrity: sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==} + engines: {node: '>=10.12.0'} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + convert-source-map: 1.9.0 + source-map: 0.7.4 + dev: true + + /validator@13.7.0: + resolution: {integrity: sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==} + engines: {node: '>= 0.10'} + dev: true + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: true + + /verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: true + + /vfile-location@4.0.1: + resolution: {integrity: sha512-JDxPlTbZrZCQXogGheBHjbRWjESSPEak770XwWPfw5mTc1v1nWGLB/apzZxsx8a0SJVfF8HK8ql8RD308vXRUw==} + dependencies: + '@types/unist': 2.0.6 + vfile: 5.3.5 + dev: true + + /vfile-message@3.1.2: + resolution: {integrity: sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==} + dependencies: + '@types/unist': 2.0.6 + unist-util-stringify-position: 3.0.2 + dev: true + + /vfile@5.3.5: + resolution: {integrity: sha512-U1ho2ga33eZ8y8pkbQLH54uKqGhFJ6GYIHnnG5AhRpAh3OWjkrRHKa/KogbmQn8We+c0KVV3rTOgR9V/WowbXQ==} + dependencies: + '@types/unist': 2.0.6 + is-buffer: 2.0.5 + unist-util-stringify-position: 3.0.2 + vfile-message: 3.1.2 + dev: true + + /vinyl@1.2.0: + resolution: {integrity: sha512-Ci3wnR2uuSAWFMSglZuB8Z2apBdtOyz8CV7dC6/U1XbltXBC+IuutUkXQISz01P+US2ouBuesSbV6zILZ6BuzQ==} + engines: {node: '>= 0.9'} + dependencies: + clone: 1.0.4 + clone-stats: 0.0.1 + replace-ext: 0.0.1 + dev: true + + /vlq@0.2.3: + resolution: {integrity: sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==} + dev: true + + /vm-browserify@1.1.2: + resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + dev: true + + /vm2@3.9.11: + resolution: {integrity: sha512-PFG8iJRSjvvBdisowQ7iVF580DXb1uCIiGaXgm7tynMR1uTBlv7UJlB1zdv5KJ+Tmq1f0Upnj3fayoEOPpCBKg==} + engines: {node: '>=6.0'} + deprecated: The library contains critical security issues and should not be used for production! The maintenance of the project has been discontinued. Consider migrating your code to isolated-vm. + hasBin: true + requiresBuild: true + dependencies: + acorn: 8.8.1 + acorn-walk: 8.2.0 + dev: true + + /void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: true + + /vue-server-renderer@2.7.13: + resolution: {integrity: sha512-GvNnUSHE04+B7EhOrk4QWbLKFMdmj2wLEEJEvtVQ/s04nKIHtxSvG4l9/i+p8q7iN3osEhfh0b/cAmXHifgSaA==} + requiresBuild: true + dependencies: + chalk: 4.1.2 + hash-sum: 2.0.0 + he: 1.2.0 + lodash.template: 4.5.0 + lodash.uniq: 4.5.0 + resolve: 1.22.1 + serialize-javascript: 6.0.0 + source-map: 0.5.6 + dev: true + + /vue@2.7.13: + resolution: {integrity: sha512-QnM6ULTNnPmn71eUO+4hdjfBIA3H0GLsBnchnI/kS678tjI45GOUZhXd0oP/gX9isikXz1PAzSnkPspp9EUNfQ==} + requiresBuild: true + dependencies: + '@vue/compiler-sfc': 2.7.13 + csstype: 3.1.1 + dev: true + + /w3c-hr-time@1.0.2: + resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + deprecated: Use your platform's native performance.now() and performance.timeOrigin. + dependencies: + browser-process-hrtime: 1.0.0 + dev: true + + /w3c-xmlserializer@2.0.0: + resolution: {integrity: sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==} + engines: {node: '>=10'} + dependencies: + xml-name-validator: 3.0.0 + dev: true + + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /watchify@3.11.1: + resolution: {integrity: sha512-WwnUClyFNRMB2NIiHgJU9RQPQNqVeFk7OmZaWf5dC5EnNa0Mgr7imBydbaJ7tGTuPM2hz1Cb4uiBvK9NVxMfog==} + hasBin: true + dependencies: + anymatch: 2.0.0 + browserify: 16.5.2 + chokidar: 2.1.8 + defined: 1.0.1 + outpipe: 1.1.1 + through2: 2.0.5 + xtend: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /weak-map@1.0.8: + resolution: {integrity: sha512-lNR9aAefbGPpHO7AEnY0hCFjz1eTkWCXYvkTRrTHs9qv8zJp+SkVYpzfLIFXQQiG3tVvbNFQgVg2bQS8YGgxyw==} + dev: true + + /web-animations-js@2.3.2: + resolution: {integrity: sha512-TOMFWtQdxzjWp8qx4DAraTWTsdhxVSiWa6NkPFSaPtZ1diKUxTn4yTix73A1euG1WbSOMMPcY51cnjTIHrGtDA==} + dev: true + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + + /webidl-conversions@5.0.0: + resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} + engines: {node: '>=8'} + dev: true + + /webidl-conversions@6.1.0: + resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==} + engines: {node: '>=10.4'} + dev: true + + /websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + dependencies: + http-parser-js: 0.5.8 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + dev: true + + /websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + dev: true + + /websocket-stream@5.2.0: + resolution: {integrity: sha512-2ZfiWuEK/bTi8AhXdYh/lFEUwXtGVcbO4vWUy5XJhf7F6nCMAC8hbXXTarxrmv2BFSwdk3P3bhvgiA9wzT+GFQ==} + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + readable-stream: 3.6.0 + safe-buffer: 5.2.1 + ws: 6.2.2 + xtend: 4.0.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + + /whatwg-encoding@1.0.5: + resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} + dependencies: + iconv-lite: 0.4.24 + dev: true + + /whatwg-fetch@2.0.4: + resolution: {integrity: sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==} + dev: true + + /whatwg-fetch@3.6.2: + resolution: {integrity: sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==} + dev: true + + /whatwg-mimetype@2.3.0: + resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} + dev: true + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + + /whatwg-url@8.7.0: + resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==} + engines: {node: '>=10'} + dependencies: + lodash: 4.17.21 + tr46: 2.1.0 + webidl-conversions: 6.1.0 + dev: true + + /when@3.7.3: + resolution: {integrity: sha512-cUsp3b0BOMVm5kupGM/V6dY2B4IeednZSGajNm6+bGKV5CG3w7qc5RAQLnBjgYuHWDUDSdndYeXr9ayBeLXH6Q==} + dev: true + + /when@3.7.8: + resolution: {integrity: sha512-5cZ7mecD3eYcMiCH4wtRPA5iFJZ50BJYDfckI5RRpQiktMiYTcn0ccLTZOvcbBume+1304fQztxeNzNS9Gvrnw==} + requiresBuild: true + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + + /which-module@2.0.0: + resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} + dev: true + + /which-typed-array@1.1.8: + resolution: {integrity: sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-abstract: 1.20.4 + for-each: 0.3.3 + has-tostringtag: 1.0.0 + is-typed-array: 1.1.9 + dev: true + + /which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wicg-inert@3.1.2: + resolution: {integrity: sha512-Ba9tGNYxXwaqKEi9sJJvPMKuo063umUPsHN0JJsjrs2j8KDSzkWLMZGZ+MH1Jf1Fq4OWZ5HsESJID6nRza2ang==} + dev: true + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: true + + /widest-line@2.0.1: + resolution: {integrity: sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==} + engines: {node: '>=4'} + dependencies: + string-width: 2.1.1 + dev: true + + /window-size@0.1.0: + resolution: {integrity: sha512-1pTPQDKTdd61ozlKGNCjhNRd+KPmgLSGa3mZTHoOliaGcESD8G1PXhh7c1fgiPjVbNVfgy2Faw4BI8/m0cC8Mg==} + engines: {node: '>= 0.8.0'} + dev: true + + /window-size@0.1.4: + resolution: {integrity: sha512-2thx4pB0cV3h+Bw7QmMXcEbdmOzv9t0HFplJH/Lz6yu60hXYy5RT8rUu+wlIreVxWsGN20mo+MHeCSfUpQBwPw==} + engines: {node: '>= 0.10.0'} + hasBin: true + dev: true + + /with@7.0.2: + resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} + engines: {node: '>= 10.0.0'} + dependencies: + '@babel/parser': 7.19.6 + '@babel/types': 7.19.4 + assert-never: 1.2.1 + babel-walk: 3.0.0-canary-5 + dev: true + + /wkx@0.4.8: + resolution: {integrity: sha512-ikPXMM9IR/gy/LwiOSqWlSL3X/J5uk9EO2hHNRXS41eTLXaUFEVw9fn/593jW/tE5tedNg8YjT5HkCa4FqQZyQ==} + dependencies: + '@types/node': 14.18.29 + dev: true + + /word-wrap@1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wordwrap@0.0.2: + resolution: {integrity: sha512-xSBsCeh+g+dinoBv3GAOWM4LcVVO68wLXRanibtBSdUvkGWQRGeE9P7IwU9EmDDi4jA6L44lz15CGMwdw9N5+Q==} + engines: {node: '>=0.4.0'} + dev: true + + /wordwrap@0.0.3: + resolution: {integrity: sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==} + engines: {node: '>=0.4.0'} + dev: true + + /wrap-ansi@2.1.0: + resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} + engines: {node: '>=0.10.0'} + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + dev: true + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + dependencies: + graceful-fs: 4.2.10 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + dev: true + + /ws@3.3.2: + resolution: {integrity: sha512-t+WGpsNxhMR4v6EClXS8r8km5ZljKJzyGhJf7goJz9k5Ye3+b5Bvno5rjqPuIBn5mnn5GBb7o8IrIWHxX1qOLQ==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + async-limiter: 1.0.1 + safe-buffer: 5.1.2 + ultron: 1.1.1 + dev: true + + /ws@3.3.3: + resolution: {integrity: sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + async-limiter: 1.0.1 + safe-buffer: 5.1.2 + ultron: 1.1.1 + dev: true + + /ws@6.2.2: + resolution: {integrity: sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + async-limiter: 1.0.1 + dev: true + + /ws@7.4.6: + resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + + /xdg-basedir@3.0.0: + resolution: {integrity: sha512-1Dly4xqlulvPD3fZUQJLY+FUIeqN3N2MM3uqe4rCJftAvOjFa3jFGfctOgluGx4ahPbUCsZkmJILiP0Vi4T6lQ==} + engines: {node: '>=4'} + dev: true + + /xdg-basedir@4.0.0: + resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} + engines: {node: '>=8'} + requiresBuild: true + dev: true + optional: true + + /xhr@2.6.0: + resolution: {integrity: sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==} + dependencies: + global: 4.4.0 + is-function: 1.0.2 + parse-headers: 2.0.5 + xtend: 4.0.2 + dev: true + + /xml-name-validator@3.0.0: + resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} + dev: true + + /xml-parse-from-string@1.0.1: + resolution: {integrity: sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g==} + dev: true + + /xml2js@0.2.8: + resolution: {integrity: sha512-ZHZBIAO55GHCn2jBYByVPHvHS+o3j8/a/qmpEe6kxO3cTnTCWC3Htq9RYJ5G4XMwMMClD2QkXA9SNdPadLyn3Q==} + dependencies: + sax: 0.5.8 + dev: true + + /xml2js@0.4.19: + resolution: {integrity: sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==} + dependencies: + sax: 1.2.4 + xmlbuilder: 9.0.7 + dev: true + + /xml2js@0.4.23: + resolution: {integrity: sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug==} + engines: {node: '>=4.0.0'} + dependencies: + sax: 1.2.4 + xmlbuilder: 11.0.1 + dev: true + + /xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + dev: true + + /xmlbuilder@13.0.2: + resolution: {integrity: sha512-Eux0i2QdDYKbdbA6AM6xE4m6ZTZr4G4xF9kahI2ukSEMCzwce2eX9WlTI5J3s+NU7hpasFsr8hWIONae7LluAQ==} + engines: {node: '>=6.0'} + dev: true + + /xmlbuilder@9.0.7: + resolution: {integrity: sha512-7YXTQc3P2l9+0rjaUbLwMKRhtmwg1M1eDf6nag7urC7pIPYLD9W/jmzQ4ptRSUbodw5S0jfoGTflLemQibSpeQ==} + engines: {node: '>=4.0'} + dev: true + + /xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + dev: true + + /xmlcreate@1.0.2: + resolution: {integrity: sha512-Mbe56Dvj00onbnSo9J0qj/XlY5bfN9KidsOnpd5tRCsR3ekB3hyyNU9fGrTdqNT5ZNvv4BsA2TcQlignsZyVcw==} + dev: true + + /xmlcreate@2.0.4: + resolution: {integrity: sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==} + dev: true + + /xmldom@0.1.19: + resolution: {integrity: sha512-pDyxjQSFQgNHkU+yjvoF+GXVGJU7e9EnOg/KcGMDihBIKjTsOeDYaECwC/O9bsUWKY+Sd9izfE43JXC46EOHKA==} + engines: {node: '>=0.1'} + deprecated: Deprecated due to CVE-2021-21366 resolved in 0.5.0 + dev: true + + /xmlhttprequest-ssl@1.6.3: + resolution: {integrity: sha512-3XfeQE/wNkvrIktn2Kf0869fC0BN6UpydVasGIeSm2B1Llihf7/0UfZM+eCkOw3P7bP4+qPgqhm7ZoxuJtFU0Q==} + engines: {node: '>=0.4.0'} + dev: true + + /xmlhttprequest@1.8.0: + resolution: {integrity: sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==} + engines: {node: '>=0.4.0'} + dev: true + + /xss@1.0.14: + resolution: {integrity: sha512-og7TEJhXvn1a7kzZGQ7ETjdQVS2UfZyTlsEdDOqvQF7GoxNfY+0YLCzBy1kPdsDDx4QuNAonQPddpsn6Xl/7sw==} + engines: {node: '>= 0.10.0'} + hasBin: true + dependencies: + commander: 2.20.3 + cssfilter: 0.0.10 + dev: true + + /xtend@1.0.3: + resolution: {integrity: sha512-wv78b3q8kHDveC/C7Yq/UUrJXsAAM1t/j5m28h/ZlqYy0+eqByglhsWR88D2j3VImQzZlNIDsSbZ3QItwgWEGw==} + engines: {node: '>=0.4'} + dev: true + + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /y18n@3.2.2: + resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} + dev: true + + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: true + + /y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + dev: true + + /yaku@0.19.3: + resolution: {integrity: sha512-QgelIZVBPKnWyvd/zoaSVOmv7lzLoa3gsjI+vjc9ts9QLeLCrWTSSHB6Y+Hslo+NntC5HelX/prt0Npt4B+pKA==} + dev: true + + /yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yamljs@0.3.0: + resolution: {integrity: sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==} + hasBin: true + dependencies: + argparse: 1.0.10 + glob: 7.2.3 + dev: true + + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: true + + /yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + dev: true + + /yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + dev: true + + /yargs-parser@7.0.0: + resolution: {integrity: sha512-WhzC+xgstid9MbVUktco/bf+KJG+Uu6vMX0LN1sLJvwmbCQVxb4D8LzogobonKycNasCZLdOzTAk1SK7+K7swg==} + dependencies: + camelcase: 4.1.0 + dev: true + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.0 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: true + + /yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + dependencies: + cliui: 7.0.4 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + dev: true + + /yargs@17.6.0: + resolution: {integrity: sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==} + engines: {node: '>=12'} + dependencies: + cliui: 8.0.1 + escalade: 3.1.1 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + dev: true + + /yargs@3.10.0: + resolution: {integrity: sha512-QFzUah88GAGy9lyDKGBqZdkYApt63rCXYBGYnEP4xDJPXNqXXnBDACnbrXnViV6jRSqAePwrATi2i8mfYm4L1A==} + dependencies: + camelcase: 1.2.1 + cliui: 2.1.0 + decamelize: 1.2.0 + window-size: 0.1.0 + dev: true + + /yargs@3.32.0: + resolution: {integrity: sha512-ONJZiimStfZzhKamYvR/xvmgW3uEkAUFSP91y2caTEPhzF6uP2JfPiVZcq66b/YR0C3uitxSV7+T1x8p5bkmMg==} + dependencies: + camelcase: 2.1.1 + cliui: 3.2.0 + decamelize: 1.2.0 + os-locale: 1.4.0 + string-width: 1.0.2 + window-size: 0.1.4 + y18n: 3.2.2 + dev: true + + /yargs@3.5.4: + resolution: {integrity: sha512-5j382E4xQSs71p/xZQsU1PtRA2HXPAjX0E0DkoGLxwNASMOKX6A9doV1NrZmj85u2Pjquz402qonBzz/yLPbPA==} + dependencies: + camelcase: 1.2.1 + decamelize: 1.2.0 + window-size: 0.1.0 + wordwrap: 0.0.2 + dev: true + + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + dev: true + + /yeast@0.1.2: + resolution: {integrity: sha512-8HFIh676uyGYP6wP13R/j6OJ/1HwJ46snpvzE7aHAN3Ryqh2yX6Xox2B4CUmTwwOIzlG3Bs7ocsP5dZH/R1Qbg==} + dev: true + + /ylru@1.3.2: + resolution: {integrity: sha512-RXRJzMiK6U2ye0BlGGZnmpwJDPgakn6aNQ0A7gHRbD4I0uvK4TW6UqkK1V0pp9jskjJBAXd3dRrbzWkqJ+6cxA==} + engines: {node: '>= 4.0.0'} + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + requiresBuild: true + dev: true + + /zen-observable-ts@0.8.21: + resolution: {integrity: sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==} + dependencies: + tslib: 1.14.1 + zen-observable: 0.8.15 + dev: true + + /zen-observable@0.8.15: + resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + dev: true + + /zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + dev: true diff --git a/turbopack/crates/turbopack/tests/node-file-trace/pnpm-workspace.yaml b/turbopack/crates/turbopack/tests/node-file-trace/pnpm-workspace.yaml new file mode 100644 index 0000000000000..ccbac807c1760 --- /dev/null +++ b/turbopack/crates/turbopack/tests/node-file-trace/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - "." diff --git a/turbopack/packages/devlow-bench/.eslintrc.cjs b/turbopack/packages/devlow-bench/.eslintrc.cjs new file mode 100644 index 0000000000000..4ca761e2f8eb5 --- /dev/null +++ b/turbopack/packages/devlow-bench/.eslintrc.cjs @@ -0,0 +1,3 @@ +module.exports = { + extends: ["@turbo/eslint-config/library"], +}; diff --git a/turbopack/packages/devlow-bench/README.md b/turbopack/packages/devlow-bench/README.md new file mode 100644 index 0000000000000..da3ea0ff0a889 --- /dev/null +++ b/turbopack/packages/devlow-bench/README.md @@ -0,0 +1,169 @@ +# devlow-bench + +DEVeloper workfLOW BENCHmarking tool + +## Installation + +```bash +npm install devlow-bench +``` + +## Usage + +```bash +Usage: devlow-bench [options] +## Selecting scenarios + --scenario=, -s= Only run the scenario with the given name + --interactive, -i Select scenarios and variants interactively + --= Filter by any variant property defined in scenarios +## Output + --json=, -j= Write the results to the given path as JSON + --console Print the results to the console + --datadog[=] Upload the results to Datadog + (requires DATADOG_API_KEY environment variables) +## Help + --help, -h, -? Show this help +``` + +## Scenarios + +A scenario file is similar to a test case file. It can contain one or multiple scenarios by using the `describe()` method to define them. + +```js +import { describe } from "devlow-bench"; + +describe( + "my scenario", + { + /* property options */ + }, + async ( + { + /* property values */ + } + ) => { + // run the scenario + } +); +``` + +The `describe()` method takes three arguments: + +- `name`: The name of the scenario +- `props`: An object with possible property values for the scenario. +- `fn`: The function that runs the scenario. It is passed an object with the property values as the first argument. + +The `props` object can contain any number of properties. The key is the name of the property. The value must either be an array of possible values (number, string, boolean), or it can be `true` as shortcut for `[true, false]` resp. `false` for `[false, true]`. The scenario will run for every possible combination of the property values, if not specified otherwise. + +### Example + +```js +import { describe } from "devlow-bench"; + +describe( + "my scenario", + { + myProperty: [1, 2, 3], + myOtherProperty: true, + }, + async ({ myProperty, myOtherProperty }) => { + console.log(myProperty, myOtherProperty); + } +); + +// will print: +// 1 true +// 2 true +// 3 true +// 1 false +// 2 false +// 3 false +``` + +## Reporting measurements + +```js +import { measureTime, reportMeasurement } from "devlow-bench"; + +// Measure a time +await measureTime("name of the timing", { + /* optional options */ +}); + +// Report some other measurement +await reportMeasurement("name of the measurement", value, unit, { + /* optional options */ +}); +``` + +Options: + +- `relativeTo`: measure time/value relative to some other measurement. +- `scenario`: override the reported scenario name (to make measurement independent of scenario name) +- `props`: override the reported scenario properties (to make measurement independent of scenario properties, object is merged with original props, to remove a prop use `null` value) + +## Browser operations + +The `devlow-bench` package provides a few helper functions to run operations in the browser. + +```js +import { newBrowserSession } from "devlow-bench/browser"; + +const session = await newBrowserSession({ + // options +}); +await session.hardNavigation("metric name", "https://example.com"); +await session.reload("metric name"); +await session.softNavigationByClick("metric name", ".selector-to-click"); +await session.close(); +``` + +Run with `BROWSER_OUTPUT=1` to show the output of the browser. + +Run with `HEADLESS=false` to show the actual browser window. + +## Shell operations + +The `devlow-bench` package provides a few helper functions to run operations in the shell. + +```js +import { command } from 'devlow-bench/shell'; + +const shell = await command("pnpm", ["run", "build"], { + env: { /* optional env vars */ } + cwd: "/optional/path/to/directory" +}); + +// Wait for successful exit +await shell.ok(); + +// Wait for exit +const exitCode = await shell.end(); + +// Wait for specific output +const [match, world] = await shell.waitForOutput(/hello (world)/); + +// Report memory usage or the process tree as metric +await shell.reportMemUsage("metric name", { /* optional options */ }); + +shell.stdout, shell.stderr + +// merged output +shell.output + +// Kill the process tree +await shell.kill(); +``` + +Run with `SHELL_OUTPUT=1` to show the output of the shell commands. + +## File operations + +The `devlow-bench` package provides a few helper functions to run operations on the file system. + +```js +import { waitForFile } from "devlow-bench/file"; + +// wait for file to exist +await waitForFile("/path/to/file", /* timeout = */ 30000); +``` diff --git a/turbopack/packages/devlow-bench/package.json b/turbopack/packages/devlow-bench/package.json new file mode 100644 index 0000000000000..997b889898f23 --- /dev/null +++ b/turbopack/packages/devlow-bench/package.json @@ -0,0 +1,49 @@ +{ + "name": "@vercel/devlow-bench", + "version": "0.3.2", + "description": "Benchmarking tool for the developer workflow", + "publishConfig": { + "access": "public" + }, + "type": "module", + "main": "dist/index.js", + "bin": "dist/cli.js", + "scripts": { + "lint": "eslint src/", + "prerelease": "pnpm run build:ts", + "build:ts": "tsc" + }, + "files": [ + "dist" + ], + "keywords": [], + "author": "Tobias Koppers", + "license": "MPL-2.0", + "exports": { + ".": "./dist/index.js", + "./browser": "./dist/browser.js", + "./shell": "./dist/shell.js", + "./file": "./dist/file.js", + "./interfaces/compose": "./dist/interfaces/compose.js", + "./interfaces/console": "./dist/interfaces/console.js", + "./interfaces/interactive": "./dist/interfaces/interactive.js", + "./interfaces/json": "./dist/interfaces/json.js" + }, + "devDependencies": { + "@turbo/eslint-config": "workspace:*", + "@types/inquirer": "^9.0.3", + "@types/minimist": "^1.2.2", + "@types/node": "^20.3.0", + "@types/split2": "^4.2.0" + }, + "dependencies": { + "@datadog/datadog-api-client": "^1.13.0", + "inquirer": "^9.2.7", + "minimist": "^1.2.8", + "picocolors": "1.0.1", + "pidusage-tree": "^2.0.5", + "playwright-chromium": "^1.39.0", + "split2": "^4.2.0", + "tree-kill": "^1.2.2" + } +} diff --git a/turbopack/packages/devlow-bench/src/browser.ts b/turbopack/packages/devlow-bench/src/browser.ts new file mode 100644 index 0000000000000..1a6ca8e86d669 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/browser.ts @@ -0,0 +1,370 @@ +import type { + Browser, + BrowserContext, + ConsoleMessage, + Page, + Request, + Response, +} from "playwright-chromium"; +import { chromium } from "playwright-chromium"; +import { measureTime, reportMeasurement } from "./index.js"; + +interface BrowserSession { + close(): Promise; + hardNavigation(metricName: string, url: string): Promise; + softNavigationByClick(metricName: string, selector: string): Promise; + reload(metricName: string): Promise; +} + +const browserOutput = Boolean(process.env.BROWSER_OUTPUT); + +async function withRequestMetrics( + metricName: string, + page: Page, + fn: () => Promise +): Promise { + const activePromises: Array> = []; + const sizeByExtension = new Map(); + const requestsByExtension = new Map(); + const responseHandler = (response: Response) => { + activePromises.push( + (async () => { + const url = response.request().url(); + const status = response.status(); + const extension = + // eslint-disable-next-line prefer-named-capture-group -- TODO: address lint + /^[^?#]+\.([a-z0-9]+)(?:[?#]|$)/i.exec(url)?.[1] ?? "none"; + const currentRequests = requestsByExtension.get(extension) ?? 0; + requestsByExtension.set(extension, currentRequests + 1); + if (status >= 200 && status < 300) { + let body; + try { + body = await response.body(); + } catch { + // empty + } + if (body) { + const size = body.length; + const current = sizeByExtension.get(extension) ?? 0; + sizeByExtension.set(extension, current + size); + } + } + })() + ); + }; + let errorCount = 0; + let warningCount = 0; + let logCount = 0; + const consoleHandler = (message: ConsoleMessage) => { + const type = message.type(); + if (type === "error") { + errorCount++; + } else if (type === "warning") { + warningCount++; + } else { + logCount++; + } + if (browserOutput) { + activePromises.push( + (async () => { + const args = []; + try { + const text = message.text(); + for (const arg of message.args()) { + args.push(await arg.jsonValue()); + } + console.log(`[${type}] ${text}`, ...args); + } catch { + // Ignore + } + })() + ); + } + }; + let uncaughtCount = 0; + const exceptionHandler = (error: Error) => { + uncaughtCount++; + if (browserOutput) { + console.error(`[UNCAUGHT]`, error); + } + }; + try { + page.on("response", responseHandler); + page.on("console", consoleHandler); + page.on("pageerror", exceptionHandler); + await fn(); + await Promise.all(activePromises); + let totalDownload = 0; + for (const [extension, size] of sizeByExtension.entries()) { + await reportMeasurement( + `${metricName}/responseSizes/${extension}`, + size, + "bytes" + ); + totalDownload += size; + } + await reportMeasurement( + `${metricName}/responseSizes`, + totalDownload, + "bytes" + ); + let totalRequests = 0; + for (const [extension, count] of requestsByExtension.entries()) { + await reportMeasurement( + `${metricName}/requests/${extension}`, + count, + "requests" + ); + totalRequests += count; + } + await reportMeasurement( + `${metricName}/requests`, + totalRequests, + "requests" + ); + await reportMeasurement(`${metricName}/console/logs`, logCount, "messages"); + await reportMeasurement( + `${metricName}/console/warnings`, + warningCount, + "messages" + ); + await reportMeasurement( + `${metricName}/console/errors`, + errorCount, + "messages" + ); + await reportMeasurement( + `${metricName}/console/uncaught`, + uncaughtCount, + "messages" + ); + await reportMeasurement( + `${metricName}/console`, + logCount + warningCount + errorCount + uncaughtCount, + "messages" + ); + } finally { + page.off("response", responseHandler); + } +} + +/** + * Waits until network requests have all been resolved + * @param page - Playwright page object + * @param delayMs - Amount of time in ms to wait after the last request resolves before cleaning up + * @param timeoutMs - Amount of time to wait before continuing. In case of timeout, this function resolves + * @returns + */ +function networkIdle( + page: Page, + delayMs = 300, + timeoutMs = 180000 +): Promise { + return new Promise((resolve) => { + const cleanup = () => { + page.off("request", requestHandler); + page.off("requestfailed", requestFinishedHandler); + page.off("requestfinished", requestFinishedHandler); + clearTimeout(fullTimeout); + if (timeout) { + clearTimeout(timeout); + } + }; + + const requests = new Map(); + const start = Date.now(); + let lastRequest: number; + let timeout: NodeJS.Timeout | null = null; + + const fullTimeout = setTimeout(() => { + cleanup(); + // eslint-disable-next-line no-console -- logging + console.error( + `Timeout while waiting for network idle. These requests are still pending: ${Array.from( + requests + ).join(", ")}} time is ${lastRequest - start}` + ); + resolve(Date.now() - lastRequest); + }, timeoutMs); + + const requestFilter = (request: Request) => { + return request.headers().accept !== "text/event-stream"; + }; + + const requestHandler = (request: Request) => { + requests.set(request.url(), (requests.get(request.url()) ?? 0) + 1); + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + // Avoid tracking some requests, but we only know this after awaiting + // so we need to do this weird stunt to ensure that + if (!requestFilter(request)) { + requestFinishedInternal(request); + } + }; + + const requestFinishedHandler = (request: Request) => { + if (requestFilter(request)) { + requestFinishedInternal(request); + } + }; + + const requestFinishedInternal = (request: Request) => { + lastRequest = Date.now(); + const currentCount = requests.get(request.url()); + if (currentCount === undefined) { + // eslint-disable-next-line no-console -- basic logging + console.error( + `Unexpected untracked but completed request ${request.url()}` + ); + return; + } + + if (currentCount === 1) { + requests.delete(request.url()); + } else { + requests.set(request.url(), currentCount - 1); + } + + if (requests.size === 0) { + timeout = setTimeout(() => { + cleanup(); + resolve(Date.now() - lastRequest); + }, delayMs); + } + }; + + page.on("request", requestHandler); + page.on("requestfailed", requestFinishedHandler); + page.on("requestfinished", requestFinishedHandler); + }); +} + +class BrowserSessionImpl implements BrowserSession { + private browser: Browser; + private context: BrowserContext; + private page: Page | null; + constructor(browser: Browser, context: BrowserContext) { + this.browser = browser; + this.context = context; + this.page = null; + } + + async close() { + if (this.page) { + await this.page.close(); + } + await this.context.close(); + await this.browser.close(); + } + + async hardNavigation(metricName: string, url: string) { + this.page = this.page ?? (await this.context.newPage()); + + const page = this.page; + await withRequestMetrics(metricName, page, async () => { + await measureTime(`${metricName}/start`); + const idle = networkIdle(page, 3000); + await page.goto(url, { + waitUntil: "commit", + }); + await measureTime(`${metricName}/html`, { + relativeTo: `${metricName}/start`, + }); + await page.waitForLoadState("domcontentloaded"); + await measureTime(`${metricName}/dom`, { + relativeTo: `${metricName}/start`, + }); + await page.waitForLoadState("load"); + await measureTime(`${metricName}/load`, { + relativeTo: `${metricName}/start`, + }); + const offset = await idle; + await measureTime(`${metricName}`, { + offset, + relativeTo: `${metricName}/start`, + }); + }); + return page; + } + + async softNavigationByClick(metricName: string, selector: string) { + const page = this.page; + if (!page) { + throw new Error( + "softNavigationByClick() must be called after hardNavigation()" + ); + } + await withRequestMetrics(metricName, page, async () => { + await measureTime(`${metricName}/start`); + const firstResponse = new Promise((resolve) => { + page.once("response", () => { + resolve(); + }); + }); + const idle = networkIdle(page, 3000); + await page.click(selector); + await firstResponse; + await measureTime(`${metricName}/firstResponse`, { + relativeTo: `${metricName}/start`, + }); + await idle; + await measureTime(`${metricName}`, { + offset: 3000, + relativeTo: `${metricName}/start`, + }); + }); + } + + async reload(metricName: string) { + const page = this.page; + if (!page) { + throw new Error("reload() must be called after hardNavigation()"); + } + await withRequestMetrics(metricName, page, async () => { + await measureTime(`${metricName}/start`); + const idle = networkIdle(page, 3000); + await page.reload({ + waitUntil: "commit", + }); + await measureTime(`${metricName}/html`, { + relativeTo: `${metricName}/start`, + }); + await page.waitForLoadState("domcontentloaded"); + await measureTime(`${metricName}/dom`, { + relativeTo: `${metricName}/start`, + }); + await page.waitForLoadState("load"); + await measureTime(`${metricName}/load`, { + relativeTo: `${metricName}/start`, + }); + await idle; + await measureTime(`${metricName}`, { + offset: 3000, + relativeTo: `${metricName}/start`, + }); + }); + } +} + +export async function newBrowserSession(options: { + headless?: boolean; + devtools?: boolean; + baseURL?: string; +}): Promise { + const browser = await chromium.launch({ + headless: options.headless ?? process.env.HEADLESS !== "false", + devtools: true, + timeout: 60000, + }); + const context = await browser.newContext({ + baseURL: options.baseURL ?? "http://localhost:3000", + viewport: { width: 1280, height: 720 }, + }); + context.setDefaultTimeout(120000); + context.setDefaultNavigationTimeout(120000); + return new BrowserSessionImpl(browser, context); +} + +// see next.js/test/lib/browsers/playwright.ts diff --git a/turbopack/packages/devlow-bench/src/cli.ts b/turbopack/packages/devlow-bench/src/cli.ts new file mode 100644 index 0000000000000..76f1a0afbbb3c --- /dev/null +++ b/turbopack/packages/devlow-bench/src/cli.ts @@ -0,0 +1,114 @@ +import minimist from "minimist"; +import { setCurrentScenarios } from "./describe.js"; +import { join } from "path"; +import { Scenario, ScenarioVariant, runScenarios } from "./index.js"; +import compose from "./interfaces/compose.js"; +import { pathToFileURL } from "url"; + +(async () => { + const knownArgs = new Set([ + "scenario", + "s", + "json", + "j", + "console", + "datadog", + "interactive", + "i", + "help", + "h", + "?", + "_", + ]); + const args = minimist(process.argv.slice(2), { + alias: { + s: "scenario", + j: "json", + i: "interactive", + "?": "help", + h: "help", + }, + }); + + if (args.help || (Object.keys(args).length === 1 && args._.length === 0)) { + console.log("Usage: devlow-bench [options] "); + console.log("## Selecting scenarios"); + console.log( + " --scenario=, -s= Only run the scenario with the given name" + ); + console.log( + " --interactive, -i Select scenarios and variants interactively" + ); + console.log( + " --= Filter by any variant property defined in scenarios" + ); + console.log("## Output"); + console.log( + " --json=, -j= Write the results to the given path as JSON" + ); + console.log( + " --console Print the results to the console" + ); + console.log( + " --datadog[=] Upload the results to Datadog" + ); + console.log( + " (requires DATADOG_API_KEY environment variables)" + ); + console.log("## Help"); + console.log(" --help, -h, -? Show this help"); + } + + const scenarios: Scenario[] = []; + setCurrentScenarios(scenarios); + + for (const path of args._) { + await import(pathToFileURL(join(process.cwd(), path)).toString()); + } + + setCurrentScenarios(null); + + const cliIface = { + filterScenarios: async (scenarios: Scenario[]) => { + if (args.scenario) { + const filter = [].concat(args.scenario); + return scenarios.filter((s) => + filter.some((filter) => s.name.includes(filter)) + ); + } + return scenarios; + }, + filterScenarioVariants: async (variants: ScenarioVariant[]) => { + const propEntries = Object.entries(args).filter( + ([key]) => !knownArgs.has(key) + ); + if (propEntries.length === 0) return variants; + for (const [key, value] of propEntries) { + const values = (Array.isArray(value) ? value : [value]).map((v) => + v.toString() + ); + variants = variants.filter((variant) => { + const prop = variant.props[key]; + if (typeof prop === "undefined") return false; + const str = prop.toString(); + return values.some((v) => str.includes(v)); + }); + } + return variants; + }, + }; + let ifaces = [ + cliIface, + args.interactive && (await import("./interfaces/interactive.js")).default(), + args.json && (await import("./interfaces/json.js")).default(args.json), + args.datadog && + (await import("./interfaces/datadog.js")).default( + typeof args.datadog === "string" ? { host: args.datadog } : undefined + ), + args.console !== false && + (await import("./interfaces/console.js")).default(), + ].filter((x) => x); + await runScenarios(scenarios, compose(...ifaces)); +})().catch((e) => { + console.error(e.stack); +}); diff --git a/turbopack/packages/devlow-bench/src/describe.ts b/turbopack/packages/devlow-bench/src/describe.ts new file mode 100644 index 0000000000000..ec691f6c95c7b --- /dev/null +++ b/turbopack/packages/devlow-bench/src/describe.ts @@ -0,0 +1,182 @@ +import type { + ConfigFor, + CurrentScenario, + Interface, + Scenario, +} from "./index.js"; +import compose from "./interfaces/compose.js"; +import { runScenarios } from "./runner.js"; + +let currentScenarios: Scenario[] | null = null; + +export function setCurrentScenarios(scenarios: Scenario[] | null): void { + currentScenarios = scenarios; +} + +export function describe

    ( + name: string, + config: ConfigFor

    , + fn: (props: P) => Promise +): void { + if (currentScenarios === null) { + const scenarios = (currentScenarios = []); + + Promise.resolve().then(async () => { + const ifaceNames = process.env.INTERFACE || "interactive,console"; + const ifaces = []; + for (const ifaceName of ifaceNames.split(",").map((s) => s.trim())) { + let iface: unknown; + try { + iface = await import(`./interfaces/${ifaceName}.js`); + } catch (e) { + iface = await import(ifaceName); + } + iface = (iface && (iface as any).default) || iface; + if (typeof iface === "function") { + iface = await iface(); + } + if (!iface) { + throw new Error(`Interface ${ifaceName} is not a valid interface`); + } + ifaces.push(iface as Interface); + } + runScenarios(scenarios, compose(...ifaces)); + }); + } + const normalizedConfig: Record = + Object.fromEntries( + Object.entries(config).map(([key, value]) => [ + key, + typeof value === "boolean" + ? [value, !value] + : (value as (string | number | boolean)[]), + ]) + ); + currentScenarios!.push({ + name, + config: normalizedConfig, + only: false, + fn: fn as ( + props: Record + ) => Promise, + }); +} + +describe.only = function describeOnly

    ( + name: string, + config: ConfigFor

    , + fn: (props: P) => Promise +): void { + describe(name, config, fn); + currentScenarios![currentScenarios!.length - 1].only = true; +}; + +let currentScenario: CurrentScenario | null = null; + +export function withCurrent( + current: CurrentScenario, + fn: () => Promise +): Promise { + const prev = currentScenario; + currentScenario = current; + return fn().finally(() => { + currentScenario = prev; + }); +} + +export const PREVIOUS = Symbol("previous measurement with that unit"); + +export async function measureTime( + name: string, + options: { + relativeTo?: string | typeof PREVIOUS; + scenario?: string; + props?: Record; + offset?: number; + } = {} +) { + const end = Date.now() - (options.offset || 0); + await reportMeasurement(name, end, "ms", { + relativeTo: PREVIOUS, + ...options, + }); +} + +export async function reportMeasurement( + name: string, + value: number, + unit: string, + options: { + relativeTo?: string | typeof PREVIOUS; + scenario?: string; + props?: Record; + } = {} +) { + if (!currentScenario) { + throw new Error("reportMeasurement() must be called inside of describe()"); + } + if (typeof name !== "string") { + throw new Error( + "reportMeasurement() must be called with a name that is a string" + ); + } + if (typeof value !== "number") { + throw new Error( + "reportMeasurement() must be called with a value that is a number" + ); + } + if (isNaN(value)) { + throw new Error( + "reportMeasurement() must be called with a value that is not NaN" + ); + } + if (!isFinite(value)) { + throw new Error( + "reportMeasurement() must be called with a value that is finite" + ); + } + if (typeof unit !== "string") { + throw new Error( + "reportMeasurement() must be called with a unit that is a string" + ); + } + let { relativeTo, scenario, props } = options; + if (relativeTo === PREVIOUS) { + relativeTo = "previous"; + for (const [prevName, prev] of currentScenario.measurements) { + if (prev.unit === unit) { + relativeTo = prevName; + } + } + } + currentScenario.measurements.set(name, { + value, + unit, + }); + let reportedValue = value; + if (relativeTo) { + const prev = currentScenario.measurements.get(relativeTo); + if (!prev) { + throw new Error(`No measurement named ${relativeTo} found`); + } + if (prev.unit !== unit) { + throw new Error( + `Measurement ${relativeTo} is not a "${unit}" measurement` + ); + } + reportedValue -= prev.value; + } + await currentScenario.iface.measurement( + scenario ?? currentScenario.scenario.scenario.name, + props + ? { + ...currentScenario.scenario.props, + ...props, + } + : currentScenario.scenario.props, + name, + reportedValue, + unit, + relativeTo + ); +} diff --git a/turbopack/packages/devlow-bench/src/file.ts b/turbopack/packages/devlow-bench/src/file.ts new file mode 100644 index 0000000000000..2f50b75e84240 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/file.ts @@ -0,0 +1,59 @@ +import { watch } from "fs"; +import { access, constants } from "fs/promises"; +import { dirname } from "path"; + +export async function waitForFile( + path: string, + timeout: number +): Promise { + let currentAction = ""; + let timeoutRef; + const timeoutPromise = new Promise((resolve, reject) => { + timeoutRef = setTimeout(() => { + reject( + new Error(`Timed out waiting for file ${path} (${currentAction}))`) + ); + }, timeout || 60000); + }); + const elements = []; + let current = path; + while (true) { + elements.push(current); + const parent = dirname(current); + if (parent === current) { + break; + } + current = parent; + } + elements.reverse(); + try { + for (const path of elements) { + const checkAccess = () => + access(path, constants.F_OK) + .then(() => true) + .catch(() => false); + if (!(await checkAccess())) { + let resolveCheckAgain = () => {}; + const watcher = watch(dirname(path), () => { + resolveCheckAgain(); + }); + currentAction = `waiting for ${path}`; + let checkAgainPromise = new Promise((resolve) => { + resolveCheckAgain = resolve; + }); + try { + do { + await Promise.race([timeoutPromise, checkAgainPromise]); + checkAgainPromise = new Promise((resolve) => { + resolveCheckAgain = resolve; + }); + } while (!(await checkAccess())); + } finally { + watcher.close(); + } + } + } + } finally { + clearTimeout(timeoutRef); + } +} diff --git a/turbopack/packages/devlow-bench/src/index.ts b/turbopack/packages/devlow-bench/src/index.ts new file mode 100644 index 0000000000000..e87fd8a368bf5 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/index.ts @@ -0,0 +1,89 @@ +export type ConfigFor

    = { + [K in keyof P]: P[K] extends string + ? string[] + : P[K] extends number + ? number[] + : P[K] extends boolean + ? boolean[] | boolean + : never; +}; + +export interface Scenario { + name: string; + config: Record; + only: boolean; + fn: (props: Record) => Promise; +} + +export interface ScenarioVariant { + scenario: Scenario; + props: Record; +} + +export interface CurrentScenario { + scenario: ScenarioVariant; + iface: FullInterface; + + measurements: Map< + string, + { + value: number; + unit: string; + } + >; +} + +export type Interface = Partial; + +export interface FullInterface { + filterScenarios(scenarios: Scenario[]): Promise; + filterScenarioVariants( + scenarioVariants: ScenarioVariant[] + ): Promise; + + start( + scenario: string, + props: Record + ): Promise; + measurement( + scenario: string, + props: Record, + name: string, + value: number, + unit: string, + relativeTo?: string + ): Promise; + end( + scenario: string, + props: Record + ): Promise; + error( + scenario: string, + props: Record, + error: unknown + ): Promise; + + finish(): Promise; +} + +export function intoFullInterface(iface: Interface): FullInterface { + return { + filterScenarios: iface.filterScenarios ?? (async (scenarios) => scenarios), + filterScenarioVariants: + iface.filterScenarioVariants ?? + (async (scenarioVariants) => scenarioVariants), + start: iface.start ?? (async () => {}), + measurement: iface.measurement ?? (async () => {}), + end: iface.end ?? (async () => {}), + error: iface.error ?? (async () => {}), + finish: iface.finish ?? (async () => {}), + }; +} + +export { + describe, + measureTime, + reportMeasurement, + PREVIOUS, +} from "./describe.js"; +export { runScenarios } from "./runner.js"; diff --git a/turbopack/packages/devlow-bench/src/interfaces/compose.ts b/turbopack/packages/devlow-bench/src/interfaces/compose.ts new file mode 100644 index 0000000000000..dac157c7f34d1 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/interfaces/compose.ts @@ -0,0 +1,34 @@ +import { Interface } from "../index.js"; + +export default function compose(...ifaces: Interface[]): Interface { + const allKeys = new Set(); + for (const iface of ifaces) { + for (const key of Object.keys(iface)) { + allKeys.add(key as keyof Interface); + } + } + const composed: any = {}; + for (const key of allKeys) { + if (key.startsWith("filter")) { + composed[key] = async (items: any, ...args: any[]) => { + for (const iface of ifaces) { + const anyIface = iface as any; + if (anyIface[key]) { + items = await anyIface[key](items, ...args); + } + } + return items; + }; + } else { + composed[key] = async (...args: any[]) => { + for (const iface of ifaces) { + const anyIface = iface as any; + if (anyIface[key]) { + await anyIface[key](...args); + } + } + }; + } + } + return composed; +} diff --git a/turbopack/packages/devlow-bench/src/interfaces/console.ts b/turbopack/packages/devlow-bench/src/interfaces/console.ts new file mode 100644 index 0000000000000..4841b634d36d9 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/interfaces/console.ts @@ -0,0 +1,42 @@ +import { Interface, Scenario, ScenarioVariant } from "../index.js"; +import inquirer from "inquirer"; +import { bgCyan, bold, magenta, red, underline } from "picocolors"; +import { formatUnit } from "../units.js"; +import { formatVariant } from "../utils.js"; + +export default function createInterface(): Interface { + const iface: Interface = { + start: async (scenario, props) => { + console.log( + bold(underline(`Running ${formatVariant(scenario, props)}...`)) + ); + }, + measurement: async (scenario, props, name, value, unit, relativeTo) => { + console.log( + bgCyan( + bold( + magenta( + `${formatVariant(scenario, props)}: ${name} = ${formatUnit( + value, + unit + )}${relativeTo ? ` (from ${relativeTo})` : ""}` + ) + ) + ) + ); + }, + error: async (scenario, props, error) => { + console.log( + bold( + red( + `${formatVariant(scenario, props)}: ${ + (error && (error as any).stack) || error + }` + ) + ) + ); + }, + }; + + return iface; +} diff --git a/turbopack/packages/devlow-bench/src/interfaces/datadog.ts b/turbopack/packages/devlow-bench/src/interfaces/datadog.ts new file mode 100644 index 0000000000000..e3b37cc68ada2 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/interfaces/datadog.ts @@ -0,0 +1,108 @@ +import type { + DistributionPointsSeries, + MetricMetadata, +} from "@datadog/datadog-api-client/dist/packages/datadog-api-client-v1/index.js"; +import type { Interface } from "../index.js"; +import datadogApiClient from "@datadog/datadog-api-client"; +import os from "os"; +import { command } from "../shell.js"; + +function toIdentifier(str: string) { + return str.replace(/\//g, ".").replace(/ /g, "_"); +} + +const UNIT_MAPPING: Record = { + ms: "millisecond", + requests: "request", + bytes: "byte", +}; + +const GIT_SHA = + process.env.GITHUB_SHA ?? + (await (async () => { + const cmd = command("git", ["rev-parse", "HEAD"]); + await cmd.ok(); + return cmd.output.trim(); + })()); + +const GIT_BRANCH = + process.env.GITHUB_REF_NAME ?? + (await (async () => { + const cmd = command("git", ["rev-parse", "--abbrev-ref", "HEAD"]); + await cmd.ok(); + return cmd.output.trim(); + })()); + +export default function createInterface({ + apiKey = process.env.DATADOG_API_KEY, + appKey = process.env.DATADOG_APP_KEY, + host = process.env.DATADOG_HOST || os.hostname(), +}: { apiKey?: string; appKey?: string; host?: string } = {}): Interface { + if (!apiKey) + throw new Error("Datadog API key is required (set DATADOG_API_KEY)"); + const commonTags = [ + `ci:${!!process.env.CI || "false"}`, + `os:${process.platform}`, + `os_release:${os.release()}`, + `cpus:${os.cpus().length}`, + `cpu_model:${os.cpus()[0].model}`, + `user:${os.userInfo().username}`, + `arch:${os.arch()}`, + `total_memory:${Math.round(os.totalmem() / 1024 / 1024 / 1024)}`, + `node_version:${process.version}`, + `git_sha:${GIT_SHA}`, + `git_branch:${GIT_BRANCH}`, + ]; + const configuration = datadogApiClient.client.createConfiguration({ + authMethods: { + apiKeyAuth: apiKey, + appKeyAuth: appKey, + }, + }); + const api = new datadogApiClient.v1.MetricsApi(configuration); + const dataPoints: DistributionPointsSeries[] = []; + const metricMetadata: Record = {}; + const iface: Interface = { + measurement: async (scenario, props, name, value, unit, relativeTo) => { + const ts = Math.round(Date.now() / 1000); + const metric = toIdentifier(`devlow_bench/${scenario}/${name}`); + if (UNIT_MAPPING[unit]) { + metricMetadata[metric] = { + unit: UNIT_MAPPING[unit], + }; + } + dataPoints.push({ + metric, + type: "distribution", + host, + tags: Object.entries(props) + .filter(([, value]) => value !== null) + .map( + ([key, value]) => + `${toIdentifier(key)}:${toIdentifier(value!.toString())}` + ) + .concat(commonTags), + points: [[ts, [value]]], + }); + }, + end: async (scenario, props) => { + await api.submitDistributionPoints({ + body: { + series: dataPoints, + }, + }); + dataPoints.length = 0; + }, + finish: async () => { + if (appKey) { + for (const [metric, metadata] of Object.entries(metricMetadata)) { + await api.updateMetricMetadata({ + metricName: metric, + body: metadata, + }); + } + } + }, + }; + return iface; +} diff --git a/turbopack/packages/devlow-bench/src/interfaces/interactive.ts b/turbopack/packages/devlow-bench/src/interfaces/interactive.ts new file mode 100644 index 0000000000000..d173cb9bed86a --- /dev/null +++ b/turbopack/packages/devlow-bench/src/interfaces/interactive.ts @@ -0,0 +1,45 @@ +import { Interface, Scenario, ScenarioVariant } from "../index.js"; +import inquirer from "inquirer"; +import { formatUnit } from "../units.js"; +import { formatVariant } from "../utils.js"; + +export default function createInterface(): Interface { + const iface: Interface = { + filterScenarios: async (scenarios) => { + if (scenarios.length === 1) { + return scenarios; + } + let answer = await inquirer.prompt({ + type: "checkbox", + name: "scenarios", + default: scenarios.slice(), + message: "Choose scenarios to run", + choices: scenarios.map((scenario) => ({ + name: scenario.name, + value: scenario, + })), + }); + return answer.scenarios; + }, + filterScenarioVariants: async (variants) => { + if (variants.length === 1) { + return variants; + } + let answer = await inquirer.prompt({ + type: "checkbox", + name: "variants", + default: variants.slice(), + message: "Choose variants to run", + choices: variants.map((variant) => { + return { + name: formatVariant(variant.scenario.name, variant.props), + value: variant, + }; + }), + }); + return answer.variants; + }, + }; + + return iface; +} diff --git a/turbopack/packages/devlow-bench/src/interfaces/json.ts b/turbopack/packages/devlow-bench/src/interfaces/json.ts new file mode 100644 index 0000000000000..5b3b22de43e37 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/interfaces/json.ts @@ -0,0 +1,82 @@ +import { Interface, Scenario, ScenarioVariant } from "../index.js"; +import inquirer from "inquirer"; +import { formatUnit } from "../units.js"; +import { formatVariant } from "../utils.js"; +import { writeFile } from "fs/promises"; + +function filterProp( + prop: Record +): Record { + const filteredProp: Record = {}; + for (const [key, value] of Object.entries(prop)) { + if (value !== null) { + filteredProp[key] = value; + } + } + return filteredProp; +} + +export default function createInterface( + file: string = (() => { + const file = process.env.JSON_OUTPUT_FILE; + if (!file) { + throw new Error("env var JSON_OUTPUT_FILE is not set"); + } + return file; + })() +): Interface { + const metrics = new Map< + string, + { + key: Record; + value: number; + unit: string; + count: number; + relativeTo?: string; + } + >(); + const iface: Interface = { + measurement: async (scenario, props, name, value, unit, relativeTo) => { + const keyObject = { + scenario: scenario, + ...filterProp(props), + name: name, + }; + const key = JSON.stringify(keyObject); + const current = metrics.get(key); + if (current) { + current.value += value; + current.count++; + } else { + metrics.set(key, { + key: keyObject, + value, + unit: unit, + count: 1, + relativeTo, + }); + } + }, + finish: async () => { + await writeFile( + file, + JSON.stringify( + [...metrics.values()].map( + ({ key, value, unit, count, relativeTo }) => { + return { + key, + value: value / count, + unit, + text: formatUnit(value / count, unit), + datapoints: count, + relativeTo, + }; + } + ) + ) + ); + }, + }; + + return iface; +} diff --git a/turbopack/packages/devlow-bench/src/runner.ts b/turbopack/packages/devlow-bench/src/runner.ts new file mode 100644 index 0000000000000..62d753d4ffe8f --- /dev/null +++ b/turbopack/packages/devlow-bench/src/runner.ts @@ -0,0 +1,64 @@ +import { withCurrent } from "./describe.js"; +import { Interface, Scenario, intoFullInterface } from "./index.js"; + +export async function runScenarios( + scenarios: Scenario[], + iface: Interface +): Promise { + const fullIface = intoFullInterface(iface); + if (scenarios.some((scenario) => scenario.only)) { + scenarios = scenarios.filter((scenario) => scenario.only); + } + scenarios = await fullIface.filterScenarios(scenarios); + let variants = []; + for (const scenario of scenarios) { + let props = [{}]; + for (const [key, options] of Object.entries(scenario.config)) { + const newProps = []; + for (const prop of props) { + if (prop === "scenario" || prop === "name") + throw new Error("Cannot use 'scenario' or 'name' as a property name"); + for (const value of options) { + newProps.push({ + ...prop, + [key]: value, + }); + } + } + props = newProps; + } + variants.push( + ...props.map((props) => ({ + scenario, + props, + })) + ); + } + variants = await fullIface.filterScenarioVariants(variants); + + for (const variant of variants) { + try { + const measurements = new Map(); + await withCurrent( + { + iface: fullIface, + measurements, + scenario: variant, + }, + async () => { + await fullIface.start(variant.scenario.name, variant.props); + measurements.set("start", { + value: Date.now(), + unit: "ms", + }); + await variant.scenario.fn(variant.props); + await fullIface.end(variant.scenario.name, variant.props); + } + ); + } catch (e) { + await fullIface.error(variant.scenario.name, variant.props, e); + } + } + + await fullIface.finish(); +} diff --git a/turbopack/packages/devlow-bench/src/shell.ts b/turbopack/packages/devlow-bench/src/shell.ts new file mode 100644 index 0000000000000..09d5433d5a5d3 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/shell.ts @@ -0,0 +1,156 @@ +import { ChildProcess, spawn } from "child_process"; +import split2 from "split2"; +import treeKill from "tree-kill"; +import pidusage from "pidusage-tree"; +import { PREVIOUS, reportMeasurement } from "./describe.js"; + +export interface Command { + ok(): Promise; + kill(): Promise; + end(): Promise; + waitForOutput(regex: RegExp): Promise; + reportMemUsage( + metricName: string, + options: { + relativeTo?: string | typeof PREVIOUS; + scenario?: string; + props?: Record; + } + ): Promise; + stdout: string; + stderr: string; + output: string; +} + +const shellOutput = !!process.env.SHELL_OUTPUT; + +class CommandImpl { + stdout: string = ""; + stderr: string = ""; + output: string = ""; + exitPromise: Promise; + waitingForOutput: (() => void)[] = []; + constructor(private process: ChildProcess) { + process.stdout?.pipe(split2()).on("data", (data) => { + const str = data.toString(); + this.stdout += str + "\n"; + this.output += str + "\n"; + if (shellOutput) { + console.log(`[STDOUT] ${str}`); + } + if (this.waitingForOutput.length !== 0) { + const waitingForOutput = this.waitingForOutput; + this.waitingForOutput = []; + for (const fn of waitingForOutput) { + fn(); + } + } + }); + process.stderr?.pipe(split2()).on("data", (data) => { + const str = data.toString(); + this.stderr += str + "\n"; + this.output += str + "\n"; + if (shellOutput) { + console.log(`[STDERR] ${str}`); + } + if (this.waitingForOutput.length !== 0) { + const waitingForOutput = this.waitingForOutput; + this.waitingForOutput = []; + for (const fn of waitingForOutput) { + fn(); + } + } + }); + this.exitPromise = new Promise((resolve, reject) => { + process.on("error", reject); + process.on("exit", resolve); + }); + } + + async ok() { + const exitCode = await this.exitPromise; + if (exitCode !== 0) { + throw new Error( + `Command exited with code ${exitCode}\n\nOutput:\n${this.output}` + ); + } + } + + async end() { + return await this.exitPromise; + } + + async kill() { + const pid = this.process.pid!; + await new Promise((resolve, reject) => + treeKill(pid, (err) => { + if (err) reject(err); + else resolve(); + }) + ); + await this.exitPromise; + } + + async waitForOutput(regex: RegExp) { + let start = this.output.length; + while (true) { + const match = this.output.slice(start).match(regex); + if (match) { + return match; + } + const waitResult = await Promise.race([ + this.exitPromise, + new Promise((resolve) => { + this.waitingForOutput.push(resolve); + }).then(() => "output"), + ]); + if (waitResult !== "output") { + throw new Error( + `Command exited with code ${waitResult}\n\nOutput:\n${this.output}` + ); + } + } + } + + async reportMemUsage( + metricName: string, + options: { + relativeTo?: string | typeof PREVIOUS; + scenario?: string; + props?: Record; + } = {} + ) { + try { + const pid = this.process.pid!; + const report = await pidusage(pid); + const memUsage = Object.values(report) + .filter((x) => x) + .map((x) => (x as any).memory) + .reduce((a, b) => a + b, 0); + await reportMeasurement(metricName, memUsage, "bytes", options); + } catch (e) { + // ignore + } + } +} + +export function command( + command: string, + args: string[], + options: { + env?: Record; + cwd?: string; + } = {} +): Command { + const process = spawn(command, args, { + shell: true, + ...options, + stdio: ["ignore", "pipe", "pipe"], + }); + if (shellOutput) { + console.log( + `[SHELL] ${command} ${args.join(" ")} ${JSON.stringify(options)}` + ); + } + return new CommandImpl(process); +} diff --git a/turbopack/packages/devlow-bench/src/table.ts b/turbopack/packages/devlow-bench/src/table.ts new file mode 100644 index 0000000000000..2321958974699 --- /dev/null +++ b/turbopack/packages/devlow-bench/src/table.ts @@ -0,0 +1,129 @@ +import { readFile } from "fs/promises"; +import minimist from "minimist"; + +(async () => { + const args = minimist(process.argv.slice(2), { + alias: { + r: "row", + c: "column", + "?": "help", + h: "help", + }, + }); + + const knownArgs = new Set(["row", "r", "column", "c", "help", "h", "?", "_"]); + if (args.help || (Object.keys(args).length === 1 && args._.length === 0)) { + console.log("Usage: devlow-table "); + console.log(" --row= Key to show as row"); + console.log(" --column= Key to show as column"); + console.log(" --= Filter values"); + console.log(" --help, -h, -? Show this help"); + } + + let data = JSON.parse(await readFile(args._[0], "utf-8")) as any[]; + + const getValue = ( + data: any, + name: string | string[], + includeKey: boolean + ): string => { + if (name === "value") { + return data.text as string; + } + if (Array.isArray(name)) { + return name + .map((n) => getValue(data, n, true)) + .filter((x) => x) + .join(" "); + } + const value = data.key[name]; + if (value === undefined) return ""; + if (value === true) return includeKey ? name : "true"; + if (value === false) return includeKey ? "" : "false"; + if (value === null) return ""; + if (includeKey) return `${name}=${value}`; + return value + ""; + }; + + for (const [key, value] of Object.entries(args)) { + if (knownArgs.has(key)) continue; + const values = (Array.isArray(value) ? value : [value]).map((v) => + v.toString() + ); + data = data.filter((item) => { + const itemValue = getValue(item, key, false); + if (itemValue === "") return false; + return values.some((v) => itemValue === v); + }); + } + + if (data.length === 0) { + console.log("No data"); + return; + } + + const row = args.row || "name"; + const column = args.column || "scenario"; + const getRow = (data: any) => getValue(data, row, false); + const getColumn = (data: any) => getValue(data, column, false); + + const allRows = new Set(data.map(getRow)); + const allColumns = new Set(data.map(getColumn)); + + const table = []; + const columnSizes = [...allColumns].map((c) => c.length); + for (const row of allRows) { + const rowData: string[] = []; + let i = 0; + for (const column of allColumns) { + let items = data + .filter((d: any) => getRow(d) === row && getColumn(d) === column) + .map((i) => i.text); + rowData.push(items.join(", ")); + columnSizes[i] = Math.max(columnSizes[i], rowData[i].length); + i++; + } + table.push(rowData); + } + + const pad = (str: string, size: number) => { + return " ".repeat(size - str.length) + str; + }; + + const firstColumnSize = Math.max(...[...allRows].map((r) => r.length)); + + // Header + { + let row = "| "; + let sepRow = "|:"; + row += " ".repeat(firstColumnSize); + sepRow += "-".repeat(firstColumnSize); + const allColumnsArray = [...allColumns]; + for (let i = 0; i < columnSizes.length; i++) { + row += " | "; + row += pad(allColumnsArray[i], columnSizes[i]); + sepRow += ":|-"; + sepRow += "-".repeat(columnSizes[i]); + } + row += " |"; + sepRow += ":|"; + console.log(row); + console.log(sepRow); + } + + // Separator + let r = 0; + for (const rowName of allRows) { + let row = "| "; + row += pad(rowName, firstColumnSize); + for (let i = 0; i < columnSizes.length; i++) { + row += " | "; + row += pad(table[r][i], columnSizes[i]); + } + row += " |"; + console.log(row); + r++; + } +})().catch((e) => { + console.error(e.stack); +}); diff --git a/turbopack/packages/devlow-bench/src/types.d.ts b/turbopack/packages/devlow-bench/src/types.d.ts new file mode 100644 index 0000000000000..95d3dd4e6ccdd --- /dev/null +++ b/turbopack/packages/devlow-bench/src/types.d.ts @@ -0,0 +1 @@ +declare module "pidusage-tree"; diff --git a/turbopack/packages/devlow-bench/src/units.ts b/turbopack/packages/devlow-bench/src/units.ts new file mode 100644 index 0000000000000..610a136c4147b --- /dev/null +++ b/turbopack/packages/devlow-bench/src/units.ts @@ -0,0 +1,25 @@ +const UNITS: Record> = { + ms: { + " s": 1000, + }, + bytes: { + " GB": 1024 * 1024 * 1024, + " MB": 1024 * 1024, + " KB": 1024, + }, + requests: { + "K requests": 1000, + }, +}; + +export function formatUnit(value: number, unit: string) { + const conversion = UNITS[unit]; + if (conversion) { + for (const [name, factor] of Object.entries(conversion)) { + if (value >= factor) { + return `${(value / factor).toFixed(2)}${name}`; + } + } + } + return `${value.toFixed(2).replace(/\.00$/, "")} ${unit}`; +} diff --git a/turbopack/packages/devlow-bench/src/utils.ts b/turbopack/packages/devlow-bench/src/utils.ts new file mode 100644 index 0000000000000..6fe0e543b637b --- /dev/null +++ b/turbopack/packages/devlow-bench/src/utils.ts @@ -0,0 +1,14 @@ +import { ScenarioVariant } from "./index.js"; + +export function formatVariant( + scenario: string, + props: Record +): string { + const keys = Object.keys(props) + .filter((key) => props[key] !== false && props[key] !== null) + .map((key) => (props[key] === true ? key : `${key}=${props[key]}`)); + if (keys.length === 0) { + return scenario; + } + return `${scenario} ${keys.join(" ")}`; +} diff --git a/turbopack/packages/devlow-bench/tsconfig.json b/turbopack/packages/devlow-bench/tsconfig.json new file mode 100644 index 0000000000000..4fafbade9abcd --- /dev/null +++ b/turbopack/packages/devlow-bench/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "strict": true, + "target": "ES2020", + "module": "NodeNext", + "types": ["node"], + "outDir": "dist", + "declaration": true, + "declarationDir": "dist" + }, + "include": ["src/**/*"] +} diff --git a/turbopack/packages/node-module-trace/package.json b/turbopack/packages/node-module-trace/package.json new file mode 100644 index 0000000000000..0494edc90e674 --- /dev/null +++ b/turbopack/packages/node-module-trace/package.json @@ -0,0 +1,10 @@ +{ + "name": "@vercel/experimental-nft", + "version": "0.0.5-alpha.0", + "description": "Node.js module trace", + "license": "MPL-2.0", + "alias": "node-file-trace", + "publishConfig": { + "access": "public" + } +} diff --git a/turbopack/packages/turbo-tracing-next-plugin/.eslintrc.js b/turbopack/packages/turbo-tracing-next-plugin/.eslintrc.js new file mode 100644 index 0000000000000..4ca761e2f8eb5 --- /dev/null +++ b/turbopack/packages/turbo-tracing-next-plugin/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ["@turbo/eslint-config/library"], +}; diff --git a/turbopack/packages/turbo-tracing-next-plugin/README.md b/turbopack/packages/turbo-tracing-next-plugin/README.md new file mode 100644 index 0000000000000..dbd260941537a --- /dev/null +++ b/turbopack/packages/turbo-tracing-next-plugin/README.md @@ -0,0 +1,39 @@ +# `@vercel/experimental-nft-next-plugin` + +## Installation + +- yarn add -D `@vercel/experimental-nft-next-plugin` +- npm install -D `@vercel/experimental-nft-next-plugin` +- pnpm install -D `@vercel/experimental-nft-next-plugin` + +## Usage + +```js +// next.config.js + +const { createNodeFileTrace } = require("@vercel/experimental-nft-next-plugin"); + +const withNodeFileTrace = createNodeFileTrace({ + // experimental nft options + log: { + all: true, + }, +}); + +module.exports = withNodeFileTrace({ + // next config +}); +``` + +### experimental nft options + +> **Note** +> +> The default options should work fine. + +- `cwd?: string`, default is `process.cwd()`, you can override it to specify another directory to run experimental nft. +- `contextDirectory?: string`, relative to cwd, default is `.`. It must be the directory where the `node_modules` directory is located. If you are in the monorepo, you should set it to the root directory of the monorepo. For yarn2+/npm workspaces, the default value will respect the `PROJECT_CWD` and `npm_config_local_prefix` environment variables injected by yarn/npm client. If the default value doesn't work, you can override it to specify the root directory of the monorepo. +- `path?: string`, additional path which will be appended into the `PATH` environment variable. +- `log?.all?: boolean`, default is `false`, whether to show all logs. +- `log?.level?: string`, default is `error`, the log level. +- `log?.detail?: boolean`, default is `false`, whether to expand the log details. diff --git a/turbopack/packages/turbo-tracing-next-plugin/package.json b/turbopack/packages/turbo-tracing-next-plugin/package.json new file mode 100644 index 0000000000000..45ccccf45ac00 --- /dev/null +++ b/turbopack/packages/turbo-tracing-next-plugin/package.json @@ -0,0 +1,27 @@ +{ + "name": "@vercel/experimental-nft-next-plugin", + "version": "0.0.3-alpha.2", + "license": "MPL-2.0", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist/**/*" + ], + "publishConfig": { + "access": "public" + }, + "dependencies": { + "@vercel/webpack-nft": "workspace:*" + }, + "peerDependencies": { + "next": ">= 12" + }, + "devDependencies": { + "@turbo/eslint-config": "workspace:*", + "next": "^13.0.6" + }, + "scripts": { + "lint": "eslint src/", + "lint:prettier": "prettier -c . --cache --ignore-path=../../.prettierignore" + } +} diff --git a/turbopack/packages/turbo-tracing-next-plugin/src/index.ts b/turbopack/packages/turbo-tracing-next-plugin/src/index.ts new file mode 100644 index 0000000000000..0b75113b46343 --- /dev/null +++ b/turbopack/packages/turbo-tracing-next-plugin/src/index.ts @@ -0,0 +1,27 @@ +import { + NodeModuleTracePlugin, + NodeModuleTracePluginOptions, +} from "@vercel/webpack-nft"; +import type { NextConfig } from "next"; + +export function createNodeFileTrace(options?: NodeModuleTracePluginOptions) { + return function withNodeFileTrace(config: NextConfig = {}) { + const createWebpackConfig = config.webpack; + config.outputFileTracing = false; + config.webpack = (webpackConfig, context) => { + const config = + createWebpackConfig?.(webpackConfig, context) ?? webpackConfig; + if (context.isServer && !context.dev) { + const plugin = new NodeModuleTracePlugin(options); + if (config.plugins) { + config.plugins.push(plugin); + } else { + config.plugins = [plugin]; + } + } + + return config; + }; + return config; + }; +} diff --git a/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.env.local.example b/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.env.local.example new file mode 100644 index 0000000000000..9dead415dc211 --- /dev/null +++ b/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.env.local.example @@ -0,0 +1 @@ +MONGODB_URI= \ No newline at end of file diff --git a/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.gitignore b/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.gitignore new file mode 100644 index 0000000000000..1437c53f70bc2 --- /dev/null +++ b/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/.gitignore @@ -0,0 +1,34 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env.local +.env.development.local +.env.test.local +.env.production.local + +# vercel +.vercel diff --git a/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/README.md b/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/README.md new file mode 100644 index 0000000000000..1f7110e2585e4 --- /dev/null +++ b/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/README.md @@ -0,0 +1,5 @@ +# MongoDB and Mongoose with Next.js + +Copied from https://github.com/vercel/next.js/tree/canary/examples/with-mongodb. + +Run `pnpm run --filter @vercel/turbo-tracing-test-app build` to build this application. diff --git a/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/components/Form.js b/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/components/Form.js new file mode 100644 index 0000000000000..b184d9c70740c --- /dev/null +++ b/turbopack/packages/turbo-tracing-next-plugin/test/with-mongodb-mongoose/components/Form.js @@ -0,0 +1,202 @@ +import { useState } from "react"; +import { useRouter } from "next/router"; +import { mutate } from "swr"; + +const Form = ({ formId, petForm, forNewPet = true }) => { + const router = useRouter(); + const contentType = "application/json"; + const [errors, setErrors] = useState({}); + const [message, setMessage] = useState(""); + + const [form, setForm] = useState({ + name: petForm.name, + owner_name: petForm.owner_name, + species: petForm.species, + age: petForm.age, + poddy_trained: petForm.poddy_trained, + diet: petForm.diet, + image_url: petForm.image_url, + likes: petForm.likes, + dislikes: petForm.dislikes, + }); + + /* The PUT method edits an existing entry in the mongodb database. */ + const putData = async (form) => { + const { id } = router.query; + + try { + const res = await fetch(`/api/pets/${id}`, { + method: "PUT", + headers: { + Accept: contentType, + "Content-Type": contentType, + }, + body: JSON.stringify(form), + }); + + // Throw error with status code in case Fetch API req failed + if (!res.ok) { + throw new Error(res.status); + } + + const { data } = await res.json(); + + mutate(`/api/pets/${id}`, data, false); // Update the local data without a revalidation + router.push("/"); + } catch (error) { + setMessage("Failed to update pet"); + } + }; + + /* The POST method adds a new entry in the mongodb database. */ + const postData = async (form) => { + try { + const res = await fetch("/api/pets", { + method: "POST", + headers: { + Accept: contentType, + "Content-Type": contentType, + }, + body: JSON.stringify(form), + }); + + // Throw error with status code in case Fetch API req failed + if (!res.ok) { + throw new Error(res.status); + } + + router.push("/"); + } catch (error) { + setMessage("Failed to add pet"); + } + }; + + const handleChange = (e) => { + const target = e.target; + const value = + target.name === "poddy_trained" ? target.checked : target.value; + const name = target.name; + + setForm({ + ...form, + [name]: value, + }); + }; + + const handleSubmit = (e) => { + e.preventDefault(); + const errs = formValidate(); + if (Object.keys(errs).length === 0) { + forNewPet ? postData(form) : putData(form); + } else { + setErrors({ errs }); + } + }; + + /* Makes sure pet info is filled for pet name, owner name, species, and image url*/ + const formValidate = () => { + let err = {}; + if (!form.name) err.name = "Name is required"; + if (!form.owner_name) err.owner_name = "Owner is required"; + if (!form.species) err.species = "Species is required"; + if (!form.image_url) err.image_url = "Image URL is required"; + return err; + }; + + return ( + <> +

    + + + + + + + + + + + + + + + + +

    { + fn eq(&self, other: &Duration) -> bool { + self.to_duration() == *other + } +} + +#[cfg(test)] +mod tests { + use std::time::Duration; + + use super::SmallDuration; + + #[test] + fn test_1_nano() { + type Sd = SmallDuration<1>; + + assert_eq!(Sd::from_nanos(1), Duration::from_nanos(1)); + assert_eq!(Sd::from_nanos(42), Duration::from_nanos(42)); + + assert_eq!(Sd::from_micros(1), Duration::from_micros(1)); + assert_eq!(Sd::from_micros(42), Duration::from_micros(42)); + + assert_eq!(Sd::from_millis(1), Duration::from_millis(1)); + assert_eq!(Sd::from_millis(42), Duration::from_millis(42)); + + assert_eq!(Sd::from_secs(1), Duration::from_secs(1)); + + // 1ns precision can only store up to ~4.29s. + assert_eq!(Sd::from_secs(4), Duration::from_secs(4)); + assert_eq!(Sd::from_secs(5), Sd::MAX); + } + + #[test] + fn test_1_micro() { + type Sd = SmallDuration<1_000>; + + // 1µs precision can't store ns-level variations. + assert_eq!(Sd::from_nanos(1), Sd::MIN); + assert_eq!(Sd::from_nanos(42), Sd::MIN); + + assert_eq!(Sd::from_micros(1), Duration::from_micros(1)); + assert_eq!(Sd::from_micros(42), Duration::from_micros(42)); + + assert_eq!(Sd::from_millis(1), Duration::from_millis(1)); + assert_eq!(Sd::from_millis(42), Duration::from_millis(42)); + + assert_eq!(Sd::from_secs(1), Duration::from_secs(1)); + assert_eq!(Sd::from_secs(42), Duration::from_secs(42)); + + // 1µs precision can only store up to ~4,294s. + assert_eq!(Sd::from_secs(4_000), Duration::from_secs(4_000)); + assert_eq!(Sd::from_secs(5_000), Sd::MAX); + } + + #[test] + fn test_1_milli() { + type Sd = SmallDuration<1_000_000>; + + // 1ms precision can't store ns-or-µs-level variations. + assert_eq!(Sd::from_nanos(1), Sd::MIN); + assert_eq!(Sd::from_nanos(42), Sd::MIN); + assert_eq!(Sd::from_micros(1), Sd::MIN); + assert_eq!(Sd::from_micros(42), Sd::MIN); + + assert_eq!(Sd::from_millis(1), Duration::from_millis(1)); + assert_eq!(Sd::from_millis(42), Duration::from_millis(42)); + + assert_eq!(Sd::from_secs(1), Duration::from_secs(1)); + assert_eq!(Sd::from_secs(42), Duration::from_secs(42)); + + // 1ms precision can only store up to ~4,294,000s. + assert_eq!(Sd::from_secs(4_000_000), Duration::from_secs(4_000_000)); + assert_eq!(Sd::from_secs(5_000_000), Sd::MAX); + } + + #[test] + fn test_1_sec() { + type Sd = SmallDuration<1_000_000_000>; + + // 1ms precision can't store ns/µs/ms-level variations. + assert_eq!(Sd::from_nanos(1), Sd::MIN); + assert_eq!(Sd::from_nanos(42), Sd::MIN); + assert_eq!(Sd::from_micros(1), Sd::MIN); + assert_eq!(Sd::from_micros(42), Sd::MIN); + assert_eq!(Sd::from_millis(1), Sd::MIN); + assert_eq!(Sd::from_millis(42), Sd::MIN); + + assert_eq!(Sd::from_secs(1), Duration::from_secs(1)); + assert_eq!(Sd::from_secs(42), Duration::from_secs(42)); + + // 1s precision can only store up to ~4,294,000,000s. + assert_eq!( + Sd::from_secs(4_000_000_000), + Duration::from_secs(4_000_000_000) + ); + assert_eq!(Sd::from_secs(5_000_000_000), Sd::MAX); + } +} diff --git a/turbopack/crates/turbo-tasks/src/state.rs b/turbopack/crates/turbo-tasks/src/state.rs new file mode 100644 index 0000000000000..d2346ba103fe1 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/state.rs @@ -0,0 +1,176 @@ +use std::{ + fmt::Debug, + mem::take, + ops::{Deref, DerefMut}, +}; + +use auto_hash_map::AutoSet; +use parking_lot::{Mutex, MutexGuard}; +use serde::{Deserialize, Deserializer, Serialize}; + +use crate::{get_invalidator, mark_stateful, trace::TraceRawVcs, Invalidator}; + +pub struct State { + inner: Mutex>, +} + +struct StateInner { + value: T, + invalidators: AutoSet, +} + +pub struct StateRef<'a, T> { + inner: MutexGuard<'a, StateInner>, + mutated: bool, +} + +impl Debug for State { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("State") + .field("value", &self.inner.lock().value) + .finish() + } +} + +impl TraceRawVcs for State { + fn trace_raw_vcs(&self, trace_context: &mut crate::trace::TraceRawVcsContext) { + self.inner.lock().value.trace_raw_vcs(trace_context); + } +} + +impl Default for State { + fn default() -> Self { + // Need to be explicit to ensure marking as stateful. + Self::new(Default::default()) + } +} + +impl PartialEq for State { + fn eq(&self, _other: &Self) -> bool { + false + } +} +impl Eq for State {} + +impl Serialize for State { + fn serialize(&self, _serializer: S) -> Result { + // For this to work at all we need to do more. Changing the state need to + // invalidate the serialization of the task that contains the state. So we + // probably need to store the state outside of the task to be able to serialize + // it independent from the creating task. + panic!("State serialization is not implemented yet"); + } +} + +impl<'de, T> Deserialize<'de> for State { + fn deserialize>(_deserializer: D) -> Result { + panic!("State serialization is not implemented yet"); + } +} + +impl Drop for State { + fn drop(&mut self) { + let mut inner = self.inner.lock(); + for invalidator in take(&mut inner.invalidators) { + invalidator.invalidate(); + } + } +} + +impl State { + pub fn new(value: T) -> Self { + mark_stateful(); + Self { + inner: Mutex::new(StateInner { + value, + invalidators: AutoSet::new(), + }), + } + } + + /// Gets the current value of the state. The current task will be registered + /// as dependency of the state and will be invalidated when the state + /// changes. + pub fn get(&self) -> StateRef<'_, T> { + let invalidator = get_invalidator(); + let mut inner = self.inner.lock(); + inner.invalidators.insert(invalidator); + StateRef { + inner, + mutated: false, + } + } + + /// Gets the current value of the state. Untracked. + pub fn get_untracked(&self) -> StateRef<'_, T> { + let inner = self.inner.lock(); + StateRef { + inner, + mutated: false, + } + } + + /// Sets the current state without comparing it with the old value. This + /// should only be used if one is sure that the value has changed. + pub fn set_unconditionally(&self, value: T) { + let mut inner = self.inner.lock(); + inner.value = value; + for invalidator in take(&mut inner.invalidators) { + invalidator.invalidate(); + } + } + + /// Updates the current state with the `update` function. The `update` + /// function need to return `true` when the value was modified. Exposing + /// the current value from the `update` function is not allowed and will + /// result in incorrect cache invalidation. + pub fn update_conditionally(&self, update: impl FnOnce(&mut T) -> bool) { + let mut inner = self.inner.lock(); + if !update(&mut inner.value) { + return; + } + for invalidator in take(&mut inner.invalidators) { + invalidator.invalidate(); + } + } +} + +impl State { + /// Update the current state when the `value` is different from the current + /// value. `T` must implement [PartialEq] for this to work. + pub fn set(&self, value: T) { + let mut inner = self.inner.lock(); + if inner.value == value { + return; + } + inner.value = value; + for invalidator in take(&mut inner.invalidators) { + invalidator.invalidate(); + } + } +} + +impl<'a, T> Deref for StateRef<'a, T> { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner.value + } +} + +impl<'a, T> DerefMut for StateRef<'a, T> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.mutated = true; + &mut self.inner.value + } +} + +impl<'a, T> Drop for StateRef<'a, T> { + fn drop(&mut self) { + if self.mutated { + for invalidator in take(&mut self.inner.invalidators) { + invalidator.invalidate(); + } + } + } +} diff --git a/turbopack/crates/turbo-tasks/src/task/function.rs b/turbopack/crates/turbo-tasks/src/task/function.rs new file mode 100644 index 0000000000000..12e83ab98a0f2 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/task/function.rs @@ -0,0 +1,489 @@ +//! # Function tasks +//! +//! This module contains the trait definitions and implementations that are +//! necessary for accepting functions as tasks when using the +//! `turbo_tasks::function` macro. +//! +//! This system is inspired by Bevy's Systems and Axum's Handlers. +//! +//! The original principle is somewhat simple: a function is accepted if all +//! of its arguments implement `TaskInput` and its return type implements +//! `TaskOutput`. There are a few hoops one needs to jump through to make this +//! work, but they are described in this blog post: +//! +//! +//! However, there is an additional complication in our case: async methods +//! that accept a reference to the receiver as their first argument. +//! +//! This complication handled through our own version of the `async_trait` +//! crate, which allows us to target `async fn` as trait bounds. The naive +//! approach runs into many issues with lifetimes, hence the need for an +//! intermediate trait. However, this implementation doesn't support all async +//! methods (see commented out tests). + +use std::{future::Future, marker::PhantomData, pin::Pin}; + +use anyhow::Result; + +use super::{TaskInput, TaskOutput}; +use crate::{magic_any::MagicAny, RawVc, Vc, VcRead, VcValueType}; + +pub type NativeTaskFuture = Pin> + Send>>; + +pub trait TaskFn: Send + Sync + 'static { + fn functor(&self, this: Option, arg: &dyn MagicAny) -> Result; +} + +pub trait IntoTaskFn { + type TaskFn: TaskFn; + + fn into_task_fn(self) -> Self::TaskFn; +} + +impl IntoTaskFn for F +where + F: TaskFnInputFunction, + Mode: TaskFnMode, + Inputs: TaskInputs, +{ + type TaskFn = FunctionTaskFn; + + fn into_task_fn(self) -> Self::TaskFn { + FunctionTaskFn { + task_fn: self, + mode: PhantomData, + inputs: PhantomData, + } + } +} + +pub trait IntoTaskFnWithThis { + type TaskFn: TaskFn; + + fn into_task_fn_with_this(self) -> Self::TaskFn; +} + +impl IntoTaskFnWithThis for F +where + F: TaskFnInputFunctionWithThis, + Mode: TaskFnMode, + This: Sync + Send + 'static, + Inputs: TaskInputs, +{ + type TaskFn = FunctionTaskFnWithThis; + + fn into_task_fn_with_this(self) -> Self::TaskFn { + FunctionTaskFnWithThis { + task_fn: self, + mode: PhantomData, + this: PhantomData, + inputs: PhantomData, + } + } +} + +pub struct FunctionTaskFn { + task_fn: F, + mode: PhantomData, + inputs: PhantomData, +} + +impl TaskFn for FunctionTaskFn +where + F: TaskFnInputFunction, + Mode: TaskFnMode, + Inputs: TaskInputs, +{ + fn functor(&self, _this: Option, arg: &dyn MagicAny) -> Result { + TaskFnInputFunction::functor(&self.task_fn, arg) + } +} + +pub struct FunctionTaskFnWithThis< + F, + Mode: TaskFnMode, + This: Sync + Send + 'static, + Inputs: TaskInputs, +> { + task_fn: F, + mode: PhantomData, + this: PhantomData, + inputs: PhantomData, +} + +impl TaskFn for FunctionTaskFnWithThis +where + F: TaskFnInputFunctionWithThis, + Mode: TaskFnMode, + This: Sync + Send + 'static, + Inputs: TaskInputs, +{ + fn functor(&self, this: Option, arg: &dyn MagicAny) -> Result { + let Some(this) = this else { + panic!("Method needs a `self` argument"); + }; + TaskFnInputFunctionWithThis::functor(&self.task_fn, this, arg) + } +} + +trait TaskFnInputFunction: Send + Sync + Clone + 'static { + fn functor(&self, arg: &dyn MagicAny) -> Result; +} + +trait TaskFnInputFunctionWithThis: + Send + Sync + Clone + 'static +{ + fn functor(&self, this: RawVc, arg: &dyn MagicAny) -> Result; +} + +pub trait TaskInputs: Send + Sync + 'static {} + +/// Modes to allow multiple `TaskFnInputFunction` blanket implementations on +/// `Fn`s. Even though the implementations are non-conflicting in practice, they +/// could be in theory (at least from with the compiler's current limitations). +/// Despite this, the compiler is still able to infer the correct mode from a +/// function. +pub trait TaskFnMode: Send + Sync + 'static {} + +pub struct FunctionMode; +impl TaskFnMode for FunctionMode {} + +pub struct AsyncFunctionMode; +impl TaskFnMode for AsyncFunctionMode {} + +pub struct MethodMode; +impl TaskFnMode for MethodMode {} + +pub struct AsyncMethodMode; +impl TaskFnMode for AsyncMethodMode {} + +macro_rules! task_inputs_impl { + ( $( $arg:ident )* ) => { + impl<$($arg,)*> TaskInputs for ($($arg,)*) + where + $($arg: TaskInput + 'static,)* + {} + } +} + +fn get_args(arg: &dyn MagicAny) -> Result<&T> { + let value = arg.downcast_ref::(); + #[cfg(debug_assertions)] + return anyhow::Context::with_context(value, || { + format!( + "Invalid argument type, expected {} got {}", + std::any::type_name::(), + (*arg).magic_type_name() + ) + }); + #[cfg(not(debug_assertions))] + return anyhow::Context::context(value, "Invalid argument type"); +} + +macro_rules! task_fn_impl { + ( $async_fn_trait:ident $arg_len:literal $( $arg:ident )* ) => { + impl TaskFnInputFunction for F + where + $($arg: TaskInput + 'static,)* + F: Fn($($arg,)*) -> Output + Send + Sync + Clone + 'static, + Output: TaskOutput + 'static, + { + #[allow(non_snake_case)] + fn functor(&self, arg: &dyn MagicAny) -> Result { + let task_fn = self.clone(); + + let ($($arg,)*) = get_args::<($($arg,)*)>(arg)?; + $( + let $arg = $arg.clone(); + )* + + Ok(Box::pin(async move { + Output::try_into_raw_vc((task_fn)($($arg,)*)) + })) + } + } + + impl TaskFnInputFunction for F + where + $($arg: TaskInput + 'static,)* + F: Fn($($arg,)*) -> FutureOutput + Send + Sync + Clone + 'static, + FutureOutput: Future + Send, + Output: TaskOutput + 'static, + { + #[allow(non_snake_case)] + fn functor(&self, arg: &dyn MagicAny) -> Result { + let task_fn = self.clone(); + + let ($($arg,)*) = get_args::<($($arg,)*)>(arg)?; + $( + let $arg = $arg.clone(); + )* + + Ok(Box::pin(async move { + Output::try_into_raw_vc((task_fn)($($arg,)*).await) + })) + } + } + + impl TaskFnInputFunctionWithThis for F + where + Recv: VcValueType, + $($arg: TaskInput + 'static,)* + F: Fn(&Recv, $($arg,)*) -> Output + Send + Sync + Clone + 'static, + Output: TaskOutput + 'static, + { + #[allow(non_snake_case)] + fn functor(&self, this: RawVc, arg: &dyn MagicAny) -> Result { + let task_fn = self.clone(); + let recv = Vc::::from(this); + + let ($($arg,)*) = get_args::<($($arg,)*)>(arg)?; + $( + let $arg = $arg.clone(); + )* + + Ok(Box::pin(async move { + let recv = recv.await?; + let recv = >::target_to_value_ref(&*recv); + Output::try_into_raw_vc((task_fn)(recv, $($arg,)*)) + })) + } + } + + impl TaskFnInputFunctionWithThis for F + where + Recv: Sync + Send + 'static, + $($arg: TaskInput + 'static,)* + F: Fn(Vc, $($arg,)*) -> Output + Send + Sync + Clone + 'static, + Output: TaskOutput + 'static, + { + #[allow(non_snake_case)] + fn functor(&self, this: RawVc, arg: &dyn MagicAny) -> Result { + let task_fn = self.clone(); + let recv = Vc::::from(this); + + let ($($arg,)*) = get_args::<($($arg,)*)>(arg)?; + $( + let $arg = $arg.clone(); + )* + + Ok(Box::pin(async move { + Output::try_into_raw_vc((task_fn)(recv, $($arg,)*)) + })) + } + } + + pub trait $async_fn_trait: Fn(A0, $($arg,)*) -> Self::OutputFuture { + type OutputFuture: Future>::Output> + Send; + type Output: TaskOutput; + } + + impl $async_fn_trait for F + where + F: Fn(A0, $($arg,)*) -> Fut, + Fut: Future + Send, + Fut::Output: TaskOutput + { + type OutputFuture = Fut; + type Output = Fut::Output; + } + + impl TaskFnInputFunctionWithThis for F + where + Recv: VcValueType, + $($arg: TaskInput + 'static,)* + F: for<'a> $async_fn_trait<&'a Recv, $($arg,)*> + Clone + Send + Sync + 'static, + { + #[allow(non_snake_case)] + fn functor(&self, this: RawVc, arg: &dyn MagicAny) -> Result { + let task_fn = self.clone(); + let recv = Vc::::from(this); + + let ($($arg,)*) = get_args::<($($arg,)*)>(arg)?; + $( + let $arg = $arg.clone(); + )* + + Ok(Box::pin(async move { + let recv = recv.await?; + let recv = >::target_to_value_ref(&*recv); + >::Output::try_into_raw_vc((task_fn)(recv, $($arg,)*).await) + })) + } + } + + impl TaskFnInputFunctionWithThis for F + where + Recv: Sync + Send + 'static, + $($arg: TaskInput + 'static,)* + F: $async_fn_trait, $($arg,)*> + Clone + Send + Sync + 'static, + { + #[allow(non_snake_case)] + fn functor(&self, this: RawVc, arg: &dyn MagicAny) -> Result { + let task_fn = self.clone(); + let recv = Vc::::from(this); + + let ($($arg,)*) = get_args::<($($arg,)*)>(arg)?; + $( + let $arg = $arg.clone(); + )* + + Ok(Box::pin(async move { + , $($arg,)*>>::Output::try_into_raw_vc((task_fn)(recv, $($arg,)*).await) + })) + } + } + }; +} + +task_fn_impl! { AsyncFn0 0 } +task_fn_impl! { AsyncFn1 1 A1 } +task_fn_impl! { AsyncFn2 2 A1 A2 } +task_fn_impl! { AsyncFn3 3 A1 A2 A3 } +task_fn_impl! { AsyncFn4 4 A1 A2 A3 A4 } +task_fn_impl! { AsyncFn5 5 A1 A2 A3 A4 A5 } +task_fn_impl! { AsyncFn6 6 A1 A2 A3 A4 A5 A6 } +task_fn_impl! { AsyncFn7 7 A1 A2 A3 A4 A5 A6 A7 } +task_fn_impl! { AsyncFn8 8 A1 A2 A3 A4 A5 A6 A7 A8 } +task_fn_impl! { AsyncFn9 9 A1 A2 A3 A4 A5 A6 A7 A8 A9 } +task_fn_impl! { AsyncFn10 10 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 } +task_fn_impl! { AsyncFn11 11 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 } +task_fn_impl! { AsyncFn12 12 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 } + +// There needs to be one more implementation than task_fn_impl to account for +// the receiver. +task_inputs_impl! {} +task_inputs_impl! { A1 } +task_inputs_impl! { A1 A2 } +task_inputs_impl! { A1 A2 A3 } +task_inputs_impl! { A1 A2 A3 A4 } +task_inputs_impl! { A1 A2 A3 A4 A5 } +task_inputs_impl! { A1 A2 A3 A4 A5 A6 } +task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 } +task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 } +task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 A9 } +task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 } +task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 } +task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 } +task_inputs_impl! { A1 A2 A3 A4 A5 A6 A7 A8 A9 A10 A11 A12 A13 } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{RcStr, VcCellNewMode, VcDefaultRead}; + + #[test] + fn test_task_fn() { + fn no_args() -> crate::Vc { + todo!() + } + + fn one_arg(_a: i32) -> crate::Vc { + todo!() + } + + async fn async_one_arg(_a: i32) -> crate::Vc { + todo!() + } + + fn with_recv(_a: &i32) -> crate::Vc { + todo!() + } + + async fn async_with_recv(_a: &i32) -> crate::Vc { + todo!() + } + + fn with_recv_and_str(_a: &i32, _s: RcStr) -> crate::Vc { + todo!() + } + + async fn async_with_recv_and_str(_a: &i32, _s: RcStr) -> crate::Vc { + todo!() + } + + async fn async_with_recv_and_str_and_result(_a: &i32, _s: RcStr) -> Result> { + todo!() + } + + fn accepts_task_fn(_task_fn: F) + where + F: TaskFn, + { + } + + struct Struct; + impl Struct { + async fn inherent_method(&self) {} + } + + unsafe impl VcValueType for Struct { + type Read = VcDefaultRead; + + type CellMode = VcCellNewMode; + + fn get_value_type_id() -> crate::ValueTypeId { + todo!() + } + } + + trait AsyncTrait { + async fn async_method(&self); + } + + impl AsyncTrait for Struct { + async fn async_method(&self) { + todo!() + } + } + + /* + async fn async_with_recv_and_str_and_lf( + _a: &i32, + _s: String, + ) -> Result, crate::Vc> { + todo!() + } + + #[async_trait::async_trait] + trait BoxAsyncTrait { + async fn box_async_method(&self); + } + + #[async_trait::async_trait] + impl BoxAsyncTrait for Struct { + async fn box_async_method(&self) { + todo!() + } + } + */ + + let _task_fn = no_args.into_task_fn(); + accepts_task_fn(no_args.into_task_fn()); + let _task_fn = one_arg.into_task_fn(); + accepts_task_fn(one_arg.into_task_fn()); + let _task_fn = async_one_arg.into_task_fn(); + accepts_task_fn(async_one_arg.into_task_fn()); + let task_fn = with_recv.into_task_fn_with_this(); + accepts_task_fn(task_fn); + let task_fn = async_with_recv.into_task_fn_with_this(); + accepts_task_fn(task_fn); + let task_fn = with_recv_and_str.into_task_fn_with_this(); + accepts_task_fn(task_fn); + let task_fn = async_with_recv_and_str.into_task_fn_with_this(); + accepts_task_fn(task_fn); + let task_fn = async_with_recv_and_str_and_result.into_task_fn_with_this(); + accepts_task_fn(task_fn); + let task_fn = ::async_method.into_task_fn_with_this(); + accepts_task_fn(task_fn); + let task_fn = Struct::inherent_method.into_task_fn_with_this(); + accepts_task_fn(task_fn); + + /* + let task_fn = ::box_async_method.into_task_fn(); + accepts_task_fn(task_fn); + let task_fn = async_with_recv_and_str_and_lf.into_task_fn(); + accepts_task_fn(task_fn); + */ + } +} diff --git a/turbopack/crates/turbo-tasks/src/task/mod.rs b/turbopack/crates/turbo-tasks/src/task/mod.rs new file mode 100644 index 0000000000000..963a3a74a99d1 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/task/mod.rs @@ -0,0 +1,9 @@ +pub(crate) mod function; +pub(crate) mod shared_reference; +pub(crate) mod task_input; +pub(crate) mod task_output; + +pub use function::{AsyncFunctionMode, FunctionMode, IntoTaskFn, TaskFn}; +pub use shared_reference::SharedReference; +pub use task_input::TaskInput; +pub use task_output::TaskOutput; diff --git a/turbopack/crates/turbo-tasks/src/task/shared_reference.rs b/turbopack/crates/turbo-tasks/src/task/shared_reference.rs new file mode 100644 index 0000000000000..0194bfdfc597d --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/task/shared_reference.rs @@ -0,0 +1,165 @@ +use std::{ + any::Any, + fmt::{Debug, Display}, + hash::Hash, +}; + +use anyhow::Result; +use serde::{ser::SerializeTuple, Deserialize, Serialize}; +use unsize::CoerceUnsize; + +use crate::{ + registry, + triomphe_utils::{coerce_to_any_send_sync, downcast_triomphe_arc}, + ValueTypeId, +}; + +/// A reference to a piece of data +#[derive(Clone)] +pub struct SharedReference(pub triomphe::Arc); + +impl SharedReference { + pub fn new(data: triomphe::Arc) -> Self { + Self(data.unsize(coerce_to_any_send_sync())) + } +} + +/// A reference to a piece of data with type information +#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Debug)] +pub struct TypedSharedReference(pub ValueTypeId, pub SharedReference); + +impl SharedReference { + pub fn downcast(self) -> Result, Self> { + match downcast_triomphe_arc(self.0) { + Ok(data) => Ok(data), + Err(data) => Err(Self(data)), + } + } + + pub(crate) fn typed(&self, type_id: ValueTypeId) -> TypedSharedReference { + TypedSharedReference(type_id, self.clone()) + } +} + +impl TypedSharedReference { + pub(crate) fn untyped(&self) -> (ValueTypeId, SharedReference) { + (self.0, self.1.clone()) + } +} + +impl Hash for SharedReference { + fn hash(&self, state: &mut H) { + Hash::hash(&(&*self.0 as *const (dyn Any + Send + Sync)), state) + } +} +impl PartialEq for SharedReference { + // Must compare with PartialEq rather than std::ptr::addr_eq since the latter + // only compares their addresses. + #[allow(ambiguous_wide_pointer_comparisons)] + fn eq(&self, other: &Self) -> bool { + triomphe::Arc::ptr_eq(&self.0, &other.0) + } +} +impl Eq for SharedReference {} +impl PartialOrd for SharedReference { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} +impl Ord for SharedReference { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + Ord::cmp( + &(&*self.0 as *const (dyn Any + Send + Sync)).cast::<()>(), + &(&*other.0 as *const (dyn Any + Send + Sync)).cast::<()>(), + ) + } +} +impl Debug for SharedReference { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("SharedReference").field(&self.0).finish() + } +} + +impl Serialize for TypedSharedReference { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let TypedSharedReference(ty, SharedReference(arc)) = self; + let value_type = registry::get_value_type(*ty); + if let Some(serializable) = value_type.any_as_serializable(arc) { + let mut t = serializer.serialize_tuple(2)?; + t.serialize_element(registry::get_value_type_global_name(*ty))?; + t.serialize_element(serializable)?; + t.end() + } else { + Err(serde::ser::Error::custom(format!( + "{:?} is not serializable", + arc + ))) + } + } +} + +impl Display for SharedReference { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "untyped value") + } +} + +impl Display for TypedSharedReference { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "value of type {}", registry::get_value_type(self.0).name) + } +} + +impl<'de> Deserialize<'de> for TypedSharedReference { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + struct Visitor; + + impl<'de> serde::de::Visitor<'de> for Visitor { + type Value = TypedSharedReference; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a serializable shared reference") + } + + fn visit_seq(self, mut seq: A) -> Result + where + A: serde::de::SeqAccess<'de>, + { + if let Some(global_name) = seq.next_element()? { + if let Some(ty) = registry::get_value_type_id_by_global_name(global_name) { + if let Some(seed) = registry::get_value_type(ty).get_any_deserialize_seed() + { + if let Some(value) = seq.next_element_seed(seed)? { + Ok(TypedSharedReference(ty, SharedReference::new(value.into()))) + } else { + Err(serde::de::Error::invalid_length( + 1, + &"tuple with type and value", + )) + } + } else { + Err(serde::de::Error::custom(format!( + "{ty} is not deserializable" + ))) + } + } else { + Err(serde::de::Error::unknown_variant(global_name, &[])) + } + } else { + Err(serde::de::Error::invalid_length( + 0, + &"tuple with type and value", + )) + } + } + } + + deserializer.deserialize_tuple(2, Visitor) + } +} diff --git a/turbopack/crates/turbo-tasks/src/task/task_input.rs b/turbopack/crates/turbo-tasks/src/task/task_input.rs new file mode 100644 index 0000000000000..b9f9ebb9d8b9c --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/task/task_input.rs @@ -0,0 +1,404 @@ +use std::{any::Any, fmt::Debug, hash::Hash}; + +use anyhow::Result; +use async_trait::async_trait; +use serde::{Deserialize, Serialize}; + +use crate::{ + MagicAny, RcStr, ResolvedVc, TaskId, TransientInstance, TransientValue, Value, ValueTypeId, Vc, +}; + +/// Trait to implement in order for a type to be accepted as a +/// [`#[turbo_tasks::function]`][crate::function] argument. +/// +/// See also [`ConcreteTaskInput`]. +#[async_trait] +pub trait TaskInput: Send + Sync + Clone + Debug + PartialEq + Eq + Hash { + async fn resolve(&self) -> Result { + Ok(self.clone()) + } + fn is_resolved(&self) -> bool { + true + } + fn is_transient(&self) -> bool { + false + } +} + +macro_rules! impl_task_input { + ($($t:ty),*) => { + $( + #[async_trait] + impl TaskInput for $t {} + )* + }; +} + +impl_task_input! { + (), + bool, + u8, + u16, + u32, + i32, + u64, + usize, + RcStr, + TaskId, + ValueTypeId +} + +#[async_trait] +impl TaskInput for Vec +where + T: TaskInput, +{ + fn is_resolved(&self) -> bool { + self.iter().all(TaskInput::is_resolved) + } + + fn is_transient(&self) -> bool { + self.iter().any(TaskInput::is_transient) + } + + async fn resolve(&self) -> Result { + let mut resolved = Vec::with_capacity(self.len()); + for value in self { + resolved.push(value.resolve().await?); + } + Ok(resolved) + } +} + +#[async_trait] +impl TaskInput for Option +where + T: TaskInput, +{ + fn is_resolved(&self) -> bool { + match self { + Some(value) => value.is_resolved(), + None => true, + } + } + + fn is_transient(&self) -> bool { + match self { + Some(value) => value.is_transient(), + None => false, + } + } + + async fn resolve(&self) -> Result { + match self { + Some(value) => Ok(Some(value.resolve().await?)), + None => Ok(None), + } + } +} + +#[async_trait] +impl TaskInput for Vc +where + T: Send, +{ + fn is_resolved(&self) -> bool { + Vc::is_resolved(*self) + } + + fn is_transient(&self) -> bool { + false + } + + async fn resolve(&self) -> Result { + Vc::resolve(*self).await + } +} + +impl TaskInput for ResolvedVc +where + T: Send, +{ + fn is_resolved(&self) -> bool { + true + } + + fn is_transient(&self) -> bool { + false + } +} + +impl TaskInput for Value +where + T: Any + + std::fmt::Debug + + Clone + + std::hash::Hash + + Eq + + Send + + Sync + + Serialize + + for<'de> Deserialize<'de> + + 'static, +{ + fn is_resolved(&self) -> bool { + true + } + + fn is_transient(&self) -> bool { + false + } +} + +impl TaskInput for TransientValue +where + T: MagicAny + Clone + Debug + Hash + Eq + 'static, +{ + fn is_transient(&self) -> bool { + true + } +} + +impl Serialize for TransientValue +where + T: MagicAny + Clone + 'static, +{ + fn serialize(&self, _serializer: S) -> Result + where + S: serde::Serializer, + { + Err(serde::ser::Error::custom( + "cannot serialize transient task inputs", + )) + } +} + +impl<'de, T> Deserialize<'de> for TransientValue +where + T: MagicAny + Clone + 'static, +{ + fn deserialize(_deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Err(serde::de::Error::custom( + "cannot deserialize transient task inputs", + )) + } +} + +impl TaskInput for TransientInstance +where + T: Sync + Send, +{ + fn is_transient(&self) -> bool { + true + } +} + +impl Serialize for TransientInstance { + fn serialize(&self, _serializer: S) -> Result + where + S: serde::Serializer, + { + Err(serde::ser::Error::custom( + "cannot serialize transient task inputs", + )) + } +} + +impl<'de, T> Deserialize<'de> for TransientInstance { + fn deserialize(_deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Err(serde::de::Error::custom( + "cannot deserialize transient task inputs", + )) + } +} + +macro_rules! tuple_impls { + ( $( $name:ident )+ ) => { + #[async_trait] + impl<$($name: TaskInput),+> TaskInput for ($($name,)+) + where $($name: TaskInput),+ + { + #[allow(non_snake_case)] + fn is_resolved(&self) -> bool { + let ($($name,)+) = self; + $($name.is_resolved() &&)+ true + } + + #[allow(non_snake_case)] + fn is_transient(&self) -> bool { + let ($($name,)+) = self; + $($name.is_transient() ||)+ false + } + + #[allow(non_snake_case)] + async fn resolve(&self) -> Result { + let ($($name,)+) = self; + Ok(($($name.resolve().await?,)+)) + } + } + }; +} + +// Implement `TaskInput` for all tuples of 1 to 16 elements. +tuple_impls! { A } +tuple_impls! { A B } +tuple_impls! { A B C } +tuple_impls! { A B C D } +tuple_impls! { A B C D E } +tuple_impls! { A B C D E F } +tuple_impls! { A B C D E F G } +tuple_impls! { A B C D E F G H } +tuple_impls! { A B C D E F G H I } +tuple_impls! { A B C D E F G H I J } +tuple_impls! { A B C D E F G H I J K } +tuple_impls! { A B C D E F G H I J K L } + +#[cfg(test)] +mod tests { + use turbo_tasks_macros::TaskInput; + + use super::*; + // This is necessary for the derive macro to work, as its expansion refers to + // the crate name directly. + use crate as turbo_tasks; + + fn assert_task_input(_: T) + where + T: TaskInput, + { + } + + #[test] + fn test_no_fields() -> Result<()> { + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + struct NoFields; + + assert_task_input(NoFields); + Ok(()) + } + + #[test] + fn test_one_unnamed_field() -> Result<()> { + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + struct OneUnnamedField(u32); + + assert_task_input(OneUnnamedField(42)); + Ok(()) + } + + #[test] + fn test_multiple_unnamed_fields() -> Result<()> { + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + struct MultipleUnnamedFields(u32, RcStr); + + assert_task_input(MultipleUnnamedFields(42, "42".into())); + Ok(()) + } + + #[test] + fn test_one_named_field() -> Result<()> { + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + struct OneNamedField { + named: u32, + } + + assert_task_input(OneNamedField { named: 42 }); + Ok(()) + } + + #[test] + fn test_multiple_named_fields() -> Result<()> { + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + struct MultipleNamedFields { + named: u32, + other: RcStr, + } + + assert_task_input(MultipleNamedFields { + named: 42, + other: "42".into(), + }); + Ok(()) + } + + #[test] + fn test_generic_field() -> Result<()> { + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + struct GenericField(T); + + assert_task_input(GenericField(42)); + assert_task_input(GenericField(RcStr::from("42"))); + Ok(()) + } + + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + enum OneVariant { + Variant, + } + + #[test] + fn test_one_variant() -> Result<()> { + assert_task_input(OneVariant::Variant); + Ok(()) + } + + #[test] + fn test_multiple_variants() -> Result<()> { + #[derive(Clone, TaskInput, PartialEq, Eq, Hash, Debug, Serialize, Deserialize)] + enum MultipleVariants { + Variant1, + Variant2, + } + + assert_task_input(MultipleVariants::Variant2); + Ok(()) + } + + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + enum MultipleVariantsAndHeterogeneousFields { + Variant1, + Variant2(u32), + Variant3 { named: u32 }, + Variant4(u32, RcStr), + Variant5 { named: u32, other: RcStr }, + } + + #[test] + fn test_multiple_variants_and_heterogeneous_fields() -> Result<()> { + assert_task_input(MultipleVariantsAndHeterogeneousFields::Variant5 { + named: 42, + other: "42".into(), + }); + Ok(()) + } + + #[test] + fn test_nested_variants() -> Result<()> { + #[derive(Clone, TaskInput, Eq, PartialEq, Hash, Debug, Serialize, Deserialize)] + enum NestedVariants { + Variant1, + Variant2(MultipleVariantsAndHeterogeneousFields), + Variant3 { named: OneVariant }, + Variant4(OneVariant, RcStr), + Variant5 { named: OneVariant, other: RcStr }, + } + + assert_task_input(NestedVariants::Variant5 { + named: OneVariant::Variant, + other: "42".into(), + }); + assert_task_input(NestedVariants::Variant2( + MultipleVariantsAndHeterogeneousFields::Variant5 { + named: 42, + other: "42".into(), + }, + )); + Ok(()) + } +} diff --git a/turbopack/crates/turbo-tasks/src/task/task_output.rs b/turbopack/crates/turbo-tasks/src/task/task_output.rs new file mode 100644 index 0000000000000..c14ed7507f67e --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/task/task_output.rs @@ -0,0 +1,60 @@ +use std::marker::PhantomData; + +use anyhow::Result; + +use crate::{RawVc, Vc}; + +/// Trait to implement in order for a type to be accepted as a +/// `turbo_tasks::function` return type. +pub trait TaskOutput { + type Return; + + fn try_from_raw_vc(raw_vc: RawVc) -> Self::Return; + fn try_into_raw_vc(self) -> Result; +} + +impl TaskOutput for Vc +where + T: ?Sized + Send, +{ + type Return = Vc; + + fn try_from_raw_vc(raw_vc: RawVc) -> Self::Return { + Vc { + node: raw_vc, + _t: PhantomData, + } + } + + fn try_into_raw_vc(self) -> Result { + Ok(self.node) + } +} + +impl TaskOutput for () { + type Return = Vc<()>; + + fn try_from_raw_vc(raw_vc: RawVc) -> Self::Return { + raw_vc.into() + } + + fn try_into_raw_vc(self) -> Result { + let unit = Vc::<()>::default(); + Ok(unit.node) + } +} + +impl TaskOutput for Result +where + T: TaskOutput, +{ + type Return = T::Return; + + fn try_from_raw_vc(raw_vc: RawVc) -> Self::Return { + T::try_from_raw_vc(raw_vc) + } + + fn try_into_raw_vc(self) -> Result { + self?.try_into_raw_vc() + } +} diff --git a/turbopack/crates/turbo-tasks/src/trace.rs b/turbopack/crates/turbo-tasks/src/trace.rs new file mode 100644 index 0000000000000..cbf1fc042d4c6 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/trace.rs @@ -0,0 +1,248 @@ +use std::{ + cell::RefCell, + collections::{BTreeMap, BTreeSet, HashMap, HashSet}, + marker::PhantomData, + path::{Path, PathBuf}, + sync::{atomic::*, Arc, Mutex}, + time::Duration, +}; + +use auto_hash_map::{AutoMap, AutoSet}; +use indexmap::{IndexMap, IndexSet}; + +use crate::{RawVc, RcStr}; + +pub struct TraceRawVcsContext { + list: Vec, +} + +impl TraceRawVcsContext { + pub(crate) fn new() -> Self { + Self { list: Vec::new() } + } + + pub(crate) fn into_vec(self) -> Vec { + self.list + } +} + +/// Trait that allows to walk data to find all [RawVc]s contained. +/// +/// This is important for Garbage Collection to mark all Cells and therefore +/// Tasks that are still in use. +/// +/// It can also be used to optimize transferring of Tasks, where knowning the +/// referenced Cells/Tasks allows pushing them earlier. +/// +/// `#[derive(TraceRawVcs)]` is available. +/// `#[trace_ignore]` can be used on fields to skip tracing for them. +pub trait TraceRawVcs { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext); + fn get_raw_vcs(&self) -> Vec { + let mut trace_context = TraceRawVcsContext::new(); + self.trace_raw_vcs(&mut trace_context); + trace_context.into_vec() + } +} + +macro_rules! ignore { + ($ty:ty) => { + impl TraceRawVcs for $ty { + fn trace_raw_vcs(&self, _context: &mut TraceRawVcsContext) {} + } + }; + + ($ty:ty, $($tys:ty),+) => { + ignore!($ty); + ignore!($($tys),+); + } +} + +ignore!(i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, char, bool, usize); +ignore!( + AtomicI8, + AtomicU8, + AtomicI16, + AtomicU16, + AtomicI32, + AtomicU32, + AtomicI64, + AtomicU64, + AtomicBool, + AtomicUsize +); +ignore!((), str, String, Duration, anyhow::Error, RcStr); +ignore!(Path, PathBuf); +ignore!(serde_json::Value); + +impl TraceRawVcs for PhantomData { + fn trace_raw_vcs(&self, _trace_context: &mut TraceRawVcsContext) {} +} + +// based on stdlib's internal `tuple_impls!` macro +macro_rules! impl_trace_tuple { + ($T:ident) => { + impl_trace_tuple!(@impl $T); + }; + ($T:ident $( $U:ident )+) => { + impl_trace_tuple!($( $U )+); + impl_trace_tuple!(@impl $T $( $U )+); + }; + (@impl $( $T:ident )+) => { + impl<$($T: TraceRawVcs),+> TraceRawVcs for ($($T,)+) { + #[allow(non_snake_case)] + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + let ($($T,)+) = self; + $( + TraceRawVcs::trace_raw_vcs($T, trace_context); + )+ + } + } + }; +} + +impl_trace_tuple!(E D C B A Z Y X W V U T); + +impl TraceRawVcs for Option { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + if let Some(item) = self { + TraceRawVcs::trace_raw_vcs(item, trace_context); + } + } +} + +impl TraceRawVcs for Vec { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for item in self.iter() { + TraceRawVcs::trace_raw_vcs(item, trace_context); + } + } +} + +impl TraceRawVcs for [T; N] { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for item in self.iter() { + TraceRawVcs::trace_raw_vcs(item, trace_context); + } + } +} + +impl TraceRawVcs for HashSet { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for item in self.iter() { + TraceRawVcs::trace_raw_vcs(item, trace_context); + } + } +} + +impl TraceRawVcs for AutoSet { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for item in self.iter() { + TraceRawVcs::trace_raw_vcs(item, trace_context); + } + } +} + +impl TraceRawVcs for BTreeSet { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for item in self.iter() { + TraceRawVcs::trace_raw_vcs(item, trace_context); + } + } +} + +impl TraceRawVcs for IndexSet { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for item in self.iter() { + TraceRawVcs::trace_raw_vcs(item, trace_context); + } + } +} + +impl TraceRawVcs for HashMap { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for (key, value) in self.iter() { + TraceRawVcs::trace_raw_vcs(key, trace_context); + TraceRawVcs::trace_raw_vcs(value, trace_context); + } + } +} + +impl TraceRawVcs for AutoMap { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for (key, value) in self.iter() { + TraceRawVcs::trace_raw_vcs(key, trace_context); + TraceRawVcs::trace_raw_vcs(value, trace_context); + } + } +} + +impl TraceRawVcs for BTreeMap { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for (key, value) in self.iter() { + TraceRawVcs::trace_raw_vcs(key, trace_context); + TraceRawVcs::trace_raw_vcs(value, trace_context); + } + } +} + +impl TraceRawVcs for IndexMap { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + for (key, value) in self.iter() { + TraceRawVcs::trace_raw_vcs(key, trace_context); + TraceRawVcs::trace_raw_vcs(value, trace_context); + } + } +} + +impl TraceRawVcs for Box { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + TraceRawVcs::trace_raw_vcs(&**self, trace_context); + } +} + +impl TraceRawVcs for Arc { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + TraceRawVcs::trace_raw_vcs(&**self, trace_context); + } +} + +impl TraceRawVcs for RawVc { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + trace_context.list.push(*self); + } +} + +impl TraceRawVcs for Result { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + match self { + Ok(o) => o.trace_raw_vcs(trace_context), + Err(e) => e.trace_raw_vcs(trace_context), + } + } +} + +impl TraceRawVcs for Mutex { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + self.lock().unwrap().trace_raw_vcs(trace_context); + } +} + +impl TraceRawVcs for RefCell { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + self.borrow().trace_raw_vcs(trace_context); + } +} + +impl TraceRawVcs for &T { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + (**self).trace_raw_vcs(trace_context); + } +} +impl TraceRawVcs for &mut T { + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + (**self).trace_raw_vcs(trace_context); + } +} + +pub use turbo_tasks_macros::TraceRawVcs; diff --git a/turbopack/crates/turbo-tasks/src/trait_helpers.rs b/turbopack/crates/turbo-tasks/src/trait_helpers.rs new file mode 100644 index 0000000000000..d8467e1e7cfaf --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/trait_helpers.rs @@ -0,0 +1,33 @@ +use std::borrow::Cow; + +use crate::{registry, FunctionId, TraitType, TraitTypeId, ValueTypeId}; + +pub fn get_trait_method( + trait_type: TraitTypeId, + value_type: ValueTypeId, + name: Cow<'static, str>, +) -> Result> { + let key = (trait_type, name); + if let Some(func) = registry::get_value_type(value_type).get_trait_method(&key) { + Ok(*func) + } else if let Some(func) = registry::get_trait(trait_type) + .methods + .get(&key.1) + .and_then(|method| method.default_method) + { + Ok(func) + } else { + Err(key.1) + } +} + +pub fn has_trait(value_type: ValueTypeId, trait_type: TraitTypeId) -> bool { + registry::get_value_type(value_type).has_trait(&trait_type) +} + +pub fn traits(value_type: ValueTypeId) -> Vec<&'static TraitType> { + registry::get_value_type(value_type) + .traits_iter() + .map(registry::get_trait) + .collect() +} diff --git a/turbopack/crates/turbo-tasks/src/trait_ref.rs b/turbopack/crates/turbo-tasks/src/trait_ref.rs new file mode 100644 index 0000000000000..43efa4af50296 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/trait_ref.rs @@ -0,0 +1,145 @@ +use std::{fmt::Debug, future::Future, marker::PhantomData}; + +use anyhow::Result; +use serde::{Deserialize, Serialize}; + +use crate::{ + manager::find_cell_by_type, + task::shared_reference::TypedSharedReference, + vc::{cast::VcCast, ReadVcFuture, VcValueTraitCast}, + RawVc, Vc, VcValueTrait, +}; + +/// Similar to a [`ReadRef`][crate::ReadRef], but contains a value trait +/// object instead. The only way to interact with a `TraitRef` is by passing +/// it around or turning it back into a value trait vc by calling +/// [`ReadRef::cell`][crate::ReadRef::cell]. +/// +/// Internally it stores a reference counted reference to a value on the heap. +pub struct TraitRef +where + T: ?Sized, +{ + shared_reference: TypedSharedReference, + _t: PhantomData, +} + +impl Debug for TraitRef { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("TraitRef") + .field("shared_reference", &self.shared_reference) + .finish() + } +} + +impl Clone for TraitRef { + fn clone(&self) -> Self { + Self { + shared_reference: self.shared_reference.clone(), + _t: PhantomData, + } + } +} + +impl PartialEq for TraitRef { + fn eq(&self, other: &Self) -> bool { + self.shared_reference == other.shared_reference + } +} + +impl Eq for TraitRef {} + +impl std::hash::Hash for TraitRef { + fn hash(&self, state: &mut H) { + self.shared_reference.hash(state) + } +} + +impl Serialize for TraitRef { + fn serialize(&self, serializer: S) -> Result { + self.shared_reference.serialize(serializer) + } +} + +impl<'de, T> Deserialize<'de> for TraitRef { + fn deserialize>(deserializer: D) -> Result { + Ok(Self { + shared_reference: TypedSharedReference::deserialize(deserializer)?, + _t: PhantomData, + }) + } +} + +// Otherwise, TraitRef> would not be Sync. +// SAFETY: TraitRef doesn't actually contain a T. +unsafe impl Sync for TraitRef where T: ?Sized {} + +// Otherwise, TraitRef> would not be Send. +// SAFETY: TraitRef doesn't actually contain a T. +unsafe impl Send for TraitRef where T: ?Sized {} + +impl Unpin for TraitRef where T: ?Sized {} + +impl TraitRef +where + T: ?Sized, +{ + pub(crate) fn new(shared_reference: TypedSharedReference) -> Self { + Self { + shared_reference, + _t: PhantomData, + } + } +} + +impl TraitRef +where + T: VcValueTrait + ?Sized + Send, +{ + /// Returns a new cell that points to a value that implements the value + /// trait `T`. + pub fn cell(trait_ref: TraitRef) -> Vc { + // See Safety clause above. + let TypedSharedReference(ty, shared_ref) = trait_ref.shared_reference; + let local_cell = find_cell_by_type(ty); + local_cell.update_shared_reference(shared_ref); + let raw_vc: RawVc = local_cell.into(); + raw_vc.into() + } +} + +/// A trait that allows a value trait vc to be converted into a trait reference. +/// +/// The signature is similar to `IntoFuture`, but we don't want trait vcs to +/// have the same future-like semantics as value vcs when it comes to producing +/// refs. This behavior is rarely needed, so in most cases, `.await`ing a trait +/// vc is a mistake. +pub trait IntoTraitRef { + type ValueTrait: VcValueTrait + ?Sized; + type Future: Future as VcCast>::Output>>; + + fn into_trait_ref(self) -> Self::Future; + fn into_trait_ref_untracked(self) -> Self::Future; + fn into_trait_ref_strongly_consistent_untracked(self) -> Self::Future; +} + +impl IntoTraitRef for Vc +where + T: VcValueTrait + ?Sized + Send, +{ + type ValueTrait = T; + + type Future = ReadVcFuture>; + + fn into_trait_ref(self) -> Self::Future { + self.node.into_read().into() + } + + fn into_trait_ref_untracked(self) -> Self::Future { + self.node.into_read_untracked().into() + } + + fn into_trait_ref_strongly_consistent_untracked(self) -> Self::Future { + self.node.into_strongly_consistent_read_untracked().into() + } +} diff --git a/turbopack/crates/turbo-tasks/src/triomphe_utils.rs b/turbopack/crates/turbo-tasks/src/triomphe_utils.rs new file mode 100644 index 0000000000000..750a1113b2644 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/triomphe_utils.rs @@ -0,0 +1,33 @@ +use std::any::Any; + +use unsize::Coercion; + +/// Attempt to downcast a [`triomphe::Arc`][`triomphe::Arc`] to a concrete type. +/// +/// Ported from [`std::sync::Arc::downcast`] to [`triomphe::Arc`]. +pub fn downcast_triomphe_arc( + this: triomphe::Arc, +) -> Result, triomphe::Arc> { + if (*this).is::() { + unsafe { + // Get the pointer to the offset (*const T) inside of the ArcInner. + let ptr = triomphe::Arc::into_raw(this); + // SAFETY: The negative offset from the data (ptr) in an Arc to the start of the + // data structure is fixed regardless of type `T`. + // + // SAFETY: Casting from a fat pointer to a thin pointer is safe, as long as the + // types are compatible (they are). + Ok(triomphe::Arc::from_raw(ptr.cast())) + } + } else { + Err(this) + } +} + +/// [`Coercion::to_any`] except that it coerces to `dyn Any + Send + Sync` as +/// opposed to `dyn Any`. +pub fn coerce_to_any_send_sync() -> Coercion { + // SAFETY: The signature of this function guarantees the coercion is valid + unsafe { Coercion::new(|x| x) } +} diff --git a/turbopack/crates/turbo-tasks/src/util.rs b/turbopack/crates/turbo-tasks/src/util.rs new file mode 100644 index 0000000000000..8c05fccc829ca --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/util.rs @@ -0,0 +1,255 @@ +use std::{ + error::Error as StdError, + fmt::{Debug, Display}, + future::Future, + hash::{Hash, Hasher}, + ops::Deref, + pin::Pin, + sync::Arc, + task::{Context, Poll}, + time::Duration, +}; + +use anyhow::{anyhow, Error}; +use pin_project_lite::pin_project; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +pub use super::{ + id_factory::{IdFactory, IdFactoryWithReuse}, + no_move_vec::NoMoveVec, + once_map::*, +}; + +/// A error struct that is backed by an Arc to allow cloning errors +#[derive(Debug, Clone)] +pub struct SharedError { + inner: Arc, +} + +impl SharedError { + pub fn new(err: Error) -> Self { + Self { + inner: Arc::new(err), + } + } +} + +impl StdError for SharedError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + self.inner.source() + } + + fn provide<'a>(&'a self, req: &mut std::error::Request<'a>) { + self.inner.provide(req); + } +} + +impl Display for SharedError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Display::fmt(&*self.inner, f) + } +} + +impl From for SharedError { + fn from(e: Error) -> Self { + Self::new(e) + } +} + +impl PartialEq for SharedError { + fn eq(&self, other: &Self) -> bool { + Arc::ptr_eq(&self.inner, &other.inner) + } +} + +impl Eq for SharedError {} + +impl Serialize for SharedError { + fn serialize(&self, serializer: S) -> Result { + let mut v = vec![self.to_string()]; + let mut source = self.source(); + while let Some(s) = source { + v.push(s.to_string()); + source = s.source(); + } + Serialize::serialize(&v, serializer) + } +} + +impl<'de> Deserialize<'de> for SharedError { + fn deserialize>(deserializer: D) -> Result { + use serde::de::Error; + let mut messages = >::deserialize(deserializer)?; + let mut e = match messages.pop() { + Some(e) => anyhow!(e), + None => return Err(Error::custom("expected at least 1 error message")), + }; + while let Some(message) = messages.pop() { + e = e.context(message); + } + Ok(SharedError::new(e)) + } +} + +impl Deref for SharedError { + type Target = Arc; + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +pub struct FormatDuration(pub Duration); + +impl Display for FormatDuration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = self.0.as_secs(); + if s > 10 { + return write!(f, "{}s", s); + } + let ms = self.0.as_millis(); + if ms > 10 { + return write!(f, "{}ms", ms); + } + write!(f, "{}ms", (self.0.as_micros() as f32) / 1000.0) + } +} + +impl Debug for FormatDuration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let s = self.0.as_secs(); + if s > 100 { + return write!(f, "{}s", s); + } + let ms = self.0.as_millis(); + if ms > 10000 { + return write!(f, "{:.2}s", (ms as f32) / 1000.0); + } + if ms > 100 { + return write!(f, "{}ms", ms); + } + write!(f, "{}ms", (self.0.as_micros() as f32) / 1000.0) + } +} + +pub struct FormatBytes(pub usize); + +impl Display for FormatBytes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let b = self.0; + const KB: usize = 1_024; + const MB: usize = 1_024 * KB; + const GB: usize = 1_024 * MB; + if b > GB { + return write!(f, "{:.2}GiB", ((b / MB) as f32) / 1_024.0); + } + if b > MB { + return write!(f, "{:.2}MiB", ((b / KB) as f32) / 1_024.0); + } + if b > KB { + return write!(f, "{:.2}KiB", (b as f32) / 1_024.0); + } + write!(f, "{}B", b) + } +} + +/// Smart pointer that stores data either in an [Arc] or as a static reference. +pub enum StaticOrArc { + Static(&'static T), + Shared(Arc), +} + +impl AsRef for StaticOrArc { + fn as_ref(&self) -> &T { + match self { + Self::Static(s) => s, + Self::Shared(b) => b, + } + } +} + +impl From<&'static T> for StaticOrArc { + fn from(s: &'static T) -> Self { + Self::Static(s) + } +} + +impl From> for StaticOrArc { + fn from(b: Arc) -> Self { + Self::Shared(b) + } +} + +impl From for StaticOrArc { + fn from(b: T) -> Self { + Self::Shared(Arc::new(b)) + } +} + +impl Deref for StaticOrArc { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.as_ref() + } +} + +impl Clone for StaticOrArc { + fn clone(&self) -> Self { + match self { + Self::Static(s) => Self::Static(s), + Self::Shared(b) => Self::Shared(b.clone()), + } + } +} + +impl PartialEq for StaticOrArc { + fn eq(&self, other: &Self) -> bool { + **self == **other + } +} + +impl Eq for StaticOrArc {} + +impl Hash for StaticOrArc { + fn hash(&self, state: &mut H) { + (**self).hash(state); + } +} + +impl Display for StaticOrArc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + (**self).fmt(f) + } +} + +impl Debug for StaticOrArc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + (**self).fmt(f) + } +} + +pin_project! { + /// A future that wraps another future and applies a function on every poll call. + pub struct WrapFuture { + wrapper: W, + #[pin] + future: F, + } +} + +impl Fn(Pin<&mut F>, &mut Context<'a>) -> Poll> WrapFuture { + pub fn new(future: F, wrapper: W) -> Self { + Self { wrapper, future } + } +} + +impl Fn(Pin<&mut F>, &mut Context<'a>) -> Poll> Future + for WrapFuture +{ + type Output = F::Output; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + let this = self.project(); + (this.wrapper)(this.future, cx) + } +} diff --git a/turbopack/crates/turbo-tasks/src/value.rs b/turbopack/crates/turbo-tasks/src/value.rs new file mode 100644 index 0000000000000..05ff7098a2b23 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/value.rs @@ -0,0 +1,161 @@ +use std::{fmt::Debug, marker::PhantomData, ops::Deref}; + +use serde::{Deserialize, Serialize}; + +use crate::SharedReference; + +/// Pass a value by value (`Value`) instead of by reference (`Vc`). +/// +/// Persistent, requires serialization. +#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)] +pub struct Value { + inner: T, +} + +impl Value { + pub fn new(value: T) -> Self { + Self { inner: value } + } + + pub fn into_value(self) -> T { + self.inner + } +} + +impl Deref for Value { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl Copy for Value {} + +impl Default for Value { + fn default() -> Self { + Value::new(Default::default()) + } +} + +/// Pass a value by value (`Value`) instead of by reference (`Vc`). +/// +/// Doesn't require serialization, and won't be stored in the persistent cache +/// in the future. +#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)] +pub struct TransientValue { + inner: T, +} + +impl TransientValue { + pub fn new(value: T) -> Self { + Self { inner: value } + } + + pub fn into_value(self) -> T { + self.inner + } +} + +impl Deref for TransientValue { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +/// Pass a reference to an instance to a turbo-tasks function. +/// +/// Equality and hash is implemented as pointer comparison. +/// +/// Doesn't require serialization, and won't be stored in the persistent cache +/// in the future, so we don't include the `ValueTypeId` in the +/// `SharedReference`. +pub struct TransientInstance { + inner: SharedReference, + phantom: PhantomData, +} + +impl Debug for TransientInstance { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("TransientInstance").finish() + } +} + +impl Clone for TransientInstance { + fn clone(&self) -> Self { + Self { + inner: self.inner.clone(), + phantom: self.phantom, + } + } +} + +impl Eq for TransientInstance {} + +impl PartialEq for TransientInstance { + fn eq(&self, other: &Self) -> bool { + self.inner == other.inner + } +} + +impl std::hash::Hash for TransientInstance { + fn hash(&self, state: &mut H) { + self.inner.hash(state); + } +} + +impl From> for triomphe::Arc { + fn from(instance: TransientInstance) -> Self { + // we know this downcast must work because we have type T + instance.inner.downcast().unwrap() + } +} + +impl From> for SharedReference { + fn from(instance: TransientInstance) -> Self { + instance.inner + } +} + +impl From> for TransientInstance { + fn from(arc: triomphe::Arc) -> Self { + Self { + inner: SharedReference::new(arc), + phantom: PhantomData, + } + } +} + +impl TryFrom for TransientInstance { + type Error = (); + + fn try_from(inner: SharedReference) -> Result { + if inner.0.downcast_ref::().is_some() { + Ok(Self { + inner, + phantom: PhantomData, + }) + } else { + Err(()) + } + } +} + +impl TransientInstance { + pub fn new(value: T) -> Self { + Self { + inner: SharedReference::new(triomphe::Arc::new(value)), + phantom: PhantomData, + } + } +} + +impl Deref for TransientInstance { + type Target = T; + + fn deref(&self) -> &Self::Target { + self.inner.0.downcast_ref().unwrap() + } +} diff --git a/turbopack/crates/turbo-tasks/src/value_type.rs b/turbopack/crates/turbo-tasks/src/value_type.rs new file mode 100644 index 0000000000000..d9d6e0246d8c2 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/value_type.rs @@ -0,0 +1,285 @@ +use std::{ + any::{type_name, Any}, + borrow::Cow, + fmt::{ + Debug, Display, Formatter, {self}, + }, + hash::Hash, + sync::Arc, +}; + +use auto_hash_map::{AutoMap, AutoSet}; +use serde::{Deserialize, Serialize}; +use tracing::Span; + +use crate::{ + id::{FunctionId, TraitTypeId}, + magic_any::{AnyDeserializeSeed, MagicAny, MagicAnyDeserializeSeed, MagicAnySerializeSeed}, + registry::{register_trait_type, register_value_type}, +}; + +type MagicSerializationFn = fn(&dyn MagicAny) -> &dyn erased_serde::Serialize; +type AnySerializationFn = fn(&(dyn Any + Sync + Send)) -> &dyn erased_serde::Serialize; + +// TODO this type need some refactoring when multiple languages are added to +// turbo-task In this case a trait_method might be of a different function type. +// It probably need to be a Vc. +// That's also needed in a distributed world, where the function might be only +// available on a remote instance. + +/// A definition of a type of data. +/// +/// Contains a list of traits and trait methods that are available on that type. +pub struct ValueType { + /// A readable name of the type + pub name: String, + /// List of traits available + pub traits: AutoSet, + /// List of trait methods available + pub trait_methods: AutoMap<(TraitTypeId, Cow<'static, str>), FunctionId>, + + /// Functors for serialization + magic_serialization: Option<(MagicSerializationFn, MagicAnyDeserializeSeed)>, + any_serialization: Option<(AnySerializationFn, AnyDeserializeSeed)>, +} + +impl Hash for ValueType { + fn hash(&self, state: &mut H) { + (self as *const ValueType).hash(state); + } +} + +impl Eq for ValueType {} + +impl PartialEq for ValueType { + fn eq(&self, other: &Self) -> bool { + std::ptr::eq(self, other) + } +} + +impl Debug for ValueType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let mut d = f.debug_struct("ValueType"); + d.field("name", &self.name); + for ((_trait_type, name), _value) in self.trait_methods.iter() { + d.field(name, &"(trait fn)"); + } + d.finish() + } +} + +impl Display for ValueType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str(&self.name) + } +} + +pub fn any_as_serialize( + this: &(dyn Any + Send + Sync), +) -> &dyn erased_serde::Serialize { + if let Some(r) = this.downcast_ref::() { + return r; + } + panic!( + "any_as_serialize::<{}> called with invalid type", + type_name::() + ); +} + +impl ValueType { + /// This is internally used by `#[turbo_tasks::value]` + pub fn new() -> Self { + Self { + name: std::any::type_name::().to_string(), + traits: AutoSet::new(), + trait_methods: AutoMap::new(), + magic_serialization: None, + any_serialization: None, + } + } + + /// This is internally used by `#[turbo_tasks::value]` + pub fn new_with_magic_serialization< + T: Debug + Eq + Hash + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static, + >() -> Self { + Self { + name: std::any::type_name::().to_string(), + traits: AutoSet::new(), + trait_methods: AutoMap::new(), + magic_serialization: Some(( + ::as_serialize::, + MagicAnyDeserializeSeed::new::(), + )), + any_serialization: Some((any_as_serialize::, AnyDeserializeSeed::new::())), + } + } + + /// This is internally used by `#[turbo_tasks::value]` + pub fn new_with_any_serialization< + T: Any + Serialize + for<'de> Deserialize<'de> + Send + Sync + 'static, + >() -> Self { + Self { + name: std::any::type_name::().to_string(), + traits: AutoSet::new(), + trait_methods: AutoMap::new(), + magic_serialization: None, + any_serialization: Some((any_as_serialize::, AnyDeserializeSeed::new::())), + } + } + + pub fn magic_as_serializable<'a>( + &self, + arc: &'a Arc, + ) -> Option<&'a dyn erased_serde::Serialize> { + if let Some(s) = self.magic_serialization { + let r: &dyn MagicAny = arc; + Some((s.0)(r)) + } else { + None + } + } + + pub fn any_as_serializable<'a>( + &self, + arc: &'a triomphe::Arc, + ) -> Option<&'a dyn erased_serde::Serialize> { + if let Some(s) = self.any_serialization { + Some((s.0)(&**arc)) + } else { + None + } + } + + pub fn get_magic_deserialize_seed(&self) -> Option { + self.magic_serialization.map(|s| s.1) + } + + pub fn get_any_deserialize_seed(&self) -> Option { + self.any_serialization.map(|s| s.1) + } + + /// This is internally used by `#[turbo_tasks::value_impl]` + pub fn register_trait_method( + &mut self, + trait_type: TraitTypeId, + name: Cow<'static, str>, + native_fn: FunctionId, + ) { + self.trait_methods.insert((trait_type, name), native_fn); + } + + pub fn get_trait_method( + &self, + trait_method_key: &(TraitTypeId, Cow<'static, str>), + ) -> Option<&FunctionId> { + self.trait_methods.get(trait_method_key) + } + + /// This is internally used by `#[turbo_tasks::value_impl]` + pub fn register_trait(&mut self, trait_type: TraitTypeId) { + self.traits.insert(trait_type); + } + + pub fn has_trait(&self, trait_type: &TraitTypeId) -> bool { + self.traits.contains(trait_type) + } + + pub fn traits_iter(&self) -> impl Iterator + '_ { + self.traits.iter().copied() + } + + pub fn register(&'static self, global_name: &'static str) { + register_value_type(global_name, self) + } +} + +pub struct TraitMethod { + pub default_method: Option, + pub arg_serializer: MagicAnySerializeSeed, + pub arg_deserializer: MagicAnyDeserializeSeed, +} + +impl Debug for TraitMethod { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("TraitMethod") + .field("default_method", &self.default_method) + .finish() + } +} + +#[derive(Debug)] +pub struct TraitType { + pub name: String, + pub(crate) methods: AutoMap, TraitMethod>, +} + +impl Hash for TraitType { + fn hash(&self, state: &mut H) { + (self as *const TraitType).hash(state); + } +} + +impl Display for TraitType { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "trait {}", self.name) + } +} + +impl Eq for TraitType {} + +impl PartialEq for TraitType { + fn eq(&self, other: &Self) -> bool { + std::ptr::eq(self, other) + } +} + +impl TraitType { + pub fn new(name: String) -> Self { + Self { + name, + methods: AutoMap::new(), + } + } + + pub fn register_trait_method(&mut self, name: Cow<'static, str>) + where + T: Serialize + for<'de> Deserialize<'de> + Debug + Eq + Hash + Send + Sync + 'static, + { + self.methods.insert( + name, + TraitMethod { + default_method: None, + arg_serializer: MagicAnySerializeSeed::new::(), + arg_deserializer: MagicAnyDeserializeSeed::new::(), + }, + ); + } + + pub fn register_default_trait_method( + &mut self, + name: Cow<'static, str>, + native_fn: FunctionId, + ) where + T: Serialize + for<'de> Deserialize<'de> + Debug + Eq + Hash + Send + Sync + 'static, + { + self.methods.insert( + name, + TraitMethod { + default_method: Some(native_fn), + arg_serializer: MagicAnySerializeSeed::new::(), + arg_deserializer: MagicAnyDeserializeSeed::new::(), + }, + ); + } + + pub fn register(&'static self, global_name: &'static str) { + register_trait_type(global_name, self); + } + + pub fn resolve_span(&'static self, name: &str) -> Span { + tracing::trace_span!( + "turbo_tasks::resolve_trait_call", + name = format_args!("{}::{name}", &self.name), + ) + } +} diff --git a/turbopack/crates/turbo-tasks/src/vc/cast.rs b/turbopack/crates/turbo-tasks/src/vc/cast.rs new file mode 100644 index 0000000000000..38325d377c74e --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/vc/cast.rs @@ -0,0 +1,76 @@ +use std::{marker::PhantomData, mem::ManuallyDrop}; + +use anyhow::Result; + +use crate::{backend::TypedCellContent, ReadRef, TraitRef, VcRead, VcValueTrait, VcValueType}; + +/// Trait defined to share behavior between values and traits within +/// [`ReadRawVcFuture`][crate::ReadRawVcFuture]. See [`VcValueTypeCast`] and +/// [`VcValueTraitCast`]. +/// +/// This trait is sealed and cannot be implemented by users. +pub trait VcCast: private::Sealed { + type Output; + + fn cast(content: TypedCellContent) -> Result; +} + +/// Casts an arbitrary cell content into a [`ReadRef`]. +pub struct VcValueTypeCast { + _phantom: PhantomData, +} + +impl VcCast for VcValueTypeCast +where + T: VcValueType, +{ + type Output = ReadRef; + + fn cast(content: TypedCellContent) -> Result { + Ok( + // Safety: the `VcValueType` implementor must guarantee that both `T` and + // `Repr` are #[repr(transparent)]. + unsafe { + // Downcast the cell content to the expected representation type, then + // transmute it to the expected type. + // See https://users.rust-lang.org/t/transmute-doesnt-work-on-generic-types/87272/9 + std::mem::transmute_copy::< + ManuallyDrop>::Repr>>, + Self::Output, + >(&ManuallyDrop::new(content.cast()?)) + }, + ) + } +} + +/// Casts an arbitrary cell content into a [`TraitRef`]. +pub struct VcValueTraitCast +where + T: ?Sized, +{ + _phantom: PhantomData, +} + +impl VcCast for VcValueTraitCast +where + T: VcValueTrait + ?Sized, +{ + type Output = TraitRef; + + fn cast(content: TypedCellContent) -> Result { + // Safety: Constructor ensures the cell content points to a value that + // implements T + content.cast_trait::() + } +} + +// Implement the sealed trait pattern for `VcCast`. +// https://rust-lang.github.io/api-guidelines/future-proofing.html +mod private { + use super::{VcValueTraitCast, VcValueTypeCast}; + use crate::{VcValueTrait, VcValueType}; + + pub trait Sealed {} + impl Sealed for VcValueTypeCast where T: VcValueType {} + impl Sealed for VcValueTraitCast where T: VcValueTrait + ?Sized {} +} diff --git a/turbopack/crates/turbo-tasks/src/vc/cell_mode.rs b/turbopack/crates/turbo-tasks/src/vc/cell_mode.rs new file mode 100644 index 0000000000000..8c50017bfa263 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/vc/cell_mode.rs @@ -0,0 +1,54 @@ +use std::marker::PhantomData; + +use super::{read::VcRead, traits::VcValueType}; +use crate::{manager::find_cell_by_type, Vc}; + +/// Trait that controls the behavior of `Vc::cell` on a value type basis. +/// +/// This trait must remain sealed within this crate. +pub trait VcCellMode +where + T: VcValueType, +{ + fn cell(value: >::Target) -> Vc; +} + +/// Mode that always updates the cell's content. +pub struct VcCellNewMode { + _phantom: PhantomData, +} + +impl VcCellMode for VcCellNewMode +where + T: VcValueType, +{ + fn cell(inner: >::Target) -> Vc { + let cell = find_cell_by_type(T::get_value_type_id()); + cell.update_shared(>::target_to_repr(inner)); + Vc { + node: cell.into(), + _t: PhantomData, + } + } +} + +/// Mode that compares the cell's content with the new value and only updates +/// if the new value is different. +pub struct VcCellSharedMode { + _phantom: PhantomData, +} + +impl VcCellMode for VcCellSharedMode +where + T: VcValueType, + >::Repr: PartialEq, +{ + fn cell(inner: >::Target) -> Vc { + let cell = find_cell_by_type(T::get_value_type_id()); + cell.compare_and_update_shared(>::target_to_repr(inner)); + Vc { + node: cell.into(), + _t: PhantomData, + } + } +} diff --git a/turbopack/crates/turbo-tasks/src/vc/default.rs b/turbopack/crates/turbo-tasks/src/vc/default.rs new file mode 100644 index 0000000000000..d5a885dae81f7 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/vc/default.rs @@ -0,0 +1,19 @@ +use turbo_tasks::Vc; + +use crate::{self as turbo_tasks}; + +/// `Vc` analog to the `Default` trait. +/// +/// Implementing this trait on `T` will make `Vc::default()` produce +/// `T::value_default()`. +/// +/// There are two ways to implement this trait: +/// 1. Annotating with `#[turbo_tasks::value_impl]`: this will make +/// `Vc::default()` always return the same underlying value (i.e. a +/// singleton). +/// 2. No annotations: this will make `Vc::default()` always return a different +/// value. +#[turbo_tasks::value_trait] +pub trait ValueDefault { + fn value_default() -> Vc; +} diff --git a/turbopack/crates/turbo-tasks/src/vc/mod.rs b/turbopack/crates/turbo-tasks/src/vc/mod.rs new file mode 100644 index 0000000000000..19f106eb545d8 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/vc/mod.rs @@ -0,0 +1,555 @@ +pub(crate) mod cast; +mod cell_mode; +pub(crate) mod default; +mod read; +pub(crate) mod resolved; +mod traits; + +use std::{ + any::Any, + hash::{Hash, Hasher}, + marker::PhantomData, + ops::Deref, +}; + +use anyhow::Result; +use auto_hash_map::AutoSet; +use serde::{Deserialize, Serialize}; + +use self::cell_mode::VcCellMode; +pub use self::{ + cast::{VcCast, VcValueTraitCast, VcValueTypeCast}, + cell_mode::{VcCellNewMode, VcCellSharedMode}, + default::ValueDefault, + read::{ReadVcFuture, VcDefaultRead, VcRead, VcTransparentRead}, + resolved::{ResolvedValue, ResolvedVc}, + traits::{Dynamic, TypedForInput, Upcast, VcValueTrait, VcValueType}, +}; +use crate::{ + debug::{ValueDebug, ValueDebugFormat, ValueDebugFormatString}, + registry, + trace::{TraceRawVcs, TraceRawVcsContext}, + CellId, CollectiblesSource, RawVc, ResolveTypeError, +}; + +/// A Value Cell (`Vc` for short) is a reference to a memoized computation +/// result stored on the heap or in persistent cache, depending on the +/// Turbo Engine backend implementation. +/// +/// In order to get a reference to the pointed value, you need to `.await` the +/// [`Vc`] to get a [`ReadRef`][crate::ReadRef]: +/// +/// ``` +/// let some_vc: Vc; +/// let some_ref: ReadRef = some_vc.await?; +/// some_ref.some_method_on_t(); +/// ``` +#[must_use] +pub struct Vc +where + T: ?Sized + Send, +{ + pub(crate) node: RawVc, + #[doc(hidden)] + pub(crate) _t: PhantomData, +} + +/// This only exists to satisfy the Rust type system. However, this struct can +/// never actually be instantiated, as dereferencing a `Vc` will result in a +/// linker error. See the implementation of `Deref` for `Vc`. +pub struct VcDeref +where + T: ?Sized, +{ + _t: PhantomData, +} + +macro_rules! do_not_use_or_you_will_be_fired { + ($($name:ident)*) => { + impl VcDeref + where + T: ?Sized, + { + $( + #[doc(hidden)] + #[allow(unused)] + #[allow(clippy::wrong_self_convention)] + #[deprecated = "This is not the method you are looking for."] + pub fn $name(self) {} + )* + } + }; +} + +// Hide raw pointer methods on `Vc`. This is an artifact of having +// implement `Deref` on `Vc` for `arbitrary_self_types` to +// do its thing. This can be removed once the `Receiver` trait no longer depends +// on `Deref`. +do_not_use_or_you_will_be_fired!( + add + addr + align_offset + as_mut + as_mut_ptr + as_ptr + as_ref + as_uninit_mut + as_uninit_ref + as_uninit_slice + as_uninit_slice_mut + byte_add + byte_offset + byte_offset_from + byte_sub + cast + cast_const + cast_mut + copy_from + copy_from_nonoverlapping + copy_to + copy_to_nonoverlapping + drop_in_place + expose_addr + from_bits + get_unchecked + get_unchecked_mut + guaranteed_eq + guaranteed_ne + is_aligned + is_aligned_to + is_empty + is_null + len + map_addr + mask + offset + offset_from + read + read_unaligned + read_volatile + replace + split_at_mut + split_at_mut_unchecked + sub + sub_ptr + swap + to_bits + to_raw_parts + with_addr + with_metadata_of + wrapping_add + wrapping_byte_add + wrapping_byte_offset + wrapping_byte_sub + wrapping_offset + wrapping_sub + write + write_bytes + write_unaligned + write_volatile +); + +// Call this macro for all the applicable methods above: + +#[doc(hidden)] +impl Deref for VcDeref +where + T: ?Sized, +{ + // `*const T` or `*mut T` would be enough here, but from an abundance of + // caution, we use `*const *mut *const T` to make sure there will never be an + // applicable method. + type Target = *const *mut *const T; + + fn deref(&self) -> &Self::Target { + extern "C" { + #[link_name = "\n\nERROR: you tried to dereference a `Vc`\n"] + fn trigger() -> !; + } + + unsafe { trigger() }; + } +} + +// This is the magic that makes `Vc` accept `self: Vc` methods through +// `arbitrary_self_types`, while not allowing any other receiver type: +// * `Vc` dereferences to `*const *mut *const T`, which means that it is +// valid under the `arbitrary_self_types` rules. +// * `*const *mut *const T` is not a valid receiver for any attribute access on +// `T`, which means that the only applicable items will be the methods +// declared on `self: Vc`. +// +// If we had used `type Target = T` instead, `vc_t.some_attr_defined_on_t` would +// have been accepted by the compiler. +#[doc(hidden)] +impl Deref for Vc +where + T: ?Sized + Send, +{ + type Target = VcDeref; + + fn deref(&self) -> &Self::Target { + extern "C" { + #[link_name = "\n\nERROR: you tried to dereference a `Vc`\n"] + fn trigger() -> !; + } + + unsafe { trigger() }; + } +} + +impl Copy for Vc where T: ?Sized + Send {} + +unsafe impl Send for Vc where T: ?Sized + Send {} +unsafe impl Sync for Vc where T: ?Sized + Send {} + +impl Clone for Vc +where + T: ?Sized + Send, +{ + fn clone(&self) -> Self { + *self + } +} + +impl Hash for Vc +where + T: ?Sized + Send, +{ + fn hash(&self, state: &mut H) { + self.node.hash(state); + } +} + +impl PartialEq> for Vc +where + T: ?Sized + Send, +{ + fn eq(&self, other: &Self) -> bool { + self.node == other.node + } +} + +impl Eq for Vc where T: ?Sized + Send {} + +impl Serialize for Vc +where + T: ?Sized + Send, +{ + fn serialize(&self, serializer: S) -> Result { + self.node.serialize(serializer) + } +} + +impl<'de, T> Deserialize<'de> for Vc +where + T: ?Sized + Send, +{ + fn deserialize>(deserializer: D) -> Result { + Ok(Vc { + node: RawVc::deserialize(deserializer)?, + _t: PhantomData, + }) + } +} + +// TODO(alexkirsz) This should not be implemented for Vc. Instead, users should +// use the `ValueDebug` implementation to get a `D: Debug`. +impl std::fmt::Debug for Vc +where + T: Send, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Vc").field("node", &self.node).finish() + } +} + +impl Vc +where + T: VcValueType, +{ + #[doc(hidden)] + pub fn cell_private(inner: >::Target) -> Self { + >::cell(inner) + } +} + +impl Vc +where + T: VcValueType>, + Inner: Any + Send + Sync, + Repr: VcValueType, +{ + pub fn cell(inner: Inner) -> Self { + >::cell(inner) + } +} + +impl Vc +where + T: ?Sized + Send, +{ + /// Connects the operation pointed to by this `Vc` to the current task. + pub fn connect(vc: Self) { + vc.node.connect() + } + + /// Returns a debug identifier for this `Vc`. + pub async fn debug_identifier(vc: Self) -> Result { + let resolved = vc.resolve().await?; + let raw_vc: RawVc = resolved.node; + if let RawVc::TaskCell(task_id, CellId { type_id, index }) = raw_vc { + let value_ty = registry::get_value_type(type_id); + Ok(format!("{}#{}: {}", value_ty.name, index, task_id)) + } else { + unreachable!() + } + } + + /// Returns the `RawVc` corresponding to this `Vc`. + pub fn into_raw(vc: Self) -> RawVc { + vc.node + } + + /// Creates a `Vc` from a `RawVc`. + /// + /// # Safety + /// + /// The caller must ensure that `RawVc` points to a value of type `T`. + pub(crate) unsafe fn from_raw(vc: RawVc) -> Self { + Vc { + node: vc, + _t: std::marker::PhantomData, + } + } + + /// Upcasts the given `Vc` to a `Vc>`. + /// + /// This is also available as an `Into`/`From` conversion. + #[inline(always)] + pub fn upcast(vc: Self) -> Vc + where + T: Upcast, + K: VcValueTrait + ?Sized + Send, + { + Vc { + node: vc.node, + _t: PhantomData, + } + } +} + +impl Vc +where + T: ?Sized + Send, +{ + /// Resolve the reference until it points to a cell directly. + /// + /// Resolving will wait for task execution to be finished, so that the + /// returned `Vc` points to a cell that stores a value. + /// + /// Resolving is necessary to compare identities of `Vc`s. + /// + /// This is async and will rethrow any fatal error that happened during task + /// execution. + pub async fn resolve(self) -> Result> { + Ok(Self { + node: self.node.resolve().await?, + _t: PhantomData, + }) + } + + /// Resolve the reference until it points to a cell directly, and wrap the + /// result in a [`ResolvedVc`], which strongly guarantees that the + /// [`Vc`] was resolved. + pub async fn to_resolved(self) -> Result> { + Ok(ResolvedVc { + node: self.resolve().await?, + }) + } + + /// Returns `true` if the reference is resolved. + /// + /// See also [`Vc::resolve`]. + pub fn is_resolved(self) -> bool { + self.node.is_resolved() + } + + /// Resolve the reference until it points to a cell directly in a strongly + /// consistent way. + /// + /// Resolving will wait for task execution to be finished, so that the + /// returned Vc points to a cell that stores a value. + /// + /// Resolving is necessary to compare identities of Vcs. + /// + /// This is async and will rethrow any fatal error that happened during task + /// execution. + pub async fn resolve_strongly_consistent(self) -> Result { + Ok(Self { + node: self.node.resolve_strongly_consistent().await?, + _t: PhantomData, + }) + } +} + +impl Vc +where + T: VcValueTrait + ?Sized + Send, +{ + /// Attempts to sidecast the given `Vc>` to a `Vc>`. + /// This operation also resolves the `Vc`. + /// + /// Returns `None` if the underlying value type does not implement `K`. + /// + /// **Note:** if the trait T is required to implement K, use + /// `Vc::upcast(vc).resolve()` instead. This provides stronger guarantees, + /// removing the need for a `Result` return type. + pub async fn try_resolve_sidecast(vc: Self) -> Result>, ResolveTypeError> + where + K: VcValueTrait + ?Sized + Send, + { + let raw_vc: RawVc = vc.node; + let raw_vc = raw_vc + .resolve_trait(::get_trait_type_id()) + .await?; + Ok(raw_vc.map(|raw_vc| Vc { + node: raw_vc, + _t: PhantomData, + })) + } + + /// Attempts to downcast the given `Vc>` to a `Vc`, where `K` + /// is of the form `Box`, and `L` is a value trait. + /// This operation also resolves the `Vc`. + /// + /// Returns `None` if the underlying value type is not a `K`. + pub async fn try_resolve_downcast(vc: Self) -> Result>, ResolveTypeError> + where + K: Upcast, + K: VcValueTrait + ?Sized + Send, + { + let raw_vc: RawVc = vc.node; + let raw_vc = raw_vc + .resolve_trait(::get_trait_type_id()) + .await?; + Ok(raw_vc.map(|raw_vc| Vc { + node: raw_vc, + _t: PhantomData, + })) + } + + /// Attempts to downcast the given `Vc>` to a `Vc`, where `K` + /// is a value type. + /// This operation also resolves the `Vc`. + /// + /// Returns `None` if the underlying value type is not a `K`. + pub async fn try_resolve_downcast_type(vc: Self) -> Result>, ResolveTypeError> + where + K: Upcast, + K: VcValueType, + { + let raw_vc: RawVc = vc.node; + let raw_vc = raw_vc + .resolve_value(::get_value_type_id()) + .await?; + Ok(raw_vc.map(|raw_vc| Vc { + node: raw_vc, + _t: PhantomData, + })) + } +} + +impl CollectiblesSource for Vc +where + T: ?Sized + Send, +{ + fn take_collectibles(self) -> AutoSet> { + self.node.take_collectibles() + } + + fn peek_collectibles(self) -> AutoSet> { + self.node.peek_collectibles() + } +} + +impl From for Vc +where + T: ?Sized + Send, +{ + fn from(node: RawVc) -> Self { + Self { + node, + _t: PhantomData, + } + } +} + +impl TraceRawVcs for Vc +where + T: ?Sized + Send, +{ + fn trace_raw_vcs(&self, trace_context: &mut TraceRawVcsContext) { + TraceRawVcs::trace_raw_vcs(&self.node, trace_context); + } +} + +impl ValueDebugFormat for Vc +where + T: ?Sized + Send, + T: Upcast>, +{ + fn value_debug_format(&self, depth: usize) -> ValueDebugFormatString { + ValueDebugFormatString::Async(Box::pin(async move { + Ok({ + let vc_value_debug = Vc::upcast::>(*self); + vc_value_debug.dbg_depth(depth).await?.to_string() + }) + })) + } +} + +impl std::future::IntoFuture for Vc +where + T: VcValueType, +{ + type Output = as std::future::Future>::Output; + type IntoFuture = ReadVcFuture; + fn into_future(self) -> Self::IntoFuture { + self.node.into_read().into() + } +} + +impl std::future::IntoFuture for &Vc +where + T: VcValueType, +{ + type Output = as std::future::IntoFuture>::Output; + type IntoFuture = as std::future::IntoFuture>::IntoFuture; + fn into_future(self) -> Self::IntoFuture { + (*self).into_future() + } +} + +impl Vc +where + T: VcValueType, +{ + /// Returns a strongly consistent read of the value. This ensures that all + /// internal tasks are finished before the read is returned. + #[must_use] + pub fn strongly_consistent(self) -> ReadVcFuture { + self.node.into_strongly_consistent_read().into() + } +} + +impl Unpin for Vc where T: ?Sized + Send {} + +impl Default for Vc +where + T: ValueDefault + Send, +{ + fn default() -> Self { + T::value_default() + } +} diff --git a/turbopack/crates/turbo-tasks/src/vc/read.rs b/turbopack/crates/turbo-tasks/src/vc/read.rs new file mode 100644 index 0000000000000..e1c7c6034d2ce --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/vc/read.rs @@ -0,0 +1,166 @@ +use std::{any::Any, marker::PhantomData, mem::ManuallyDrop, pin::Pin, task::Poll}; + +use anyhow::Result; +use futures::Future; + +use super::traits::VcValueType; +use crate::{ReadRawVcFuture, VcCast, VcValueTrait, VcValueTraitCast, VcValueTypeCast}; + +/// Trait that controls [`crate::Vc`]'s read representation. +/// +/// Has two implementations: +/// * [`VcDefaultRead`] +/// * [`VcTransparentRead`] +/// +/// This trait must remain sealed within this crate. +pub trait VcRead +where + T: VcValueType, +{ + /// The read target type. This is the type that will be returned when + /// `.await`ing a `Vc` of a value type. + /// + /// For instance, the target of `.await`ing a `Vc` will be a + /// `Completion`. When using `#[turbo_tasks::value(transparent)]`, the + /// target will be different than the value type. + type Target; + + /// The representation type. This is what will be used to + /// serialize/deserialize the value, and this determines the + /// type that the value will be upcasted to for storage. + /// + /// For instance, when storing generic collection types such as + /// `Vec>`, we first cast them to a shared `Vec>` + /// type instead, which has an equivalent memory representation to any + /// `Vec>` type. This allows sharing implementations of methods and + /// traits between all `Vec>`. + type Repr: VcValueType; + + /// Convert a reference to a value to a reference to the target type. + fn value_to_target_ref(value: &T) -> &Self::Target; + + /// Convert the target type to the repr. + fn target_to_repr(target: Self::Target) -> Self::Repr; + + /// Convert a reference to a target type to a reference to a value. + fn target_to_value_ref(target: &Self::Target) -> &T; +} + +/// Representation for standard `#[turbo_tasks::value]`, where a read return a +/// reference to the value type[] +pub struct VcDefaultRead { + _phantom: PhantomData, +} + +impl VcRead for VcDefaultRead +where + T: VcValueType, +{ + type Target = T; + type Repr = T; + + fn value_to_target_ref(value: &T) -> &Self::Target { + value + } + + fn target_to_repr(target: Self::Target) -> T { + target + } + + fn target_to_value_ref(target: &Self::Target) -> &T { + target + } +} + +/// Representation for `#[turbo_tasks::value(transparent)]` types, where reads +/// return a reference to the target type. +pub struct VcTransparentRead { + _phantom: PhantomData<(T, Target, Repr)>, +} + +impl VcRead for VcTransparentRead +where + T: VcValueType, + Target: Any + Send + Sync, + Repr: VcValueType, +{ + type Target = Target; + type Repr = Repr; + + fn value_to_target_ref(value: &T) -> &Self::Target { + // Safety: the `VcValueType` implementor must guarantee that both `T` and + // `Target` are #[repr(transparent)]. This is guaranteed by the + // `#[turbo_tasks::value(transparent)]` macro. + // We can't use `std::mem::transmute` here as it doesn't support generic types. + // See https://users.rust-lang.org/t/transmute-doesnt-work-on-generic-types/87272/9 + unsafe { + std::mem::transmute_copy::, &Self::Target>(&ManuallyDrop::new(value)) + } + } + + fn target_to_repr(target: Self::Target) -> Self::Repr { + // Safety: see `Self::value_to_target` above. + unsafe { + std::mem::transmute_copy::, Self::Repr>(&ManuallyDrop::new( + target, + )) + } + } + + fn target_to_value_ref(target: &Self::Target) -> &T { + // Safety: see `Self::value_to_target` above. + unsafe { + std::mem::transmute_copy::, &T>(&ManuallyDrop::new(target)) + } + } +} + +pub struct ReadVcFuture> +where + T: ?Sized, + Cast: VcCast, +{ + raw: ReadRawVcFuture, + _phantom_t: PhantomData, + _phantom_cast: PhantomData, +} + +impl From for ReadVcFuture> +where + T: VcValueType, +{ + fn from(raw: ReadRawVcFuture) -> Self { + Self { + raw, + _phantom_t: PhantomData, + _phantom_cast: PhantomData, + } + } +} + +impl From for ReadVcFuture> +where + T: VcValueTrait + ?Sized, +{ + fn from(raw: ReadRawVcFuture) -> Self { + Self { + raw, + _phantom_t: PhantomData, + _phantom_cast: PhantomData, + } + } +} + +impl Future for ReadVcFuture +where + T: ?Sized, + Cast: VcCast, +{ + type Output = Result; + + fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { + // Safety: We never move the contents of `self` + let raw = unsafe { self.map_unchecked_mut(|this| &mut this.raw) }; + Poll::Ready(std::task::ready!(raw.poll(cx)).and_then(Cast::cast)) + } +} diff --git a/turbopack/crates/turbo-tasks/src/vc/resolved.rs b/turbopack/crates/turbo-tasks/src/vc/resolved.rs new file mode 100644 index 0000000000000..8bdc40f648e70 --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/vc/resolved.rs @@ -0,0 +1,164 @@ +use std::{ + cell::RefCell, + collections::{BTreeMap, BTreeSet, HashMap, HashSet}, + hash::{Hash, Hasher}, + marker::PhantomData, + ops::Deref, + path::{Path, PathBuf}, + sync::{ + atomic::{ + AtomicBool, AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicU16, AtomicU32, AtomicU64, + AtomicU8, AtomicUsize, + }, + Arc, Mutex, + }, + time::Duration, +}; + +use auto_hash_map::{AutoMap, AutoSet}; +use indexmap::{IndexMap, IndexSet}; + +use crate::{vc::Vc, RcStr}; + +pub struct ResolvedVc +where + T: ?Sized + Send, +{ + pub(crate) node: Vc, +} + +impl Copy for ResolvedVc where T: ?Sized + Send {} + +impl Clone for ResolvedVc +where + T: ?Sized + Send, +{ + fn clone(&self) -> Self { + *self + } +} + +impl Deref for ResolvedVc +where + T: ?Sized + Send, +{ + type Target = Vc; + + fn deref(&self) -> &Self::Target { + &self.node + } +} + +impl PartialEq> for ResolvedVc +where + T: ?Sized + Send, +{ + fn eq(&self, other: &Self) -> bool { + self.node == other.node + } +} + +impl Eq for ResolvedVc where T: ?Sized + Send {} + +impl Hash for ResolvedVc +where + T: ?Sized + Send, +{ + fn hash(&self, state: &mut H) { + self.node.hash(state); + } +} + +impl std::fmt::Debug for ResolvedVc +where + T: Send, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ResolvedVc") + .field("node", &self.node.node) + .finish() + } +} + +/// Indicates that a type does not contain any instances of [`Vc`]. It may +/// contain [`ResolvedVc`]. +/// +/// # Safety +/// +/// This trait is marked as unsafe. You should not derive it yourself, but +/// instead you should rely on [`#[turbo_tasks::value(resolved)]`][macro@ +/// turbo_tasks::value] to do it for you. +pub unsafe trait ResolvedValue {} + +unsafe impl ResolvedValue for ResolvedVc {} + +macro_rules! impl_resolved { + ($ty:ty) => { + unsafe impl ResolvedValue for $ty {} + }; + + ($ty:ty, $($tys:ty),+) => { + impl_resolved!($ty); + impl_resolved!($($tys),+); + } +} + +impl_resolved!(i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, char, bool, usize); +impl_resolved!( + AtomicI8, + AtomicU8, + AtomicI16, + AtomicU16, + AtomicI32, + AtomicU32, + AtomicI64, + AtomicU64, + AtomicBool, + AtomicUsize +); +impl_resolved!((), str, String, Duration, anyhow::Error, RcStr); +impl_resolved!(Path, PathBuf); +impl_resolved!(serde_json::Value); + +// based on stdlib's internal `tuple_impls!` macro +macro_rules! impl_resolved_tuple { + ($T:ident) => { + impl_resolved_tuple!(@impl $T); + }; + ($T:ident $( $U:ident )+) => { + impl_resolved_tuple!($( $U )+); + impl_resolved_tuple!(@impl $T $( $U )+); + }; + (@impl $( $T:ident )+) => { + unsafe impl<$($T: ResolvedValue),+> ResolvedValue for ($($T,)+) {} + }; +} + +impl_resolved_tuple!(E D C B A Z Y X W V U T); + +unsafe impl ResolvedValue for Option {} +unsafe impl ResolvedValue for Vec {} +unsafe impl ResolvedValue for [T; N] {} +unsafe impl ResolvedValue for [T] {} +unsafe impl ResolvedValue for HashSet {} +unsafe impl ResolvedValue for AutoSet {} +unsafe impl ResolvedValue for BTreeSet {} +unsafe impl ResolvedValue for IndexSet {} +unsafe impl ResolvedValue for HashMap {} +unsafe impl ResolvedValue + for AutoMap +{ +} +unsafe impl ResolvedValue for BTreeMap {} +unsafe impl ResolvedValue for IndexMap {} +unsafe impl ResolvedValue for Box {} +unsafe impl ResolvedValue for Arc {} +unsafe impl ResolvedValue for Result {} +unsafe impl ResolvedValue for Mutex {} +unsafe impl ResolvedValue for RefCell {} +unsafe impl ResolvedValue for PhantomData {} + +unsafe impl ResolvedValue for &T {} +unsafe impl ResolvedValue for &mut T {} + +pub use turbo_tasks_macros::ResolvedValue; diff --git a/turbopack/crates/turbo-tasks/src/vc/traits.rs b/turbopack/crates/turbo-tasks/src/vc/traits.rs new file mode 100644 index 0000000000000..526db09af974b --- /dev/null +++ b/turbopack/crates/turbo-tasks/src/vc/traits.rs @@ -0,0 +1,62 @@ +use super::{cell_mode::VcCellMode, read::VcRead}; +use crate::{TraitTypeId, ValueTypeId}; + +/// A trait implemented on all values types that can be put into a Value Cell +/// ([`Vc`][crate::Vc]). +/// +/// # Safety +/// +/// The implementor of this trait must ensure that the read and cell mode +/// implementations are correct for the value type. Otherwise, it is possible to +/// generate invalid reads, for instance by using +/// [`VcTransparentRead`][crate::VcTransparentRead] for a value type that is not +/// `#[repr(transparent)]`. +pub unsafe trait VcValueType: Sized + Send + Sync + 'static { + /// How to read the value. + type Read: VcRead; + + /// How to update cells of this value type. + type CellMode: VcCellMode; + + /// Returns the type id of the value type. + fn get_value_type_id() -> ValueTypeId; +} + +/// A trait implemented on all values trait object references that can be put +/// into a Value Cell ([`Vc<&dyn Trait>`][crate::Vc]). +pub trait VcValueTrait { + fn get_trait_type_id() -> TraitTypeId; +} + +/// Marker trait that indicates that a [`Vc`][crate::Vc] can be upcasted +/// to a [`Vc`][crate::Vc]. +/// +/// # Safety +/// +/// The implementor of this trait must ensure that `Self` implements the +/// trait `T`. +pub unsafe trait Upcast: Send +where + T: VcValueTrait + ?Sized + Send, +{ +} + +/// Marker trait that indicates that a [`Vc`][crate::Vc] can accept all +/// methods declared on a [`Vc`][crate::Vc]. +/// +/// # Safety +/// +/// The implementor of this trait must ensure that `Self` implements the +/// trait `T`. +pub unsafe trait Dynamic: Send +where + T: VcValueTrait + ?Sized + Send, +{ +} + +/// Marker trait that a turbo_tasks::value is prepared for +/// serialization as [`Value<...>`][crate::Value] input. +/// Either use [`#[turbo_tasks::value(serialization: +/// auto_for_input)]`][macro@crate::value] or avoid [`Value<...>`][crate::Value] +/// in favor of a real [Vc][crate::Vc]. +pub trait TypedForInput: VcValueType {} diff --git a/turbopack/crates/turbopack-bench/Cargo.toml b/turbopack/crates/turbopack-bench/Cargo.toml new file mode 100644 index 0000000000000..3646b0bba790e --- /dev/null +++ b/turbopack/crates/turbopack-bench/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "turbopack-bench" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[[bench]] +name = "mod" +harness = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true, features = ["backtrace"] } +chromiumoxide = { workspace = true, features = [ + "tokio-runtime", +], default-features = false } +criterion = { workspace = true, features = ["async_tokio"] } +futures = { workspace = true } +once_cell = { workspace = true } +owo-colors = { workspace = true } +parking_lot = { workspace = true } +portpicker = "0.1.1" +rand = { workspace = true } +regex = { workspace = true } +serde_json = { workspace = true } +tempfile = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tungstenite = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-testing = { workspace = true } +turbopack-create-test-app = { workspace = true } +url = { workspace = true } + +[target.'cfg(unix)'.dependencies] +nix = "0.26.1" diff --git a/turbopack/crates/turbopack-bench/README.md b/turbopack/crates/turbopack-bench/README.md new file mode 100644 index 0000000000000..241222daaaf28 --- /dev/null +++ b/turbopack/crates/turbopack-bench/README.md @@ -0,0 +1,51 @@ + + +# Benchmarking Turbopack + +The simplest way to run Turbopack's benchmark suite is with the command `cargo bench -p turbopack-bench`. This will benchmark Turbopack's Next.js development server in a variety of scenarios and it's what we use to track Turbopack's performance over time. + +`cargo bench -p turbopack-bench` accepts different options via environment variables. To vary the number of modules tested, set `TURBOPACK_BENCH_COUNTS`. For example, to test against an app with 5,000 modules instead of the default 1,000, run + +```sh +TURBOPACK_BENCH_COUNTS=5000 cargo bench -p turbopack-bench +``` + +## Benchmarking Turbopack against other bundlers + +The benchmark numbers we share on [the Turbopack website](https://turbo.build/pack) are informed by running Turbopack's benchmark suite against Turbopack and other bundlers. These are run in a controlled environment prior to being published. We use the `bench_startup` and `bench_hmr_to_eval` benchmarks currently (see below). + +To run Turbopack benchmarks against other bundlers, run: + +```sh +cargo bench -p turbopack-bench -p turbopack-cli +``` + +and optionally filter the benchmarks run to specific bundlers, such as: + +```sh +cargo bench -p turbopack-bench -p turbopack-cli -- "hmr_to_eval/(Turbopack CSR|Vite)" +``` + +or a specific suite: + +```sh +cargo bench -p turbopack-bench -- "bench_hydration/Next\.js canary Turbo RSC" +``` + +**Note**: The Turbopack benchmark suite includes a mix of server-side rendered and client-only rendered examples -- these are reflected in "CSR" or "SSR" in the benchmark name. Turbopack supports both, while some other bundlers only support client-rendered examples. Take that into account when comparing CSR results against SSR. + +**Hint**: These benchmarks take a long time to complete, since they try to capture at least 10 samples for every scenario. There is a `TURBOPACK_BENCH_PROGRESS=1` env var to show values while the benchmarks are running. + +## Benchmark Suite scenarios + +The benchmark suite runs Turbopack and other bundlers in a variety of scenarios. The tests use a real headless browser and perform a variety of common scenarios in web development, and wait for results to be reflected in the page. + +- **bench_startup:** Time from startup (without cache) until the app is rendered in the browser (it doesn't have to be interactive/hydrated for this.) +- **bench_hydration:** Time from startup (without cache) until the app is interactive in the browser (it needs to be hydrated for that.) This metric is not captured for CSR since the first render is interactive. +- **bench_hmr_to_eval:** Time from changing a file until the new code is evaluated in the browser. Evaluating the code does not mean the change is visible to the user yet. For instance, when a React component changes, it needs to be re-rendered in the browser. This mostly measures the time spent computing the update in the bundler itself and sending it to the client. +- **bench_hmr_to_commit:** Time from changing a file until the change is reflected in the browser. We are using a `useEffect` hook within a React component to measure the time it takes for the updated React component to be committed to the DOM. This is a good measure of the end to end performance perceived by the user. +- **bench_startup_cache:** Time from startup with persistent cache until the app is rendered in the browser (it doesn't have to be interactive/hydrated for this.). Turbopack doesn't include a persistent cache yet. (This benchmark is disabled by default and can be enabled with `TURBOPACK_BENCH_CACHED=1`) +- **bench_hydration:** Time from startup with persistent cache until the app is interactive in the browser (it needs to be hydrated for that.) This metric is not captured for CSR since the first render is interactive. Turbopack doesn't include a persistent cache yet. (This benchmark is disabled by default and can be enabled with `TURBOPACK_BENCH_CACHED=1`) diff --git a/turbopack/crates/turbopack-bench/benches/mod.rs b/turbopack/crates/turbopack-bench/benches/mod.rs new file mode 100644 index 0000000000000..fbb66c36f6d96 --- /dev/null +++ b/turbopack/crates/turbopack-bench/benches/mod.rs @@ -0,0 +1,37 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use turbopack_bench::bundlers::Bundler; + +fn get_bundlers() -> Vec> { + turbopack_bench::bundlers::get_bundlers() +} + +fn bench_startup(c: &mut Criterion) { + turbopack_bench::bench_startup(c, &get_bundlers()) +} + +fn bench_hydration(c: &mut Criterion) { + turbopack_bench::bench_hydration(c, &get_bundlers()) +} + +fn bench_startup_cached(c: &mut Criterion) { + turbopack_bench::bench_startup_cached(c, &get_bundlers()) +} + +fn bench_hydration_cached(c: &mut Criterion) { + turbopack_bench::bench_hydration_cached(c, &get_bundlers()) +} + +fn bench_hmr_to_eval(c: &mut Criterion) { + turbopack_bench::bench_hmr_to_eval(c, &get_bundlers()) +} + +fn bench_hmr_to_commit(c: &mut Criterion) { + turbopack_bench::bench_hmr_to_commit(c, &get_bundlers()) +} + +criterion_group!( + name = benches; + config = Criterion::default(); + targets = bench_startup, bench_hydration, bench_startup_cached, bench_hydration_cached, bench_hmr_to_eval, bench_hmr_to_commit +); +criterion_main!(benches); diff --git a/turbopack/crates/turbopack-bench/src/bundlers/mod.rs b/turbopack/crates/turbopack-bench/src/bundlers/mod.rs new file mode 100644 index 0000000000000..a5f659e7aa262 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/mod.rs @@ -0,0 +1,217 @@ +use std::{path::Path, process::Child, time::Duration}; + +use anyhow::Result; + +use self::{ + nextjs::{NextJs, NextJsVersion}, + parcel::Parcel, + vite::Vite, + webpack::Webpack, +}; +use crate::bundlers::rspack::Rspack; + +mod nextjs; +mod parcel; +mod rspack; +mod vite; +mod webpack; + +#[derive(Debug, Clone, Copy)] +pub enum RenderType { + /// App is completely rendered on client side, the initial HTML is empty. + ClientSideRendered, + /// App is intially rendered on server side, then hydrated on client side. + ServerSidePrerendered, + /// App is rendered on server side, but additional client side javascript + /// emits events on hydration and changes + ServerSideRenderedWithEvents, + /// App is rendered on server side, without any client side events. + #[allow(dead_code)] + ServerSideRenderedWithoutInteractivity, +} + +pub trait Bundler { + fn get_name(&self) -> &str; + fn get_path(&self) -> &str { + "/" + } + fn react_version(&self) -> &str { + "^18.2.0" + } + fn render_type(&self) -> RenderType { + RenderType::ClientSideRendered + } + /// There is a hydration done event emitted by client side JavaScript + fn has_hydration_event(&self) -> bool { + !matches!( + self.render_type(), + RenderType::ServerSideRenderedWithoutInteractivity + ) + } + + fn prepare(&self, _template_dir: &Path) -> Result<()> { + Ok(()) + } + fn prepare_each(&self, _template_dir: &Path) -> Result<()> { + Ok(()) + } + fn start_server(&self, test_dir: &Path) -> Result<(Child, String)>; + + /// The maximum amount of time to wait for HMR during the setup and warmup + /// phase. + fn max_init_update_timeout(&self, _module_count: usize) -> Duration { + Duration::from_secs(60) + } + + /// The maximum amount of time to wait for HMR during the actual benchmark. + /// This is a lot shorter than the init timeout because we expect + /// updates to generally happen quickly, and we don't want to wait for a + /// long time when an update is dropped. + fn max_update_timeout(&self, _module_count: usize) -> Duration { + Duration::from_secs(5) + } +} + +pub fn get_bundlers() -> Vec> { + vec![ + Box::new(NextJs::new( + NextJsVersion::Canary, + "Next.js canary Turbo SSR", + "/page", + true, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::Canary, + "Next.js canary Turbo RSC", + "/app", + true, + RenderType::ServerSideRenderedWithEvents, + )), + Box::new(NextJs::new( + NextJsVersion::Canary, + "Next.js canary Turbo RCC", + "/client", + true, + RenderType::ServerSideRenderedWithEvents, + )), + Box::new(NextJs::new( + NextJsVersion::V14, + "Next.js 14 Turbo SSR", + "/page", + true, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::V14, + "Next.js 14 Turbo RSC", + "/app", + true, + RenderType::ServerSideRenderedWithEvents, + )), + Box::new(NextJs::new( + NextJsVersion::V14, + "Next.js 14 Turbo RCC", + "/client", + true, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::V13, + "Next.js 13 Turbo SSR", + "/page", + true, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::V13, + "Next.js 13 Turbo RSC", + "/app", + true, + RenderType::ServerSideRenderedWithEvents, + )), + Box::new(NextJs::new( + NextJsVersion::V13, + "Next.js 13 Turbo RCC", + "/client", + true, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::Canary, + "Next.js canary webpack SSR", + "/page", + false, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::Canary, + "Next.js canary webpack RSC", + "/app", + false, + RenderType::ServerSideRenderedWithEvents, + )), + Box::new(NextJs::new( + NextJsVersion::Canary, + "Next.js canary webpack RCC", + "/client", + false, + RenderType::ServerSideRenderedWithEvents, + )), + Box::new(NextJs::new( + NextJsVersion::V14, + "Next.js 14 webpack SSR", + "/page", + false, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::V14, + "Next.js 14 webpack RSC", + "/app", + false, + RenderType::ServerSideRenderedWithEvents, + )), + Box::new(NextJs::new( + NextJsVersion::V14, + "Next.js 14 webpack RCC", + "/client", + false, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::V13, + "Next.js 13 webpack SSR", + "/page", + false, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::V13, + "Next.js 13 webpack RSC", + "/app", + false, + RenderType::ServerSideRenderedWithEvents, + )), + Box::new(NextJs::new( + NextJsVersion::V13, + "Next.js 13 webpack RCC", + "/client", + false, + RenderType::ServerSidePrerendered, + )), + Box::new(NextJs::new( + NextJsVersion::V12, + "Next.js 12 webpack SSR", + "/page", + false, + RenderType::ServerSidePrerendered, + )), + Box::new(Parcel {}), + Box::new(Vite::new(false, false)), + Box::new(Vite::new(true, false)), + Box::new(Vite::new(false, true)), + Box::new(Webpack {}), + Box::new(Rspack {}), + ] +} diff --git a/turbopack/crates/turbopack-bench/src/bundlers/nextjs/mod.rs b/turbopack/crates/turbopack-bench/src/bundlers/nextjs/mod.rs new file mode 100644 index 0000000000000..ef51f8d3bdaf8 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/nextjs/mod.rs @@ -0,0 +1,173 @@ +use std::{ + fs, + path::Path, + process::{Child, Command, Stdio}, + time::Duration, +}; + +use anyhow::{anyhow, Context, Result}; +use regex::Regex; + +use super::RenderType; +use crate::{ + bundlers::Bundler, + util::{ + npm::{ + NpmPackage, {self}, + }, + wait_for_match, + }, +}; + +#[derive(Debug)] +pub enum NextJsVersion { + V12, + V13, + V14, + Canary, +} + +#[derive(Debug)] +pub struct NextJs { + version: NextJsVersion, + name: String, + path: String, + turbo: bool, + render_type: RenderType, +} + +impl NextJs { + pub fn new( + version: NextJsVersion, + name: &str, + path: &str, + turbo: bool, + render_type: RenderType, + ) -> Self { + Self { + name: name.to_owned(), + path: path.to_owned(), + render_type, + turbo, + version, + } + } +} + +impl Bundler for NextJs { + fn get_name(&self) -> &str { + &self.name + } + + fn get_path(&self) -> &str { + &self.path + } + + fn render_type(&self) -> RenderType { + self.render_type + } + + fn react_version(&self) -> &str { + self.version.react_version() + } + + fn prepare(&self, install_dir: &Path) -> Result<()> { + npm::install( + install_dir, + &[NpmPackage::new("next", self.version.version())], + ) + .context("failed to install `next` module")?; + + if self.version.app_dir() { + fs::write( + install_dir.join("next.config.js"), + include_bytes!("next.config.js"), + )?; + } + Ok(()) + } + + fn start_server(&self, test_dir: &Path) -> Result<(Child, String)> { + // Using `node_modules/.bin/next` would sometimes error with `Error: Cannot find + // module '../build/output/log'` + let mut proc = Command::new("node"); + proc.args([ + test_dir + .join("node_modules") + .join("next") + .join("dist") + .join("bin") + .join("next") + .to_str() + .unwrap(), + "dev", + "--port", + &match self.version { + NextJsVersion::V12 => { + // Next.js 12 has a bug where requests for port 0 are ignored and it falls + // back to the default 3000. Use portpicker instead. + portpicker::pick_unused_port() + .ok_or_else(|| anyhow!("failed to pick unused port"))? + } + _ => 0, + } + .to_string(), + ]) + .current_dir(test_dir) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()); + if self.turbo { + proc.arg("--turbo"); + } + let mut proc = proc.spawn().context("failed to run `next` command")?; + + let addr = wait_for_match( + proc.stdout + .as_mut() + .ok_or_else(|| anyhow!("missing stdout"))?, + match self.version { + NextJsVersion::V12 => Regex::new("started server.*url: (.*)"), + _ => Regex::new("- Local:\\s+(.*)"), + }?, + ) + .ok_or_else(|| anyhow!("failed to find devserver address"))?; + + Ok((proc, format!("{addr}/page"))) + } + + fn max_update_timeout(&self, module_count: usize) -> std::time::Duration { + match (self.render_type, self.turbo) { + (RenderType::ServerSidePrerendered, true) => Duration::from_millis(500), + // Arbitrary default timeout that seems to work well for Next.js Webpack + _ => Duration::from_millis(5000 + (module_count as f64 / 2.0).ceil() as u64), + } + } +} + +impl NextJsVersion { + /// Returns the version of Next.js to install from npm. + pub fn version(&self) -> &'static str { + match self { + NextJsVersion::V12 => "^12", + NextJsVersion::V13 => "^13", + NextJsVersion::V14 => "^14", + NextJsVersion::Canary => "canary", + } + } + + /// Returns the version of React to install from npm alongside this version + /// of Next.js. + pub fn react_version(&self) -> &'static str { + match self { + NextJsVersion::V12 => "^18.2.0", + NextJsVersion::V13 => "^18.2.0", + NextJsVersion::V14 => "^18.2.0", + NextJsVersion::Canary => "rc", + } + } + + /// Returns whether this version of Next.js supports the appDir option. + pub fn app_dir(&self) -> bool { + matches!(self, NextJsVersion::V13 | NextJsVersion::Canary) + } +} diff --git a/turbopack/crates/turbopack-bench/src/bundlers/nextjs/next.config.js b/turbopack/crates/turbopack-bench/src/bundlers/nextjs/next.config.js new file mode 100644 index 0000000000000..f053ebf7976e3 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/nextjs/next.config.js @@ -0,0 +1 @@ +module.exports = {}; diff --git a/turbopack/crates/turbopack-bench/src/bundlers/parcel.rs b/turbopack/crates/turbopack-bench/src/bundlers/parcel.rs new file mode 100644 index 0000000000000..308d0344248c0 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/parcel.rs @@ -0,0 +1,72 @@ +use std::{ + path::Path, + process::{Child, Command, Stdio}, +}; + +use anyhow::{anyhow, Context, Result}; +use regex::Regex; + +use crate::{ + bundlers::Bundler, + util::{ + npm::{ + NpmPackage, {self}, + }, + wait_for_match, + }, +}; + +pub struct Parcel; +impl Bundler for Parcel { + fn get_name(&self) -> &str { + "Parcel CSR" + } + + fn prepare(&self, install_dir: &Path) -> Result<()> { + npm::install( + install_dir, + &[ + NpmPackage::new("parcel", "^2.8.0"), + // `process` would otherwise be auto-installed by Parcel. Do this in advance as + // to not influence the benchmark. + NpmPackage::new("process", "^0.11.10"), + ], + ) + .context("failed to install from npm")?; + + Ok(()) + } + + fn start_server(&self, test_dir: &Path) -> Result<(Child, String)> { + let mut proc = Command::new("node") + .args([ + (test_dir + .join("node_modules") + .join("parcel") + .join("lib") + .join("bin.js") + .to_str() + .unwrap()), + "--port", + &portpicker::pick_unused_port() + .ok_or_else(|| anyhow!("failed to pick unused port"))? + .to_string(), + "index.html", + ]) + .current_dir(test_dir) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .context("failed to run `parcel` command")?; + + let addr = wait_for_match( + proc.stdout + .as_mut() + .ok_or_else(|| anyhow!("missing stdout"))?, + Regex::new("Server running at\\s+(.*)")?, + ) + .ok_or_else(|| anyhow!("failed to find devserver address"))?; + + Ok((proc, addr)) + } +} diff --git a/turbopack/crates/turbopack-bench/src/bundlers/rspack/mod.rs b/turbopack/crates/turbopack-bench/src/bundlers/rspack/mod.rs new file mode 100644 index 0000000000000..44a9f2204ece2 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/rspack/mod.rs @@ -0,0 +1,74 @@ +use std::{ + fs, + path::Path, + process::{Child, Command, Stdio}, +}; + +use anyhow::{anyhow, Context, Result}; +use regex::Regex; + +use crate::{ + bundlers::Bundler, + util::{ + npm::{ + NpmPackage, {self}, + }, + wait_for_match, + }, +}; + +pub struct Rspack; +impl Bundler for Rspack { + fn get_name(&self) -> &str { + "Rspack CSR" + } + + fn prepare(&self, install_dir: &Path) -> Result<()> { + npm::install( + install_dir, + &[ + NpmPackage::new("react-refresh", "^0.14.0"), + NpmPackage::new("@rspack/cli", "0.1.9"), + ], + ) + .context("failed to install from npm")?; + + fs::write( + install_dir.join("rspack.config.js"), + include_bytes!("rspack.config.js"), + )?; + + Ok(()) + } + + fn start_server(&self, test_dir: &Path) -> Result<(Child, String)> { + let mut proc = Command::new("node") + .args([ + (test_dir + .join("node_modules") + .join("@rspack") + .join("cli") + .join("bin") + .join("rspack") + .to_str() + .unwrap()), + "serve", + ]) + .env("NO_COLOR", "1") + .current_dir(test_dir) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .context("failed to run `rspack-dev-server` command")?; + + let addr = wait_for_match( + proc.stderr + .as_mut() + .ok_or_else(|| anyhow!("missing stderr"))?, + Regex::new("Loopback:\\s+(.*)")?, + ) + .ok_or_else(|| anyhow!("failed to find devserver address"))?; + + Ok((proc, addr)) + } +} diff --git a/turbopack/crates/turbopack-bench/src/bundlers/rspack/rspack.config.js b/turbopack/crates/turbopack-bench/src/bundlers/rspack/rspack.config.js new file mode 100644 index 0000000000000..db0f385f01a65 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/rspack/rspack.config.js @@ -0,0 +1,14 @@ +const path = require("path"); + +module.exports = { + entry: { + main: "./src/index.jsx", + }, + output: { + filename: "main.js", + path: path.resolve(__dirname, "dist"), + }, + devServer: { + port: 0, + }, +}; diff --git a/turbopack/crates/turbopack-bench/src/bundlers/vite/mod.rs b/turbopack/crates/turbopack-bench/src/bundlers/vite/mod.rs new file mode 100644 index 0000000000000..fa998e529fa0d --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/vite/mod.rs @@ -0,0 +1,110 @@ +use std::{ + fs, + path::Path, + process::{Child, Command, Stdio}, +}; + +use anyhow::{anyhow, Context, Result}; +use regex::Regex; + +use crate::{ + bundlers::Bundler, + util::{ + npm::{ + NpmPackage, {self}, + }, + wait_for_match, + }, +}; + +pub struct Vite { + swc: bool, + ssr: bool, +} + +impl Vite { + pub fn new(swc: bool, ssr: bool) -> Self { + Vite { swc, ssr } + } +} + +impl Bundler for Vite { + fn get_name(&self) -> &str { + if self.ssr { + if self.swc { + "Vite SWC SSR" + } else { + "Vite SSR" + } + } else if self.swc { + "Vite SWC CSR" + } else { + "Vite CSR" + } + } + + fn prepare(&self, install_dir: &Path) -> Result<()> { + let mut packages = vec![NpmPackage::new("vite", "4.3.0-beta.2")]; + if self.swc { + packages.push(NpmPackage::new("@vitejs/plugin-react-swc", "^3.2.0")); + } else { + packages.push(NpmPackage::new("@vitejs/plugin-react", "^3.1.0")); + }; + if self.ssr { + packages.push(NpmPackage::new("express", "^4.18.2")); + } + npm::install(install_dir, &packages).context("failed to install from npm")?; + + fs::write( + install_dir.join("vite.config.js"), + if self.swc { + include_bytes!("vite.swc.config.js") as &[u8] + } else { + include_bytes!("vite.config.js") as &[u8] + }, + )?; + + Ok(()) + } + + fn start_server(&self, test_dir: &Path) -> Result<(Child, String)> { + let args = if self.ssr { + vec![test_dir + .join("vite-server.mjs") + .to_str() + .unwrap() + .to_string()] + } else { + vec![ + test_dir + .join("node_modules") + .join("vite") + .join("bin") + .join("vite.js") + .to_str() + .unwrap() + .to_string(), + "--port".to_string(), + "0".to_string(), + ] + }; + let mut proc = Command::new("node") + .args(args) + .env("NO_COLOR", "1") + .current_dir(test_dir) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .context("failed to run `vite` command")?; + + let addr = wait_for_match( + proc.stdout + .as_mut() + .ok_or_else(|| anyhow!("missing stdout"))?, + Regex::new("Local:\\s+(.*)")?, + ) + .ok_or_else(|| anyhow!("failed to find devserver address"))?; + + Ok((proc, addr)) + } +} diff --git a/turbopack/crates/turbopack-bench/src/bundlers/vite/vite.config.js b/turbopack/crates/turbopack-bench/src/bundlers/vite/vite.config.js new file mode 100644 index 0000000000000..081c8d9f69fcb --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/vite/vite.config.js @@ -0,0 +1,6 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], +}); diff --git a/turbopack/crates/turbopack-bench/src/bundlers/vite/vite.swc.config.js b/turbopack/crates/turbopack-bench/src/bundlers/vite/vite.swc.config.js new file mode 100644 index 0000000000000..642ef87a8e9a7 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/vite/vite.swc.config.js @@ -0,0 +1,7 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react-swc"; + +export default defineConfig({ + plugins: [react()], + esbuild: { jsx: "automatic" }, +}); diff --git a/turbopack/crates/turbopack-bench/src/bundlers/webpack/mod.rs b/turbopack/crates/turbopack-bench/src/bundlers/webpack/mod.rs new file mode 100644 index 0000000000000..d4304b2172b6d --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/webpack/mod.rs @@ -0,0 +1,80 @@ +use std::{ + fs, + path::Path, + process::{Child, Command, Stdio}, +}; + +use anyhow::{anyhow, Context, Result}; +use regex::Regex; + +use crate::{ + bundlers::Bundler, + util::{ + npm::{ + NpmPackage, {self}, + }, + wait_for_match, + }, +}; + +pub struct Webpack; +impl Bundler for Webpack { + fn get_name(&self) -> &str { + "Webpack CSR" + } + + fn prepare(&self, install_dir: &Path) -> Result<()> { + npm::install( + install_dir, + &[ + NpmPackage::new("@pmmmwh/react-refresh-webpack-plugin", "^0.5.7"), + NpmPackage::new("@swc/core", "^1.2.249"), + NpmPackage::new("@swc/helpers", "^0.4.13"), + NpmPackage::new("react-refresh", "^0.14.0"), + NpmPackage::new("swc-loader", "^0.2.3"), + NpmPackage::new("webpack", "^5.75.0"), + NpmPackage::new("webpack-cli", "^4.10.0"), + NpmPackage::new("webpack-dev-server", "^4.11.0"), + ], + ) + .context("failed to install from npm")?; + + fs::write( + install_dir.join("webpack.config.js"), + include_bytes!("webpack.config.js"), + )?; + + Ok(()) + } + + fn start_server(&self, test_dir: &Path) -> Result<(Child, String)> { + let mut proc = Command::new("node") + .args([ + (test_dir + .join("node_modules") + .join("webpack-dev-server") + .join("bin") + .join("webpack-dev-server.js") + .to_str() + .unwrap()), + "--port", + "0", + ]) + .env("NO_COLOR", "1") + .current_dir(test_dir) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .context("failed to run `webpack-dev-server` command")?; + + let addr = wait_for_match( + proc.stderr + .as_mut() + .ok_or_else(|| anyhow!("missing stderr"))?, + Regex::new("\\[webpack\\-dev\\-server\\] Loopback:\\s+(.*)")?, + ) + .ok_or_else(|| anyhow!("failed to find devserver address"))?; + + Ok((proc, addr)) + } +} diff --git a/turbopack/crates/turbopack-bench/src/bundlers/webpack/webpack.config.js b/turbopack/crates/turbopack-bench/src/bundlers/webpack/webpack.config.js new file mode 100644 index 0000000000000..0b794b4f59ba2 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/bundlers/webpack/webpack.config.js @@ -0,0 +1,54 @@ +const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin"); + +module.exports = { + mode: "development", + resolve: { + extensions: [".jsx", "..."], + }, + module: { + unsafeCache: true, + rules: [ + { + test: /\.jsx$/, + loader: "swc-loader", + options: { + jsc: { + parser: { + syntax: "ecmascript", + jsx: true, + dynamicImport: true, + privateMethod: true, + functionBind: true, + classPrivateProperty: true, + exportDefaultFrom: true, + exportNamespaceFrom: true, + decorators: true, + decoratorsBeforeExport: true, + importMeta: true, + }, + externalHelpers: true, + transform: { + react: { + runtime: "automatic", + refresh: true, + }, + }, + }, + }, + }, + ], + }, + devServer: { + hot: true, + }, + cache: { + type: "filesystem", + }, + node: { + global: true, + }, + experiments: { + futureDefaults: true, + }, + plugins: [new ReactRefreshWebpackPlugin()], +}; diff --git a/turbopack/crates/turbopack-bench/src/lib.rs b/turbopack/crates/turbopack-bench/src/lib.rs new file mode 100644 index 0000000000000..4e3df12db039f --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/lib.rs @@ -0,0 +1,535 @@ +use std::{ + fs::{self}, + panic::AssertUnwindSafe, + path::Path, + sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, + }, + time::Duration, +}; + +use anyhow::{anyhow, Context, Result}; +use criterion::{ + measurement::{Measurement, WallTime}, + BenchmarkGroup, BenchmarkId, Criterion, +}; +use once_cell::sync::Lazy; +use tokio::{ + runtime::Runtime, + time::{sleep, timeout}, +}; +use turbo_tasks::util::FormatDuration; +use util::{ + build_test, create_browser, + env::{read_env, read_env_bool, read_env_list}, + module_picker::ModulePicker, + AsyncBencherExtension, PreparedApp, BINDING_NAME, +}; + +use self::{bundlers::RenderType, util::resume_on_error}; +use crate::{bundlers::Bundler, util::PageGuard}; + +pub mod bundlers; +pub mod util; + +pub fn bench_startup(c: &mut Criterion, bundlers: &[Box]) { + let mut g = c.benchmark_group("bench_startup"); + g.sample_size(10); + g.measurement_time(Duration::from_secs(60)); + + bench_startup_internal(g, false, bundlers); +} + +pub fn bench_hydration(c: &mut Criterion, bundlers: &[Box]) { + let mut g = c.benchmark_group("bench_hydration"); + g.sample_size(10); + g.measurement_time(Duration::from_secs(60)); + + bench_startup_internal(g, true, bundlers); +} + +fn bench_startup_internal( + mut g: BenchmarkGroup, + hydration: bool, + bundlers: &[Box], +) { + let runtime = Runtime::new().unwrap(); + let browser = Lazy::new(|| runtime.block_on(create_browser())); + + for bundler in bundlers { + let wait_for_hydration = match bundler.render_type() { + RenderType::ClientSideRendered => { + // For bundlers without server rendered html "startup" means time to hydration + // as they only render an empty screen without hydration. Since startup and + // hydration would be the same we skip the hydration benchmark for them. + if hydration { + continue; + } else { + true + } + } + RenderType::ServerSidePrerendered => hydration, + RenderType::ServerSideRenderedWithEvents => hydration, + RenderType::ServerSideRenderedWithoutInteractivity => { + // For bundlers without interactivity there is no hydration event to wait for + if hydration { + continue; + } else { + false + } + } + }; + for module_count in get_module_counts() { + let test_app = Lazy::new(|| build_test(module_count, bundler.as_ref())); + let input = (bundler.as_ref(), &test_app); + resume_on_error(AssertUnwindSafe(|| { + g.bench_with_input( + BenchmarkId::new(bundler.get_name(), format!("{} modules", module_count)), + &input, + |b, &(bundler, test_app)| { + let test_app = &**test_app; + let browser = &*browser; + b.to_async(&runtime).try_iter_custom(|iters, m| async move { + let mut value = m.zero(); + + for _ in 0..iters { + let mut app = + PreparedApp::new(bundler, test_app.path().to_path_buf()) + .await?; + let start = m.start(); + app.start_server()?; + let mut guard = app.with_page(browser).await?; + if wait_for_hydration { + guard.wait_for_hydration().await?; + } + let duration = m.end(start); + value = m.add(&value, &duration); + + // Defer the dropping of the guard. + drop(guard); + } + Ok(value) + }); + }, + ); + })); + } + } + g.finish(); +} + +#[derive(Copy, Clone)] +enum CodeLocation { + Effect, + Evaluation, +} + +pub fn bench_hmr_to_eval(c: &mut Criterion, bundlers: &[Box]) { + let mut g = c.benchmark_group("bench_hmr_to_eval"); + g.sample_size(10); + g.measurement_time(Duration::from_secs(60)); + + bench_hmr_internal(g, CodeLocation::Evaluation, bundlers); +} + +pub fn bench_hmr_to_commit(c: &mut Criterion, bundlers: &[Box]) { + let mut g = c.benchmark_group("bench_hmr_to_commit"); + g.sample_size(10); + g.measurement_time(Duration::from_secs(60)); + + bench_hmr_internal(g, CodeLocation::Effect, bundlers); +} + +fn bench_hmr_internal( + mut g: BenchmarkGroup, + location: CodeLocation, + bundlers: &[Box], +) { + // Only capture one sample for warmup + g.warm_up_time(Duration::from_millis(1)); + + let runtime = Runtime::new().unwrap(); + let browser = Lazy::new(|| runtime.block_on(create_browser())); + let hmr_warmup = read_env("TURBOPACK_BENCH_HMR_WARMUP", 10).unwrap(); + + for bundler in bundlers { + if matches!( + bundler.render_type(), + RenderType::ServerSideRenderedWithEvents + | RenderType::ServerSideRenderedWithoutInteractivity + ) && matches!(location, CodeLocation::Evaluation) + { + // We can't measure evaluation time for these bundlers since it's not evaluated + // in the browser + continue; + } + for module_count in get_module_counts() { + let test_app = Lazy::new(|| build_test(module_count, bundler.as_ref())); + let input = (bundler.as_ref(), &test_app); + let module_picker = + Lazy::new(|| Arc::new(ModulePicker::new(test_app.modules().to_vec()))); + + resume_on_error(AssertUnwindSafe(|| { + g.bench_with_input( + BenchmarkId::new(bundler.get_name(), format!("{} modules", module_count)), + &input, + |b, &(bundler, test_app)| { + let test_app = &**test_app; + let modules = test_app.modules(); + let module_picker = &*module_picker; + let browser = &*browser; + + let max_init_update_timeout = bundler.max_init_update_timeout(module_count); + let max_update_timeout = bundler.max_update_timeout(module_count); + + b.to_async(&runtime).try_iter_async( + &runtime, + || async { + let mut app = PreparedApp::new_without_copy( + bundler, + test_app.path().to_path_buf(), + ) + .await?; + app.start_server()?; + let mut guard = app.with_page(browser).await?; + if bundler.has_hydration_event() { + guard.wait_for_hydration().await?; + } else { + guard.page().wait_for_navigation().await?; + } + guard + .page() + .evaluate_expression("globalThis.HMR_IS_HAPPENING = true") + .await + .context( + "Unable to evaluate JavaScript in the page for HMR check \ + flag", + )?; + + // There's a possible race condition between hydration and + // connection to the HMR server. We attempt to make updates with an + // exponential backoff until one succeeds. + let mut exponential_duration = Duration::from_millis(100); + loop { + match make_change( + &modules[0].0, + bundler, + &mut guard, + location, + exponential_duration, + &WallTime, + ) + .await + { + Ok(_) => { + break; + } + Err(e) => { + exponential_duration *= 2; + if exponential_duration > max_init_update_timeout { + return Err( + e.context("failed to make warmup change") + ); + } + } + } + } + + // Once we know the HMR server is connected, we make a few warmup + // changes. + let mut hmr_warmup_iter = 0; + let mut hmr_warmup_dropped = 0; + while hmr_warmup_iter < hmr_warmup { + match make_change( + &modules[0].0, + bundler, + &mut guard, + location, + max_update_timeout, + &WallTime, + ) + .await + { + Err(_) => { + // We don't care about dropped updates during warmup. + hmr_warmup_dropped += 1; + + if hmr_warmup_dropped >= hmr_warmup { + return Err(anyhow!( + "failed to make warmup change {} times", + hmr_warmup_dropped + )); + } + } + Ok(_) => { + hmr_warmup_iter += 1; + } + } + } + + Ok(guard) + }, + |mut guard, iters, m, verbose| { + let module_picker = Arc::clone(module_picker); + async move { + let mut value = m.zero(); + let mut dropped = 0; + let mut iter = 0; + while iter < iters { + let module = module_picker.pick(); + let duration = match make_change( + module, + bundler, + &mut guard, + location, + max_update_timeout, + &m, + ) + .await + { + Err(_) => { + // Some bundlers (e.g. Turbopack and Vite) can drop + // updates under certain conditions. We don't want + // to crash or stop the benchmark + // because of this. Instead, we keep going and + // report the number of dropped updates at the end. + dropped += 1; + continue; + } + Ok(duration) => duration, + }; + value = m.add(&value, &duration); + + iter += 1; + if verbose && iter != iters && iter.count_ones() == 1 { + eprint!( + " [{:?} {:?}/{}{}]", + duration, + FormatDuration(value / (iter as u32)), + iter, + if dropped > 0 { + format!(" ({} dropped)", dropped) + } else { + "".to_string() + } + ); + } + } + + Ok((guard, value)) + } + }, + |guard| async move { + let hmr_is_happening = guard + .page() + .evaluate_expression("globalThis.HMR_IS_HAPPENING") + .await + .unwrap(); + // Make sure that we are really measuring HMR and not accidentically + // full refreshing the page + assert!(hmr_is_happening.value().unwrap().as_bool().unwrap()); + }, + ); + }, + ); + })); + } + } +} + +fn insert_code( + path: &Path, + bundler: &dyn Bundler, + message: &str, + location: CodeLocation, +) -> Result Result<()>> { + let mut contents = fs::read_to_string(path)?; + + const PRAGMA_EVAL_START: &str = "/* @turbopack-bench:eval-start */"; + const PRAGMA_EVAL_END: &str = "/* @turbopack-bench:eval-end */"; + + let eval_start = contents + .find(PRAGMA_EVAL_START) + .ok_or_else(|| anyhow!("unable to find effect start pragma in {}", contents))?; + let eval_end = contents + .find(PRAGMA_EVAL_END) + .ok_or_else(|| anyhow!("unable to find effect end pragma in {}", contents))?; + + match (location, bundler.render_type()) { + (CodeLocation::Effect, _) => { + contents.replace_range( + eval_start + PRAGMA_EVAL_START.len()..eval_end, + &format!("\nEFFECT_PROPS.message = \"{message}\";\n"), + ); + } + ( + CodeLocation::Evaluation, + RenderType::ClientSideRendered | RenderType::ServerSidePrerendered, + ) => { + let code = format!( + "\nglobalThis.{BINDING_NAME} && globalThis.{BINDING_NAME}(\"{message}\");\n" + ); + contents.replace_range(eval_start + PRAGMA_EVAL_START.len()..eval_end, &code); + } + ( + CodeLocation::Evaluation, + RenderType::ServerSideRenderedWithEvents + | RenderType::ServerSideRenderedWithoutInteractivity, + ) => { + panic!("evaluation can't be measured for bundlers which evaluate on server side"); + } + } + + let path = path.to_owned(); + Ok(move || Ok(fs::write(&path, contents)?)) +} + +static CHANGE_TIMEOUT_MESSAGE: &str = "update was not registered by bundler"; + +async fn make_change<'a>( + module: &Path, + bundler: &dyn Bundler, + guard: &mut PageGuard<'a>, + location: CodeLocation, + timeout_duration: Duration, + measurement: &WallTime, +) -> Result { + static CHANGE_COUNTER: AtomicUsize = AtomicUsize::new(0); + + let msg = format!( + "TURBOPACK_BENCH_CHANGE_{}", + CHANGE_COUNTER.fetch_add(1, Ordering::Relaxed) + ); + + // Keep the IO out of the measurement. + let commit = insert_code(module, bundler, &msg, location)?; + + let start = measurement.start(); + + commit()?; + + // Wait for the change introduced above to be reflected at runtime. + // This expects HMR or automatic reloading to occur. + timeout(timeout_duration, guard.wait_for_binding(&msg)) + .await + .context(CHANGE_TIMEOUT_MESSAGE)??; + + let duration = measurement.end(start); + + if cfg!(target_os = "linux") { + // TODO(sokra) triggering HMR updates too fast can have weird effects on Linux + tokio::time::sleep(std::cmp::max(duration, Duration::from_millis(100))).await; + } + Ok(duration) +} + +pub fn bench_startup_cached(c: &mut Criterion, bundlers: &[Box]) { + let mut g = c.benchmark_group("bench_startup_cached"); + g.sample_size(10); + g.measurement_time(Duration::from_secs(60)); + + bench_startup_cached_internal(g, false, bundlers); +} + +pub fn bench_hydration_cached(c: &mut Criterion, bundlers: &[Box]) { + let mut g = c.benchmark_group("bench_hydration_cached"); + g.sample_size(10); + g.measurement_time(Duration::from_secs(60)); + + bench_startup_cached_internal(g, true, bundlers); +} + +fn bench_startup_cached_internal( + mut g: BenchmarkGroup, + hydration: bool, + bundlers: &[Box], +) { + if !read_env_bool("TURBOPACK_BENCH_CACHED") { + return; + } + + let runtime = Runtime::new().unwrap(); + let browser = Lazy::new(|| runtime.block_on(create_browser())); + + for bundler in bundlers { + let wait_for_hydration = match bundler.render_type() { + RenderType::ClientSideRendered => { + // For bundlers without server rendered html "startup" means time to hydration + // as they only render an empty screen without hydration. Since startup and + // hydration would be the same we skip the hydration benchmark for them. + if hydration { + continue; + } else { + true + } + } + RenderType::ServerSidePrerendered => hydration, + RenderType::ServerSideRenderedWithEvents => hydration, + RenderType::ServerSideRenderedWithoutInteractivity => { + // For bundlers without interactivity there is no hydration event to wait for + if hydration { + continue; + } else { + false + } + } + }; + for module_count in get_module_counts() { + let test_app = Lazy::new(|| build_test(module_count, bundler.as_ref())); + let input = (bundler.as_ref(), &test_app); + + resume_on_error(AssertUnwindSafe(|| { + g.bench_with_input( + BenchmarkId::new(bundler.get_name(), format!("{} modules", module_count)), + &input, + |b, &(bundler, test_app)| { + let test_app = &**test_app; + let browser = &*browser; + b.to_async(&runtime).try_iter_custom(|iters, m| async move { + // Run a complete build, shut down, and test running it again + let mut app = + PreparedApp::new(bundler, test_app.path().to_path_buf()).await?; + app.start_server()?; + let mut guard = app.with_page(browser).await?; + if bundler.has_hydration_event() { + guard.wait_for_hydration().await?; + } else { + guard.page().wait_for_navigation().await?; + } + + let mut app = guard.close_page().await?; + + // Give it 4 seconds time to store the cache + sleep(Duration::from_secs(4)).await; + + app.stop_server()?; + + let mut value = m.zero(); + for _ in 0..iters { + let start = m.start(); + app.start_server()?; + let mut guard = app.with_page(browser).await?; + if wait_for_hydration { + guard.wait_for_hydration().await?; + } + let duration = m.end(start); + value = m.add(&value, &duration); + + app = guard.close_page().await?; + app.stop_server()?; + } + + drop(app); + Ok(value) + }); + }, + ); + })); + } + } +} + +fn get_module_counts() -> Vec { + read_env_list("TURBOPACK_BENCH_COUNTS", vec![1_000usize]).unwrap() +} diff --git a/turbopack/crates/turbopack-bench/src/util/env.rs b/turbopack/crates/turbopack-bench/src/util/env.rs new file mode 100644 index 0000000000000..aa557c64cdf1c --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/util/env.rs @@ -0,0 +1,47 @@ +use std::{error::Error, str::FromStr}; + +use anyhow::{anyhow, Context, Result}; + +/// Reads an environment variable. +pub fn read_env(name: &str, default: T) -> Result +where + T: FromStr, + ::Err: Error + Send + Sync + 'static, +{ + let config = std::env::var(name).ok(); + match config.as_deref() { + None | Some("") => Ok(default), + Some(config) => config + .parse() + .with_context(|| anyhow!("Invalid value for {}", name)), + } +} + +/// Reads an boolean-like environment variable, where any value but "0", "no", +/// or "false" is are considered true. +pub fn read_env_bool(name: &str) -> bool { + let config = std::env::var(name).ok(); + !matches!( + config.as_deref(), + None | Some("") | Some("0") | Some("no") | Some("false") + ) +} + +/// Reads a comma-separated environment variable as a vector. +pub fn read_env_list(name: &str, default: Vec) -> Result> +where + T: FromStr, + ::Err: Error + Send + Sync + 'static, +{ + let config = std::env::var(name).ok(); + match config.as_deref() { + None | Some("") => Ok(default), + Some(config) => config + .split(',') + .map(|s| { + s.parse() + .with_context(|| anyhow!("Invalid value for {}", name)) + }) + .collect(), + } +} diff --git a/turbopack/crates/turbopack-bench/src/util/mod.rs b/turbopack/crates/turbopack-bench/src/util/mod.rs new file mode 100644 index 0000000000000..cf9b317a96b81 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/util/mod.rs @@ -0,0 +1,272 @@ +use std::{ + io::{ + BufRead, BufReader, Read, Write, {self}, + }, + panic::UnwindSafe, + process::Command, + time::{Duration, Instant}, +}; + +use anyhow::Result; +use chromiumoxide::{ + browser::{Browser, BrowserConfig}, + error::CdpError::Ws, +}; +use criterion::{async_executor::AsyncExecutor, black_box, measurement::WallTime, AsyncBencher}; +use futures::{Future, StreamExt}; +pub use page_guard::PageGuard; +use parking_lot::Mutex; +pub use prepared_app::PreparedApp; +use regex::Regex; +use tungstenite::{error::ProtocolError::ResetWithoutClosingHandshake, Error::Protocol}; +use turbo_tasks::util::FormatDuration; +use turbo_tasks_testing::retry::{retry, retry_async}; +use turbopack_create_test_app::test_app_builder::{ + EffectMode, PackageJsonConfig, TestApp, TestAppBuilder, +}; + +use self::env::read_env_bool; +use crate::bundlers::{Bundler, RenderType}; + +pub mod env; +pub mod module_picker; +pub mod npm; +mod page_guard; +mod prepared_app; + +pub const BINDING_NAME: &str = "__turbopackBenchBinding"; + +fn retry_default(args: A, f: F) -> Result +where + F: Fn(&mut A) -> Result, +{ + // waits 5, 10, 20, 40 seconds = 75 seconds total + retry(args, f, 3, Duration::from_secs(5)) +} + +async fn retry_async_default(args: A, f: F) -> Result +where + F: Fn(&mut A) -> Fut, + Fut: Future>, +{ + // waits 5, 10, 20, 40 seconds = 75 seconds total + retry_async(args, f, 3, Duration::from_secs(5)).await +} + +pub fn build_test(module_count: usize, bundler: &dyn Bundler) -> TestApp { + let test_app = TestAppBuilder { + module_count, + directories_count: module_count / 20, + package_json: Some(PackageJsonConfig { + react_version: bundler.react_version().to_string(), + }), + effect_mode: match bundler.render_type() { + RenderType::ServerSideRenderedWithEvents => EffectMode::Component, + _ => EffectMode::Hook, + }, + ..Default::default() + } + .build() + .unwrap(); + + let npm = command("npm") + .args(["install", "--loglevel=error"]) + .current_dir(test_app.path()) + .output() + .unwrap(); + + if !npm.status.success() { + io::stdout().write_all(&npm.stdout).unwrap(); + io::stderr().write_all(&npm.stderr).unwrap(); + panic!("npm install failed. See above."); + } + + retry_default((), |_| bundler.prepare(test_app.path())).unwrap(); + + test_app +} + +pub async fn create_browser() -> Browser { + let with_head = read_env_bool("TURBOPACK_BENCH_WITH_HEAD"); + let with_devtools = read_env_bool("TURBOPACK_BENCH_DEVTOOLS"); + let mut builder = BrowserConfig::builder(); + builder = builder.no_sandbox(); + if with_head { + builder = builder.with_head(); + } + if with_devtools { + builder = builder.arg("--auto-open-devtools-for-tabs"); + } + let (browser, mut handler) = retry_async( + builder.build().unwrap(), + |c| { + let c = c.clone(); + Browser::launch(c) + }, + 3, + Duration::from_millis(100), + ) + .await + .expect("Launching the browser failed"); + + // See https://crates.io/crates/chromiumoxide + tokio::task::spawn(async move { + loop { + if let Err(Ws(Protocol(ResetWithoutClosingHandshake))) = handler.next().await.unwrap() { + break; + } + } + }); + + browser +} + +pub fn resume_on_error(f: F) { + let runs_as_bench = std::env::args().find(|a| a == "--bench"); + let ignore_errors = read_env_bool("TURBOPACK_BENCH_IGNORE_ERRORS"); + + if runs_as_bench.is_some() || ignore_errors { + use std::panic::catch_unwind; + // panics are already printed to the console, so no need to handle the result. + let _ = catch_unwind(f); + } else { + f(); + } +} + +pub trait AsyncBencherExtension { + fn try_iter_custom(&mut self, routine: R) + where + R: Fn(u64, WallTime) -> F, + F: Future>; + + fn try_iter_async( + &mut self, + runner: A, + setup: S, + routine: R, + teardown: T, + ) where + S: Fn() -> SF, + SF: Future>, + R: Fn(I, u64, WallTime, bool) -> F, + F: Future>, + T: Fn(I) -> TF, + TF: Future; +} + +impl<'a, 'b, A: AsyncExecutor> AsyncBencherExtension for AsyncBencher<'a, 'b, A, WallTime> { + fn try_iter_custom(&mut self, routine: R) + where + R: Fn(u64, WallTime) -> F, + F: Future>, + { + let log_progress = read_env_bool("TURBOPACK_BENCH_PROGRESS"); + + let routine = &routine; + self.iter_custom(|iters| async move { + let measurement = WallTime; + let value = routine(iters, measurement).await.expect("routine failed"); + if log_progress { + eprint!(" {:?}/{}", FormatDuration(value / (iters as u32)), iters); + } + value + }); + } + + fn try_iter_async( + &mut self, + runner: A, + setup: S, + routine: R, + teardown: T, + ) where + S: Fn() -> SF, + SF: Future>, + R: Fn(I, u64, WallTime, bool) -> F, + F: Future>, + T: Fn(I) -> TF, + TF: Future, + { + let log_progress = read_env_bool("TURBOPACK_BENCH_PROGRESS"); + + let setup = &setup; + let routine = &routine; + let teardown = &teardown; + let input_mutex = &Mutex::new(Some(black_box(runner.block_on(async { + if log_progress { + eprint!(" setup..."); + } + let start = Instant::now(); + let input = retry_async_default((), |_| setup()) + .await + .expect("failed to setup"); + if log_progress { + let duration = start.elapsed(); + eprint!(" [{:?}]", FormatDuration(duration)); + } + input + })))); + + self.iter_custom(|iters| async move { + let measurement = WallTime; + + let input = input_mutex + .lock() + .take() + .expect("iter_custom only executes its closure once"); + + let (output, value) = routine(input, iters, measurement, log_progress) + .await + .expect("Routine failed"); + let output = black_box(output); + + if log_progress { + eprint!(" {:?}/{}", FormatDuration(value / (iters as u32)), iters); + } + + input_mutex.lock().replace(output); + + value + }); + + let input = input_mutex.lock().take().unwrap(); + if log_progress { + eprint!(" teardown..."); + } + let start = Instant::now(); + runner.block_on(teardown(input)); + let duration = start.elapsed(); + if log_progress { + eprintln!(" [{:?}]", FormatDuration(duration)); + } + } +} + +pub fn command(bin: &str) -> Command { + if cfg!(windows) { + let mut command = Command::new("cmd.exe"); + command.args(["/C", bin]); + command + } else { + Command::new(bin) + } +} + +pub fn wait_for_match(readable: R, re: Regex) -> Option +where + R: Read, +{ + // See https://docs.rs/async-process/latest/async_process/#examples + let mut line_reader = BufReader::new(readable).lines(); + // Read until the match appears in the buffer + let mut matched: Option = None; + while let Some(Ok(line)) = line_reader.next() { + if let Some(cap) = re.captures(&line) { + matched = Some(cap.get(1).unwrap().as_str().into()); + break; + } + } + + matched +} diff --git a/turbopack/crates/turbopack-bench/src/util/module_picker.rs b/turbopack/crates/turbopack-bench/src/util/module_picker.rs new file mode 100644 index 0000000000000..faaa1014026fa --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/util/module_picker.rs @@ -0,0 +1,46 @@ +use std::{collections::HashMap, path::PathBuf}; + +use rand::{rngs::StdRng, seq::SliceRandom, SeedableRng}; + +/// Picks modules at random, but with a fixed seed so runs are somewhat +/// reproducible. +/// +/// This must be initialized outside of `bench_with_input` so we don't repeat +/// the same sequence in different samples. +pub struct ModulePicker { + depths: Vec, + modules_by_depth: HashMap>, + rng: parking_lot::Mutex, +} + +impl ModulePicker { + /// Creates a new module picker. + pub fn new(mut modules: Vec<(PathBuf, usize)>) -> Self { + let rng = StdRng::seed_from_u64(42); + + // Ensure the module order is deterministic. + modules.sort(); + + let mut modules_by_depth: HashMap<_, Vec<_>> = HashMap::new(); + for (module, depth) in modules { + modules_by_depth.entry(depth).or_default().push(module); + } + let mut depths: Vec<_> = modules_by_depth.keys().copied().collect(); + // Ensure the depth order is deterministic. + depths.sort(); + + Self { + depths, + modules_by_depth, + rng: parking_lot::Mutex::new(rng), + } + } + + /// Picks a random module with a uniform distribution over all depths. + pub fn pick(&self) -> &PathBuf { + let mut rng = self.rng.lock(); + // Sample from all depths uniformly. + let depth = self.depths.choose(&mut *rng).unwrap(); + self.modules_by_depth[depth].choose(&mut *rng).unwrap() + } +} diff --git a/turbopack/crates/turbopack-bench/src/util/npm.rs b/turbopack/crates/turbopack-bench/src/util/npm.rs new file mode 100644 index 0000000000000..b6e37de3864f2 --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/util/npm.rs @@ -0,0 +1,76 @@ +use std::{ + fs::{ + File, {self}, + }, + io::{ + Write, {self}, + }, + path::Path, +}; + +use anyhow::{anyhow, Result}; +use serde_json::json; + +use crate::util::command; + +pub struct NpmPackage<'a> { + pub name: &'a str, + pub version: &'a str, +} + +impl<'a> NpmPackage<'a> { + pub fn new(name: &'a str, version: &'a str) -> Self { + NpmPackage { name, version } + } +} + +impl<'a> std::fmt::Display for NpmPackage<'a> { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + fmt.write_fmt(format_args!("{}@{}", self.name, self.version)) + } +} + +pub fn install(install_dir: &Path, packages: &[NpmPackage<'_>]) -> Result<()> { + if !fs::metadata(install_dir.join("package.json")) + .map(|metadata| metadata.is_file()) + .unwrap_or(false) + { + // Create a simple package.json if one doesn't exist + + let package_json = json!({ + "private": true, + "version": "0.0.0", + }); + + File::create(install_dir.join("package.json"))? + .write_all(format!("{:#}", package_json).as_bytes())?; + } + + let mut args = vec![ + "install".to_owned(), + "--force".to_owned(), + // install-links will copy local dependencies into the node_modules folder instead of + // symlinking, which fixes our root detection. + "--install-links".to_owned(), + "true".to_owned(), + ]; + args.append( + &mut packages + .iter() + .map(|p| p.to_string()) + .collect::>(), + ); + + let npm = command("npm") + .args(args) + .current_dir(install_dir) + .output()?; + + if !npm.status.success() { + io::stdout().write_all(&npm.stdout)?; + io::stderr().write_all(&npm.stderr)?; + return Err(anyhow!("npm install failed. See above.")); + } + + Ok(()) +} diff --git a/turbopack/crates/turbopack-bench/src/util/page_guard.rs b/turbopack/crates/turbopack-bench/src/util/page_guard.rs new file mode 100644 index 0000000000000..5848d9085780e --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/util/page_guard.rs @@ -0,0 +1,106 @@ +use std::{sync::Arc, time::Duration}; + +use anyhow::{anyhow, Context, Result}; +use chromiumoxide::{ + cdp::js_protocol::runtime::{EventBindingCalled, EventExceptionThrown}, + listeners::EventStream, + Page, +}; +use futures::{Stream, StreamExt}; +use tokio::time::timeout; + +use crate::{PreparedApp, BINDING_NAME}; + +const MAX_HYDRATION_TIMEOUT: Duration = Duration::from_secs(120); +const TEST_APP_HYDRATION_DONE: &str = "Hydration done"; + +/// Closes a browser page on Drop. +pub struct PageGuard<'a> { + page: Option, + app: Option>, + events: Box + Unpin>, +} + +enum Event { + EventBindingCalled(Arc), + EventExceptionThrown(Arc), +} + +impl<'a> PageGuard<'a> { + /// Creates a new guard for the given page. + pub fn new( + page: Page, + events: EventStream, + errors: EventStream, + app: PreparedApp<'a>, + ) -> Self { + Self { + page: Some(page), + app: Some(app), + events: Box::new(futures::stream::select( + events.map(Event::EventBindingCalled), + errors.map(Event::EventExceptionThrown), + )), + } + } + + /// Returns a reference to the page. + pub fn page(&self) -> &Page { + // Invariant: page is always Some while the guard is alive. + self.page.as_ref().unwrap() + } + + /// Closes the page, returns the app. + pub async fn close_page(mut self) -> Result> { + // Invariant: the page is always Some while the guard is alive. + self.page.take().unwrap().close().await?; + Ok( + // Invariant: the app is always Some while the guard is alive. + self.app.take().unwrap(), + ) + } + + /// Waits until the binding is called with the given payload. + pub async fn wait_for_binding(&mut self, payload: &str) -> Result<()> { + while let Some(event) = self.events.next().await { + match event { + Event::EventBindingCalled(event) => { + if event.name == BINDING_NAME && event.payload == payload { + return Ok(()); + } + } + Event::EventExceptionThrown(event) => { + return Err(anyhow!( + "Exception throw in page: {}", + event.exception_details + )); + } + } + } + + Err(anyhow!("event stream ended before binding was called")) + } + + /// Waits until the page and the page JavaScript is hydrated. + pub async fn wait_for_hydration(&mut self) -> Result<()> { + timeout( + MAX_HYDRATION_TIMEOUT, + self.wait_for_binding(TEST_APP_HYDRATION_DONE), + ) + .await + .context("Timeout happened while waiting for hydration")? + .context("Error happened while waiting for hydration")?; + Ok(()) + } +} + +impl<'a> Drop for PageGuard<'a> { + fn drop(&mut self) { + // The page might have been closed already in `close_page`. + if let Some(page) = self.page.take() { + // This is a way to block on a future in a destructor. It's not ideal, but for + // the purposes of this benchmark it's fine. + futures::executor::block_on(page.close()).expect("failed to close page"); + } + } +} diff --git a/turbopack/crates/turbopack-bench/src/util/prepared_app.rs b/turbopack/crates/turbopack-bench/src/util/prepared_app.rs new file mode 100644 index 0000000000000..23a73edf82d9e --- /dev/null +++ b/turbopack/crates/turbopack-bench/src/util/prepared_app.rs @@ -0,0 +1,241 @@ +use std::{ + future::Future, + path::{Path, PathBuf}, + pin::Pin, + process::Child, +}; + +use anyhow::{anyhow, Context, Result}; +use chromiumoxide::{ + cdp::{ + browser_protocol::network::EventResponseReceived, + js_protocol::runtime::{AddBindingParams, EventBindingCalled, EventExceptionThrown}, + }, + Browser, Page, +}; +use futures::{FutureExt, StreamExt}; +use tokio::task::spawn_blocking; +use url::Url; + +use crate::{bundlers::Bundler, util::PageGuard, BINDING_NAME}; + +fn copy_dir_boxed( + from: PathBuf, + to: PathBuf, +) -> Pin> + Sync + Send>> { + Box::pin(copy_dir(from, to)) +} + +async fn copy_dir(from: PathBuf, to: PathBuf) -> anyhow::Result<()> { + let dir = spawn_blocking(|| std::fs::read_dir(from)).await??; + let mut jobs = Vec::new(); + let mut file_futures = Vec::new(); + for entry in dir { + let entry = entry?; + let ty = entry.file_type()?; + let to = to.join(entry.file_name()); + if ty.is_dir() { + jobs.push(tokio::spawn(async move { + tokio::fs::create_dir(&to).await?; + copy_dir_boxed(entry.path(), to).await + })); + } else if ty.is_file() { + file_futures.push(async move { + tokio::fs::copy(entry.path(), to).await?; + Ok::<_, anyhow::Error>(()) + }); + } + } + + for future in file_futures { + jobs.push(tokio::spawn(future)); + } + + for job in jobs { + job.await??; + } + + Ok(()) +} + +enum PreparedDir { + TempDir(tempfile::TempDir), + Path(PathBuf), +} + +pub struct PreparedApp<'a> { + bundler: &'a dyn Bundler, + server: Option<(Child, String)>, + test_dir: PreparedDir, +} + +impl<'a> PreparedApp<'a> { + pub async fn new(bundler: &'a dyn Bundler, template_dir: PathBuf) -> Result> { + let test_dir = tempfile::tempdir()?; + + tokio::fs::create_dir_all(&test_dir).await?; + copy_dir(template_dir, test_dir.path().to_path_buf()).await?; + + Ok(Self { + bundler, + server: None, + test_dir: PreparedDir::TempDir(test_dir), + }) + } + + pub async fn new_without_copy( + bundler: &'a dyn Bundler, + template_dir: PathBuf, + ) -> Result> { + Ok(Self { + bundler, + server: None, + test_dir: PreparedDir::Path(template_dir), + }) + } + + pub fn start_server(&mut self) -> Result<()> { + assert!(self.server.is_none(), "Server already started"); + + self.server = Some(self.bundler.start_server(self.path())?); + + Ok(()) + } + + pub async fn with_page(self, browser: &Browser) -> Result> { + let server = self.server.as_ref().context("Server must be started")?; + let page = browser + .new_page("about:blank") + .await + .context("Unable to open about:blank")?; + // Bindings survive page reloads. Set them up as early as possible. + add_binding(&page) + .await + .context("Failed to add bindings to the browser tab")?; + + let mut errors = page + .event_listener::() + .await + .context("Unable to listen to exception events")?; + let binding_events = page + .event_listener::() + .await + .context("Unable to listen to binding events")?; + let mut network_response_events = page + .event_listener::() + .await + .context("Unable to listen to response received events")?; + + let destination = Url::parse(&server.1)?.join(self.bundler.get_path())?; + // We can't use page.goto() here since this will wait for the naviation to be + // completed. A naviation would be complete when all sync script are + // evaluated, but the page actually can rendered earlier without JavaScript + // needing to be evaluated. + // So instead we navigate via JavaScript and wait only for the HTML response to + // be completed. + page.evaluate_expression(format!("window.location='{destination}'")) + .await + .context("Unable to evaluate javascript to naviagate to target page")?; + + // Wait for HTML response completed + loop { + match network_response_events.next().await { + Some(event) => { + if event.response.url == destination.as_str() { + break; + } + } + None => return Err(anyhow!("event stream ended too early")), + } + } + + // Make sure no runtime errors occurred when loading the page + assert!(errors.next().now_or_never().is_none()); + + let page_guard = PageGuard::new(page, binding_events, errors, self); + + Ok(page_guard) + } + + pub fn stop_server(&mut self) -> Result<()> { + let mut proc = self.server.take().expect("Server never started").0; + stop_process(&mut proc)?; + Ok(()) + } + + pub fn path(&self) -> &Path { + match self.test_dir { + PreparedDir::TempDir(ref dir) => dir.path(), + PreparedDir::Path(ref path) => path, + } + } +} + +impl<'a> Drop for PreparedApp<'a> { + fn drop(&mut self) { + if let Some(mut server) = self.server.take() { + stop_process(&mut server.0).expect("failed to stop process"); + } + } +} + +/// Adds benchmark-specific bindings to the page. +async fn add_binding(page: &Page) -> Result<()> { + page.execute(AddBindingParams::new(BINDING_NAME)).await?; + Ok(()) +} + +#[cfg(unix)] +fn stop_process(proc: &mut Child) -> Result<()> { + use std::time::Duration; + + use nix::{ + sys::signal::{kill, Signal}, + unistd::Pid, + }; + use owo_colors::OwoColorize; + + const KILL_DEADLINE: Duration = Duration::from_secs(5); + const KILL_DEADLINE_CHECK_STEPS: u32 = 10; + + let pid = Pid::from_raw(proc.id() as _); + match kill(pid, Signal::SIGINT) { + Ok(()) => { + let expire = std::time::Instant::now() + KILL_DEADLINE; + while let Ok(None) = proc.try_wait() { + if std::time::Instant::now() > expire { + break; + } + std::thread::sleep(KILL_DEADLINE / KILL_DEADLINE_CHECK_STEPS); + } + if let Ok(None) = proc.try_wait() { + eprintln!( + "{event_type} - process {pid} did not exit after SIGINT, sending SIGKILL", + event_type = "error".red(), + pid = pid + ); + kill_process(proc)?; + } + } + Err(_) => { + eprintln!( + "{event_type} - failed to send SIGINT to process {pid}, sending SIGKILL", + event_type = "error".red(), + pid = pid + ); + kill_process(proc)?; + } + } + Ok(()) +} + +#[cfg(not(unix))] +fn stop_process(proc: &mut Child) -> Result<()> { + kill_process(proc) +} + +fn kill_process(proc: &mut Child) -> Result<()> { + proc.kill()?; + proc.wait()?; + Ok(()) +} diff --git a/turbopack/crates/turbopack-binding/Cargo.toml b/turbopack/crates/turbopack-binding/Cargo.toml new file mode 100644 index 0000000000000..d33e7b4d08c9a --- /dev/null +++ b/turbopack/crates/turbopack-binding/Cargo.toml @@ -0,0 +1,243 @@ +[package] +name = "turbopack-binding" +version = "0.1.0" +edition = "2021" +license = "MPL-2.0" +autobenches = false + +[lib] +bench = false + +[features] +__swc = [] +__swc_core = ["__swc"] +__swc_core_serde = ["swc_core/ecma_ast_serde"] +__swc_core_next_core = [ + "__swc_core", + "swc_core/common_concurrent", + "swc_core/ecma_ast", + "swc_core/ecma_visit", + "swc_core/ecma_loader_node", + "swc_core/ecma_loader_lru", + "swc_core/ecma_utils", + "swc_core/ecma_minifier", + "swc_core/ecma_preset_env", + "swc_core/ecma_transforms", + "swc_core/ecma_transforms_react", + "swc_core/ecma_transforms_typescript", + "swc_core/ecma_transforms_optimization", + "swc_core/ecma_parser", + "swc_core/ecma_parser_typescript", + "swc_core/cached", + "swc_core/base", +] + +__swc_core_binding_napi = [ + "__swc_core", + "swc_core/base_concurrent", + "swc_core/base_node", + "swc_core/common_concurrent", + "swc_core/ecma_ast", + "swc_core/ecma_loader_node", + "swc_core/ecma_loader_lru", + "swc_core/bundler", + "swc_core/bundler_concurrent", + "swc_core/ecma_codegen", + "swc_core/ecma_minifier", + "swc_core/ecma_parser", + "swc_core/ecma_parser_typescript", + "swc_core/ecma_transforms", + "swc_core/ecma_transforms_optimization", + "swc_core/ecma_transforms_react", + "swc_core/ecma_transforms_typescript", + "swc_core/ecma_utils", + "swc_core/ecma_visit", +] +__swc_core_binding_napi_plugin = [ + "swc_core/plugin_transform_host_native", + "turbopack-ecmascript-plugins/swc_ecma_transform_plugin", +] +__swc_core_binding_napi_plugin_filesystem_cache = [ + "swc_core/plugin_transform_host_native_filesystem_cache", +] +__swc_core_binding_napi_plugin_shared_runtime = [ + "swc_core/plugin_transform_host_native_shared_runtime", +] +__swc_core_binding_napi_allocator = ["swc_core/allocator_node"] + +__swc_core_binding_wasm = [ + "__swc_core", + "swc_core/common_concurrent", + "swc_core/binding_macro_wasm", + "swc_core/ecma_codegen", + "swc_core/ecma_minifier", + "swc_core/ecma_transforms", + "swc_core/ecma_transforms_typescript", + "swc_core/ecma_transforms_optimization", + "swc_core/ecma_transforms_react", + "swc_core/ecma_parser", + "swc_core/ecma_parser_typescript", + "swc_core/ecma_utils", + "swc_core/ecma_visit", +] +__swc_core_binding_wasm_plugin = ["swc_core/plugin_transform_host_js"] + +__swc_core_testing_transform = ["swc_core/testing_transform"] + +__turbo = [] +__turbo_tasks_malloc = ["__turbo", "turbo-tasks-malloc"] +__turbo_tasks_malloc_custom_allocator = ["turbo-tasks-malloc/custom_allocator"] +__turbo_tasks = ["__turbo", "turbo-tasks"] +__turbo_tasks_tokio_tracing = ["turbo-tasks/tokio_tracing"] +__turbo_tasks_build = ["__turbo", "turbo-tasks-build"] +__turbo_tasks_bytes = ["__turbo", "turbo-tasks-bytes"] +__turbo_tasks_env = ["__turbo", "turbo-tasks-env"] +__turbo_tasks_fetch = ["__turbo", "turbo-tasks-fetch"] +__turbo_tasks_fetch_native-tls = ["__turbo", "turbo-tasks-fetch/native-tls"] +__turbo_tasks_fetch_rustls-tls = ["__turbo", "turbo-tasks-fetch/rustls-tls"] +__turbo_tasks_fs = ["__turbo", "turbo-tasks-fs"] +__turbo_tasks_fs_dynamic_embed_contents = [ + "turbo-tasks-fs/dynamic_embed_contents", +] +__turbo_tasks_hash = ["__turbo", "turbo-tasks-hash"] +__turbo_tasks_macros = ["__turbo", "turbo-tasks-macros"] +__turbo_tasks_macros_shared = ["__turbo", "turbo-tasks-macros-shared"] +__turbo_tasks_memory = ["__turbo", "turbo-tasks-memory"] +__turbo_tasks_memory_print_task_invalidation = [ + "__turbo_tasks_memory", + "turbo-tasks-memory/print_task_invalidation", +] +__turbo_tasks_testing = ["__turbo", "turbo-tasks-testing"] +__turbo_updater = ["__turbo", "turbo-updater"] + +__turbopack = ["turbopack"] +__turbopack_bench = ["__turbopack", "turbopack-bench"] +__turbopack_nodejs = ["__turbopack", "turbopack-nodejs"] +__turbopack_nodejs_dynamic_embed_contents = [ + "turbopack-nodejs/dynamic_embed_contents", +] +__turbopack_cli_utils = ["__turbopack", "turbopack-cli-utils"] +__turbopack_core = ["__turbopack", "turbopack-core"] +__turbopack_core_issue_path = ["turbopack-core/issue_path"] +__turbopack_create_test_app = ["__turbopack", "turbopack-create-test-app"] +__turbopack_css = ["__turbopack", "turbopack-css"] +__turbopack_browser = ["__turbopack", "turbopack-browser"] +__turbopack_browser_dynamic_embed_contents = [ + "turbopack-browser/dynamic_embed_contents", +] +__turbopack_dev_server = ["__turbopack", "turbopack-dev-server"] +__turbopack_ecmascript = ["__turbopack", "turbopack-ecmascript"] +# [Note]: currently all of the transform features are enabled by default +__turbopack_ecmascript_plugin = [ + "__turbopack", + "turbopack-ecmascript-plugins", + "turbopack-ecmascript-plugins/transform_emotion", +] +__turbopack_ecmascript_runtime = ["__turbopack", "turbopack-ecmascript-runtime"] +__turbopack_ecmascript_hmr_protocol = [ + "__turbopack", + "turbopack-ecmascript-hmr-protocol", +] +__turbopack_trace_utils = ["__turbopack", "turbopack-trace-utils"] +__turbopack_trace_server = ["__turbopack", "turbopack-trace-server"] + +__turbopack_env = ["__turbopack", "turbopack-env"] +__turbopack_image = ["__turbopack", "turbopack-image"] +__turbopack_image_avif = ["turbopack-image/avif"] +__turbopack_image_webp = ["turbopack-image/webp"] +__turbopack_json = ["__turbopack", "turbopack-json"] +__turbopack_mdx = ["__turbopack", "turbopack-mdx"] +__turbopack_node = ["__turbopack", "turbopack-node"] +__turbopack_node_dynamic_embed_contents = [ + "turbopack-node/dynamic_embed_contents", +] +__turbopack_static = ["__turbopack", "turbopack-static"] +__turbopack_swc_utils = ["__turbopack", "turbopack-swc-utils"] +__turbopack_tests = [] +__turbopack_test_utils = ["__turbopack", "turbopack-test-utils"] + +__features = [] +__feature_mdx_rs = ["__features", "mdxjs/serializable"] +__feature_node_file_trace = ["__features", "node-file-trace/node-api"] +__feature_node_file_trace_cli = ["node-file-trace/cli"] +__feature_node_file_trace_custom_allocator = [ + "node-file-trace/custom_allocator", +] +__feature_auto_hash_map = ["__features", "auto-hash-map"] +__feature_swc_ast_explorer = [] +__feature_tracing_signpost = ["__features", "tracing-signpost"] + +__swc_custom_transform = [] +__swc_transform_styled_components = [ + "__swc", + "__swc_custom_transform", + "styled_components", +] +__swc_transform_styled_jsx = [ + "__swc", + "__swc_custom_transform", + "swc_core/ecma_preset_env", + "styled_jsx", +] +__swc_transform_emotion = ["__swc", "__swc_custom_transform", "swc_emotion"] +__swc_transform_relay = ["__swc", "__swc_custom_transform", "swc_relay"] +__swc_transform_modularize_imports = [ + "__swc", + "__swc_custom_transform", + "modularize_imports", +] +__swc_testing = ["__swc", "testing"] + +[lints] +workspace = true + +[dependencies] +mdxjs = { optional = true, workspace = true } +modularize_imports = { optional = true, workspace = true } +styled_components = { optional = true, workspace = true } +styled_jsx = { optional = true, workspace = true } +swc_core = { optional = true, workspace = true } +swc_emotion = { optional = true, workspace = true } +swc_relay = { optional = true, workspace = true } +testing = { optional = true, workspace = true } + +auto-hash-map = { optional = true, workspace = true } +tracing-signpost = { optional = true, workspace = true } + +node-file-trace = { optional = true, workspace = true } +turbo-tasks = { optional = true, workspace = true } +turbo-tasks-build = { optional = true, workspace = true } +turbo-tasks-bytes = { optional = true, workspace = true } +turbo-tasks-env = { optional = true, workspace = true } +turbo-tasks-fetch = { optional = true, workspace = true } +turbo-tasks-fs = { optional = true, workspace = true } +turbo-tasks-hash = { optional = true, workspace = true } +turbo-tasks-macros = { optional = true, workspace = true } +turbo-tasks-macros-shared = { optional = true, workspace = true } +turbo-tasks-malloc = { optional = true, workspace = true, default-features = false } +turbo-tasks-memory = { optional = true, workspace = true } +turbo-tasks-testing = { optional = true, workspace = true } +turbo-updater = { optional = true, workspace = true } +turbopack = { optional = true, workspace = true } +turbopack-bench = { optional = true, workspace = true } +turbopack-browser = { optional = true, workspace = true } +turbopack-cli-utils = { optional = true, workspace = true } +turbopack-core = { optional = true, workspace = true } +turbopack-create-test-app = { optional = true, workspace = true } +turbopack-css = { optional = true, workspace = true } +turbopack-dev-server = { optional = true, workspace = true } +turbopack-ecmascript = { optional = true, workspace = true } +turbopack-ecmascript-hmr-protocol = { optional = true, workspace = true } +turbopack-ecmascript-plugins = { optional = true, workspace = true, default-features = false } +turbopack-ecmascript-runtime = { optional = true, workspace = true } +turbopack-env = { optional = true, workspace = true } +turbopack-image = { optional = true, workspace = true } +turbopack-json = { optional = true, workspace = true } +turbopack-mdx = { optional = true, workspace = true } +turbopack-node = { optional = true, workspace = true } +turbopack-nodejs = { optional = true, workspace = true } +turbopack-static = { optional = true, workspace = true } +turbopack-swc-utils = { optional = true, workspace = true } +turbopack-test-utils = { optional = true, workspace = true } +turbopack-trace-server = { optional = true, workspace = true } +turbopack-trace-utils = { optional = true, workspace = true } diff --git a/turbopack/crates/turbopack-binding/README.md b/turbopack/crates/turbopack-binding/README.md new file mode 100644 index 0000000000000..f88c8f7399030 --- /dev/null +++ b/turbopack/crates/turbopack-binding/README.md @@ -0,0 +1,5 @@ +### turbopack-binding + +Currently this is an internal package, does not provide any public interface or stability guarantees yet. Do not use it unless you are sure. + +Package name is also TBD, subject to change. diff --git a/turbopack/crates/turbopack-binding/src/lib.rs b/turbopack/crates/turbopack-binding/src/lib.rs new file mode 100644 index 0000000000000..4dd28f7467de2 --- /dev/null +++ b/turbopack/crates/turbopack-binding/src/lib.rs @@ -0,0 +1,117 @@ +#[cfg(feature = "__swc")] +pub mod swc { + #[cfg(feature = "__swc_core")] + pub use swc_core as core; + + #[cfg(feature = "__swc_custom_transform")] + pub mod custom_transform { + #[cfg(feature = "__swc_transform_modularize_imports")] + pub use modularize_imports; + #[cfg(feature = "__swc_transform_styled_components")] + pub use styled_components; + #[cfg(feature = "__swc_transform_styled_jsx")] + pub use styled_jsx; + #[cfg(feature = "__swc_transform_emotion")] + pub use swc_emotion as emotion; + #[cfg(feature = "__swc_transform_relay")] + pub use swc_relay as relay; + } + + #[cfg(feature = "testing")] + pub use testing; +} + +#[cfg(feature = "__turbo")] +pub mod turbo { + #[cfg(feature = "__turbo_tasks")] + pub use turbo_tasks as tasks; + #[cfg(feature = "__turbo_tasks_build")] + pub use turbo_tasks_build as tasks_build; + #[cfg(feature = "__turbo_tasks_bytes")] + pub use turbo_tasks_bytes as tasks_bytes; + #[cfg(feature = "__turbo_tasks_env")] + pub use turbo_tasks_env as tasks_env; + #[cfg(feature = "__turbo_tasks_fetch")] + pub use turbo_tasks_fetch as tasks_fetch; + #[cfg(feature = "__turbo_tasks_fs")] + pub use turbo_tasks_fs as tasks_fs; + #[cfg(feature = "__turbo_tasks_hash")] + pub use turbo_tasks_hash as tasks_hash; + #[cfg(feature = "__turbo_tasks_macros")] + pub use turbo_tasks_macros as tasks_macros; + #[cfg(feature = "__turbo_tasks_macros_shared")] + pub use turbo_tasks_macros_shared as tasks_macros_shared; + #[cfg(feature = "__turbo_tasks_malloc")] + pub use turbo_tasks_malloc as malloc; + #[cfg(feature = "__turbo_tasks_memory")] + pub use turbo_tasks_memory as tasks_memory; + #[cfg(feature = "__turbo_tasks_testing")] + pub use turbo_tasks_testing as tasks_testing; + #[cfg(feature = "__turbo_updater")] + pub use turbo_updater as updater; +} + +#[cfg(feature = "__turbopack")] +pub mod turbopack { + pub use turbopack; + #[cfg(feature = "__turbopack_bench")] + pub use turbopack_bench as bench; + #[cfg(feature = "__turbopack_browser")] + pub use turbopack_browser as browser; + #[cfg(feature = "__turbopack_cli_utils")] + pub use turbopack_cli_utils as cli_utils; + #[cfg(feature = "__turbopack_core")] + pub use turbopack_core as core; + #[cfg(feature = "__turbopack_create_test_app")] + pub use turbopack_create_test_app as create_test_app; + #[cfg(feature = "__turbopack_css")] + pub use turbopack_css as css; + #[cfg(feature = "__turbopack_dev_server")] + pub use turbopack_dev_server as dev_server; + #[cfg(feature = "__turbopack_ecmascript")] + pub use turbopack_ecmascript as ecmascript; + #[cfg(feature = "__turbopack_ecmascript_hmr_protocol")] + pub use turbopack_ecmascript_hmr_protocol as ecmascript_hmr_protocol; + #[cfg(feature = "__turbopack_ecmascript_plugin")] + pub use turbopack_ecmascript_plugins as ecmascript_plugin; + #[cfg(feature = "__turbopack_ecmascript_runtime")] + pub use turbopack_ecmascript_runtime as ecmascript_runtime; + #[cfg(feature = "__turbopack_env")] + pub use turbopack_env as env; + #[cfg(feature = "__turbopack_image")] + pub use turbopack_image as image; + #[cfg(feature = "__turbopack_json")] + pub use turbopack_json as json; + #[cfg(feature = "__turbopack_mdx")] + pub use turbopack_mdx as mdx; + #[cfg(feature = "__turbopack_node")] + pub use turbopack_node as node; + #[cfg(feature = "__turbopack_nodejs")] + pub use turbopack_nodejs as nodejs; + #[cfg(feature = "__turbopack_static")] + pub use turbopack_static as r#static; + #[cfg(feature = "__turbopack_swc_utils")] + pub use turbopack_swc_utils as swc_utils; + #[cfg(feature = "__turbopack_test_utils")] + pub use turbopack_test_utils as test_utils; + #[cfg(feature = "__turbopack_tests")] + pub use turbopack_tests as tests; + #[cfg(feature = "__turbopack_trace_server")] + pub use turbopack_trace_server as trace_server; + #[cfg(feature = "__turbopack_trace_utils")] + pub use turbopack_trace_utils as trace_utils; +} + +#[cfg(feature = "__features")] +pub mod features { + #[cfg(feature = "__feature_auto_hash_map")] + pub use auto_hash_map; + #[cfg(feature = "__feature_mdx_rs")] + pub use mdxjs; + #[cfg(feature = "__feature_node_file_trace")] + pub use node_file_trace; + #[cfg(feature = "__feature_swc_ast_explorer")] + pub use swc_ast_explorer; + #[cfg(feature = "__feature_tracing_signpost")] + pub use tracing_signpost; +} diff --git a/turbopack/crates/turbopack-browser/Cargo.toml b/turbopack/crates/turbopack-browser/Cargo.toml new file mode 100644 index 0000000000000..6bdbf326f71f4 --- /dev/null +++ b/turbopack/crates/turbopack-browser/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "turbopack-browser" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[features] +# enable "HMR" for embedded assets +dynamic_embed_contents = ["turbo-tasks-fs/dynamic_embed_contents"] +# enable test utilities such as `RuntimeType::Dummy` +test = ["turbopack-ecmascript-runtime/test"] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +indexmap = { workspace = true } +indoc = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +serde_qs = { workspace = true } +tracing = { workspace = true } +urlencoding = { workspace = true } + +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-hash = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } +turbopack-ecmascript-runtime = { workspace = true } +turbopack-resolve = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-browser/build.rs b/turbopack/crates/turbopack-browser/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-browser/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-browser/src/chunking_context.rs b/turbopack/crates/turbopack-browser/src/chunking_context.rs new file mode 100644 index 0000000000000..616a30e01590c --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/chunking_context.rs @@ -0,0 +1,512 @@ +use anyhow::{bail, Context, Result}; +use tracing::Instrument; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + chunk::{ + availability_info::AvailabilityInfo, + chunk_group::{make_chunk_group, MakeChunkGroupResult}, + Chunk, ChunkGroupResult, ChunkItem, ChunkableModule, ChunkingContext, + EntryChunkGroupResult, EvaluatableAssets, MinifyType, ModuleId, + }, + environment::Environment, + ident::AssetIdent, + module::Module, + output::{OutputAsset, OutputAssets}, +}; +use turbopack_ecmascript::{ + async_chunk::module::AsyncLoaderModule, + chunk::EcmascriptChunk, + manifest::{chunk_asset::ManifestAsyncModule, loader_item::ManifestLoaderChunkItem}, +}; +use turbopack_ecmascript_runtime::RuntimeType; + +use crate::ecmascript::{ + chunk::EcmascriptDevChunk, + evaluate::chunk::EcmascriptDevEvaluateChunk, + list::asset::{EcmascriptDevChunkList, EcmascriptDevChunkListSource}, +}; + +pub struct BrowserChunkingContextBuilder { + chunking_context: BrowserChunkingContext, +} + +impl BrowserChunkingContextBuilder { + pub fn name(mut self, name: RcStr) -> Self { + self.chunking_context.name = Some(name); + self + } + + pub fn hot_module_replacement(mut self) -> Self { + self.chunking_context.enable_hot_module_replacement = true; + self + } + + pub fn asset_base_path(mut self, asset_base_path: Vc>) -> Self { + self.chunking_context.asset_base_path = asset_base_path; + self + } + + pub fn chunk_base_path(mut self, chunk_base_path: Vc>) -> Self { + self.chunking_context.chunk_base_path = chunk_base_path; + self + } + + pub fn reference_chunk_source_maps(mut self, source_maps: bool) -> Self { + self.chunking_context.reference_chunk_source_maps = source_maps; + self + } + + pub fn reference_css_chunk_source_maps(mut self, source_maps: bool) -> Self { + self.chunking_context.reference_css_chunk_source_maps = source_maps; + self + } + + pub fn runtime_type(mut self, runtime_type: RuntimeType) -> Self { + self.chunking_context.runtime_type = runtime_type; + self + } + + pub fn manifest_chunks(mut self, manifest_chunks: bool) -> Self { + self.chunking_context.manifest_chunks = manifest_chunks; + self + } + + pub fn minify_type(mut self, minify_type: MinifyType) -> Self { + self.chunking_context.minify_type = minify_type; + self + } + + pub fn build(self) -> Vc { + BrowserChunkingContext::new(Value::new(self.chunking_context)) + } +} + +/// A chunking context for development mode. +/// It uses readable filenames and module ids to improve development. +/// It also uses a chunking heuristic that is incremental and cacheable. +/// It splits "node_modules" separately as these are less likely to change +/// during development +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Debug, Clone, Hash)] +pub struct BrowserChunkingContext { + name: Option, + /// This path get stripped off of chunk paths before generating output asset + /// paths. + context_path: Vc, + /// This path is used to compute the url to request chunks from + output_root: Vc, + /// This path is used to compute the url to request assets from + client_root: Vc, + /// Chunks are placed at this path + chunk_root_path: Vc, + /// Chunks reference source maps assets + reference_chunk_source_maps: bool, + /// Css chunks reference source maps assets + reference_css_chunk_source_maps: bool, + /// Static assets are placed at this path + asset_root_path: Vc, + /// Base path that will be prepended to all chunk URLs when loading them. + /// This path will not appear in chunk paths or chunk data. + chunk_base_path: Vc>, + /// URL prefix that will be prepended to all static asset URLs when loading + /// them. + asset_base_path: Vc>, + /// Enable HMR for this chunking + enable_hot_module_replacement: bool, + /// The environment chunks will be evaluated in. + environment: Vc, + /// The kind of runtime to include in the output. + runtime_type: RuntimeType, + /// Whether to minify resulting chunks + minify_type: MinifyType, + /// Whether to use manifest chunks for lazy compilation + manifest_chunks: bool, +} + +impl BrowserChunkingContext { + pub fn builder( + context_path: Vc, + output_root: Vc, + client_root: Vc, + chunk_root_path: Vc, + asset_root_path: Vc, + environment: Vc, + runtime_type: RuntimeType, + ) -> BrowserChunkingContextBuilder { + BrowserChunkingContextBuilder { + chunking_context: BrowserChunkingContext { + name: None, + context_path, + output_root, + client_root, + chunk_root_path, + reference_chunk_source_maps: true, + reference_css_chunk_source_maps: true, + asset_root_path, + chunk_base_path: Default::default(), + asset_base_path: Default::default(), + enable_hot_module_replacement: false, + environment, + runtime_type, + minify_type: MinifyType::NoMinify, + manifest_chunks: false, + }, + } + } +} + +impl BrowserChunkingContext { + /// Returns the kind of runtime to include in output chunks. + /// + /// This is defined directly on `BrowserChunkingContext` so it is zero-cost + /// when `RuntimeType` has a single variant. + pub fn runtime_type(&self) -> RuntimeType { + self.runtime_type + } + + /// Returns the asset base path. + pub fn chunk_base_path(&self) -> Vc> { + self.chunk_base_path + } + + /// Returns the minify type. + pub fn minify_type(&self) -> MinifyType { + self.minify_type + } +} + +#[turbo_tasks::value_impl] +impl BrowserChunkingContext { + #[turbo_tasks::function] + fn new(this: Value) -> Vc { + this.into_value().cell() + } + + #[turbo_tasks::function] + fn generate_evaluate_chunk( + self: Vc, + ident: Vc, + other_chunks: Vc, + evaluatable_assets: Vc, + ) -> Vc> { + Vc::upcast(EcmascriptDevEvaluateChunk::new( + self, + ident, + other_chunks, + evaluatable_assets, + )) + } + + #[turbo_tasks::function] + fn generate_chunk_list_register_chunk( + self: Vc, + ident: Vc, + evaluatable_assets: Vc, + other_chunks: Vc, + source: Value, + ) -> Vc> { + Vc::upcast(EcmascriptDevChunkList::new( + self, + ident, + evaluatable_assets, + other_chunks, + source, + )) + } + + #[turbo_tasks::function] + async fn generate_chunk( + self: Vc, + chunk: Vc>, + ) -> Result>> { + Ok( + if let Some(ecmascript_chunk) = + Vc::try_resolve_downcast_type::(chunk).await? + { + Vc::upcast(EcmascriptDevChunk::new(self, ecmascript_chunk)) + } else if let Some(output_asset) = + Vc::try_resolve_sidecast::>(chunk).await? + { + output_asset + } else { + bail!("Unable to generate output asset for chunk"); + }, + ) + } +} + +#[turbo_tasks::value_impl] +impl ChunkingContext for BrowserChunkingContext { + #[turbo_tasks::function] + fn name(&self) -> Vc { + if let Some(name) = &self.name { + Vc::cell(name.clone()) + } else { + Vc::cell("unknown".into()) + } + } + + #[turbo_tasks::function] + fn context_path(&self) -> Vc { + self.context_path + } + + #[turbo_tasks::function] + fn output_root(&self) -> Vc { + self.output_root + } + + #[turbo_tasks::function] + fn environment(&self) -> Vc { + self.environment + } + + #[turbo_tasks::function] + async fn chunk_path( + &self, + ident: Vc, + extension: RcStr, + ) -> Result> { + let root_path = self.chunk_root_path; + let name = ident.output_name(self.context_path, extension).await?; + Ok(root_path.join(name.clone_value())) + } + + #[turbo_tasks::function] + async fn asset_url(self: Vc, ident: Vc) -> Result> { + let this = self.await?; + let asset_path = ident.path().await?.to_string(); + let asset_path = asset_path + .strip_prefix(&format!("{}/", this.client_root.await?.path)) + .context("expected asset_path to contain client_root")?; + + Ok(Vc::cell( + format!( + "{}{}", + this.asset_base_path + .await? + .as_ref() + .map(|s| s.as_str()) + .unwrap_or("/"), + asset_path + ) + .into(), + )) + } + + #[turbo_tasks::function] + async fn reference_chunk_source_maps( + &self, + chunk: Vc>, + ) -> Result> { + let mut source_maps = self.reference_chunk_source_maps; + let path = chunk.ident().path().await?; + let extension = path.extension_ref().unwrap_or_default(); + #[allow(clippy::single_match, reason = "future extensions")] + match extension { + ".css" => { + source_maps = self.reference_css_chunk_source_maps; + } + _ => {} + } + Ok(Vc::cell(source_maps)) + } + + #[turbo_tasks::function] + async fn asset_path( + &self, + content_hash: RcStr, + original_asset_ident: Vc, + ) -> Result> { + let source_path = original_asset_ident.path().await?; + let basename = source_path.file_name(); + let asset_path = match source_path.extension_ref() { + Some(ext) => format!( + "{basename}.{content_hash}.{ext}", + basename = &basename[..basename.len() - ext.len() - 1], + content_hash = &content_hash[..8] + ), + None => format!( + "{basename}.{content_hash}", + content_hash = &content_hash[..8] + ), + }; + Ok(self.asset_root_path.join(asset_path.into())) + } + + #[turbo_tasks::function] + fn is_hot_module_replacement_enabled(&self) -> Vc { + Vc::cell(self.enable_hot_module_replacement) + } + + #[turbo_tasks::function] + async fn chunk_group( + self: Vc, + module: Vc>, + availability_info: Value, + ) -> Result> { + let span = tracing::info_span!( + "chunking", + module = module.ident().to_string().await?.to_string() + ); + async move { + let this = self.await?; + let input_availability_info = availability_info.into_value(); + let MakeChunkGroupResult { + chunks, + availability_info, + } = make_chunk_group( + Vc::upcast(self), + [Vc::upcast(module)], + input_availability_info, + ) + .await?; + + let mut assets: Vec>> = chunks + .iter() + .map(|chunk| self.generate_chunk(*chunk)) + .collect(); + + if this.enable_hot_module_replacement { + let mut ident = module.ident(); + match input_availability_info { + AvailabilityInfo::Root => {} + AvailabilityInfo::Untracked => { + ident = ident.with_modifier(Vc::cell("untracked".into())); + } + AvailabilityInfo::Complete { + available_chunk_items, + } => { + ident = ident.with_modifier(Vc::cell( + available_chunk_items.hash().await?.to_string().into(), + )); + } + } + assets.push(self.generate_chunk_list_register_chunk( + ident, + EvaluatableAssets::empty(), + Vc::cell(assets.clone()), + Value::new(EcmascriptDevChunkListSource::Dynamic), + )); + } + + // Resolve assets + for asset in assets.iter_mut() { + *asset = asset.resolve().await?; + } + + Ok(ChunkGroupResult { + assets: Vc::cell(assets), + availability_info, + } + .cell()) + } + .instrument(span) + .await + } + + #[turbo_tasks::function] + async fn evaluated_chunk_group( + self: Vc, + ident: Vc, + evaluatable_assets: Vc, + availability_info: Value, + ) -> Result> { + let span = { + let ident = ident.to_string().await?.to_string(); + tracing::info_span!("chunking", chunking_type = "evaluated", ident = ident) + }; + async move { + let this = self.await?; + let availability_info = availability_info.into_value(); + + let evaluatable_assets_ref = evaluatable_assets.await?; + + // TODO this collect is unnecessary, but it hits a compiler bug when it's not + // used + let entries = evaluatable_assets_ref + .iter() + .map(|&evaluatable| Vc::upcast(evaluatable)) + .collect::>(); + + let MakeChunkGroupResult { + chunks, + availability_info, + } = make_chunk_group(Vc::upcast(self), entries, availability_info).await?; + + let mut assets: Vec>> = chunks + .iter() + .map(|chunk| self.generate_chunk(*chunk)) + .collect(); + + let other_assets = Vc::cell(assets.clone()); + + if this.enable_hot_module_replacement { + assets.push(self.generate_chunk_list_register_chunk( + ident, + evaluatable_assets, + other_assets, + Value::new(EcmascriptDevChunkListSource::Entry), + )); + } + + assets.push(self.generate_evaluate_chunk(ident, other_assets, evaluatable_assets)); + + // Resolve assets + for asset in assets.iter_mut() { + *asset = asset.resolve().await?; + } + + Ok(ChunkGroupResult { + assets: Vc::cell(assets), + availability_info, + } + .cell()) + } + .instrument(span) + .await + } + + #[turbo_tasks::function] + fn entry_chunk_group( + self: Vc, + _path: Vc, + _module: Vc>, + _evaluatable_assets: Vc, + _availability_info: Value, + ) -> Result> { + bail!("Browser chunking context does not support entry chunk groups") + } + + #[turbo_tasks::function] + async fn async_loader_chunk_item( + self: Vc, + module: Vc>, + availability_info: Value, + ) -> Result>> { + Ok(if self.await?.manifest_chunks { + let manifest_asset = + ManifestAsyncModule::new(module, Vc::upcast(self), availability_info); + Vc::upcast(ManifestLoaderChunkItem::new( + manifest_asset, + Vc::upcast(self), + )) + } else { + let module = AsyncLoaderModule::new(module, Vc::upcast(self), availability_info); + Vc::upcast(module.as_chunk_item(Vc::upcast(self))) + }) + } + + #[turbo_tasks::function] + async fn async_loader_chunk_item_id( + self: Vc, + module: Vc>, + ) -> Result> { + Ok(if self.await?.manifest_chunks { + self.chunk_item_id_from_ident(ManifestLoaderChunkItem::asset_ident_for(module)) + } else { + self.chunk_item_id_from_ident(AsyncLoaderModule::asset_ident_for(module)) + }) + } +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/chunk.rs b/turbopack/crates/turbopack-browser/src/ecmascript/chunk.rs new file mode 100644 index 0000000000000..7e6c651b8cbd7 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/chunk.rs @@ -0,0 +1,169 @@ +use anyhow::Result; +use indexmap::IndexSet; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{Chunk, ChunkingContext, OutputChunk, OutputChunkRuntimeInfo}, + ident::AssetIdent, + introspect::{Introspectable, IntrospectableChildren}, + output::{OutputAsset, OutputAssets}, + source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset}, + version::VersionedContent, +}; +use turbopack_ecmascript::chunk::EcmascriptChunk; + +use crate::{ecmascript::content::EcmascriptDevChunkContent, BrowserChunkingContext}; + +/// Development Ecmascript chunk. +#[turbo_tasks::value(shared)] +pub(crate) struct EcmascriptDevChunk { + chunking_context: Vc, + chunk: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunk { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new( + chunking_context: Vc, + chunk: Vc, + ) -> Vc { + EcmascriptDevChunk { + chunking_context, + chunk, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptDevChunk { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("Ecmascript Dev Chunk".into())) + } +} + +#[turbo_tasks::value_impl] +impl OutputChunk for EcmascriptDevChunk { + #[turbo_tasks::function] + fn runtime_info(&self) -> Vc { + OutputChunkRuntimeInfo { + included_ids: Some(self.chunk.entry_ids()), + ..Default::default() + } + .cell() + } +} + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("ecmascript dev chunk".into()) +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunk { + #[turbo_tasks::function] + async fn own_content(self: Vc) -> Result> { + let this = self.await?; + Ok(EcmascriptDevChunkContent::new( + this.chunking_context, + self, + this.chunk.chunk_content(), + )) + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptDevChunk { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + let ident = self.chunk.ident().with_modifier(modifier()); + AssetIdent::from_path(self.chunking_context.chunk_path(ident, ".js".into())) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let chunk_references = this.chunk.references().await?; + let include_source_map = *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await?; + let mut references = + Vec::with_capacity(chunk_references.len() + if include_source_map { 1 } else { 0 }); + + references.extend(chunk_references.iter().copied()); + + if include_source_map { + references.push(Vc::upcast(SourceMapAsset::new(Vc::upcast(self)))); + } + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptDevChunk { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + self.own_content().content() + } + + #[turbo_tasks::function] + fn versioned_content(self: Vc) -> Vc> { + Vc::upcast(self.own_content()) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for EcmascriptDevChunk { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.own_content().generate_source_map() + } + + #[turbo_tasks::function] + fn by_section(self: Vc, section: RcStr) -> Vc { + self.own_content().by_section(section) + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("dev ecmascript chunk".into()) +} + +#[turbo_tasks::function] +fn introspectable_details() -> Vc { + Vc::cell("generates a development ecmascript chunk".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for EcmascriptDevChunk { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + fn title(self: Vc) -> Vc { + self.ident().to_string() + } + + #[turbo_tasks::function] + fn details(&self) -> Vc { + introspectable_details() + } + + #[turbo_tasks::function] + async fn children(&self) -> Result> { + let mut children = IndexSet::new(); + let chunk = Vc::upcast::>(self.chunk) + .resolve() + .await?; + children.insert((Vc::cell("chunk".into()), chunk)); + Ok(Vc::cell(children)) + } +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/content.rs b/turbopack/crates/turbopack-browser/src/ecmascript/content.rs new file mode 100644 index 0000000000000..f74dad4f42fe4 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/content.rs @@ -0,0 +1,176 @@ +use std::io::Write; + +use anyhow::{bail, Result}; +use indoc::writedoc; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::File; +use turbopack_core::{ + asset::AssetContent, + chunk::{ChunkingContext, MinifyType, ModuleId}, + code_builder::{Code, CodeBuilder}, + output::OutputAsset, + source_map::{GenerateSourceMap, OptionSourceMap}, + version::{MergeableVersionedContent, Version, VersionedContent, VersionedContentMerger}, +}; +use turbopack_ecmascript::{chunk::EcmascriptChunkContent, minify::minify, utils::StringifyJs}; + +use super::{ + chunk::EcmascriptDevChunk, content_entry::EcmascriptDevChunkContentEntries, + merged::merger::EcmascriptDevChunkContentMerger, version::EcmascriptDevChunkVersion, +}; +use crate::BrowserChunkingContext; + +#[turbo_tasks::value(serialization = "none")] +pub struct EcmascriptDevChunkContent { + pub(super) entries: Vc, + pub(super) chunking_context: Vc, + pub(super) chunk: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunkContent { + #[turbo_tasks::function] + pub(crate) async fn new( + chunking_context: Vc, + chunk: Vc, + content: Vc, + ) -> Result> { + let entries = EcmascriptDevChunkContentEntries::new(content) + .resolve() + .await?; + Ok(EcmascriptDevChunkContent { + entries, + chunking_context, + chunk, + } + .cell()) + } + + #[turbo_tasks::function] + pub async fn entries( + self: Vc, + ) -> Result> { + Ok(self.await?.entries) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunkContent { + #[turbo_tasks::function] + pub(crate) async fn own_version(self: Vc) -> Result> { + let this = self.await?; + Ok(EcmascriptDevChunkVersion::new( + this.chunking_context.output_root(), + this.chunk.ident().path(), + this.entries, + )) + } + + #[turbo_tasks::function] + async fn code(self: Vc) -> Result> { + let this = self.await?; + let output_root = this.chunking_context.output_root().await?; + let chunk_path_vc = this.chunk.ident().path(); + let chunk_path = chunk_path_vc.await?; + let chunk_server_path = if let Some(path) = output_root.get_path_to(&chunk_path) { + path + } else { + bail!( + "chunk path {} is not in output root {}", + chunk_path.to_string(), + output_root.to_string() + ); + }; + let mut code = CodeBuilder::default(); + + // When a chunk is executed, it will either register itself with the current + // instance of the runtime, or it will push itself onto the list of pending + // chunks (`self.TURBOPACK`). + // + // When the runtime executes (see the `evaluate` module), it will pick up and + // register all pending chunks, and replace the list of pending chunks + // with itself so later chunks can register directly with it. + writedoc!( + code, + r#" + (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([{chunk_path}, {{ + "#, + chunk_path = StringifyJs(chunk_server_path) + )?; + + for (id, entry) in this.entries.await?.iter() { + write!(code, "\n{}: ", StringifyJs(&id))?; + code.push_code(&*entry.code.await?); + write!(code, ",")?; + } + + write!(code, "\n}}]);")?; + + if code.has_source_map() { + let filename = chunk_path.file_name(); + write!( + code, + "\n\n//# sourceMappingURL={}.map", + urlencoding::encode(filename) + )?; + } + + let code = code.build().cell(); + if matches!( + this.chunking_context.await?.minify_type(), + MinifyType::Minify + ) { + return Ok(minify(chunk_path_vc, code)); + } + + Ok(code) + } +} + +#[turbo_tasks::value_impl] +impl VersionedContent for EcmascriptDevChunkContent { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let code = self.code().await?; + Ok(AssetContent::file( + File::from(code.source_code().clone()).into(), + )) + } + + #[turbo_tasks::function] + fn version(self: Vc) -> Vc> { + Vc::upcast(self.own_version()) + } +} + +#[turbo_tasks::value_impl] +impl MergeableVersionedContent for EcmascriptDevChunkContent { + #[turbo_tasks::function] + fn get_merger(&self) -> Vc> { + Vc::upcast(EcmascriptDevChunkContentMerger::new()) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for EcmascriptDevChunkContent { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.code().generate_source_map() + } + + #[turbo_tasks::function] + async fn by_section(&self, section: RcStr) -> Result> { + // Weirdly, the ContentSource will have already URL decoded the ModuleId, and we + // can't reparse that via serde. + if let Ok(id) = ModuleId::parse(§ion) { + for (entry_id, entry) in self.entries.await?.iter() { + if id == **entry_id { + let sm = entry.code.generate_source_map(); + return Ok(sm); + } + } + } + + Ok(Vc::cell(None)) + } +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/content_entry.rs b/turbopack/crates/turbopack-browser/src/ecmascript/content_entry.rs new file mode 100644 index 0000000000000..2aa8bd4ac61a1 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/content_entry.rs @@ -0,0 +1,120 @@ +use std::io::Write as _; + +use anyhow::Result; +use indexmap::IndexMap; +use tracing::{info_span, Instrument}; +use turbo_tasks::{ReadRef, TryJoinIterExt, ValueToString, Vc}; +use turbopack_core::{ + chunk::{AsyncModuleInfo, ChunkItem, ChunkItemExt, ModuleId}, + code_builder::{Code, CodeBuilder}, + error::PrettyPrintError, + issue::{code_gen::CodeGenerationIssue, IssueExt, IssueSeverity, StyledString}, +}; +use turbopack_ecmascript::chunk::{ + EcmascriptChunkContent, EcmascriptChunkItem, EcmascriptChunkItemExt, +}; + +/// A chunk item's content entry. +/// +/// Instead of storing the [`Vc>`] itself from +/// which `code` and `hash` are derived, we store `Vc`s directly. This avoids +/// creating tasks in a hot loop when iterating over thousands of entries when +/// computing updates. +#[turbo_tasks::value] +#[derive(Debug)] +pub struct EcmascriptDevChunkContentEntry { + pub code: Vc, + pub hash: Vc, +} + +impl EcmascriptDevChunkContentEntry { + pub async fn new( + chunk_item: Vc>, + async_module_info: Option>, + ) -> Result { + let code = chunk_item.code(async_module_info).resolve().await?; + Ok(EcmascriptDevChunkContentEntry { + code, + hash: code.source_code_hash().resolve().await?, + }) + } +} + +#[turbo_tasks::value(transparent)] +pub struct EcmascriptDevChunkContentEntries( + IndexMap, EcmascriptDevChunkContentEntry>, +); + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunkContentEntries { + #[turbo_tasks::function] + pub async fn new( + chunk_content: Vc, + ) -> Result> { + let chunk_content = chunk_content.await?; + + let entries: IndexMap<_, _> = chunk_content + .chunk_items + .iter() + .map(|&(chunk_item, async_module_info)| async move { + async move { + Ok(( + chunk_item.id().await?, + EcmascriptDevChunkContentEntry::new(chunk_item, async_module_info).await?, + )) + } + .instrument(info_span!( + "chunk item", + name = display(chunk_item.asset_ident().to_string().await?) + )) + .await + }) + .try_join() + .await? + .into_iter() + .collect(); + + Ok(Vc::cell(entries)) + } +} + +#[turbo_tasks::function] +async fn item_code( + item: Vc>, + async_module_info: Option>, +) -> Result> { + Ok( + match item + .content_with_async_module_info(async_module_info) + .module_factory() + .resolve() + .await + { + Ok(factory) => factory, + Err(error) => { + let id = item.id().to_string().await; + let id = id.as_ref().map_or_else(|_| "unknown", |id| &**id); + let error = error.context(format!( + "An error occurred while generating the chunk item {}", + id + )); + let error_message = format!("{}", PrettyPrintError(&error)); + let js_error_message = serde_json::to_string(&error_message)?; + CodeGenerationIssue { + severity: IssueSeverity::Error.cell(), + path: item.asset_ident().path(), + title: StyledString::Text("Code generation for chunk item errored".into()) + .cell(), + message: StyledString::Text(error_message.into()).cell(), + } + .cell() + .emit(); + let mut code = CodeBuilder::default(); + code += "(() => {{\n\n"; + writeln!(code, "throw new Error({error});", error = &js_error_message)?; + code += "\n}})"; + code.build().cell() + } + }, + ) +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/evaluate/chunk.rs b/turbopack/crates/turbopack-browser/src/ecmascript/evaluate/chunk.rs new file mode 100644 index 0000000000000..57b5bc6390f8a --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/evaluate/chunk.rs @@ -0,0 +1,280 @@ +use std::io::Write; + +use anyhow::{bail, Result}; +use indoc::writedoc; +use serde::Serialize; +use turbo_tasks::{RcStr, ReadRef, TryJoinIterExt, Value, ValueToString, Vc}; +use turbo_tasks_fs::File; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ + ChunkData, ChunkItemExt, ChunkableModule, ChunkingContext, ChunksData, EvaluatableAssets, + MinifyType, ModuleId, + }, + code_builder::{Code, CodeBuilder}, + ident::AssetIdent, + module::Module, + output::{OutputAsset, OutputAssets}, + source_map::{GenerateSourceMap, OptionSourceMap, SourceMapAsset}, +}; +use turbopack_ecmascript::{ + chunk::{EcmascriptChunkData, EcmascriptChunkPlaceable}, + minify::minify, + utils::StringifyJs, +}; +use turbopack_ecmascript_runtime::RuntimeType; + +use crate::BrowserChunkingContext; + +/// An Ecmascript chunk that: +/// * Contains the Turbopack dev runtime code; and +/// * Evaluates a list of runtime entries. +#[turbo_tasks::value(shared)] +pub(crate) struct EcmascriptDevEvaluateChunk { + chunking_context: Vc, + ident: Vc, + other_chunks: Vc, + evaluatable_assets: Vc, +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevEvaluateChunk { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new( + chunking_context: Vc, + ident: Vc, + other_chunks: Vc, + evaluatable_assets: Vc, + ) -> Vc { + EcmascriptDevEvaluateChunk { + chunking_context, + ident, + other_chunks, + evaluatable_assets, + } + .cell() + } + + #[turbo_tasks::function] + async fn chunks_data(self: Vc) -> Result> { + let this = self.await?; + Ok(ChunkData::from_assets( + this.chunking_context.output_root(), + this.other_chunks, + )) + } + + #[turbo_tasks::function] + async fn code(self: Vc) -> Result> { + let this = self.await?; + let chunking_context = this.chunking_context.await?; + let environment = this.chunking_context.environment(); + + let output_root = this.chunking_context.output_root().await?; + let chunk_path_vc = self.ident().path(); + let chunk_path = chunk_path_vc.await?; + let chunk_public_path = if let Some(path) = output_root.get_path_to(&chunk_path) { + path + } else { + bail!( + "chunk path {} is not in output root {}", + chunk_path.to_string(), + output_root.to_string() + ); + }; + + let other_chunks_data = self.chunks_data().await?; + let other_chunks_data = other_chunks_data.iter().try_join().await?; + let other_chunks_data: Vec<_> = other_chunks_data + .iter() + .map(|chunk_data| EcmascriptChunkData::new(chunk_data)) + .collect(); + + let runtime_module_ids = this + .evaluatable_assets + .await? + .iter() + .map({ + let chunking_context = this.chunking_context; + move |entry| async move { + if let Some(placeable) = + Vc::try_resolve_sidecast::>(*entry) + .await? + { + Ok(Some( + placeable + .as_chunk_item(Vc::upcast(chunking_context)) + .id() + .await?, + )) + } else { + Ok(None) + } + } + }) + .try_join() + .await? + .into_iter() + .flatten() + .collect(); + + let params = EcmascriptDevChunkRuntimeParams { + other_chunks: &other_chunks_data, + runtime_module_ids, + }; + + let mut code = CodeBuilder::default(); + + // We still use the `TURBOPACK` global variable to store the chunk here, + // as there may be another runtime already loaded in the page. + // This is the case in integration tests. + writedoc!( + code, + r#" + (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + {}, + {{}}, + {} + ]); + "#, + StringifyJs(&chunk_public_path), + StringifyJs(¶ms), + )?; + + match chunking_context.runtime_type() { + RuntimeType::Development => { + let runtime_code = turbopack_ecmascript_runtime::get_browser_runtime_code( + environment, + chunking_context.chunk_base_path(), + Vc::cell(output_root.to_string().into()), + ); + code.push_code(&*runtime_code.await?); + } + RuntimeType::Production => { + let runtime_code = turbopack_ecmascript_runtime::get_browser_runtime_code( + environment, + chunking_context.chunk_base_path(), + Vc::cell(output_root.to_string().into()), + ); + code.push_code(&*runtime_code.await?); + } + #[cfg(feature = "test")] + RuntimeType::Dummy => { + let runtime_code = turbopack_ecmascript_runtime::get_dummy_runtime_code(); + code.push_code(&runtime_code); + } + } + + if code.has_source_map() { + let filename = chunk_path.file_name(); + write!( + code, + "\n\n//# sourceMappingURL={}.map", + urlencoding::encode(filename) + )?; + } + + let code = code.build().cell(); + if matches!( + this.chunking_context.await?.minify_type(), + MinifyType::Minify + ) { + return Ok(minify(chunk_path_vc, code)); + } + + Ok(code) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptDevEvaluateChunk { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("Ecmascript Dev Evaluate Chunk".into())) + } +} + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("ecmascript dev evaluate chunk".into()) +} + +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptDevEvaluateChunk { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let mut ident = self.ident.await?.clone_value(); + + ident.add_modifier(modifier()); + + let evaluatable_assets = self.evaluatable_assets.await?; + ident.modifiers.extend( + evaluatable_assets + .iter() + .map(|entry| entry.ident().to_string()), + ); + + for chunk in &*self.other_chunks.await? { + ident.add_modifier(chunk.ident().to_string()); + } + + let ident = AssetIdent::new(Value::new(ident)); + Ok(AssetIdent::from_path( + self.chunking_context.chunk_path(ident, ".js".into()), + )) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let mut references = Vec::new(); + + let include_source_map = *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await?; + + if include_source_map { + references.push(Vc::upcast(SourceMapAsset::new(Vc::upcast(self)))); + } + + for chunk_data in &*self.chunks_data().await? { + references.extend(chunk_data.references().await?.iter().copied()); + } + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptDevEvaluateChunk { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let code = self.code().await?; + Ok(AssetContent::file( + File::from(code.source_code().clone()).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for EcmascriptDevEvaluateChunk { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.code().generate_source_map() + } +} + +#[derive(Debug, Serialize)] +#[serde(rename_all = "camelCase")] +struct EcmascriptDevChunkRuntimeParams<'a, T> { + /// Other chunks in the chunk group this chunk belongs to, if any. Does not + /// include the chunk itself. + /// + /// These chunks must be loaed before the runtime modules can be + /// instantiated. + other_chunks: &'a [T], + /// List of module IDs that this chunk should instantiate when executed. + runtime_module_ids: Vec>, +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/evaluate/mod.rs b/turbopack/crates/turbopack-browser/src/ecmascript/evaluate/mod.rs new file mode 100644 index 0000000000000..90699270917e0 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/evaluate/mod.rs @@ -0,0 +1 @@ +pub(crate) mod chunk; diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/list/asset.rs b/turbopack/crates/turbopack-browser/src/ecmascript/list/asset.rs new file mode 100644 index 0000000000000..bc0cc39046feb --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/list/asset.rs @@ -0,0 +1,145 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkingContext, EvaluatableAssets}, + ident::AssetIdent, + module::Module, + output::{OutputAsset, OutputAssets}, + version::VersionedContent, +}; + +use super::content::EcmascriptDevChunkListContent; +use crate::BrowserChunkingContext; + +/// An asset that represents a list of chunks that exist together in a chunk +/// group, and should be *updated* together. +/// +/// The chunk list's content registers itself as a Turbopack chunk and a chunk +/// list. +/// +/// Then, on updates, it merges updates from its chunks into a single update +/// when possible. This is useful for keeping track of changes that affect more +/// than one chunk, or affect the chunk group, e.g.: +/// * moving a module from one chunk to another; +/// * changing a chunk's path. +#[turbo_tasks::value(shared)] +pub(crate) struct EcmascriptDevChunkList { + pub(super) chunking_context: Vc, + pub(super) ident: Vc, + pub(super) evaluatable_assets: Vc, + pub(super) chunks: Vc, + pub(super) source: EcmascriptDevChunkListSource, +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunkList { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new( + chunking_context: Vc, + ident: Vc, + evaluatable_assets: Vc, + chunks: Vc, + source: Value, + ) -> Vc { + EcmascriptDevChunkList { + chunking_context, + ident, + evaluatable_assets, + chunks, + source: source.into_value(), + } + .cell() + } + + #[turbo_tasks::function] + fn own_content(self: Vc) -> Vc { + EcmascriptDevChunkListContent::new(self) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptDevChunkList { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("Ecmascript Dev Chunk List".into())) + } +} + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("ecmascript dev chunk list".into()) +} + +#[turbo_tasks::function] +fn dynamic_modifier() -> Vc { + Vc::cell("dynamic".into()) +} + +#[turbo_tasks::function] +fn chunk_list_chunk_reference_description() -> Vc { + Vc::cell("chunk list chunk".into()) +} + +#[turbo_tasks::function] +fn chunk_key() -> Vc { + Vc::cell("chunk".into()) +} + +#[turbo_tasks::value_impl] +impl OutputAsset for EcmascriptDevChunkList { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + let mut ident = self.ident.await?.clone_value(); + for &evaluatable_asset in self.evaluatable_assets.await?.iter() { + ident.add_asset(Vc::::default(), evaluatable_asset.ident()); + } + + ident.add_modifier(modifier()); + + match self.source { + EcmascriptDevChunkListSource::Entry => {} + EcmascriptDevChunkListSource::Dynamic => { + ident.add_modifier(dynamic_modifier()); + } + } + + // We must not include the actual chunks idents as part of the chunk list's + // ident, because it must remain stable whenever a chunk is added or + // removed from the list. + + let ident = AssetIdent::new(Value::new(ident)); + Ok(AssetIdent::from_path( + self.chunking_context.chunk_path(ident, ".js".into()), + )) + } + + #[turbo_tasks::function] + async fn references(&self) -> Result> { + Ok(self.chunks) + } +} + +#[turbo_tasks::value_impl] +impl Asset for EcmascriptDevChunkList { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + self.own_content().content() + } + + #[turbo_tasks::function] + fn versioned_content(self: Vc) -> Vc> { + Vc::upcast(self.own_content()) + } +} + +#[derive(Debug, Clone, Copy, Hash)] +#[turbo_tasks::value(serialization = "auto_for_input")] +#[serde(rename_all = "camelCase")] +pub enum EcmascriptDevChunkListSource { + /// The chunk list is from a runtime entry. + Entry, + /// The chunk list is from a dynamic import. + Dynamic, +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/list/content.rs b/turbopack/crates/turbopack-browser/src/ecmascript/list/content.rs new file mode 100644 index 0000000000000..478de6c10d54c --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/list/content.rs @@ -0,0 +1,176 @@ +use std::io::Write; + +use anyhow::{Context, Result}; +use indexmap::IndexMap; +use indoc::writedoc; +use serde::Serialize; +use turbo_tasks::{IntoTraitRef, TryJoinIterExt, Vc}; +use turbo_tasks_fs::File; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::ChunkingContext, + code_builder::{Code, CodeBuilder}, + output::OutputAsset, + version::{ + MergeableVersionedContent, Update, Version, VersionedContent, VersionedContentMerger, + }, +}; +use turbopack_ecmascript::utils::StringifyJs; + +use super::{ + asset::{EcmascriptDevChunkList, EcmascriptDevChunkListSource}, + update::update_chunk_list, + version::EcmascriptDevChunkListVersion, +}; + +/// Contents of an [`EcmascriptDevChunkList`]. +#[turbo_tasks::value] +pub(super) struct EcmascriptDevChunkListContent { + chunk_list_path: String, + pub(super) chunks_contents: IndexMap>>, + source: EcmascriptDevChunkListSource, +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunkListContent { + /// Creates a new [`EcmascriptDevChunkListContent`]. + #[turbo_tasks::function] + pub async fn new(chunk_list: Vc) -> Result> { + let chunk_list_ref = chunk_list.await?; + let output_root = chunk_list_ref.chunking_context.output_root().await?; + Ok(EcmascriptDevChunkListContent { + chunk_list_path: output_root + .get_path_to(&*chunk_list.ident().path().await?) + .context("chunk list path not in output root")? + .to_string(), + chunks_contents: chunk_list_ref + .chunks + .await? + .iter() + .map(|chunk| { + let output_root = output_root.clone(); + async move { + Ok(( + output_root + .get_path_to(&*chunk.ident().path().await?) + .map(|path| path.to_string()), + chunk.versioned_content(), + )) + } + }) + .try_join() + .await? + .into_iter() + .filter_map(|(path, content)| path.map(|path| (path, content))) + .collect(), + source: chunk_list_ref.source, + } + .cell()) + } + + /// Computes the version of this content. + #[turbo_tasks::function] + pub async fn version(self: Vc) -> Result> { + let this = self.await?; + + let mut by_merger = IndexMap::<_, Vec<_>>::new(); + let mut by_path = IndexMap::<_, _>::new(); + + for (chunk_path, chunk_content) in &this.chunks_contents { + if let Some(mergeable) = + Vc::try_resolve_sidecast::>(*chunk_content) + .await? + { + let merger = mergeable.get_merger().resolve().await?; + by_merger.entry(merger).or_default().push(*chunk_content); + } else { + by_path.insert( + chunk_path.clone(), + chunk_content.version().into_trait_ref().await?, + ); + } + } + + let by_merger = by_merger + .into_iter() + .map(|(merger, contents)| async move { + Ok(( + merger, + merger + .merge(Vc::cell(contents)) + .version() + .into_trait_ref() + .await?, + )) + }) + .try_join() + .await? + .into_iter() + .collect(); + + Ok(EcmascriptDevChunkListVersion { by_path, by_merger }.cell()) + } + + #[turbo_tasks::function] + pub(super) async fn code(self: Vc) -> Result> { + let this = self.await?; + + let params = EcmascriptDevChunkListParams { + path: &this.chunk_list_path, + chunks: this.chunks_contents.keys().map(|s| s.as_str()).collect(), + source: this.source, + }; + + let mut code = CodeBuilder::default(); + + // When loaded, JS chunks must register themselves with the `TURBOPACK` global + // variable. Similarly, we register the chunk list with the + // `TURBOPACK_CHUNK_LISTS` global variable. + writedoc!( + code, + r#" + (globalThis.TURBOPACK = globalThis.TURBOPACK || []).push([ + {}, + {{}}, + ]); + (globalThis.TURBOPACK_CHUNK_LISTS = globalThis.TURBOPACK_CHUNK_LISTS || []).push({:#}); + "#, + StringifyJs(&this.chunk_list_path), + StringifyJs(¶ms), + )?; + + Ok(Code::cell(code.build())) + } +} + +#[turbo_tasks::value_impl] +impl VersionedContent for EcmascriptDevChunkListContent { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let code = self.code().await?; + Ok(AssetContent::file( + File::from(code.source_code().clone()).into(), + )) + } + + #[turbo_tasks::function] + fn version(self: Vc) -> Vc> { + Vc::upcast(self.version()) + } + + #[turbo_tasks::function] + fn update(self: Vc, from_version: Vc>) -> Vc { + update_chunk_list(self, from_version) + } +} + +#[derive(Debug, Clone, Serialize)] +#[serde(rename_all = "camelCase")] +struct EcmascriptDevChunkListParams<'a> { + /// Path to the chunk list to register. + path: &'a str, + /// All chunks that belong to the chunk list. + chunks: Vec<&'a str>, + /// Where this chunk list is from. + source: EcmascriptDevChunkListSource, +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/list/mod.rs b/turbopack/crates/turbopack-browser/src/ecmascript/list/mod.rs new file mode 100644 index 0000000000000..cb3fddcd2276a --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/list/mod.rs @@ -0,0 +1,4 @@ +pub(crate) mod asset; +pub(crate) mod content; +pub(crate) mod update; +pub(crate) mod version; diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/list/update.rs b/turbopack/crates/turbopack-browser/src/ecmascript/list/update.rs new file mode 100644 index 0000000000000..87284f950c755 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/list/update.rs @@ -0,0 +1,177 @@ +use std::sync::Arc; + +use anyhow::Result; +use indexmap::IndexMap; +use serde::Serialize; +use turbo_tasks::{IntoTraitRef, TraitRef, Vc}; +use turbopack_core::version::{ + MergeableVersionedContent, PartialUpdate, TotalUpdate, Update, Version, VersionedContent, + VersionedContentMerger, +}; + +use super::{content::EcmascriptDevChunkListContent, version::EcmascriptDevChunkListVersion}; + +/// Update of a chunk list from one version to another. +#[derive(Serialize)] +#[serde(tag = "type")] +#[serde(rename_all = "camelCase")] +struct ChunkListUpdate<'a> { + /// A map from chunk path to a corresponding update of that chunk. + #[serde(skip_serializing_if = "IndexMap::is_empty")] + chunks: IndexMap<&'a str, ChunkUpdate>, + /// List of merged updates since the last version. + #[serde(skip_serializing_if = "Vec::is_empty")] + merged: Vec>, +} + +/// Update of a chunk from one version to another. +#[derive(Serialize)] +#[serde(tag = "type")] +#[serde(rename_all = "camelCase")] +enum ChunkUpdate { + /// The chunk was updated and must be reloaded. + Total, + /// The chunk was updated and can be merged with the previous version. + Partial { instruction: Arc }, + /// The chunk was added. + Added, + /// The chunk was deleted. + Deleted, +} + +impl<'a> ChunkListUpdate<'a> { + /// Returns `true` if this update is empty. + fn is_empty(&self) -> bool { + let ChunkListUpdate { chunks, merged } = self; + chunks.is_empty() && merged.is_empty() + } +} + +/// Computes the update of a chunk list from one version to another. +#[turbo_tasks::function] +pub(super) async fn update_chunk_list( + content: Vc, + from_version: Vc>, +) -> Result> { + let to_version = content.version(); + let from_version = if let Some(from) = + Vc::try_resolve_downcast_type::(from_version).await? + { + from + } else { + // It's likely `from_version` is `NotFoundVersion`. + return Ok(Update::Total(TotalUpdate { + to: Vc::upcast::>(to_version) + .into_trait_ref() + .await?, + }) + .cell()); + }; + + let to = to_version.await?; + let from = from_version.await?; + + // When to and from point to the same value we can skip comparing them. + // This will happen since `TraitRef>>::cell` will not clone + // the value, but only make the cell point to the same immutable value + // (Arc). + if from.ptr_eq(&to) { + return Ok(Update::None.cell()); + } + + let content = content.await?; + + // There are two kind of updates nested within a chunk list update: + // * merged updates; and + // * single chunk updates. + // In order to compute merged updates, we first need to group mergeable chunks + // by common mergers. Then, we compute the update of each group separately. + // Single chunk updates are computed separately and only require a stable chunk + // path to identify the chunk across versions. + let mut by_merger = IndexMap::<_, Vec<_>>::new(); + let mut by_path = IndexMap::<_, _>::new(); + + for (chunk_path, chunk_content) in &content.chunks_contents { + if let Some(mergeable) = + Vc::try_resolve_sidecast::>(*chunk_content).await? + { + let merger = mergeable.get_merger().resolve().await?; + by_merger.entry(merger).or_default().push(*chunk_content); + } else { + by_path.insert(chunk_path, chunk_content); + } + } + + let mut chunks = IndexMap::<_, _>::new(); + + for (chunk_path, from_chunk_version) in &from.by_path { + if let Some(chunk_content) = by_path.remove(chunk_path) { + let chunk_update = chunk_content + .update(TraitRef::cell(from_chunk_version.clone())) + .await?; + + match &*chunk_update { + Update::Total(_) => { + chunks.insert(chunk_path.as_ref(), ChunkUpdate::Total); + } + Update::Partial(partial) => { + chunks.insert( + chunk_path.as_ref(), + ChunkUpdate::Partial { + instruction: partial.instruction.clone(), + }, + ); + } + Update::None => {} + } + } else { + chunks.insert(chunk_path.as_ref(), ChunkUpdate::Deleted); + } + } + + for chunk_path in by_path.keys() { + chunks.insert(chunk_path.as_ref(), ChunkUpdate::Added); + } + + let mut merged = vec![]; + + for (merger, chunks_contents) in by_merger { + if let Some(from_version) = from.by_merger.get(&merger) { + let content = merger.merge(Vc::cell(chunks_contents)); + + let chunk_update = content.update(TraitRef::cell(from_version.clone())).await?; + + match &*chunk_update { + // Getting a total or not found update from a merger is unexpected. If it + // happens, we have no better option than to short-circuit + // the update. + Update::Total(_) => { + return Ok(Update::Total(TotalUpdate { + to: Vc::upcast::>(to_version) + .into_trait_ref() + .await?, + }) + .cell()); + } + Update::Partial(partial) => { + merged.push(partial.instruction.clone()); + } + Update::None => {} + } + } + } + let update = ChunkListUpdate { chunks, merged }; + + let update = if update.is_empty() { + Update::None + } else { + Update::Partial(PartialUpdate { + to: Vc::upcast::>(to_version) + .into_trait_ref() + .await?, + instruction: Arc::new(serde_json::to_value(&update)?), + }) + }; + + Ok(update.into()) +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/list/version.rs b/turbopack/crates/turbopack-browser/src/ecmascript/list/version.rs new file mode 100644 index 0000000000000..7dd142e36609c --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/list/version.rs @@ -0,0 +1,65 @@ +use anyhow::Result; +use indexmap::IndexMap; +use turbo_tasks::{RcStr, TraitRef, TryJoinIterExt, Vc}; +use turbo_tasks_hash::{encode_hex, Xxh3Hash64Hasher}; +use turbopack_core::version::{Version, VersionedContentMerger}; + +type VersionTraitRef = TraitRef>; + +/// The version of a [`EcmascriptDevChunkListContent`]. +/// +/// [`EcmascriptDevChunkListContent`]: super::content::EcmascriptDevChunkListContent +#[turbo_tasks::value(shared)] +pub(super) struct EcmascriptDevChunkListVersion { + /// A map from chunk path to its version. + #[turbo_tasks(trace_ignore)] + pub by_path: IndexMap, + /// A map from chunk merger to the version of the merged contents of chunks. + #[turbo_tasks(trace_ignore)] + pub by_merger: IndexMap>, VersionTraitRef>, +} + +#[turbo_tasks::value_impl] +impl Version for EcmascriptDevChunkListVersion { + #[turbo_tasks::function] + async fn id(&self) -> Result> { + let by_path = { + let mut by_path = self + .by_path + .iter() + .map(|(path, version)| async move { + let id = TraitRef::cell(version.clone()).id().await?.clone_value(); + Ok((path, id)) + }) + .try_join() + .await?; + by_path.sort(); + by_path + }; + let by_merger = { + let mut by_merger = self + .by_merger + .iter() + .map(|(_merger, version)| async move { + Ok(TraitRef::cell(version.clone()).id().await?.clone_value()) + }) + .try_join() + .await?; + by_merger.sort(); + by_merger + }; + let mut hasher = Xxh3Hash64Hasher::new(); + hasher.write_value(by_path.len()); + for (path, id) in by_path { + hasher.write_value(path); + hasher.write_value(id); + } + hasher.write_value(by_merger.len()); + for id in by_merger { + hasher.write_value(id); + } + let hash = hasher.finish(); + let hex_hash = encode_hex(hash); + Ok(Vc::cell(hex_hash.into())) + } +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/merged/content.rs b/turbopack/crates/turbopack-browser/src/ecmascript/merged/content.rs new file mode 100644 index 0000000000000..a852ca7d90f9f --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/merged/content.rs @@ -0,0 +1,58 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{TryJoinIterExt, Vc}; +use turbopack_core::{ + asset::AssetContent, + version::{Update, Version, VersionedContent}, +}; + +use super::{ + super::content::EcmascriptDevChunkContent, update::update_ecmascript_merged_chunk, + version::EcmascriptDevMergedChunkVersion, +}; + +/// Composite [`EcmascriptChunkContent`] that is the result of merging multiple +/// EcmaScript chunk's contents together through the +/// [`EcmascriptChunkContentMerger`]. +/// +/// [`EcmascriptChunkContentMerger`]: super::merger::EcmascriptChunkContentMerger +#[turbo_tasks::value(serialization = "none", shared)] +pub(super) struct EcmascriptDevMergedChunkContent { + pub contents: Vec>, +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevMergedChunkContent { + #[turbo_tasks::function] + pub async fn version(self: Vc) -> Result> { + Ok(EcmascriptDevMergedChunkVersion { + versions: self + .await? + .contents + .iter() + .map(|content| async move { content.own_version().await }) + .try_join() + .await?, + } + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl VersionedContent for EcmascriptDevMergedChunkContent { + #[turbo_tasks::function] + fn content(self: Vc) -> Result> { + bail!("EcmascriptDevMergedChunkContent does not have content") + } + + #[turbo_tasks::function] + fn version(self: Vc) -> Vc> { + Vc::upcast(self.version()) + } + + #[turbo_tasks::function] + async fn update(self: Vc, from_version: Vc>) -> Result> { + Ok(update_ecmascript_merged_chunk(self, from_version) + .await? + .cell()) + } +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/merged/merger.rs b/turbopack/crates/turbopack-browser/src/ecmascript/merged/merger.rs new file mode 100644 index 0000000000000..f2ac81dfe6563 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/merged/merger.rs @@ -0,0 +1,48 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{TryJoinIterExt, Vc}; +use turbopack_core::version::{VersionedContent, VersionedContentMerger, VersionedContents}; + +use super::{super::content::EcmascriptDevChunkContent, content::EcmascriptDevMergedChunkContent}; + +/// Merges multiple [`EcmascriptChunkContent`] into a single +/// [`EcmascriptDevMergedChunkContent`]. This is useful for generating a single +/// update for multiple ES chunks updating all at the same time. +#[turbo_tasks::value] +pub(crate) struct EcmascriptDevChunkContentMerger; + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunkContentMerger { + /// Creates a new [`EcmascriptDevChunkContentMerger`]. + #[turbo_tasks::function] + pub fn new() -> Vc { + Self::cell(EcmascriptDevChunkContentMerger) + } +} + +#[turbo_tasks::value_impl] +impl VersionedContentMerger for EcmascriptDevChunkContentMerger { + #[turbo_tasks::function] + async fn merge( + &self, + contents: Vc, + ) -> Result>> { + let contents = contents + .await? + .iter() + .map(|content| async move { + if let Some(content) = + Vc::try_resolve_downcast_type::(*content).await? + { + Ok(content) + } else { + bail!("expected Vc") + } + }) + .try_join() + .await?; + + Ok(Vc::upcast( + EcmascriptDevMergedChunkContent { contents }.cell(), + )) + } +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/merged/mod.rs b/turbopack/crates/turbopack-browser/src/ecmascript/merged/mod.rs new file mode 100644 index 0000000000000..38431505fc60f --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/merged/mod.rs @@ -0,0 +1,4 @@ +pub(crate) mod content; +pub(crate) mod merger; +pub(crate) mod update; +pub(crate) mod version; diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/merged/update.rs b/turbopack/crates/turbopack-browser/src/ecmascript/merged/update.rs new file mode 100644 index 0000000000000..3afac4632e67d --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/merged/update.rs @@ -0,0 +1,282 @@ +use std::sync::Arc; + +use anyhow::Result; +use indexmap::{IndexMap, IndexSet}; +use serde::Serialize; +use turbo_tasks::{IntoTraitRef, ReadRef, TryJoinIterExt, Vc}; +use turbo_tasks_fs::rope::Rope; +use turbopack_core::{ + chunk::{ChunkingContext, ModuleId}, + code_builder::Code, + output::OutputAsset, + source_map::GenerateSourceMap, + version::{PartialUpdate, TotalUpdate, Update, Version}, +}; + +use super::{ + super::{ + update::{update_ecmascript_chunk, EcmascriptChunkUpdate}, + version::EcmascriptDevChunkVersion, + }, + content::EcmascriptDevMergedChunkContent, + version::EcmascriptDevMergedChunkVersion, +}; + +#[derive(Serialize, Default)] +#[serde(tag = "type", rename_all = "camelCase")] +struct EcmascriptMergedUpdate<'a> { + /// A map from module id to latest module entry. + #[serde(skip_serializing_if = "IndexMap::is_empty")] + entries: IndexMap, EcmascriptModuleEntry>, + /// A map from chunk path to the chunk update. + #[serde(skip_serializing_if = "IndexMap::is_empty")] + chunks: IndexMap<&'a str, EcmascriptMergedChunkUpdate>, +} + +impl EcmascriptMergedUpdate<'_> { + fn is_empty(&self) -> bool { + self.entries.is_empty() && self.chunks.is_empty() + } +} + +#[derive(Serialize)] +#[serde(tag = "type", rename_all = "camelCase")] +enum EcmascriptMergedChunkUpdate { + Added(EcmascriptMergedChunkAdded), + Deleted(EcmascriptMergedChunkDeleted), + Partial(EcmascriptMergedChunkPartial), +} + +#[derive(Serialize, Default)] +#[serde(rename_all = "camelCase")] +struct EcmascriptMergedChunkAdded { + #[serde(skip_serializing_if = "IndexSet::is_empty")] + modules: IndexSet>, +} + +#[derive(Serialize, Default)] +#[serde(rename_all = "camelCase")] +struct EcmascriptMergedChunkDeleted { + // Technically, this is redundant, since the client will already know all + // modules in the chunk from the previous version. However, it's useful for + // merging updates without access to an initial state. + #[serde(skip_serializing_if = "IndexSet::is_empty")] + modules: IndexSet>, +} + +#[derive(Serialize, Default)] +#[serde(rename_all = "camelCase")] +struct EcmascriptMergedChunkPartial { + #[serde(skip_serializing_if = "IndexSet::is_empty")] + added: IndexSet>, + #[serde(skip_serializing_if = "IndexSet::is_empty")] + deleted: IndexSet>, +} + +#[derive(Serialize)] +struct EcmascriptModuleEntry { + code: Rope, + url: String, + map: Option, +} + +impl EcmascriptModuleEntry { + async fn from_code(id: &ModuleId, code: Vc, chunk_path: &str) -> Result { + let map = match &*code.generate_source_map().await? { + Some(map) => { + let map = map.await?.to_source_map().await?; + let mut map_str = vec![]; + (*map).to_writer(&mut map_str)?; + Some(String::from_utf8(map_str)?) + } + None => None, + }; + + Ok(Self::new(id, code.await?, map, chunk_path)) + } + + fn new(id: &ModuleId, code: ReadRef, map: Option, chunk_path: &str) -> Self { + /// serde_qs can't serialize a lone enum when it's [serde::untagged]. + #[derive(Serialize)] + struct Id<'a> { + id: &'a ModuleId, + } + let id = serde_qs::to_string(&Id { id }).unwrap(); + + EcmascriptModuleEntry { + // Cloning a rope is cheap. + code: code.source_code().clone(), + url: format!("{}?{}", chunk_path, &id), + map, + } + } +} + +/// Helper structure to get a module's hash from multiple different chunk +/// versions, without having to actually merge the versions into a single +/// hashmap, which would be expensive. +struct MergedModuleMap { + versions: Vec>, +} + +impl MergedModuleMap { + /// Creates a new `MergedModuleMap` from the given versions. + fn new(versions: Vec>) -> Self { + Self { versions } + } + + /// Returns the hash of the module with the given id, or `None` if the + /// module is not present in any of the versions. + fn get(&self, id: &ReadRef) -> Option { + for version in &self.versions { + if let Some(hash) = version.entries_hashes.get(id) { + return Some(*hash); + } + } + None + } +} + +pub(super) async fn update_ecmascript_merged_chunk( + content: Vc, + from_version: Vc>, +) -> Result { + let to_merged_version = content.version(); + let from_merged_version = if let Some(from) = + Vc::try_resolve_downcast_type::(from_version).await? + { + from + } else { + // It's likely `from_version` is `NotFoundVersion`. + return Ok(Update::Total(TotalUpdate { + to: Vc::upcast::>(to_merged_version) + .into_trait_ref() + .await?, + })); + }; + + let to = to_merged_version.await?; + let from = from_merged_version.await?; + + // When to and from point to the same value we can skip comparing them. + // This will happen since `TraitRef>>::cell` will not clone + // the value, but only make the cell point to the same immutable value + // (Arc). + if from.ptr_eq(&to) { + return Ok(Update::None); + } + + let mut from_versions_by_chunk_path: IndexMap<_, _> = from + .versions + .iter() + .map(|version| (&*version.chunk_path, version)) + .collect(); + + let merged_module_map = MergedModuleMap::new(from.versions.to_vec()); + + let content = content.await?; + let to_contents = content + .contents + .iter() + .map(|content| async move { + let content_ref = content.await?; + let output_root = content_ref.chunking_context.output_root().await?; + let path = content_ref.chunk.ident().path().await?; + Ok((*content, content_ref, output_root, path)) + }) + .try_join() + .await?; + + let mut merged_update = EcmascriptMergedUpdate::default(); + + for (content, content_ref, output_root, path) in &to_contents { + let Some(chunk_path) = output_root.get_path_to(path) else { + continue; + }; + + let chunk_update = if let Some(from_version) = + from_versions_by_chunk_path.remove(chunk_path) + { + // The chunk was present in the previous version, so we must update it. + let update = update_ecmascript_chunk(*content, from_version).await?; + + match update { + EcmascriptChunkUpdate::None => { + // Nothing changed, so we can skip this chunk. + continue; + } + EcmascriptChunkUpdate::Partial(chunk_partial) => { + // The chunk was updated. + let mut partial = EcmascriptMergedChunkPartial::default(); + + for (module_id, (module_hash, module_code)) in chunk_partial.added { + partial.added.insert(module_id.clone()); + + if merged_module_map.get(&module_id) != Some(module_hash) { + let entry = EcmascriptModuleEntry::from_code( + &module_id, + module_code, + chunk_path, + ) + .await?; + merged_update.entries.insert(module_id, entry); + } + } + + partial.deleted.extend(chunk_partial.deleted.into_keys()); + + for (module_id, module_code) in chunk_partial.modified { + let entry = + EcmascriptModuleEntry::from_code(&module_id, module_code, chunk_path) + .await?; + merged_update.entries.insert(module_id, entry); + } + + EcmascriptMergedChunkUpdate::Partial(partial) + } + } + } else { + // The chunk was added in this version. + let mut added = EcmascriptMergedChunkAdded::default(); + + for (id, entry) in &content_ref.entries.await? { + let hash = *entry.hash.await?; + added.modules.insert(id.clone()); + + if merged_module_map.get(id) != Some(hash) { + let entry = + EcmascriptModuleEntry::from_code(id, entry.code, chunk_path).await?; + merged_update.entries.insert(id.clone(), entry); + } + } + + EcmascriptMergedChunkUpdate::Added(added) + }; + + merged_update.chunks.insert(chunk_path, chunk_update); + } + + // Deleted chunks. + for (chunk_path, chunk_version) in from_versions_by_chunk_path { + let hashes = &chunk_version.entries_hashes; + merged_update.chunks.insert( + chunk_path, + EcmascriptMergedChunkUpdate::Deleted(EcmascriptMergedChunkDeleted { + modules: hashes.keys().cloned().collect(), + }), + ); + } + + let update = if merged_update.is_empty() { + Update::None + } else { + Update::Partial(PartialUpdate { + to: Vc::upcast::>(to_merged_version) + .into_trait_ref() + .await?, + instruction: Arc::new(serde_json::to_value(&merged_update)?), + }) + }; + + Ok(update) +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/merged/version.rs b/turbopack/crates/turbopack-browser/src/ecmascript/merged/version.rs new file mode 100644 index 0000000000000..dd55cf5216b0f --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/merged/version.rs @@ -0,0 +1,39 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, ReadRef, TryJoinIterExt, Vc}; +use turbo_tasks_hash::{encode_hex, Xxh3Hash64Hasher}; +use turbopack_core::version::Version; + +use super::super::version::EcmascriptDevChunkVersion; + +/// The version of a [`super::content::EcmascriptMergedChunkContent`]. This is +/// essentially a composite [`EcmascriptChunkVersion`]. +#[turbo_tasks::value(serialization = "none", shared)] +pub(super) struct EcmascriptDevMergedChunkVersion { + #[turbo_tasks(trace_ignore)] + pub(super) versions: Vec>, +} + +#[turbo_tasks::value_impl] +impl Version for EcmascriptDevMergedChunkVersion { + #[turbo_tasks::function] + async fn id(&self) -> Result> { + let mut hasher = Xxh3Hash64Hasher::new(); + hasher.write_value(self.versions.len()); + let sorted_ids = { + let mut sorted_ids = self + .versions + .iter() + .map(|version| async move { ReadRef::cell(version.clone()).id().await }) + .try_join() + .await?; + sorted_ids.sort(); + sorted_ids + }; + for id in sorted_ids { + hasher.write_value(id); + } + let hash = hasher.finish(); + let hex_hash = encode_hex(hash); + Ok(Vc::cell(hex_hash.into())) + } +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/mod.rs b/turbopack/crates/turbopack-browser/src/ecmascript/mod.rs new file mode 100644 index 0000000000000..a819a6d13264e --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/mod.rs @@ -0,0 +1,10 @@ +pub(crate) mod chunk; +pub(crate) mod content; +pub(crate) mod content_entry; +pub(crate) mod evaluate; +pub(crate) mod list; +pub(crate) mod merged; +pub(crate) mod update; +pub(crate) mod version; + +pub use content::EcmascriptDevChunkContent; diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/runtime.rs b/turbopack/crates/turbopack-browser/src/ecmascript/runtime.rs new file mode 100644 index 0000000000000..68b103bed10c9 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/runtime.rs @@ -0,0 +1,215 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{Value, ValueToString, Vc}; +use turbopack_core::{ + asset::Asset, + chunk::{ChunkGroup, ChunkListReference, ChunkingContext}, + ident::AssetIdent, +}; +use turbopack_ecmascript::chunk::{ + ChunkingContext, EcmascriptChunk, EcmascriptChunkPlaceables, EcmascriptChunkRuntime, + EcmascriptChunkRuntimeContent, +}; + +use crate::ecmascript::content::EcmascriptDevChunkContent; + +/// Development runtime for Ecmascript chunks. +#[turbo_tasks::value(shared)] +pub(crate) struct EcmascriptDevChunkRuntime { + /// The chunking context that created this runtime. + chunking_context: Vc>, + /// All chunks of this chunk group need to be ready for execution to start. + /// When None, it will use a chunk group created from the current chunk. + chunk_group: Option>, + /// If any evaluated entries are set, the main runtime code will be included + /// in the chunk and the provided entries will be evaluated as soon as the + /// chunk executes. + evaluated_entries: Option>, +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunkRuntime { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new( + chunking_context: Vc>, + evaluated_entries: Option>, + ) -> Vc { + EcmascriptDevChunkRuntime { + chunking_context, + chunk_group: None, + evaluated_entries, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for EcmascriptDevChunkRuntime { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell("Ecmascript Dev Runtime".to_string())) + } +} + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("ecmascript dev chunk".to_string()) +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkRuntime for EcmascriptDevChunkRuntime { + #[turbo_tasks::function] + async fn decorate_asset_ident( + &self, + origin_chunk: Vc, + ident: Vc, + ) -> Result> { + let Self { + chunking_context: _, + chunk_group, + evaluated_entries, + } = self; + + let mut ident = ident.await?.clone_value(); + + // Add a constant modifier to qualify this runtime. + ident.add_modifier(modifier()); + + // Only add other modifiers when the chunk is evaluated. Otherwise, it will + // not receive any params and as such won't differ from another chunk in a + // different chunk group. + if let Some(evaluated_entries) = evaluated_entries { + ident.modifiers.extend( + evaluated_entries + .await? + .iter() + .map(|entry| entry.ident().to_string()), + ); + + // When the chunk group has changed, e.g. due to optimization, we want to + // include the information too. Since the optimization is + // deterministic, it's enough to include the entry chunk which is the only + // factor that influences the chunk group chunks. + // We want to avoid a cycle when this chunk is the entry chunk. + if let Some(chunk_group) = chunk_group { + let entry = chunk_group.entry().resolve().await?; + if entry != origin_chunk.into() { + ident.add_modifier(entry.ident().to_string()); + } + } + } + + Ok(AssetIdent::new(Value::new(ident))) + } + + #[turbo_tasks::function] + fn with_chunk_group(&self, chunk_group: Vc) -> Vc { + EcmascriptDevChunkRuntime::cell(EcmascriptDevChunkRuntime { + chunking_context: self.chunking_context, + chunk_group: Some(chunk_group), + evaluated_entries: self.evaluated_entries, + }) + } + + #[turbo_tasks::function] + fn references(&self, origin_chunk: Vc) -> Vc { + let Self { + chunk_group, + chunking_context, + evaluated_entries, + } = self; + + let mut references = vec![]; + if evaluated_entries.is_some() { + let chunk_group = + chunk_group.unwrap_or_else(|| ChunkGroup::from_chunk(origin_chunk.into())); + references.push(Vc::upcast(ChunkListReference::new( + chunking_context.output_root(), + chunk_group, + ))); + } + Vc::cell(references) + } + + #[turbo_tasks::function] + fn content(&self, origin_chunk: Vc) -> Vc { + Vc::upcast(EcmascriptDevChunkContent::new( + origin_chunk, + self.chunking_context, + self.chunk_group, + self.evaluated_entries, + )) + } + + #[turbo_tasks::function] + async fn merge( + &self, + runtimes: Vec>, + ) -> Result> { + let Self { + chunking_context, + chunk_group, + evaluated_entries, + } = self; + + let chunking_context = chunking_context.resolve().await?; + let chunk_group = if let Some(chunk_group) = chunk_group { + Some(chunk_group.resolve().await?) + } else { + None + }; + + let mut evaluated_entries = if let Some(evaluated_entries) = evaluated_entries { + Some(evaluated_entries.await?.clone_value()) + } else { + None + }; + + for runtime in runtimes { + let Some(runtime) = + Vc::try_resolve_downcast_type::(runtime).await? + else { + bail!("cannot merge EcmascriptDevChunkRuntime with non-EcmascriptDevChunkRuntime"); + }; + + let Self { + chunking_context: other_chunking_context, + chunk_group: other_chunk_group, + evaluated_entries: other_evaluated_entries, + } = &*runtime.await?; + + let other_chunking_context = other_chunking_context.resolve().await?; + let other_chunk_group = if let Some(other_chunk_group) = other_chunk_group { + Some(other_chunk_group.resolve().await?) + } else { + None + }; + + if chunking_context != other_chunking_context { + bail!("cannot merge EcmascriptDevChunkRuntime with different chunking contexts",); + } + + if chunk_group != other_chunk_group { + bail!("cannot merge EcmascriptDevChunkRuntime with different chunk groups",); + } + + match (&mut evaluated_entries, other_evaluated_entries) { + (Some(evaluated_entries), Some(other_evaluated_entries)) => { + evaluated_entries.extend(other_evaluated_entries.await?.iter().copied()); + } + (None, Some(other_evaluated_entries)) => { + evaluated_entries = Some(other_evaluated_entries.await?.clone_value()); + } + _ => {} + } + } + + Ok(EcmascriptDevChunkRuntime { + chunking_context, + chunk_group, + evaluated_entries: evaluated_entries.map(Vc::cell), + } + .cell() + .into()) + } +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/update.rs b/turbopack/crates/turbopack-browser/src/ecmascript/update.rs new file mode 100644 index 0000000000000..42409015bf958 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/update.rs @@ -0,0 +1,68 @@ +use anyhow::Result; +use indexmap::IndexMap; +use turbo_tasks::{ReadRef, Vc}; +use turbopack_core::{chunk::ModuleId, code_builder::Code}; + +use super::{content::EcmascriptDevChunkContent, version::EcmascriptDevChunkVersion}; + +pub(super) enum EcmascriptChunkUpdate { + None, + Partial(EcmascriptChunkPartialUpdate), +} + +pub(super) struct EcmascriptChunkPartialUpdate { + pub added: IndexMap, (u64, Vc)>, + pub deleted: IndexMap, u64>, + pub modified: IndexMap, Vc>, +} + +pub(super) async fn update_ecmascript_chunk( + content: Vc, + from: &ReadRef, +) -> Result { + let to = content.own_version().await?; + + // When to and from point to the same value we can skip comparing them. + // This will happen since `TraitRef>>::cell` will not clone + // the value, but only make the cell point to the same immutable value + // (Arc). + if from.ptr_eq(&to) { + return Ok(EcmascriptChunkUpdate::None); + } + + let content = content.await?; + + let entries = content.entries.await?; + let mut added = IndexMap::default(); + let mut modified = IndexMap::default(); + let mut deleted = IndexMap::default(); + + for (id, from_hash) in &from.entries_hashes { + if let Some(entry) = entries.get(id) { + if *entry.hash.await? != *from_hash { + modified.insert(id.clone(), entry.code); + } + } else { + deleted.insert(id.clone(), *from_hash); + } + } + + // Remaining entries are added + for (id, entry) in entries.iter() { + if !from.entries_hashes.contains_key(id) { + added.insert(id.clone(), (*entry.hash.await?, entry.code)); + } + } + + let update = if added.is_empty() && modified.is_empty() && deleted.is_empty() { + EcmascriptChunkUpdate::None + } else { + EcmascriptChunkUpdate::Partial(EcmascriptChunkPartialUpdate { + added, + modified, + deleted, + }) + }; + + Ok(update) +} diff --git a/turbopack/crates/turbopack-browser/src/ecmascript/version.rs b/turbopack/crates/turbopack-browser/src/ecmascript/version.rs new file mode 100644 index 0000000000000..a666b3f11bca4 --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/ecmascript/version.rs @@ -0,0 +1,66 @@ +use anyhow::{bail, Result}; +use indexmap::IndexMap; +use turbo_tasks::{RcStr, ReadRef, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbo_tasks_hash::{encode_hex, Xxh3Hash64Hasher}; +use turbopack_core::{chunk::ModuleId, version::Version}; + +use super::content_entry::EcmascriptDevChunkContentEntries; + +#[turbo_tasks::value(serialization = "none")] +pub(super) struct EcmascriptDevChunkVersion { + pub(super) chunk_path: String, + pub(super) entries_hashes: IndexMap, u64>, +} + +#[turbo_tasks::value_impl] +impl EcmascriptDevChunkVersion { + #[turbo_tasks::function] + pub async fn new( + output_root: Vc, + chunk_path: Vc, + entries: Vc, + ) -> Result> { + let output_root = output_root.await?; + let chunk_path = chunk_path.await?; + let chunk_path = if let Some(path) = output_root.get_path_to(&chunk_path) { + path + } else { + bail!( + "chunk path {} is not in client root {}", + chunk_path.to_string(), + output_root.to_string() + ); + }; + let entries = entries.await?; + let mut entries_hashes = IndexMap::with_capacity(entries.len()); + for (id, entry) in entries.iter() { + entries_hashes.insert(id.clone(), *entry.hash.await?); + } + Ok(EcmascriptDevChunkVersion { + chunk_path: chunk_path.to_string(), + entries_hashes, + } + .cell()) + } +} + +#[turbo_tasks::value_impl] +impl Version for EcmascriptDevChunkVersion { + #[turbo_tasks::function] + fn id(&self) -> Vc { + let mut hasher = Xxh3Hash64Hasher::new(); + hasher.write_ref(&self.chunk_path); + let sorted_hashes = { + let mut hashes: Vec<_> = self.entries_hashes.values().copied().collect(); + hashes.sort(); + hashes + }; + for hash in sorted_hashes { + hasher.write_value(hash); + } + let hash = hasher.finish(); + let hex_hash = encode_hex(hash); + Vc::cell(hex_hash.into()) + } +} diff --git a/turbopack/crates/turbopack-browser/src/lib.rs b/turbopack/crates/turbopack-browser/src/lib.rs new file mode 100644 index 0000000000000..7dead634c88bd --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/lib.rs @@ -0,0 +1,20 @@ +#![feature(lint_reasons)] +#![feature(iter_intersperse)] +#![feature(int_roundings)] +#![feature(arbitrary_self_types)] + +pub(crate) mod chunking_context; +pub mod ecmascript; +pub mod react_refresh; + +pub use chunking_context::{BrowserChunkingContext, BrowserChunkingContextBuilder}; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + turbopack_ecmascript_runtime::register(); + turbopack_resolve::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-browser/src/react_refresh.rs b/turbopack/crates/turbopack-browser/src/react_refresh.rs new file mode 100644 index 0000000000000..359a7703fc7fe --- /dev/null +++ b/turbopack/crates/turbopack-browser/src/react_refresh.rs @@ -0,0 +1,115 @@ +use anyhow::Result; +use turbo_tasks::{Value, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, + reference_type::{CommonJsReferenceSubType, ReferenceType}, + resolve::parse::Request, +}; +use turbopack_resolve::{ + ecmascript::apply_cjs_specific_options, resolve_options_context::ResolveOptionsContext, +}; + +#[turbo_tasks::function] +fn react_refresh_request() -> Vc { + Request::parse_string("@next/react-refresh-utils/dist/runtime".into()) +} + +#[turbo_tasks::function] +fn react_refresh_request_in_next() -> Vc { + Request::parse_string("next/dist/compiled/@next/react-refresh-utils/dist/runtime".into()) +} + +#[turbo_tasks::value] +pub enum ResolveReactRefreshResult { + NotFound, + Found(Vc), +} + +impl ResolveReactRefreshResult { + pub fn as_request(&self) -> Option> { + match self { + ResolveReactRefreshResult::NotFound => None, + ResolveReactRefreshResult::Found(r) => Some(*r), + } + } + pub fn is_found(&self) -> bool { + match self { + ResolveReactRefreshResult::NotFound => false, + ResolveReactRefreshResult::Found(_) => true, + } + } +} + +/// Checks whether we can resolve the React Refresh runtime module from the +/// given path. Emits an issue if we can't. +#[turbo_tasks::function] +pub async fn assert_can_resolve_react_refresh( + path: Vc, + resolve_options_context: Vc, +) -> Result> { + let resolve_options = apply_cjs_specific_options(turbopack_resolve::resolve::resolve_options( + path, + resolve_options_context, + )); + for request in [react_refresh_request_in_next(), react_refresh_request()] { + let result = turbopack_core::resolve::resolve( + path, + Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), + request, + resolve_options, + ) + .first_source(); + + if result.await?.is_some() { + return Ok(ResolveReactRefreshResult::Found(request).cell()); + } + } + ReactRefreshResolvingIssue { path }.cell().emit(); + Ok(ResolveReactRefreshResult::NotFound.cell()) +} + +/// An issue that occurred while resolving the React Refresh runtime module. +#[turbo_tasks::value(shared)] +pub struct ReactRefreshResolvingIssue { + path: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for ReactRefreshResolvingIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + IssueSeverity::Warning.into() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Could not resolve React Refresh runtime".into()).cell() + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Resolve.cell() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.path + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some( + StyledString::Line(vec![ + StyledString::Text( + "React Refresh will be disabled.\nTo enable React Refresh, install the ".into(), + ), + StyledString::Code("react-refresh".into()), + StyledString::Text(" and ".into()), + StyledString::Code("@next/react-refresh-utils".into()), + StyledString::Text(" modules.".into()), + ]) + .cell(), + )) + } +} diff --git a/turbopack/crates/turbopack-cli-utils/Cargo.toml b/turbopack/crates/turbopack-cli-utils/Cargo.toml new file mode 100644 index 0000000000000..079f6d851f8de --- /dev/null +++ b/turbopack/crates/turbopack-cli-utils/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "turbopack-cli-utils" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, features = ["derive"] } +crossterm = "0.26.0" +owo-colors = { workspace = true } +serde = { workspace = true, features = ["derive"] } +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbopack-core = { workspace = true } +turbopack-resolve = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-cli-utils/build.rs b/turbopack/crates/turbopack-cli-utils/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-cli-utils/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-cli-utils/src/issue.rs b/turbopack/crates/turbopack-cli-utils/src/issue.rs new file mode 100644 index 0000000000000..fd73e10ff7e0b --- /dev/null +++ b/turbopack/crates/turbopack-cli-utils/src/issue.rs @@ -0,0 +1,599 @@ +use std::{ + borrow::Cow, + cmp::min, + collections::{hash_map::Entry, HashMap, HashSet}, + fmt::Write as _, + path::{Path, PathBuf}, + str::FromStr, + sync::{Arc, Mutex}, +}; + +use anyhow::{anyhow, Result}; +use crossterm::style::{StyledContent, Stylize}; +use owo_colors::{OwoColorize as _, Style}; +use turbo_tasks::{RawVc, ReadRef, TransientInstance, TransientValue, TryJoinIterExt, Vc}; +use turbo_tasks_fs::{source_context::get_source_context, FileLinesContent}; +use turbopack_core::issue::{ + CapturedIssues, Issue, IssueReporter, IssueSeverity, PlainIssue, PlainIssueProcessingPathItem, + PlainIssueSource, StyledString, +}; + +use crate::source_context::format_source_context_lines; + +#[derive(Clone, Copy, PartialEq, Eq, Debug)] +pub struct IssueSeverityCliOption(pub IssueSeverity); + +impl serde::Serialize for IssueSeverityCliOption { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(&self.0.to_string()) + } +} + +impl<'de> serde::Deserialize<'de> for IssueSeverityCliOption { + fn deserialize>(deserializer: D) -> Result { + let s = String::deserialize(deserializer)?; + IssueSeverityCliOption::from_str(&s).map_err(serde::de::Error::custom) + } +} + +impl clap::ValueEnum for IssueSeverityCliOption { + fn value_variants<'a>() -> &'a [Self] { + const VARIANTS: [IssueSeverityCliOption; 8] = [ + IssueSeverityCliOption(IssueSeverity::Bug), + IssueSeverityCliOption(IssueSeverity::Fatal), + IssueSeverityCliOption(IssueSeverity::Error), + IssueSeverityCliOption(IssueSeverity::Warning), + IssueSeverityCliOption(IssueSeverity::Hint), + IssueSeverityCliOption(IssueSeverity::Note), + IssueSeverityCliOption(IssueSeverity::Suggestion), + IssueSeverityCliOption(IssueSeverity::Info), + ]; + &VARIANTS + } + + fn to_possible_value<'a>(&self) -> Option { + Some(clap::builder::PossibleValue::new(self.0.as_str()).help(self.0.as_help_str())) + } +} + +impl FromStr for IssueSeverityCliOption { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + ::from_str(s, true).map_err(|s| anyhow!("{}", s)) + } +} + +fn severity_to_style(severity: IssueSeverity) -> Style { + match severity { + IssueSeverity::Bug => Style::new().bright_red().underline(), + IssueSeverity::Fatal => Style::new().bright_red().underline(), + IssueSeverity::Error => Style::new().bright_red(), + IssueSeverity::Warning => Style::new().bright_yellow(), + IssueSeverity::Hint => Style::new().bold(), + IssueSeverity::Note => Style::new().bold(), + IssueSeverity::Suggestion => Style::new().bright_green().underline(), + IssueSeverity::Info => Style::new().bright_green(), + } +} + +fn format_source_content(source: &PlainIssueSource, formatted_issue: &mut String) { + if let FileLinesContent::Lines(lines) = source.asset.content.lines_ref() { + if let Some((start, end)) = source.range { + let lines = lines.iter().map(|l| l.content.as_str()); + let ctx = get_source_context(lines, start.line, start.column, end.line, end.column); + format_source_context_lines(&ctx, formatted_issue); + } + } +} + +fn format_optional_path( + path: &Option>>, + formatted_issue: &mut String, +) -> Result<()> { + if let Some(path) = path { + let mut last_context = None; + for item in path.iter().rev() { + let PlainIssueProcessingPathItem { + file_path: ref context, + ref description, + } = **item; + if let Some(context) = context { + let option_context = Some(context.clone()); + if last_context == option_context { + writeln!(formatted_issue, " at {}", description)?; + } else { + writeln!( + formatted_issue, + " at {} ({})", + context.to_string().bright_blue(), + description + )?; + last_context = option_context; + } + } else { + writeln!(formatted_issue, " at {}", description)?; + last_context = None; + } + } + } + Ok(()) +} + +pub fn format_issue( + plain_issue: &PlainIssue, + path: Option, + options: &LogOptions, +) -> String { + let &LogOptions { + ref current_dir, + log_detail, + .. + } = options; + + let mut issue_text = String::new(); + + let severity = plain_issue.severity; + // TODO CLICKABLE PATHS + let context_path = plain_issue + .file_path + .replace("[project]", ¤t_dir.to_string_lossy()) + .replace("/./", "/") + .replace("\\\\?\\", ""); + let stgae = plain_issue.stage.to_string(); + + let mut styled_issue = style_issue_source(plain_issue, &context_path); + let description = &plain_issue.description; + if let Some(description) = description { + writeln!( + styled_issue, + "\n{}", + render_styled_string_to_ansi(description) + ) + .unwrap(); + } + + if log_detail { + styled_issue.push('\n'); + let detail = &plain_issue.detail; + if let Some(detail) = detail { + for line in render_styled_string_to_ansi(detail).split('\n') { + writeln!(styled_issue, "| {line}").unwrap(); + } + } + let documentation_link = &plain_issue.documentation_link; + if !documentation_link.is_empty() { + writeln!(styled_issue, "\ndocumentation: {documentation_link}").unwrap(); + } + if let Some(path) = path { + writeln!(styled_issue, "{}", path).unwrap(); + } + } + + write!( + issue_text, + "{} - [{}] {}", + severity.style(severity_to_style(severity)), + stgae, + plain_issue.file_path + ) + .unwrap(); + + for line in styled_issue.lines() { + writeln!(issue_text, " {line}").unwrap(); + } + + issue_text +} + +pub type GroupedIssues = HashMap>>>; + +const DEFAULT_SHOW_COUNT: usize = 3; + +const ORDERED_GROUPS: &[IssueSeverity] = &[ + IssueSeverity::Bug, + IssueSeverity::Fatal, + IssueSeverity::Error, + IssueSeverity::Warning, + IssueSeverity::Hint, + IssueSeverity::Note, + IssueSeverity::Suggestion, + IssueSeverity::Info, +]; + +#[turbo_tasks::value(shared)] +#[derive(Debug, Clone)] +pub struct LogOptions { + pub current_dir: PathBuf, + pub project_dir: PathBuf, + pub show_all: bool, + pub log_detail: bool, + pub log_level: IssueSeverity, +} + +/// Tracks the state of currently seen issues. +/// +/// An issue is considered seen as long as a single source has pulled the issue. +/// When a source repulls emitted issues due to a recomputation somewhere in its +/// graph, there are a few possibilities: +/// +/// 1. An issue from this pull is brand new to all sources, in which case it +/// will be logged and the issue's count is inremented. +/// 2. An issue from this pull is brand new to this source but another source +/// has already pulled it, in which case it will be logged and the issue's +/// count is incremented. +/// 3. The previous pull from this source had already seen the issue, in which +/// case the issue will be skipped and the issue's count remains constant. +/// 4. An issue seen in a previous pull was not repulled, and the issue's count +/// is decremented. +/// +/// Once an issue's count reaches zero, it's removed. If it is ever seen again, +/// it is considered new and will be relogged. +#[derive(Default)] +struct SeenIssues { + /// Keeps track of all issue pulled from the source. Used so that we can + /// decrement issues that are not pulled in the current synchronization. + source_to_issue_ids: HashMap>, + + /// Counts the number of times a particular issue is seen across all + /// sources. As long as the count is positive, an issue is considered + /// "seen" and will not be relogged. Once the count reaches zero, the + /// issue is removed and the next time its seen it will be considered new. + issues_count: HashMap, +} + +impl SeenIssues { + fn new() -> Self { + Default::default() + } + + /// Synchronizes state between the issues previously pulled from this + /// source, to the issues now pulled. + fn new_ids(&mut self, source: RawVc, issue_ids: HashSet) -> HashSet { + let old = self.source_to_issue_ids.entry(source).or_default(); + + // difference is the issues that were never counted before. + let difference = issue_ids + .iter() + .filter(|id| match self.issues_count.entry(**id) { + Entry::Vacant(e) => { + // If the issue not currently counted, then it's new and should be logged. + e.insert(1); + true + } + Entry::Occupied(mut e) => { + if old.contains(*id) { + // If old contains the id, then we don't need to change the count, but we + // do need to remove the entry. Doing so allows us to iterate the final old + // state and decrement old issues. + old.remove(*id); + } else { + // If old didn't contain the entry, then this issue was already counted + // from a difference source. + *e.get_mut() += 1; + } + false + } + }) + .cloned() + .collect::>(); + + // Old now contains only the ids that were not present in the new issue_ids. + for id in old.iter() { + match self.issues_count.entry(*id) { + Entry::Vacant(_) => unreachable!("issue must already be tracked to appear in old"), + Entry::Occupied(mut e) => { + let v = e.get_mut(); + if *v == 1 { + // If this was the last counter of the issue, then we need to prune the + // value to free memory. + e.remove(); + } else { + // Another source counted the issue, and it must not be relogged until all + // sources remove it. + *v -= 1; + } + } + } + } + + *old = issue_ids; + difference + } +} + +/// Logs emitted issues to console logs, deduplicating issues between peeks of +/// the collected issues. The ConsoleUi can be shared and capture issues from +/// multiple sources, with deduplication operating across all issues. +#[turbo_tasks::value(shared, serialization = "none", eq = "manual")] +#[derive(Clone)] +pub struct ConsoleUi { + options: LogOptions, + + #[turbo_tasks(trace_ignore, debug_ignore)] + seen: Arc>, +} + +impl PartialEq for ConsoleUi { + fn eq(&self, other: &Self) -> bool { + self.options == other.options + } +} + +#[turbo_tasks::value_impl] +impl ConsoleUi { + #[turbo_tasks::function] + pub fn new(options: TransientInstance) -> Vc { + ConsoleUi { + options: (*options).clone(), + seen: Arc::new(Mutex::new(SeenIssues::new())), + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl IssueReporter for ConsoleUi { + #[turbo_tasks::function] + async fn report_issues( + &self, + issues: TransientInstance, + source: TransientValue, + min_failing_severity: Vc, + ) -> Result> { + let issues = &*issues; + let LogOptions { + ref current_dir, + ref project_dir, + show_all, + log_detail, + log_level, + .. + } = self.options; + let mut grouped_issues: GroupedIssues = HashMap::new(); + + let issues = issues + .iter_with_shortest_path() + .map(|(issue, path)| async move { + let plain_issue = issue.into_plain(path); + let id = plain_issue.internal_hash(false).await?; + Ok((plain_issue.await?, *id)) + }) + .try_join() + .await?; + + let issue_ids = issues.iter().map(|(_, id)| *id).collect::>(); + let mut new_ids = self + .seen + .lock() + .unwrap() + .new_ids(source.into_value(), issue_ids); + + let mut has_fatal = false; + for (plain_issue, id) in issues { + if !new_ids.remove(&id) { + continue; + } + + let severity = plain_issue.severity; + if severity <= *min_failing_severity.await? { + has_fatal = true; + } + + let context_path = + make_relative_to_cwd(&plain_issue.file_path, project_dir, current_dir); + let stage = plain_issue.stage.to_string(); + let processing_path = &*plain_issue.processing_path; + let severity_map = grouped_issues.entry(severity).or_default(); + let category_map = severity_map.entry(stage.clone()).or_default(); + let issues = category_map.entry(context_path.to_string()).or_default(); + + let mut styled_issue = style_issue_source(&plain_issue, &context_path); + let description = &plain_issue.description; + if let Some(description) = description { + writeln!( + &mut styled_issue, + "\n{}", + render_styled_string_to_ansi(description) + )?; + } + + if log_detail { + styled_issue.push('\n'); + let detail = &plain_issue.detail; + if let Some(detail) = detail { + for line in render_styled_string_to_ansi(detail).split('\n') { + writeln!(&mut styled_issue, "| {line}")?; + } + } + let documentation_link = &plain_issue.documentation_link; + if !documentation_link.is_empty() { + writeln!(&mut styled_issue, "\ndocumentation: {documentation_link}")?; + } + format_optional_path(processing_path, &mut styled_issue)?; + } + issues.push(styled_issue); + } + + for severity in ORDERED_GROUPS.iter().copied().filter(|l| *l <= log_level) { + if let Some(severity_map) = grouped_issues.get_mut(&severity) { + let severity_map_size = severity_map.len(); + let indent = if severity_map_size == 1 { + print!("{} - ", severity.style(severity_to_style(severity))); + "" + } else { + println!("{} -", severity.style(severity_to_style(severity))); + " " + }; + let severity_map_take_count = if show_all { + severity_map_size + } else { + DEFAULT_SHOW_COUNT + }; + let mut categories = severity_map.keys().cloned().collect::>(); + categories.sort(); + for category in categories.iter().take(severity_map_take_count) { + let category_issues = severity_map.get_mut(category).unwrap(); + let category_issues_size = category_issues.len(); + let indent = if category_issues_size == 1 && indent.is_empty() { + print!("[{category}] "); + "".to_string() + } else { + println!("{indent}[{category}]"); + format!("{indent} ") + }; + let (mut contextes, mut vendor_contextes): (Vec<_>, Vec<_>) = category_issues + .iter_mut() + .partition(|(context, _)| !context.contains("node_modules")); + contextes.sort_by_key(|(c, _)| *c); + if show_all { + vendor_contextes.sort_by_key(|(c, _)| *c); + contextes.extend(vendor_contextes); + } + let category_issues_take_count = if show_all { + category_issues_size + } else { + min(contextes.len(), DEFAULT_SHOW_COUNT) + }; + for (context, issues) in contextes.into_iter().take(category_issues_take_count) + { + issues.sort(); + println!("{indent}{}", context.bright_blue()); + let issues_size = issues.len(); + let issues_take_count = if show_all { + issues_size + } else { + DEFAULT_SHOW_COUNT + }; + for issue in issues.iter().take(issues_take_count) { + let mut i = 0; + for line in issue.lines() { + println!("{indent} {line}"); + i += 1; + } + if i > 1 { + // Spacing after multi line issues + println!(); + } + } + if issues_size > issues_take_count { + println!("{indent} {}", show_all_message("issues", issues_size)); + } + } + if category_issues_size > category_issues_take_count { + println!( + "{indent}{}", + show_all_message_with_shown_count( + "paths", + category_issues_size, + category_issues_take_count + ) + ); + } + } + if severity_map_size > severity_map_take_count { + println!( + "{indent}{}", + show_all_message("categories", severity_map_size) + ) + } + } + } + + Ok(Vc::cell(has_fatal)) + } +} + +fn make_relative_to_cwd<'a>(path: &'a str, project_dir: &Path, cwd: &Path) -> Cow<'a, str> { + if let Some(path_in_project) = path.strip_prefix("[project]/") { + let abs_path = if std::path::MAIN_SEPARATOR != '/' { + project_dir.join(path_in_project.replace('/', std::path::MAIN_SEPARATOR_STR)) + } else { + project_dir.join(path_in_project) + }; + let relative = abs_path + .strip_prefix(cwd) + .unwrap_or(&abs_path) + .to_string_lossy() + .to_string(); + relative.into() + } else { + path.into() + } +} + +fn show_all_message(label: &str, size: usize) -> StyledContent { + show_all_message_with_shown_count(label, size, DEFAULT_SHOW_COUNT) +} + +fn show_all_message_with_shown_count( + label: &str, + size: usize, + shown: usize, +) -> StyledContent { + if shown == 0 { + format!( + "... [{} {label}] are hidden, run with {} to show them", + size, + "--show-all".bright_green() + ) + .bold() + } else { + format!( + "... [{} more {label}] are hidden, run with {} to show all", + size - shown, + "--show-all".bright_green() + ) + .bold() + } +} + +fn render_styled_string_to_ansi(styled_string: &StyledString) -> String { + match styled_string { + StyledString::Line(parts) => { + let mut string = String::new(); + for part in parts { + string.push_str(&render_styled_string_to_ansi(part)); + } + string.push('\n'); + string + } + StyledString::Stack(parts) => { + let mut string = String::new(); + for part in parts { + string.push_str(&render_styled_string_to_ansi(part)); + string.push('\n'); + } + string + } + StyledString::Text(string) => string.to_string(), + StyledString::Code(string) => string.blue().to_string(), + StyledString::Strong(string) => string.bold().to_string(), + } +} + +fn style_issue_source(plain_issue: &PlainIssue, context_path: &str) -> String { + let title = &plain_issue.title; + let formatted_title = match title { + StyledString::Text(text) => text.bold().to_string(), + _ => render_styled_string_to_ansi(title), + }; + + if let Some(source) = &plain_issue.source { + let mut styled_issue = match source.range { + Some((start, _)) => format!( + "{}:{}:{} {}", + context_path, + start.line + 1, + start.column, + formatted_title + ), + None => format!("{} {}", context_path, formatted_title), + }; + styled_issue.push('\n'); + format_source_content(source, &mut styled_issue); + styled_issue + } else { + formatted_title + } +} diff --git a/turbopack/crates/turbopack-cli-utils/src/lib.rs b/turbopack/crates/turbopack-cli-utils/src/lib.rs new file mode 100644 index 0000000000000..6c544788bb63b --- /dev/null +++ b/turbopack/crates/turbopack-cli-utils/src/lib.rs @@ -0,0 +1,17 @@ +#![feature(async_closure)] +#![feature(min_specialization)] +#![feature(round_char_boundary)] +#![feature(thread_id_value)] +#![feature(arbitrary_self_types)] + +pub mod issue; +pub mod runtime_entry; +pub mod source_context; + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_resolve::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-cli-utils/src/runtime_entry.rs b/turbopack/crates/turbopack-cli-utils/src/runtime_entry.rs new file mode 100644 index 0000000000000..8d20decbdb90b --- /dev/null +++ b/turbopack/crates/turbopack-cli-utils/src/runtime_entry.rs @@ -0,0 +1,84 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + chunk::{EvaluatableAsset, EvaluatableAssetExt, EvaluatableAssets}, + context::AssetContext, + issue::IssueSeverity, + module::Module, + resolve::{origin::PlainResolveOrigin, parse::Request}, + source::Source, +}; +use turbopack_resolve::ecmascript::cjs_resolve; + +#[turbo_tasks::value(shared)] +pub enum RuntimeEntry { + Request(Vc, Vc), + Evaluatable(Vc>), + Source(Vc>), +} + +#[turbo_tasks::value_impl] +impl RuntimeEntry { + #[turbo_tasks::function] + pub async fn resolve_entry( + self: Vc, + asset_context: Vc>, + ) -> Result> { + let (request, path) = match *self.await? { + RuntimeEntry::Evaluatable(e) => return Ok(EvaluatableAssets::one(e)), + RuntimeEntry::Source(source) => { + return Ok(EvaluatableAssets::one(source.to_evaluatable(asset_context))); + } + RuntimeEntry::Request(r, path) => (r, path), + }; + + let modules = cjs_resolve( + Vc::upcast(PlainResolveOrigin::new(asset_context, path)), + request, + None, + IssueSeverity::Error.cell(), + ) + .resolve() + .await? + .primary_modules() + .await?; + + let mut runtime_entries = Vec::with_capacity(modules.len()); + for &module in &modules { + if let Some(entry) = + Vc::try_resolve_sidecast::>(module).await? + { + runtime_entries.push(entry); + } else { + bail!( + "runtime reference resolved to an asset ({}) that cannot be evaluated", + module.ident().to_string().await? + ); + } + } + + Ok(Vc::cell(runtime_entries)) + } +} + +#[turbo_tasks::value(transparent)] +pub struct RuntimeEntries(Vec>); + +#[turbo_tasks::value_impl] +impl RuntimeEntries { + #[turbo_tasks::function] + pub async fn resolve_entries( + self: Vc, + asset_context: Vc>, + ) -> Result> { + let mut runtime_entries = Vec::new(); + + for reference in &self.await? { + let resolved_entries = reference.resolve_entry(asset_context).await?; + runtime_entries.extend(&resolved_entries); + } + + Ok(Vc::cell(runtime_entries)) + } +} diff --git a/turbopack/crates/turbopack-cli-utils/src/source_context.rs b/turbopack/crates/turbopack-cli-utils/src/source_context.rs new file mode 100644 index 0000000000000..a178d99972056 --- /dev/null +++ b/turbopack/crates/turbopack-cli-utils/src/source_context.rs @@ -0,0 +1,135 @@ +use std::fmt::{Display, Write}; + +use owo_colors::OwoColorize; +use turbo_tasks_fs::source_context::{SourceContextLine, SourceContextLines}; + +struct MarkerRange { + start: char, + end: char, + pos: usize, + len: usize, +} + +impl Display for MarkerRange { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + for _ in 0..self.pos { + f.write_char(' ')?; + } + f.write_char(self.start)?; + if self.len > 1 { + for _ in 2..self.len { + f.write_char('-')?; + } + f.write_char(self.end)?; + } + Ok(()) + } +} + +pub fn format_source_context_lines(ctx: &SourceContextLines, f: &mut impl Write) { + const PADDING: usize = 6; + const SPACE: char = ' '; + for line in &ctx.0 { + match line { + SourceContextLine::Context { line, outside } => { + writeln!( + f, + "{}", + format_args!("{line:>PADDING$} | {outside}").dimmed() + ) + .unwrap(); + } + SourceContextLine::Start { + line, + before, + inside, + } => { + writeln!( + f, + "{SPACE:PADDING$} | {}", + MarkerRange { + start: 'v', + end: '-', + pos: before.len(), + len: inside.len(), + } + .bold(), + ) + .unwrap(); + writeln!(f, "{line:>PADDING$} + {}{}", before.dimmed(), inside.bold()).unwrap(); + } + SourceContextLine::End { + line, + inside, + after, + } => { + writeln!(f, "{line:>PADDING$} + {}{}", inside.bold(), after.dimmed()).unwrap(); + writeln!( + f, + "{SPACE:PADDING$} +{}", + MarkerRange { + start: '-', + end: '^', + pos: 0, + len: inside.len() + 1, + } + .bold() + ) + .unwrap(); + } + SourceContextLine::StartAndEnd { + line, + before, + inside, + after, + } => { + writeln!( + f, + "{SPACE:PADDING$} + {}", + MarkerRange { + start: 'v', + end: 'v', + pos: before.len(), + len: inside.len(), + } + .bold() + ) + .unwrap(); + if inside.len() >= 2 { + writeln!( + f, + "{line:>PADDING$} + {}{}{}", + before.dimmed(), + inside.bold(), + after.dimmed() + ) + .unwrap(); + } else { + writeln!( + f, + "{line:>PADDING$} + {}{}{}", + before.bold(), + inside.bold(), + after.bold() + ) + .unwrap(); + } + writeln!( + f, + "{SPACE:PADDING$} + {}", + MarkerRange { + start: '^', + end: '^', + pos: before.len(), + len: inside.len(), + } + .bold() + ) + .unwrap(); + } + SourceContextLine::Inside { line, inside } => { + writeln!(f, "{:>PADDING$} + {}", line.bold(), inside.bold()).unwrap(); + } + } + } +} diff --git a/turbopack/crates/turbopack-cli/Cargo.toml b/turbopack/crates/turbopack-cli/Cargo.toml new file mode 100644 index 0000000000000..5f8904a166c95 --- /dev/null +++ b/turbopack/crates/turbopack-cli/Cargo.toml @@ -0,0 +1,84 @@ +[package] +name = "turbopack-cli" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[[bin]] +name = "turbopack-cli" +path = "src/main.rs" +bench = false + +[lib] +bench = false + +[[bench]] +name = "mod" +harness = false + +[features] +# By default, we enable native-tls for reqwest via downstream transitive features. +# This is for the convenience of running daily dev workflows, i.e running +# `cargo xxx` without explicitly specifying features, not that we want to +# promote this as default backend. Actual configuration is done when building turbopack-cli. +default = ["custom_allocator", "native-tls"] +serializable = [] +tokio_console = [ + "dep:console-subscriber", + "tokio/tracing", + "turbo-tasks/tokio_tracing", +] +profile = [] +custom_allocator = ["turbo-tasks-malloc/custom_allocator"] +native-tls = ["turbo-tasks-fetch/native-tls"] +rustls-tls = ["turbo-tasks-fetch/rustls-tls"] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true, features = ["backtrace"] } +clap = { workspace = true, features = ["derive", "env"] } +console-subscriber = { workspace = true, optional = true } +dunce = { workspace = true } +futures = { workspace = true } +mime = { workspace = true } +owo-colors = { workspace = true } +serde = { workspace = true } +tokio = { workspace = true, features = ["full"] } +tracing-subscriber = { workspace = true, features = ["env-filter", "json"] } +turbo-tasks = { workspace = true } +turbo-tasks-env = { workspace = true } +turbo-tasks-fetch = { workspace = true, default-features = false } +turbo-tasks-fs = { workspace = true } +turbo-tasks-malloc = { workspace = true, default-features = false } +turbo-tasks-memory = { workspace = true } +turbopack = { workspace = true } +turbopack-browser = { workspace = true } +turbopack-cli-utils = { workspace = true } +turbopack-core = { workspace = true } +turbopack-dev-server = { workspace = true } +turbopack-ecmascript-plugins = { workspace = true, features = [ + "transform_emotion", +] } +turbopack-ecmascript-runtime = { workspace = true } +turbopack-env = { workspace = true } +turbopack-node = { workspace = true } +turbopack-nodejs = { workspace = true } +turbopack-resolve = { workspace = true } +turbopack-trace-server = { workspace = true } +turbopack-trace-utils = { workspace = true } +webbrowser = { workspace = true } + +[dev-dependencies] +criterion = { workspace = true, features = ["async_tokio"] } +regex = { workspace = true } +turbopack-bench = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } + +[target.'cfg(target_os = "macos")'.dependencies] +tracing-signpost = { workspace = true } diff --git a/turbopack/crates/turbopack-cli/benches/bundler.rs b/turbopack/crates/turbopack-cli/benches/bundler.rs new file mode 100644 index 0000000000000..75c3e29ed2b68 --- /dev/null +++ b/turbopack/crates/turbopack-cli/benches/bundler.rs @@ -0,0 +1,87 @@ +use std::{ + path::Path, + process::{Child, Command, Stdio}, + time::Duration, +}; + +use anyhow::{anyhow, Context, Result}; +use regex::Regex; +use turbopack_bench::{ + bundlers::{Bundler, RenderType}, + util::{ + npm::{ + NpmPackage, {self}, + }, + wait_for_match, + }, +}; + +pub struct Turbopack; + +impl Turbopack { + pub fn new() -> Self { + Turbopack + } +} + +impl Bundler for Turbopack { + fn get_name(&self) -> &str { + "Turbopack CSR" + } + + fn get_path(&self) -> &str { + "/" + } + + fn render_type(&self) -> RenderType { + RenderType::ClientSideRendered + } + + fn prepare(&self, install_dir: &Path) -> Result<()> { + npm::install( + install_dir, + &[ + NpmPackage::new("react-refresh", "^0.14.0"), + NpmPackage::new("@next/react-refresh-utils", "^13.3.0"), + NpmPackage::new("@swc/helpers", "0.4.11"), + ], + ) + .context("failed to install from npm")?; + + Ok(()) + } + + fn start_server(&self, test_dir: &Path) -> Result<(Child, String)> { + let binary = std::env::var("CARGO_BIN_EXE_turobpack-cli") + .unwrap_or_else(|_| std::env!("CARGO_BIN_EXE_turbopack-cli").to_string()); + let mut proc = Command::new(binary) + .args([ + "dev", + "--dir", + test_dir + .to_str() + .ok_or_else(|| anyhow!("failed to convert test directory path to string"))?, + "src/index", + "--no-open", + "--port", + "0", + ]) + .stdout(Stdio::piped()) + .spawn()?; + + // Wait for the devserver address to appear in stdout. + let addr = wait_for_match( + proc.stdout + .as_mut() + .ok_or_else(|| anyhow!("missing stdout"))?, + Regex::new("started server on .+, url: (.*)")?, + ) + .ok_or_else(|| anyhow!("failed to find devserver address"))?; + + Ok((proc, addr)) + } + + fn max_update_timeout(&self, _module_count: usize) -> std::time::Duration { + Duration::from_millis(500) + } +} diff --git a/turbopack/crates/turbopack-cli/benches/mod.rs b/turbopack/crates/turbopack-cli/benches/mod.rs new file mode 100644 index 0000000000000..7236f5cc340b7 --- /dev/null +++ b/turbopack/crates/turbopack-cli/benches/mod.rs @@ -0,0 +1,39 @@ +use criterion::{criterion_group, criterion_main, Criterion}; +use turbopack_bench::bundlers::Bundler; + +mod bundler; + +fn get_bundlers() -> Vec> { + vec![Box::new(bundler::Turbopack::new())] +} + +fn bench_startup(c: &mut Criterion) { + turbopack_bench::bench_startup(c, &get_bundlers()) +} + +fn bench_hydration(c: &mut Criterion) { + turbopack_bench::bench_hydration(c, &get_bundlers()) +} + +fn bench_startup_cached(c: &mut Criterion) { + turbopack_bench::bench_startup_cached(c, &get_bundlers()) +} + +fn bench_hydration_cached(c: &mut Criterion) { + turbopack_bench::bench_hydration_cached(c, &get_bundlers()) +} + +fn bench_hmr_to_eval(c: &mut Criterion) { + turbopack_bench::bench_hmr_to_eval(c, &get_bundlers()) +} + +fn bench_hmr_to_commit(c: &mut Criterion) { + turbopack_bench::bench_hmr_to_commit(c, &get_bundlers()) +} + +criterion_group!( + name = benches; + config = Criterion::default(); + targets = bench_startup, bench_hydration, bench_startup_cached, bench_hydration_cached, bench_hmr_to_eval, bench_hmr_to_commit +); +criterion_main!(benches); diff --git a/turbopack/crates/turbopack-cli/build.rs b/turbopack/crates/turbopack-cli/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-cli/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-cli/js/package.json b/turbopack/crates/turbopack-cli/js/package.json new file mode 100644 index 0000000000000..21dd9ca55c833 --- /dev/null +++ b/turbopack/crates/turbopack-cli/js/package.json @@ -0,0 +1,16 @@ +{ + "name": "@vercel/turbopack-cli", + "version": "0.0.0", + "description": "Turbopack-cli runtime", + "license": "UNLICENSED", + "private": true, + "scripts": { + "check": "tsc --noEmit" + }, + "dependencies": { + "@vercel/turbopack-ecmascript-runtime": "*" + }, + "devDependencies": { + "@types/node": "^18.11.11" + } +} diff --git a/turbopack/crates/turbopack-cli/js/src/entry/bootstrap.ts b/turbopack/crates/turbopack-cli/js/src/entry/bootstrap.ts new file mode 100644 index 0000000000000..ed6a95a855f35 --- /dev/null +++ b/turbopack/crates/turbopack-cli/js/src/entry/bootstrap.ts @@ -0,0 +1,5 @@ +import { initializeHMR } from "./client"; + +initializeHMR({ + assetPrefix: "", +}); diff --git a/turbopack/crates/turbopack-cli/js/src/entry/client.ts b/turbopack/crates/turbopack-cli/js/src/entry/client.ts new file mode 100644 index 0000000000000..e508087323207 --- /dev/null +++ b/turbopack/crates/turbopack-cli/js/src/entry/client.ts @@ -0,0 +1,19 @@ +import { connect } from "@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/hmr-client"; +import { + connectHMR, + addMessageListener, + sendMessage, +} from "@vercel/turbopack-ecmascript-runtime/browser/dev/hmr-client/websocket"; + +export function initializeHMR(options: { assetPrefix: string }) { + connect({ + addMessageListener, + sendMessage, + onUpdateError: console.error, + }); + connectHMR({ + assetPrefix: options.assetPrefix, + log: true, + path: "/turbopack-hmr", + }); +} diff --git a/turbopack/crates/turbopack-cli/js/tsconfig.json b/turbopack/crates/turbopack-cli/js/tsconfig.json new file mode 100644 index 0000000000000..199259563288a --- /dev/null +++ b/turbopack/crates/turbopack-cli/js/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + // type checking + "strict": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + + // environment + "jsx": "react-jsx", + "lib": ["ESNext", "DOM"], + "target": "esnext", + + // modules + "baseUrl": ".", + "module": "nodenext", + "moduleResolution": "nodenext", + "types": [], + + // emit + "noEmit": true, + "stripInternal": true + }, + "include": ["src"] +} diff --git a/turbopack/crates/turbopack-cli/src/arguments.rs b/turbopack/crates/turbopack-cli/src/arguments.rs new file mode 100644 index 0000000000000..e76fd4243911f --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/arguments.rs @@ -0,0 +1,110 @@ +use std::{ + net::IpAddr, + path::{Path, PathBuf}, +}; + +use clap::{Args, Parser}; +use turbopack_cli_utils::issue::IssueSeverityCliOption; + +#[derive(Debug, Parser)] +#[clap(author, version, about, long_about = None)] +pub enum Arguments { + Build(BuildArguments), + Dev(DevArguments), +} + +impl Arguments { + /// The directory of the application. see [CommonArguments]::dir + pub fn dir(&self) -> Option<&Path> { + match self { + Arguments::Build(args) => args.common.dir.as_deref(), + Arguments::Dev(args) => args.common.dir.as_deref(), + } + } +} + +#[derive(Debug, Args, Clone)] +pub struct CommonArguments { + /// The entrypoints of the project. Resolved relative to the project's + /// directory (`--dir`). + #[clap(value_parser)] + pub entries: Option>, + + /// The directory of the application. + /// If no directory is provided, the current directory will be used. + #[clap(short, long, value_parser)] + pub dir: Option, + + /// The root directory of the project. Nothing outside of this directory can + /// be accessed. e. g. the monorepo root. + /// If no directory is provided, `dir` will be used. + #[clap(long, value_parser)] + pub root: Option, + + /// Filter by issue severity. + #[clap(short, long)] + pub log_level: Option, + + /// Show all log messages without limit. + #[clap(long)] + pub show_all: bool, + + /// Expand the log details. + #[clap(long)] + pub log_detail: bool, + + /// Whether to enable full task stats recording in Turbo Engine. + #[clap(long)] + pub full_stats: bool, + + /// Enable experimental garbage collection with the provided memory limit in + /// MB. + #[clap(long)] + pub memory_limit: Option, +} + +#[derive(Debug, Args)] +#[clap(author, version, about, long_about = None)] +pub struct DevArguments { + #[clap(flatten)] + pub common: CommonArguments, + + /// The port number on which to start the application + /// Note: setting env PORT allows to configure port without explicit cli + /// args. However, this is temporary measure to conform with existing + /// next.js devserver and can be removed in the future. + #[clap(short, long, value_parser, default_value_t = 3000, env = "PORT")] + pub port: u16, + + /// Hostname on which to start the application + #[clap(short = 'H', long, value_parser, default_value = "0.0.0.0")] + pub hostname: IpAddr, + + /// Compile all, instead of only compiling referenced assets when their + /// parent asset is requested + #[clap(long)] + pub eager_compile: bool, + + /// Don't open the browser automatically when the dev server has started. + #[clap(long)] + pub no_open: bool, + + // == + // = Inherited options from next-dev, need revisit later. + // == + /// If port is not explicitly specified, use different port if it's already + /// in use. + #[clap(long)] + pub allow_retry: bool, +} + +#[derive(Debug, Args)] +#[clap(author, version, about, long_about = None)] +pub struct BuildArguments { + #[clap(flatten)] + pub common: CommonArguments, + + /// Don't minify build output. + #[clap(long)] + pub no_minify: bool, +} diff --git a/turbopack/crates/turbopack-cli/src/build/mod.rs b/turbopack/crates/turbopack-cli/src/build/mod.rs new file mode 100644 index 0000000000000..ea28d84326762 --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/build/mod.rs @@ -0,0 +1,351 @@ +use std::{ + collections::HashSet, + env::current_dir, + path::{PathBuf, MAIN_SEPARATOR}, + sync::Arc, +}; + +use anyhow::{bail, Context, Result}; +use turbo_tasks::{RcStr, TransientInstance, TryJoinIterExt, TurboTasks, Value, Vc}; +use turbo_tasks_fs::FileSystem; +use turbo_tasks_memory::MemoryBackend; +use turbopack::ecmascript::EcmascriptModuleAsset; +use turbopack_cli_utils::issue::{ConsoleUi, LogOptions}; +use turbopack_core::{ + asset::Asset, + chunk::{ + availability_info::AvailabilityInfo, ChunkableModule, ChunkingContext, ChunkingContextExt, + EvaluatableAssets, MinifyType, + }, + environment::{BrowserEnvironment, Environment, ExecutionEnvironment}, + issue::{handle_issues, IssueReporter, IssueSeverity}, + module::Module, + output::OutputAsset, + reference::all_assets_from_entries, + reference_type::{EntryReferenceSubType, ReferenceType}, + resolve::{ + origin::{PlainResolveOrigin, ResolveOriginExt}, + parse::Request, + }, +}; +use turbopack_ecmascript_runtime::RuntimeType; +use turbopack_env::dotenv::load_env; +use turbopack_node::execution_context::ExecutionContext; +use turbopack_nodejs::NodeJsChunkingContext; + +use crate::{ + arguments::BuildArguments, + contexts::{get_client_asset_context, get_client_compile_time_info, NodeEnv}, + util::{ + normalize_dirs, normalize_entries, output_fs, project_fs, EntryRequest, EntryRequests, + NormalizedDirs, + }, +}; + +pub fn register() { + turbopack::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} + +pub struct TurbopackBuildBuilder { + turbo_tasks: Arc>, + project_dir: RcStr, + root_dir: RcStr, + entry_requests: Vec, + browserslist_query: RcStr, + log_level: IssueSeverity, + show_all: bool, + log_detail: bool, + minify_type: MinifyType, +} + +impl TurbopackBuildBuilder { + pub fn new( + turbo_tasks: Arc>, + project_dir: RcStr, + root_dir: RcStr, + ) -> Self { + TurbopackBuildBuilder { + turbo_tasks, + project_dir, + root_dir, + entry_requests: vec![], + browserslist_query: "chrome 64, edge 79, firefox 67, opera 51, safari 12".into(), + log_level: IssueSeverity::Warning, + show_all: false, + log_detail: false, + minify_type: MinifyType::Minify, + } + } + + pub fn entry_request(mut self, entry_asset_path: EntryRequest) -> Self { + self.entry_requests.push(entry_asset_path); + self + } + + pub fn browserslist_query(mut self, browserslist_query: RcStr) -> Self { + self.browserslist_query = browserslist_query; + self + } + + pub fn log_level(mut self, log_level: IssueSeverity) -> Self { + self.log_level = log_level; + self + } + + pub fn show_all(mut self, show_all: bool) -> Self { + self.show_all = show_all; + self + } + + pub fn log_detail(mut self, log_detail: bool) -> Self { + self.log_detail = log_detail; + self + } + + pub fn minify_type(mut self, minify_type: MinifyType) -> Self { + self.minify_type = minify_type; + self + } + + pub async fn build(self) -> Result<()> { + let task = self.turbo_tasks.spawn_once_task::<(), _>(async move { + let build_result = build_internal( + self.project_dir.clone(), + self.root_dir, + EntryRequests( + self.entry_requests + .iter() + .cloned() + .map(EntryRequest::cell) + .collect(), + ) + .cell(), + self.browserslist_query, + self.minify_type, + ); + + // Await the result to propagate any errors. + build_result.await?; + + let issue_reporter: Vc> = + Vc::upcast(ConsoleUi::new(TransientInstance::new(LogOptions { + project_dir: PathBuf::from(self.project_dir), + current_dir: current_dir().unwrap(), + show_all: self.show_all, + log_detail: self.log_detail, + log_level: self.log_level, + }))); + + handle_issues( + build_result, + issue_reporter, + IssueSeverity::Error.into(), + None, + None, + ) + .await?; + + Ok(Default::default()) + }); + + self.turbo_tasks.wait_task_completion(task, true).await?; + + Ok(()) + } +} + +#[turbo_tasks::function] +async fn build_internal( + project_dir: RcStr, + root_dir: RcStr, + entry_requests: Vc, + browserslist_query: RcStr, + minify_type: MinifyType, +) -> Result> { + let env = Environment::new(Value::new(ExecutionEnvironment::Browser( + BrowserEnvironment { + dom: true, + web_worker: false, + service_worker: false, + browserslist_query: browserslist_query.clone(), + } + .into(), + ))); + let output_fs = output_fs(project_dir.clone()); + let project_fs = project_fs(root_dir.clone()); + let project_relative = project_dir.strip_prefix(&*root_dir).unwrap(); + let project_relative: RcStr = project_relative + .strip_prefix(MAIN_SEPARATOR) + .unwrap_or(project_relative) + .replace(MAIN_SEPARATOR, "/") + .into(); + let project_path = project_fs.root().join(project_relative); + let build_output_root = output_fs.root().join("dist".into()); + + let node_env = NodeEnv::Production.cell(); + + let chunking_context = Vc::upcast( + NodeJsChunkingContext::builder( + project_path, + build_output_root, + build_output_root, + build_output_root, + build_output_root, + env, + match *node_env.await? { + NodeEnv::Development => RuntimeType::Development, + NodeEnv::Production => RuntimeType::Production, + }, + ) + .minify_type(minify_type) + .build(), + ); + + let compile_time_info = get_client_compile_time_info(browserslist_query, node_env); + let execution_context = + ExecutionContext::new(project_path, chunking_context, load_env(project_path)); + let asset_context = + get_client_asset_context(project_path, execution_context, compile_time_info, node_env); + + let entry_requests = (*entry_requests + .await? + .iter() + .cloned() + .map(|r| async move { + Ok(match &*r.await? { + EntryRequest::Relative(p) => Request::relative( + Value::new(p.clone().into()), + Default::default(), + Default::default(), + false, + ), + EntryRequest::Module(m, p) => Request::module( + m.clone(), + Value::new(p.clone().into()), + Default::default(), + Default::default(), + ), + }) + }) + .try_join() + .await?) + .to_vec(); + + let origin = PlainResolveOrigin::new(asset_context, output_fs.root().join("_".into())); + let project_dir = &project_dir; + let entries = entry_requests + .into_iter() + .map(|request_vc| async move { + let ty = Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)); + let request = request_vc.await?; + origin + .resolve_asset(request_vc, origin.resolve_options(ty.clone()), ty) + .first_module() + .await? + .with_context(|| { + format!( + "Unable to resolve entry {} from directory {}.", + request.request().unwrap(), + project_dir + ) + }) + }) + .try_join() + .await?; + + let entry_chunk_groups = entries + .into_iter() + .map(|entry_module| async move { + Ok( + if let Some(ecmascript) = + Vc::try_resolve_downcast_type::(entry_module).await? + { + Vc::cell(vec![ + Vc::try_resolve_downcast_type::(chunking_context) + .await? + .unwrap() + .entry_chunk_group( + build_output_root + .join( + ecmascript + .ident() + .path() + .file_stem() + .await? + .as_deref() + .unwrap() + .into(), + ) + .with_extension("entry.js".into()), + Vc::upcast(ecmascript), + EvaluatableAssets::one(Vc::upcast(ecmascript)), + Value::new(AvailabilityInfo::Root), + ) + .await? + .asset, + ]) + } else if let Some(chunkable) = + Vc::try_resolve_sidecast::>(entry_module).await? + { + chunking_context.root_chunk_group_assets(chunkable) + } else { + // TODO convert into a serve-able asset + bail!( + "Entry module is not chunkable, so it can't be used to bootstrap the \ + application" + ) + }, + ) + }) + .try_join() + .await?; + + let mut chunks: HashSet>> = HashSet::new(); + for chunk_group in entry_chunk_groups { + chunks.extend(&*all_assets_from_entries(chunk_group).await?); + } + + chunks + .iter() + .map(|c| c.content().write(c.ident().path())) + .try_join() + .await?; + + Ok(Default::default()) +} + +pub async fn build(args: &BuildArguments) -> Result<()> { + let NormalizedDirs { + project_dir, + root_dir, + } = normalize_dirs(&args.common.dir, &args.common.root)?; + + let tt = TurboTasks::new(MemoryBackend::new( + args.common + .memory_limit + .map_or(usize::MAX, |l| l * 1024 * 1024), + )); + + let mut builder = TurbopackBuildBuilder::new(tt, project_dir, root_dir) + .log_detail(args.common.log_detail) + .log_level( + args.common + .log_level + .map_or_else(|| IssueSeverity::Warning, |l| l.0), + ) + .minify_type(if args.no_minify { + MinifyType::NoMinify + } else { + MinifyType::Minify + }) + .show_all(args.common.show_all); + + for entry in normalize_entries(&args.common.entries) { + builder = builder.entry_request(EntryRequest::Relative(entry)); + } + + builder.build().await?; + + Ok(()) +} diff --git a/turbopack/crates/turbopack-cli/src/contexts.rs b/turbopack/crates/turbopack-cli/src/contexts.rs new file mode 100644 index 0000000000000..9b439048978e7 --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/contexts.rs @@ -0,0 +1,225 @@ +use std::{collections::HashMap, fmt}; + +use anyhow::Result; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_fs::{FileSystem, FileSystemPath}; +use turbopack::{ + ecmascript::{EcmascriptInputTransform, TreeShakingMode}, + module_options::{ + JsxTransformOptions, ModuleOptionsContext, ModuleRule, ModuleRuleCondition, + ModuleRuleEffect, + }, + ModuleAssetContext, +}; +use turbopack_browser::react_refresh::assert_can_resolve_react_refresh; +use turbopack_core::{ + compile_time_defines, + compile_time_info::{CompileTimeDefines, CompileTimeInfo}, + condition::ContextCondition, + context::AssetContext, + environment::{BrowserEnvironment, Environment, ExecutionEnvironment}, + resolve::options::{ImportMap, ImportMapping}, +}; +use turbopack_ecmascript_plugins::transform::{ + emotion::{EmotionTransformConfig, EmotionTransformer}, + styled_components::{StyledComponentsTransformConfig, StyledComponentsTransformer}, + styled_jsx::StyledJsxTransformer, +}; +use turbopack_node::{ + execution_context::ExecutionContext, transforms::postcss::PostCssTransformOptions, +}; +use turbopack_resolve::resolve_options_context::ResolveOptionsContext; + +#[turbo_tasks::value(shared)] +pub enum NodeEnv { + Development, + Production, +} + +impl fmt::Display for NodeEnv { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + NodeEnv::Development => f.write_str("development"), + NodeEnv::Production => f.write_str("production"), + } + } +} + +async fn foreign_code_context_condition() -> Result { + Ok(ContextCondition::InDirectory("node_modules".to_string())) +} + +#[turbo_tasks::function] +pub async fn get_client_import_map(project_path: Vc) -> Result> { + let mut import_map = ImportMap::empty(); + + import_map.insert_singleton_alias("@swc/helpers", project_path); + import_map.insert_singleton_alias("styled-jsx", project_path); + import_map.insert_singleton_alias("react", project_path); + import_map.insert_singleton_alias("react-dom", project_path); + + import_map.insert_wildcard_alias( + "@vercel/turbopack-ecmascript-runtime/", + ImportMapping::PrimaryAlternative( + "./*".into(), + Some(turbopack_ecmascript_runtime::embed_fs().root()), + ) + .cell(), + ); + + Ok(import_map.cell()) +} + +#[turbo_tasks::function] +pub async fn get_client_resolve_options_context( + project_path: Vc, +) -> Result> { + let next_client_import_map = get_client_import_map(project_path); + let module_options_context = ResolveOptionsContext { + enable_node_modules: Some(project_path.root().resolve().await?), + custom_conditions: vec!["development".into()], + import_map: Some(next_client_import_map), + browser: true, + module: true, + ..Default::default() + }; + Ok(ResolveOptionsContext { + enable_typescript: true, + enable_react: true, + rules: vec![( + foreign_code_context_condition().await?, + module_options_context.clone().cell(), + )], + ..module_options_context + } + .cell()) +} + +#[turbo_tasks::function] +async fn get_client_module_options_context( + project_path: Vc, + execution_context: Vc, + env: Vc, + node_env: Vc, +) -> Result> { + let module_options_context = ModuleOptionsContext { + preset_env_versions: Some(env), + execution_context: Some(execution_context), + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), + ..Default::default() + }; + + let resolve_options_context = get_client_resolve_options_context(project_path); + + let enable_react_refresh = matches!(*node_env.await?, NodeEnv::Development) + && assert_can_resolve_react_refresh(project_path, resolve_options_context) + .await? + .is_found(); + + let enable_jsx = Some( + JsxTransformOptions { + react_refresh: enable_react_refresh, + ..Default::default() + } + .cell(), + ); + + let versions = *env.runtime_versions().await?; + + let conditions = ModuleRuleCondition::any(vec![ + ModuleRuleCondition::ResourcePathEndsWith(".js".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".jsx".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".ts".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".tsx".to_string()), + ]); + + let custom_rules = ModuleRule::new( + conditions, + vec![ModuleRuleEffect::ExtendEcmascriptTransforms { + prepend: Vc::cell(vec![ + EcmascriptInputTransform::Plugin(Vc::cell(Box::new( + EmotionTransformer::new(&EmotionTransformConfig::default()) + .expect("Should be able to create emotion transformer"), + ) as _)), + EcmascriptInputTransform::Plugin(Vc::cell(Box::new( + StyledComponentsTransformer::new(&StyledComponentsTransformConfig::default()), + ) as _)), + EcmascriptInputTransform::Plugin(Vc::cell(Box::new(StyledJsxTransformer::new( + !module_options_context.use_swc_css, + versions, + )) as _)), + ]), + append: Vc::cell(vec![]), + }], + ); + + let module_options_context = ModuleOptionsContext { + enable_jsx, + enable_postcss_transform: Some(PostCssTransformOptions::default().cell()), + enable_typescript_transform: Some(Default::default()), + rules: vec![( + foreign_code_context_condition().await?, + module_options_context.clone().cell(), + )], + custom_rules: vec![custom_rules], + ..module_options_context + } + .cell(); + + Ok(module_options_context) +} + +#[turbo_tasks::function] +pub fn get_client_asset_context( + project_path: Vc, + execution_context: Vc, + compile_time_info: Vc, + node_env: Vc, +) -> Vc> { + let resolve_options_context = get_client_resolve_options_context(project_path); + let module_options_context = get_client_module_options_context( + project_path, + execution_context, + compile_time_info.environment(), + node_env, + ); + + let asset_context: Vc> = Vc::upcast(ModuleAssetContext::new( + Vc::cell(HashMap::new()), + compile_time_info, + module_options_context, + resolve_options_context, + Vc::cell("client".into()), + )); + + asset_context +} + +fn client_defines(node_env: &NodeEnv) -> Vc { + compile_time_defines!( + process.turbopack = true, + process.env.TURBOPACK = true, + process.env.NODE_ENV = node_env.to_string() + ) + .cell() +} + +#[turbo_tasks::function] +pub async fn get_client_compile_time_info( + browserslist_query: RcStr, + node_env: Vc, +) -> Result> { + Ok( + CompileTimeInfo::builder(Environment::new(Value::new(ExecutionEnvironment::Browser( + BrowserEnvironment { + dom: true, + web_worker: false, + service_worker: false, + browserslist_query, + } + .into(), + )))) + .defines(client_defines(&*node_env.await?)) + .cell(), + ) +} diff --git a/turbopack/crates/turbopack-cli/src/dev/mod.rs b/turbopack/crates/turbopack-cli/src/dev/mod.rs new file mode 100644 index 0000000000000..263ff4e3eeae6 --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/dev/mod.rs @@ -0,0 +1,517 @@ +use std::{ + collections::HashSet, + env::current_dir, + future::{join, Future}, + io::{stdout, Write}, + net::{IpAddr, SocketAddr}, + path::{PathBuf, MAIN_SEPARATOR}, + sync::Arc, + time::{Duration, Instant}, +}; + +use anyhow::{Context, Result}; +use owo_colors::OwoColorize; +use turbo_tasks::{ + util::{FormatBytes, FormatDuration}, + RcStr, TransientInstance, TurboTasks, UpdateInfo, Value, Vc, +}; +use turbo_tasks_fs::FileSystem; +use turbo_tasks_malloc::TurboMalloc; +use turbo_tasks_memory::MemoryBackend; +use turbopack::evaluate_context::node_build_environment; +use turbopack_cli_utils::issue::{ConsoleUi, LogOptions}; +use turbopack_core::{ + issue::{IssueReporter, IssueSeverity}, + resolve::parse::Request, + server_fs::ServerFileSystem, +}; +use turbopack_dev_server::{ + introspect::IntrospectionSource, + source::{ + combined::CombinedContentSource, router::PrefixedRouterContentSource, + static_assets::StaticAssetsContentSource, ContentSource, + }, + DevServer, DevServerBuilder, +}; +use turbopack_ecmascript_runtime::RuntimeType; +use turbopack_env::dotenv::load_env; +use turbopack_node::execution_context::ExecutionContext; +use turbopack_nodejs::NodeJsChunkingContext; + +use self::web_entry_source::create_web_entry_source; +use crate::{ + arguments::DevArguments, + contexts::NodeEnv, + util::{ + normalize_dirs, normalize_entries, output_fs, project_fs, EntryRequest, NormalizedDirs, + }, +}; + +pub(crate) mod web_entry_source; + +pub struct TurbopackDevServerBuilder { + turbo_tasks: Arc>, + project_dir: RcStr, + root_dir: RcStr, + entry_requests: Vec, + eager_compile: bool, + hostname: Option, + issue_reporter: Option>, + port: Option, + browserslist_query: RcStr, + log_level: IssueSeverity, + show_all: bool, + log_detail: bool, + allow_retry: bool, +} + +impl TurbopackDevServerBuilder { + pub fn new( + turbo_tasks: Arc>, + project_dir: RcStr, + root_dir: RcStr, + ) -> TurbopackDevServerBuilder { + TurbopackDevServerBuilder { + turbo_tasks, + project_dir, + root_dir, + entry_requests: vec![], + eager_compile: false, + hostname: None, + issue_reporter: None, + port: None, + browserslist_query: "last 1 Chrome versions, last 1 Firefox versions, last 1 Safari \ + versions, last 1 Edge versions" + .into(), + log_level: IssueSeverity::Warning, + show_all: false, + log_detail: false, + allow_retry: false, + } + } + + pub fn entry_request(mut self, entry_asset_path: EntryRequest) -> TurbopackDevServerBuilder { + self.entry_requests.push(entry_asset_path); + self + } + + pub fn eager_compile(mut self, eager_compile: bool) -> TurbopackDevServerBuilder { + self.eager_compile = eager_compile; + self + } + + pub fn hostname(mut self, hostname: IpAddr) -> TurbopackDevServerBuilder { + self.hostname = Some(hostname); + self + } + + pub fn port(mut self, port: u16) -> TurbopackDevServerBuilder { + self.port = Some(port); + self + } + + pub fn browserslist_query(mut self, browserslist_query: RcStr) -> TurbopackDevServerBuilder { + self.browserslist_query = browserslist_query; + self + } + + pub fn log_level(mut self, log_level: IssueSeverity) -> TurbopackDevServerBuilder { + self.log_level = log_level; + self + } + + pub fn show_all(mut self, show_all: bool) -> TurbopackDevServerBuilder { + self.show_all = show_all; + self + } + + pub fn allow_retry(mut self, allow_retry: bool) -> TurbopackDevServerBuilder { + self.allow_retry = allow_retry; + self + } + + pub fn log_detail(mut self, log_detail: bool) -> TurbopackDevServerBuilder { + self.log_detail = log_detail; + self + } + + pub fn issue_reporter( + mut self, + issue_reporter: Box, + ) -> TurbopackDevServerBuilder { + self.issue_reporter = Some(issue_reporter); + self + } + + /// Attempts to find an open port to bind. + fn find_port(&self, host: IpAddr, port: u16, max_attempts: u16) -> Result { + // max_attempts of 1 means we loop 0 times. + let max_attempts = max_attempts - 1; + let mut attempts = 0; + loop { + let current_port = port + attempts; + let addr = SocketAddr::new(host, current_port); + let listen_result = DevServer::listen(addr); + + if let Err(e) = &listen_result { + if self.allow_retry && attempts < max_attempts { + // Returned error from `listen` is not `std::io::Error` but `anyhow::Error`, + // so we need to access its source to check if it is + // `std::io::ErrorKind::AddrInUse`. + let should_retry = e + .source() + .and_then(|e| { + e.downcast_ref::() + .map(|e| e.kind() == std::io::ErrorKind::AddrInUse) + }) + .unwrap_or(false); + + if should_retry { + println!( + "{} - Port {} is in use, trying {} instead", + "warn ".yellow(), + current_port, + current_port + 1 + ); + attempts += 1; + continue; + } + } + } + + return listen_result; + } + } + + pub async fn build(self) -> Result { + let port = self.port.context("port must be set")?; + let host = self.hostname.context("hostname must be set")?; + + let server = self.find_port(host, port, 10)?; + + let turbo_tasks = self.turbo_tasks; + let project_dir: RcStr = self.project_dir; + let root_dir: RcStr = self.root_dir; + let eager_compile = self.eager_compile; + let show_all = self.show_all; + let log_detail: bool = self.log_detail; + let browserslist_query: RcStr = self.browserslist_query; + let log_args = TransientInstance::new(LogOptions { + current_dir: current_dir().unwrap(), + project_dir: PathBuf::from(project_dir.clone()), + show_all, + log_detail, + log_level: self.log_level, + }); + let entry_requests = TransientInstance::new(self.entry_requests); + let tasks = turbo_tasks.clone(); + let issue_provider = self.issue_reporter.unwrap_or_else(|| { + // Initialize a ConsoleUi reporter if no custom reporter was provided + Box::new(move || Vc::upcast(ConsoleUi::new(log_args.clone()))) + }); + + let source = move || { + source( + root_dir.clone(), + project_dir.clone(), + entry_requests.clone(), + eager_compile, + browserslist_query.clone(), + ) + }; + + let issue_reporter_arc = Arc::new(move || issue_provider.get_issue_reporter()); + Ok(server.serve(tasks, source, issue_reporter_arc)) + } +} + +#[turbo_tasks::function] +async fn source( + root_dir: RcStr, + project_dir: RcStr, + entry_requests: TransientInstance>, + eager_compile: bool, + browserslist_query: RcStr, +) -> Result>> { + let project_relative = project_dir.strip_prefix(&*root_dir).unwrap(); + let project_relative: RcStr = project_relative + .strip_prefix(MAIN_SEPARATOR) + .unwrap_or(project_relative) + .replace(MAIN_SEPARATOR, "/") + .into(); + + let output_fs = output_fs(project_dir); + let fs = project_fs(root_dir); + let project_path: Vc = fs.root().join(project_relative); + + let env = load_env(project_path); + let build_output_root = output_fs.root().join(".turbopack/build".into()); + + let build_chunking_context = NodeJsChunkingContext::builder( + project_path, + build_output_root, + build_output_root, + build_output_root.join("chunks".into()), + build_output_root.join("assets".into()), + node_build_environment(), + RuntimeType::Development, + ) + .build(); + + let execution_context = + ExecutionContext::new(project_path, Vc::upcast(build_chunking_context), env); + + let server_fs = Vc::upcast::>(ServerFileSystem::new()); + let server_root = server_fs.root(); + let entry_requests = entry_requests + .iter() + .map(|r| match r { + EntryRequest::Relative(p) => Request::relative( + Value::new(p.clone().into()), + Default::default(), + Default::default(), + false, + ), + EntryRequest::Module(m, p) => Request::module( + m.clone(), + Value::new(p.clone().into()), + Default::default(), + Default::default(), + ), + }) + .collect(); + + let web_source = create_web_entry_source( + project_path, + execution_context, + entry_requests, + server_root, + env, + eager_compile, + NodeEnv::Development.cell(), + browserslist_query, + ); + let static_source = Vc::upcast(StaticAssetsContentSource::new( + Default::default(), + project_path.join("public".into()), + )); + let main_source = CombinedContentSource::new(vec![static_source, web_source]); + let introspect = Vc::upcast( + IntrospectionSource { + roots: HashSet::from([Vc::upcast(main_source)]), + } + .cell(), + ); + let main_source = Vc::upcast(main_source); + let source = Vc::upcast(PrefixedRouterContentSource::new( + Default::default(), + vec![("__turbopack__".into(), introspect)], + main_source, + )); + + Ok(source) +} + +pub fn register() { + turbopack::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} + +/// Start a devserver with the given args. +pub async fn start_server(args: &DevArguments) -> Result<()> { + let start = Instant::now(); + + #[cfg(feature = "tokio_console")] + console_subscriber::init(); + register(); + + let NormalizedDirs { + project_dir, + root_dir, + } = normalize_dirs(&args.common.dir, &args.common.root)?; + + let tt = TurboTasks::new(MemoryBackend::new( + args.common + .memory_limit + .map_or(usize::MAX, |l| l * 1024 * 1024), + )); + + let tt_clone = tt.clone(); + + let mut server = TurbopackDevServerBuilder::new(tt, project_dir, root_dir) + .eager_compile(args.eager_compile) + .hostname(args.hostname) + .port(args.port) + .log_detail(args.common.log_detail) + .show_all(args.common.show_all) + .log_level( + args.common + .log_level + .map_or_else(|| IssueSeverity::Warning, |l| l.0), + ); + + for entry in normalize_entries(&args.common.entries) { + server = server.entry_request(EntryRequest::Relative(entry)) + } + + #[cfg(feature = "serializable")] + { + server = server.allow_retry(args.allow_retry); + } + + let server = server.build().await?; + + { + let addr = &server.addr; + let hostname = if addr.ip().is_loopback() || addr.ip().is_unspecified() { + "localhost".to_string() + } else if addr.is_ipv6() { + // When using an IPv6 address, we need to surround the IP in brackets to + // distinguish it from the port's `:`. + format!("[{}]", addr.ip()) + } else { + addr.ip().to_string() + }; + let index_uri = match addr.port() { + 443 => format!("https://{hostname}"), + 80 => format!("http://{hostname}"), + port => format!("http://{hostname}:{port}"), + }; + println!( + "{} - started server on {}, url: {}", + "ready".green(), + server.addr, + index_uri + ); + if !args.no_open { + let _ = webbrowser::open(&index_uri); + } + } + + let stats_future = async move { + if args.common.log_detail { + println!( + "{event_type} - initial compilation {start} ({memory})", + event_type = "event".purple(), + start = FormatDuration(start.elapsed()), + memory = FormatBytes(TurboMalloc::memory_usage()) + ); + } + + let mut progress_counter = 0; + loop { + let update_future = profile_timeout( + tt_clone.as_ref(), + tt_clone.aggregated_update_info(Duration::from_millis(100), Duration::MAX), + ); + + if let Some(UpdateInfo { + duration, + tasks, + reasons, + .. + }) = update_future.await + { + progress_counter = 0; + match (args.common.log_detail, !reasons.is_empty()) { + (true, true) => { + println!( + "\x1b[2K{event_type} - {reasons} {duration} ({tasks} tasks, {memory})", + event_type = "event".purple(), + duration = FormatDuration(duration), + tasks = tasks, + memory = FormatBytes(TurboMalloc::memory_usage()) + ); + } + (true, false) => { + println!( + "\x1b[2K{event_type} - compilation {duration} ({tasks} tasks, \ + {memory})", + event_type = "event".purple(), + duration = FormatDuration(duration), + tasks = tasks, + memory = FormatBytes(TurboMalloc::memory_usage()) + ); + } + (false, true) => { + println!( + "\x1b[2K{event_type} - {reasons} {duration}", + event_type = "event".purple(), + duration = FormatDuration(duration), + ); + } + (false, false) => { + if duration > Duration::from_secs(1) { + println!( + "\x1b[2K{event_type} - compilation {duration}", + event_type = "event".purple(), + duration = FormatDuration(duration), + ); + } + } + } + } else { + progress_counter += 1; + if args.common.log_detail { + print!( + "\x1b[2K{event_type} - updating for {progress_counter}s... ({memory})\r", + event_type = "event".purple(), + memory = FormatBytes(TurboMalloc::memory_usage()) + ); + } else { + print!( + "\x1b[2K{event_type} - updating for {progress_counter}s...\r", + event_type = "event".purple(), + ); + } + let _ = stdout().lock().flush(); + } + } + }; + + join!(stats_future, async { server.future.await.unwrap() }).await; + + Ok(()) +} + +#[cfg(feature = "profile")] +// When profiling, exits the process when no new updates have been received for +// a given timeout and there are no more tasks in progress. +async fn profile_timeout(tt: &TurboTasks, future: impl Future) -> T { + /// How long to wait in between updates before force-exiting the process + /// during profiling. + const PROFILE_EXIT_TIMEOUT: Duration = Duration::from_secs(5); + + futures::pin_mut!(future); + loop { + match tokio::time::timeout(PROFILE_EXIT_TIMEOUT, &mut future).await { + Ok(res) => return res, + Err(_) => { + if tt.get_in_progress_count() == 0 { + std::process::exit(0) + } + } + } + } +} + +#[cfg(not(feature = "profile"))] +fn profile_timeout( + _tt: &TurboTasks, + future: impl Future, +) -> impl Future { + future +} + +pub trait IssueReporterProvider: Send + Sync + 'static { + fn get_issue_reporter(&self) -> Vc>; +} + +impl IssueReporterProvider for T +where + T: Fn() -> Vc> + Send + Sync + Clone + 'static, +{ + fn get_issue_reporter(&self) -> Vc> { + self() + } +} diff --git a/turbopack/crates/turbopack-cli/src/dev/web_entry_source.rs b/turbopack/crates/turbopack-cli/src/dev/web_entry_source.rs new file mode 100644 index 0000000000000..70029791c00c6 --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/dev/web_entry_source.rs @@ -0,0 +1,160 @@ +use anyhow::{anyhow, Result}; +use turbo_tasks::{RcStr, TryJoinIterExt, Value, Vc}; +use turbo_tasks_env::ProcessEnv; +use turbo_tasks_fs::FileSystemPath; +use turbopack::ecmascript::EcmascriptModuleAsset; +use turbopack_browser::{react_refresh::assert_can_resolve_react_refresh, BrowserChunkingContext}; +use turbopack_cli_utils::runtime_entry::{RuntimeEntries, RuntimeEntry}; +use turbopack_core::{ + chunk::{ChunkableModule, ChunkingContext}, + environment::Environment, + file_source::FileSource, + reference_type::{EntryReferenceSubType, ReferenceType}, + resolve::{ + origin::{PlainResolveOrigin, ResolveOriginExt}, + parse::Request, + }, +}; +use turbopack_dev_server::{ + html::DevHtmlAsset, + source::{asset_graph::AssetGraphContentSource, ContentSource}, +}; +use turbopack_ecmascript_runtime::RuntimeType; +use turbopack_node::execution_context::ExecutionContext; + +use crate::{ + contexts::{ + get_client_asset_context, get_client_compile_time_info, get_client_resolve_options_context, + NodeEnv, + }, + embed_js::embed_file_path, +}; + +#[turbo_tasks::function] +pub fn get_client_chunking_context( + project_path: Vc, + server_root: Vc, + environment: Vc, +) -> Vc> { + Vc::upcast( + BrowserChunkingContext::builder( + project_path, + server_root, + server_root, + server_root.join("/_chunks".into()), + server_root.join("/_assets".into()), + environment, + RuntimeType::Development, + ) + .hot_module_replacement() + .build(), + ) +} + +#[turbo_tasks::function] +pub async fn get_client_runtime_entries( + project_path: Vc, +) -> Result> { + let resolve_options_context = get_client_resolve_options_context(project_path); + + let mut runtime_entries = Vec::new(); + + let enable_react_refresh = + assert_can_resolve_react_refresh(project_path, resolve_options_context) + .await? + .as_request(); + // It's important that React Refresh come before the regular bootstrap file, + // because the bootstrap contains JSX which requires Refresh's global + // functions to be available. + if let Some(request) = enable_react_refresh { + runtime_entries.push(RuntimeEntry::Request(request, project_path.join("_".into())).cell()) + }; + + runtime_entries.push( + RuntimeEntry::Source(Vc::upcast(FileSource::new(embed_file_path( + "entry/bootstrap.ts".into(), + )))) + .cell(), + ); + + Ok(Vc::cell(runtime_entries)) +} + +#[turbo_tasks::function] +pub async fn create_web_entry_source( + project_path: Vc, + execution_context: Vc, + entry_requests: Vec>, + server_root: Vc, + _env: Vc>, + eager_compile: bool, + node_env: Vc, + browserslist_query: RcStr, +) -> Result>> { + let compile_time_info = get_client_compile_time_info(browserslist_query, node_env); + let asset_context = + get_client_asset_context(project_path, execution_context, compile_time_info, node_env); + let chunking_context = + get_client_chunking_context(project_path, server_root, compile_time_info.environment()); + let entries = get_client_runtime_entries(project_path); + + let runtime_entries = entries.resolve_entries(asset_context); + + let origin = PlainResolveOrigin::new(asset_context, project_path.join("_".into())); + let entries = entry_requests + .into_iter() + .map(|request| async move { + let ty = Value::new(ReferenceType::Entry(EntryReferenceSubType::Web)); + Ok(origin + .resolve_asset(request, origin.resolve_options(ty.clone()), ty) + .resolve() + .await? + .primary_modules() + .await? + .first() + .copied()) + }) + .try_join() + .await?; + + let entries: Vec<_> = entries + .into_iter() + .flatten() + .map(|module| async move { + if let Some(ecmascript) = + Vc::try_resolve_downcast_type::(module).await? + { + Ok(( + Vc::upcast(ecmascript), + chunking_context, + Some(runtime_entries.with_entry(Vc::upcast(ecmascript))), + )) + } else if let Some(chunkable) = + Vc::try_resolve_sidecast::>(module).await? + { + // TODO this is missing runtime code, so it's probably broken and we should also + // add an ecmascript chunk with the runtime code + Ok((chunkable, chunking_context, None)) + } else { + // TODO convert into a serve-able asset + Err(anyhow!( + "Entry module is not chunkable, so it can't be used to bootstrap the \ + application" + )) + } + }) + .try_join() + .await?; + + let entry_asset = Vc::upcast(DevHtmlAsset::new( + server_root.join("index.html".into()), + entries, + )); + + let graph = Vc::upcast(if eager_compile { + AssetGraphContentSource::new_eager(server_root, entry_asset) + } else { + AssetGraphContentSource::new_lazy(server_root, entry_asset) + }); + Ok(graph) +} diff --git a/turbopack/crates/turbopack-cli/src/embed_js.rs b/turbopack/crates/turbopack-cli/src/embed_js.rs new file mode 100644 index 0000000000000..676341316d70b --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/embed_js.rs @@ -0,0 +1,17 @@ +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::{embed_directory, FileContent, FileSystem, FileSystemPath}; + +#[turbo_tasks::function] +fn embed_fs() -> Vc> { + embed_directory!("turbopack-cli", "$CARGO_MANIFEST_DIR/js/src") +} + +#[turbo_tasks::function] +pub(crate) fn embed_file(path: RcStr) -> Vc { + embed_fs().root().join(path).read() +} + +#[turbo_tasks::function] +pub(crate) fn embed_file_path(path: RcStr) -> Vc { + embed_fs().root().join(path) +} diff --git a/turbopack/crates/turbopack-cli/src/lib.rs b/turbopack/crates/turbopack-cli/src/lib.rs new file mode 100644 index 0000000000000..a2a5c4dd2c743 --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/lib.rs @@ -0,0 +1,19 @@ +#![feature(future_join)] +#![feature(min_specialization)] +#![feature(arbitrary_self_types)] + +pub mod arguments; +pub mod build; +pub(crate) mod contexts; +pub mod dev; +pub(crate) mod embed_js; +pub(crate) mod util; + +pub fn register() { + turbopack::register(); + turbopack_nodejs::register(); + turbopack_browser::register(); + turbopack_ecmascript_plugins::register(); + turbopack_resolve::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-cli/src/main.rs b/turbopack/crates/turbopack-cli/src/main.rs new file mode 100644 index 0000000000000..0129194f88bd0 --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/main.rs @@ -0,0 +1,84 @@ +#![feature(future_join)] +#![feature(min_specialization)] + +use std::path::Path; + +use anyhow::{Context, Result}; +use clap::Parser; +use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter, Registry}; +use turbo_tasks_malloc::TurboMalloc; +use turbopack_cli::{arguments::Arguments, register}; +use turbopack_trace_utils::{ + exit::ExitHandler, + raw_trace::RawTraceLayer, + trace_writer::TraceWriter, + tracing_presets::{ + TRACING_OVERVIEW_TARGETS, TRACING_TURBOPACK_TARGETS, TRACING_TURBO_TASKS_TARGETS, + }, +}; + +#[global_allocator] +static ALLOC: TurboMalloc = TurboMalloc; + +fn main() { + let args = Arguments::parse(); + + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .on_thread_stop(|| { + TurboMalloc::thread_stop(); + }) + .build() + .unwrap() + .block_on(main_inner(args)) + .unwrap(); +} + +async fn main_inner(args: Arguments) -> Result<()> { + let exit_handler = ExitHandler::listen(); + + let trace = std::env::var("TURBOPACK_TRACING").ok(); + if let Some(mut trace) = trace { + // Trace presets + match trace.as_str() { + "overview" => { + trace = TRACING_OVERVIEW_TARGETS.join(","); + } + "turbopack" => { + trace = TRACING_TURBOPACK_TARGETS.join(","); + } + "turbo-tasks" => { + trace = TRACING_TURBO_TASKS_TARGETS.join(","); + } + _ => {} + } + + let subscriber = Registry::default(); + + let subscriber = subscriber.with(EnvFilter::builder().parse(trace).unwrap()); + + let internal_dir = args + .dir() + .unwrap_or_else(|| Path::new(".")) + .join(".turbopack"); + std::fs::create_dir_all(&internal_dir) + .context("Unable to create .turbopack directory") + .unwrap(); + let trace_file = internal_dir.join("trace.log"); + let trace_writer = std::fs::File::create(trace_file).unwrap(); + let (trace_writer, guard) = TraceWriter::new(trace_writer); + let subscriber = subscriber.with(RawTraceLayer::new(trace_writer)); + + exit_handler + .on_exit(async move { tokio::task::spawn_blocking(|| drop(guard)).await.unwrap() }); + + subscriber.init(); + } + + register(); + + match args { + Arguments::Build(args) => turbopack_cli::build::build(&args).await, + Arguments::Dev(args) => turbopack_cli::dev::start_server(&args).await, + } +} diff --git a/turbopack/crates/turbopack-cli/src/util.rs b/turbopack/crates/turbopack-cli/src/util.rs new file mode 100644 index 0000000000000..7ab0ee363a795 --- /dev/null +++ b/turbopack/crates/turbopack-cli/src/util.rs @@ -0,0 +1,74 @@ +use std::{env::current_dir, path::PathBuf}; + +use anyhow::{Context, Result}; +use dunce::canonicalize; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::{DiskFileSystem, FileSystem}; + +#[turbo_tasks::value(transparent)] +pub struct EntryRequests(pub Vec>); + +#[turbo_tasks::value(shared)] +#[derive(Clone)] +pub enum EntryRequest { + Relative(RcStr), + Module(RcStr, RcStr), +} + +pub struct NormalizedDirs { + /// Normalized project directory path as an absolute path + pub project_dir: RcStr, + /// Normalized root directory path as an absolute path + pub root_dir: RcStr, +} + +/// Normalizes (canonicalizes and represents as an absolute path in a String) +/// the project and root directories. +pub fn normalize_dirs( + project_dir: &Option, + root_dir: &Option, +) -> Result { + let project_dir: RcStr = project_dir + .as_ref() + .map(canonicalize) + .unwrap_or_else(current_dir) + .context("project directory can't be found")? + .to_str() + .context("project directory contains invalid characters")? + .into(); + + let root_dir = match root_dir.as_ref() { + Some(root) => canonicalize(root) + .context("root directory can't be found")? + .to_str() + .context("root directory contains invalid characters")? + .into(), + None => project_dir.clone(), + }; + + Ok(NormalizedDirs { + project_dir, + root_dir, + }) +} + +pub fn normalize_entries(entries: &Option>) -> Vec { + entries + .as_ref() + .map(|v| v.iter().map(|v| RcStr::from(&**v)).collect()) + .unwrap_or_else(|| vec!["src/entry".into()]) +} + +#[turbo_tasks::function] +pub async fn project_fs(project_dir: RcStr) -> Result>> { + let disk_fs = DiskFileSystem::new("project".into(), project_dir, vec![]); + disk_fs.await?.start_watching()?; + Ok(Vc::upcast(disk_fs)) +} + +#[turbo_tasks::function] +pub async fn output_fs(project_dir: RcStr) -> Result>> { + let disk_fs = DiskFileSystem::new("output".into(), project_dir, vec![]); + disk_fs.await?.start_watching()?; + Ok(Vc::upcast(disk_fs)) +} diff --git a/turbopack/crates/turbopack-core/Cargo.toml b/turbopack/crates/turbopack-core/Cargo.toml new file mode 100644 index 0000000000000..a5d30aae00ee5 --- /dev/null +++ b/turbopack/crates/turbopack-core/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "turbopack-core" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +async-recursion = { workspace = true } +async-trait = { workspace = true } +auto-hash-map = { workspace = true } +browserslist-rs = { workspace = true } +futures = { workspace = true } +indexmap = { workspace = true } +lazy_static = { workspace = true } +once_cell = { workspace = true } +patricia_tree = "0.5.5" +ref-cast = "1.0.20" +regex = { workspace = true } +serde = { workspace = true, features = ["rc"] } +serde_json = { workspace = true, features = ["preserve_order"] } +sourcemap = { workspace = true } +swc_core = { workspace = true, features = ["ecma_preset_env", "common"] } +tracing = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-env = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-hash = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } + +[dev-dependencies] +rstest = { workspace = true } +tokio = { workspace = true } +turbo-tasks-memory = { workspace = true } +turbo-tasks-testing = { workspace = true } + +[features] +default = [] +issue_path = [] diff --git a/turbopack/crates/turbopack-core/build.rs b/turbopack/crates/turbopack-core/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-core/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-core/src/asset.rs b/turbopack/crates/turbopack-core/src/asset.rs new file mode 100644 index 0000000000000..dddcb3b674653 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/asset.rs @@ -0,0 +1,92 @@ +use anyhow::Result; +use turbo_tasks::{Completion, RcStr, Vc}; +use turbo_tasks_fs::{ + FileContent, FileJsonContent, FileLinesContent, FileSystemPath, LinkContent, LinkType, +}; + +use crate::version::{VersionedAssetContent, VersionedContent}; + +/// An asset. It also forms a graph when following [Asset::references]. +#[turbo_tasks::value_trait] +pub trait Asset { + /// The content of the [Asset]. + fn content(self: Vc) -> Vc; + + /// The content of the [Asset] alongside its version. + async fn versioned_content(self: Vc) -> Result>> { + Ok(Vc::upcast(VersionedAssetContent::new(self.content()))) + } +} + +#[turbo_tasks::value(shared)] +#[derive(Clone)] +pub enum AssetContent { + File(Vc), + // for the relative link, the target is raw value read from the link + // for the absolute link, the target is stripped of the root path while reading + // See [LinkContent::Link] for more details. + Redirect { target: RcStr, link_type: LinkType }, +} + +#[turbo_tasks::value_impl] +impl AssetContent { + #[turbo_tasks::function] + pub fn file(file: Vc) -> Vc { + AssetContent::File(file).cell() + } + + #[turbo_tasks::function] + pub async fn parse_json(self: Vc) -> Result> { + let this = self.await?; + match &*this { + AssetContent::File(content) => Ok(content.parse_json()), + AssetContent::Redirect { .. } => { + Ok(FileJsonContent::unparseable("a redirect can't be parsed as json").cell()) + } + } + } + + #[turbo_tasks::function] + pub async fn file_content(self: Vc) -> Result> { + let this = self.await?; + match &*this { + AssetContent::File(content) => Ok(*content), + AssetContent::Redirect { .. } => Ok(FileContent::NotFound.cell()), + } + } + + #[turbo_tasks::function] + pub async fn lines(self: Vc) -> Result> { + let this = self.await?; + match &*this { + AssetContent::File(content) => Ok(content.lines()), + AssetContent::Redirect { .. } => Ok(FileLinesContent::Unparseable.cell()), + } + } + + #[turbo_tasks::function] + pub async fn parse_json_with_comments(self: Vc) -> Result> { + let this = self.await?; + match &*this { + AssetContent::File(content) => Ok(content.parse_json_with_comments()), + AssetContent::Redirect { .. } => { + Ok(FileJsonContent::unparseable("a redirect can't be parsed as json").cell()) + } + } + } + + #[turbo_tasks::function] + pub async fn write(self: Vc, path: Vc) -> Result> { + let this = self.await?; + Ok(match &*this { + AssetContent::File(file) => path.write(*file), + AssetContent::Redirect { target, link_type } => path.write_link( + LinkContent::Link { + target: target.clone(), + link_type: *link_type, + } + .cell(), + ), + }) + } +} diff --git a/turbopack/crates/turbopack-core/src/changed.rs b/turbopack/crates/turbopack-core/src/changed.rs new file mode 100644 index 0000000000000..159d40f4d06a6 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/changed.rs @@ -0,0 +1,88 @@ +use anyhow::Result; +use turbo_tasks::{ + graph::{GraphTraversal, NonDeterministic}, + Completion, Completions, Vc, +}; + +use crate::{ + asset::Asset, + module::Module, + output::{OutputAsset, OutputAssets}, + reference::primary_referenced_modules, +}; + +async fn get_referenced_output_assets( + parent: Vc>, +) -> Result>> + Send> { + Ok(parent.references().await?.clone_value().into_iter()) +} + +async fn get_referenced_modules( + parent: Vc>, +) -> Result>> + Send> { + Ok(primary_referenced_modules(parent) + .await? + .clone_value() + .into_iter()) +} + +/// Returns a completion that changes when any content of any asset in the whole +/// asset graph changes. +#[turbo_tasks::function] +pub async fn any_content_changed_of_module(root: Vc>) -> Result> { + let completions = NonDeterministic::new() + .skip_duplicates() + .visit([root], get_referenced_modules) + .await + .completed()? + .into_inner() + .into_iter() + .map(|m| content_changed(Vc::upcast(m))) + .collect(); + + Ok(Vc::::cell(completions).completed()) +} + +/// Returns a completion that changes when any content of any asset in the whole +/// asset graph changes. +#[turbo_tasks::function] +pub async fn any_content_changed_of_output_asset( + root: Vc>, +) -> Result> { + let completions = NonDeterministic::new() + .skip_duplicates() + .visit([root], get_referenced_output_assets) + .await + .completed()? + .into_inner() + .into_iter() + .map(|m| content_changed(Vc::upcast(m))) + .collect(); + + Ok(Vc::::cell(completions).completed()) +} + +/// Returns a completion that changes when any content of any asset in the given +/// output asset graphs changes. +#[turbo_tasks::function] +pub async fn any_content_changed_of_output_assets( + roots: Vc, +) -> Result> { + Ok(Vc::::cell( + roots + .await? + .iter() + .map(|&a| any_content_changed_of_output_asset(a)) + .collect(), + ) + .completed()) +} + +/// Returns a completion that changes when the content of the given asset +/// changes. +#[turbo_tasks::function] +pub async fn content_changed(asset: Vc>) -> Result> { + // Reading the file content is enough to add as dependency + asset.content().file_content().await?; + Ok(Completion::new()) +} diff --git a/turbopack/crates/turbopack-core/src/chunk/availability_info.rs b/turbopack/crates/turbopack-core/src/chunk/availability_info.rs new file mode 100644 index 0000000000000..2657b814502f5 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/availability_info.rs @@ -0,0 +1,50 @@ +use anyhow::Result; +use turbo_tasks::Vc; + +use super::available_chunk_items::{AvailableChunkItemInfoMap, AvailableChunkItems}; + +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Hash, Clone, Copy, Debug)] +pub enum AvailabilityInfo { + /// Availability of modules is not tracked + Untracked, + /// Availablility of modules is tracked, but no modules are available + Root, + /// There are modules already available. + Complete { + available_chunk_items: Vc, + }, +} + +impl AvailabilityInfo { + pub fn available_chunk_items(&self) -> Option> { + match self { + Self::Untracked => None, + Self::Root => None, + Self::Complete { + available_chunk_items, + .. + } => Some(*available_chunk_items), + } + } + + pub async fn with_chunk_items( + self, + chunk_items: Vc, + ) -> Result { + Ok(match self { + AvailabilityInfo::Untracked => AvailabilityInfo::Untracked, + AvailabilityInfo::Root => AvailabilityInfo::Complete { + available_chunk_items: AvailableChunkItems::new(chunk_items).resolve().await?, + }, + AvailabilityInfo::Complete { + available_chunk_items, + } => AvailabilityInfo::Complete { + available_chunk_items: available_chunk_items + .with_chunk_items(chunk_items) + .resolve() + .await?, + }, + }) + } +} diff --git a/turbopack/crates/turbopack-core/src/chunk/available_chunk_items.rs b/turbopack/crates/turbopack-core/src/chunk/available_chunk_items.rs new file mode 100644 index 0000000000000..35444b9500957 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/available_chunk_items.rs @@ -0,0 +1,103 @@ +use anyhow::Result; +use indexmap::IndexMap; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{ + debug::ValueDebugFormat, trace::TraceRawVcs, TryFlatJoinIterExt, TryJoinIterExt, ValueToString, + Vc, +}; +use turbo_tasks_hash::Xxh3Hash64Hasher; + +use super::ChunkItem; + +#[derive(PartialEq, Eq, TraceRawVcs, Copy, Clone, Serialize, Deserialize, ValueDebugFormat)] +pub struct AvailableChunkItemInfo { + pub is_async: bool, +} + +#[turbo_tasks::value(transparent)] +pub struct OptionAvailableChunkItemInfo(Option); + +#[turbo_tasks::value(transparent)] +pub struct AvailableChunkItemInfoMap(IndexMap>, AvailableChunkItemInfo>); + +/// Allows to gather information about which assets are already available. +/// Adding more roots will form a linked list like structure to allow caching +/// `include` queries. +#[turbo_tasks::value] +pub struct AvailableChunkItems { + parent: Option>, + chunk_items: Vc, +} + +#[turbo_tasks::value_impl] +impl AvailableChunkItems { + #[turbo_tasks::function] + pub fn new(chunk_items: Vc) -> Vc { + AvailableChunkItems { + parent: None, + chunk_items, + } + .cell() + } + + #[turbo_tasks::function] + pub async fn with_chunk_items( + self: Vc, + chunk_items: Vc, + ) -> Result> { + let chunk_items = chunk_items + .await? + .into_iter() + .map(|(&chunk_item, &info)| async move { + Ok(self + .get(chunk_item) + .await? + .is_none() + .then_some((chunk_item, info))) + }) + .try_flat_join() + .await?; + Ok(AvailableChunkItems { + parent: Some(self), + chunk_items: Vc::cell(chunk_items.into_iter().collect()), + } + .cell()) + } + + #[turbo_tasks::function] + pub async fn hash(self: Vc) -> Result> { + let this = self.await?; + let mut hasher = Xxh3Hash64Hasher::new(); + if let Some(parent) = this.parent { + hasher.write_value(parent.hash().await?); + } else { + hasher.write_value(0u64); + } + let item_idents = this + .chunk_items + .await? + .iter() + .map(|(&chunk_item, _)| chunk_item.asset_ident().to_string()) + .try_join() + .await?; + for ident in item_idents { + hasher.write_value(ident); + } + Ok(Vc::cell(hasher.finish())) + } + + #[turbo_tasks::function] + pub async fn get( + self: Vc, + chunk_item: Vc>, + ) -> Result> { + let this = self.await?; + if let Some(&info) = this.chunk_items.await?.get(&chunk_item) { + return Ok(Vc::cell(Some(info))); + }; + if let Some(parent) = this.parent { + return Ok(parent.get(chunk_item)); + } + Ok(Vc::cell(None)) + } +} diff --git a/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs new file mode 100644 index 0000000000000..b2b3f5dec36dc --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/chunk_group.rs @@ -0,0 +1,190 @@ +use std::collections::HashSet; + +use anyhow::Result; +use auto_hash_map::AutoSet; +use indexmap::{IndexMap, IndexSet}; +use turbo_tasks::{TryFlatJoinIterExt, TryJoinIterExt, Value, Vc}; + +use super::{ + availability_info::AvailabilityInfo, available_chunk_items::AvailableChunkItemInfo, + chunk_content, chunking::make_chunks, AsyncModuleInfo, Chunk, ChunkContentResult, ChunkItem, + ChunkingContext, +}; +use crate::{module::Module, output::OutputAssets, reference::ModuleReference}; + +pub struct MakeChunkGroupResult { + pub chunks: Vec>>, + pub availability_info: AvailabilityInfo, +} + +/// Creates a chunk group from a set of entries. +pub async fn make_chunk_group( + chunking_context: Vc>, + entries: impl IntoIterator>>, + availability_info: AvailabilityInfo, +) -> Result { + let ChunkContentResult { + chunk_items, + async_modules, + external_module_references, + forward_edges_inherit_async, + local_back_edges_inherit_async, + available_async_modules_back_edges_inherit_async, + } = chunk_content(chunking_context, entries, availability_info).await?; + + // Find all local chunk items that are self async + let self_async_children = chunk_items + .iter() + .copied() + .map(|chunk_item| async move { + let is_self_async = *chunk_item.is_self_async().await?; + Ok(is_self_async.then_some(chunk_item)) + }) + .try_flat_join() + .await?; + + // Get all available async modules and concatenate with local async modules + let mut async_chunk_items = available_async_modules_back_edges_inherit_async + .keys() + .copied() + .chain(self_async_children.into_iter()) + .map(|chunk_item| (chunk_item, AutoSet::>>::new())) + .collect::>(); + + // Propagate async inheritance + let mut i = 0; + loop { + let Some((&chunk_item, _)) = async_chunk_items.get_index(i) else { + break; + }; + // The first few entries are from + // available_async_modules_back_edges_inherit_async and need to use that map, + // all other entries are local + let map = if i < available_async_modules_back_edges_inherit_async.len() { + &available_async_modules_back_edges_inherit_async + } else { + &local_back_edges_inherit_async + }; + if let Some(parents) = map.get(&chunk_item) { + for &parent in parents.iter() { + // Add item, it will be iterated by this loop too + async_chunk_items + .entry(parent) + .or_default() + .insert(chunk_item); + } + } + i += 1; + } + + // Create map for chunk items with empty [Option>] + let mut chunk_items = chunk_items + .into_iter() + .map(|chunk_item| (chunk_item, None)) + .collect::>>>(); + + // Insert AsyncModuleInfo for every async module + for (async_item, referenced_async_modules) in async_chunk_items { + let referenced_async_modules = + if let Some(references) = forward_edges_inherit_async.get(&async_item) { + references + .iter() + .copied() + .filter(|item| referenced_async_modules.contains(item)) + .collect() + } else { + Default::default() + }; + chunk_items.insert( + async_item, + Some(AsyncModuleInfo::new(referenced_async_modules)), + ); + } + + // Compute new [AvailabilityInfo] + let availability_info = { + let map = chunk_items + .iter() + .map(|(&chunk_item, async_info)| { + ( + chunk_item, + AvailableChunkItemInfo { + is_async: async_info.is_some(), + }, + ) + }) + .collect(); + let map = Vc::cell(map); + availability_info.with_chunk_items(map).await? + }; + + // Insert async chunk loaders for every referenced async module + let async_loaders = async_modules + .into_iter() + .map(|module| { + chunking_context.async_loader_chunk_item(module, Value::new(availability_info)) + }) + .collect::>(); + let has_async_loaders = !async_loaders.is_empty(); + let async_loader_chunk_items = async_loaders.iter().map(|&chunk_item| (chunk_item, None)); + + // And also add output assets referenced by async chunk loaders + let async_loader_references = async_loaders + .iter() + .map(|&loader| loader.references()) + .try_join() + .await?; + let async_loader_external_module_references = async_loader_references + .iter() + .flat_map(|references| references.iter().copied()) + .collect(); + + // Pass chunk items to chunking algorithm + let mut chunks = make_chunks( + chunking_context, + Vc::cell(chunk_items.into_iter().collect()), + "".into(), + references_to_output_assets(external_module_references).await?, + ) + .await? + .clone_value(); + + if has_async_loaders { + // Pass async chunk loaders to chunking algorithm + // We want them to be separate since they are specific to this chunk group due + // to available chunk items differing + let async_loader_chunks = make_chunks( + chunking_context, + Vc::cell(async_loader_chunk_items.into_iter().collect()), + "async-loader-".into(), + references_to_output_assets(async_loader_external_module_references).await?, + ) + .await?; + + // concatenate chunks + chunks.extend(async_loader_chunks.iter().copied()); + } + + Ok(MakeChunkGroupResult { + chunks, + availability_info, + }) +} + +async fn references_to_output_assets( + references: IndexSet>>, +) -> Result> { + let output_assets = references + .into_iter() + .map(|reference| reference.resolve_reference().primary_output_assets()) + .try_join() + .await?; + let mut set = HashSet::new(); + let output_assets = output_assets + .iter() + .flatten() + .copied() + .filter(|&asset| set.insert(asset)) + .collect::>(); + Ok(OutputAssets::new(output_assets)) +} diff --git a/turbopack/crates/turbopack-core/src/chunk/chunking.rs b/turbopack/crates/turbopack-core/src/chunk/chunking.rs new file mode 100644 index 0000000000000..c359c0c038bab --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/chunking.rs @@ -0,0 +1,366 @@ +use std::{ + borrow::Cow, + mem::{replace, take}, + pin::Pin, +}; + +use anyhow::Result; +use futures::Future; +use indexmap::IndexMap; +use once_cell::sync::Lazy; +use regex::Regex; +use tracing::Level; +use turbo_tasks::{RcStr, ReadRef, TryJoinIterExt, ValueToString, Vc}; + +use super::{ + AsyncModuleInfo, Chunk, ChunkItem, ChunkItemsWithAsyncModuleInfo, ChunkType, ChunkingContext, + Chunks, +}; +use crate::output::OutputAssets; + +#[turbo_tasks::value] +struct ChunkItemInfo { + ty: Vc>, + name: Vc, + size: usize, +} + +#[turbo_tasks::function] +async fn chunk_item_info( + chunking_context: Vc>, + chunk_item: Vc>, + async_info: Option>, +) -> Result> { + let asset_ident = chunk_item.asset_ident().to_string(); + let ty = chunk_item.ty().resolve().await?; + let chunk_item_size = ty.chunk_item_size(chunking_context, chunk_item, async_info); + Ok(ChunkItemInfo { + ty, + size: *chunk_item_size.await?, + name: asset_ident.resolve().await?, + } + .cell()) +} + +/// Creates chunks based on heuristics for the passed `chunk_items`. Also +/// attaches `referenced_output_assets` to the first chunk. +#[turbo_tasks::function] +pub async fn make_chunks( + chunking_context: Vc>, + chunk_items: Vc, + key_prefix: RcStr, + mut referenced_output_assets: Vc, +) -> Result> { + let chunk_items = chunk_items + .await? + .iter() + .map(|&(chunk_item, async_info)| async move { + let chunk_item_info = chunk_item_info(chunking_context, chunk_item, async_info).await?; + Ok((chunk_item, async_info, chunk_item_info)) + }) + .try_join() + .await?; + let mut map = IndexMap::<_, Vec<_>>::new(); + for (chunk_item, async_info, chunk_item_info) in chunk_items { + map.entry(chunk_item_info.ty) + .or_default() + .push((chunk_item, async_info, chunk_item_info)); + } + + let mut chunks = Vec::new(); + for (ty, chunk_items) in map { + let ty_name = ty.to_string().await?; + + let chunk_items = chunk_items + .into_iter() + .map(|(chunk_item, async_info, chunk_item_info)| async move { + Ok(( + chunk_item, + async_info, + chunk_item_info.size, + chunk_item_info.name.await?, + )) + }) + .try_join() + .await?; + + let mut split_context = SplitContext { + ty, + chunking_context, + chunks: &mut chunks, + referenced_output_assets: &mut referenced_output_assets, + empty_referenced_output_assets: OutputAssets::empty().resolve().await?, + }; + + app_vendors_split( + chunk_items, + format!("{key_prefix}{ty_name}"), + &mut split_context, + ) + .await?; + } + + Ok(Vc::cell(chunks)) +} + +type ChunkItemWithInfo = ( + Vc>, + Option>, + usize, + ReadRef, +); + +struct SplitContext<'a> { + ty: Vc>, + chunking_context: Vc>, + chunks: &'a mut Vec>>, + referenced_output_assets: &'a mut Vc, + empty_referenced_output_assets: Vc, +} + +/// Handle chunk items based on their total size. If the total size is too +/// small, they will be pushed into `remaining`, if possible. If the total size +/// is too large, it will return `false` and the caller should hand of the chunk +/// items to be further split. Otherwise it creates a chunk. +async fn handle_split_group( + chunk_items: &mut Vec, + key: &mut String, + split_context: &mut SplitContext<'_>, + remaining: Option<&mut Vec>, +) -> Result { + Ok(match (chunk_size(chunk_items), remaining) { + (ChunkSize::Large, _) => false, + (ChunkSize::Perfect, _) | (ChunkSize::Small, None) => { + make_chunk(take(chunk_items), key, split_context).await?; + true + } + (ChunkSize::Small, Some(remaining)) => { + remaining.extend(take(chunk_items)); + true + } + }) +} + +/// Creates a chunk with the given `chunk_items. `key` should be unique. +#[tracing::instrument(level = Level::TRACE, skip_all, fields(key = display(key)))] +async fn make_chunk( + chunk_items: Vec, + key: &mut String, + split_context: &mut SplitContext<'_>, +) -> Result<()> { + split_context.chunks.push( + split_context.ty.chunk( + split_context.chunking_context, + chunk_items + .into_iter() + .map(|(chunk_item, async_info, ..)| (chunk_item, async_info)) + .collect(), + replace( + split_context.referenced_output_assets, + split_context.empty_referenced_output_assets, + ), + ), + ); + Ok(()) +} + +/// Split chunk items into app code and vendor code. Continues splitting with +/// [package_name_split] if necessary. +#[tracing::instrument(level = Level::TRACE, skip_all, fields(name = display(&name)))] +async fn app_vendors_split( + chunk_items: Vec, + mut name: String, + split_context: &mut SplitContext<'_>, +) -> Result<()> { + let mut app_chunk_items = Vec::new(); + let mut vendors_chunk_items = Vec::new(); + for item in chunk_items { + let (_, _, _, asset_ident) = &item; + if is_app_code(asset_ident) { + app_chunk_items.push(item); + } else { + vendors_chunk_items.push(item); + } + } + let mut remaining = Vec::new(); + let mut key = format!("{}-app", name); + if !handle_split_group( + &mut app_chunk_items, + &mut key, + split_context, + Some(&mut remaining), + ) + .await? + { + folder_split(app_chunk_items, 0, key.into(), split_context).await?; + } + let mut key = format!("{}-vendors", name); + if !handle_split_group( + &mut vendors_chunk_items, + &mut key, + split_context, + Some(&mut remaining), + ) + .await? + { + package_name_split(vendors_chunk_items, key, split_context).await?; + } + if !remaining.is_empty() + && !handle_split_group(&mut remaining, &mut name, split_context, None).await? + { + package_name_split(remaining, name, split_context).await?; + } + Ok(()) +} + +/// Split chunk items by node_modules package name. Continues splitting with +/// [folder_split] if necessary. +#[tracing::instrument(level = Level::TRACE, skip_all, fields(name = display(&name)))] +async fn package_name_split( + chunk_items: Vec, + mut name: String, + split_context: &mut SplitContext<'_>, +) -> Result<()> { + let mut map = IndexMap::<_, Vec>::new(); + for item in chunk_items { + let (_, _, _, asset_ident) = &item; + let package_name = package_name(asset_ident); + if let Some(list) = map.get_mut(package_name) { + list.push(item); + } else { + map.insert(package_name.to_string(), vec![item]); + } + } + let mut remaining = Vec::new(); + for (package_name, mut list) in map { + let mut key = format!("{}-{}", name, package_name); + if !handle_split_group(&mut list, &mut key, split_context, Some(&mut remaining)).await? { + folder_split(list, 0, key.into(), split_context).await?; + } + } + if !remaining.is_empty() + && !handle_split_group(&mut remaining, &mut name, split_context, None).await? + { + folder_split(remaining, 0, name.into(), split_context).await?; + } + Ok(()) +} + +/// A boxed version of [folder_split] for recursion. +fn folder_split_boxed<'a, 'b>( + chunk_items: Vec, + location: usize, + name: Cow<'a, str>, + split_context: &'a mut SplitContext<'b>, +) -> Pin> + Send + 'a>> { + Box::pin(folder_split(chunk_items, location, name, split_context)) +} + +/// Split chunk items by folder structure. +#[tracing::instrument(level = Level::TRACE, skip_all, fields(name = display(&name), location))] +async fn folder_split( + mut chunk_items: Vec, + mut location: usize, + name: Cow<'_, str>, + split_context: &mut SplitContext<'_>, +) -> Result<()> { + let mut map = IndexMap::<_, (_, Vec)>::new(); + loop { + for item in chunk_items { + let (_, _, _, asset_ident) = &item; + let (folder_name, new_location) = folder_name(asset_ident, location); + if let Some((_, list)) = map.get_mut(folder_name) { + list.push(item); + } else { + map.insert(folder_name.to_string(), (new_location, vec![item])); + } + } + if map.len() == 1 { + // shortcut + let (folder_name, (new_location, list)) = map.into_iter().next().unwrap(); + if let Some(new_location) = new_location { + chunk_items = list; + location = new_location; + map = IndexMap::new(); + continue; + } else { + let mut key = format!("{}-{}", name, folder_name); + make_chunk(list, &mut key, split_context).await?; + return Ok(()); + } + } else { + break; + } + } + let mut remaining = Vec::new(); + for (folder_name, (new_location, mut list)) in map { + let mut key = format!("{}-{}", name, folder_name); + if !handle_split_group(&mut list, &mut key, split_context, Some(&mut remaining)).await? { + if let Some(new_location) = new_location { + folder_split_boxed(list, new_location, Cow::Borrowed(&name), split_context).await?; + } else { + make_chunk(list, &mut key, split_context).await?; + } + } + } + if !remaining.is_empty() { + let (_, _, _, asset_ident) = &remaining[0]; + let mut key = format!("{}-{}", name, &asset_ident[..location]); + if !handle_split_group(&mut remaining, &mut key, split_context, None).await? { + make_chunk(remaining, &mut key, split_context).await?; + } + } + Ok(()) +} + +/// Returns `true` if the given `ident` is app code. +fn is_app_code(ident: &str) -> bool { + !ident.contains("/node_modules/") +} + +/// Returns the package name of the given `ident`. +fn package_name(ident: &str) -> &str { + static PACKAGE_NAME_REGEX: Lazy = + Lazy::new(|| Regex::new(r"/node_modules/((?:@[^/]+/)?[^/]+)").unwrap()); + if let Some(result) = PACKAGE_NAME_REGEX.find_iter(ident).last() { + &result.as_str()["/node_modules/".len()..] + } else { + "" + } +} + +/// Returns the folder name at the given `location` of the given `ident`. Also +/// returns the next folder name location if any. +fn folder_name(ident: &str, location: usize) -> (&str, Option) { + if let Some(offset) = ident[location..].find('/') { + let new_location = location + offset + 1; + (&ident[..new_location], Some(new_location)) + } else { + (ident, None) + } +} + +const LARGE_CHUNK: usize = 1_000_000; +const SMALL_CHUNK: usize = 100_000; + +enum ChunkSize { + Large, + Perfect, + Small, +} + +/// Determines the total size of the passed chunk items. Returns too small, too +/// large or perfect fit. +fn chunk_size(chunk_items: &[ChunkItemWithInfo]) -> ChunkSize { + let mut total_size = 0; + for (_, _, size, _) in chunk_items { + total_size += size; + } + if total_size >= LARGE_CHUNK { + ChunkSize::Large + } else if total_size > SMALL_CHUNK { + ChunkSize::Perfect + } else { + ChunkSize::Small + } +} diff --git a/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs b/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs new file mode 100644 index 0000000000000..027fad30732cb --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/chunking_context.rs @@ -0,0 +1,318 @@ +use anyhow::Result; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, RcStr, TaskInput, Upcast, Value, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbo_tasks_hash::DeterministicHash; + +use super::{availability_info::AvailabilityInfo, ChunkableModule, EvaluatableAssets}; +use crate::{ + chunk::{ChunkItem, ModuleId}, + environment::Environment, + ident::AssetIdent, + module::Module, + output::{OutputAsset, OutputAssets}, +}; + +#[derive( + Debug, + Default, + TaskInput, + Clone, + Copy, + PartialEq, + Eq, + PartialOrd, + Ord, + Hash, + Serialize, + Deserialize, + TraceRawVcs, + DeterministicHash, +)] +pub enum MinifyType { + #[default] + Minify, + NoMinify, +} + +#[turbo_tasks::value(shared)] +pub struct ChunkGroupResult { + pub assets: Vc, + pub availability_info: AvailabilityInfo, +} + +#[turbo_tasks::value(shared)] +pub struct EntryChunkGroupResult { + pub asset: Vc>, + pub availability_info: AvailabilityInfo, +} + +/// A context for the chunking that influences the way chunks are created +#[turbo_tasks::value_trait] +pub trait ChunkingContext { + fn name(self: Vc) -> Vc; + fn context_path(self: Vc) -> Vc; + fn output_root(self: Vc) -> Vc; + + // TODO remove this, a chunking context should not be bound to a specific + // environment since this can change due to transitions in the module graph + fn environment(self: Vc) -> Vc; + + // TODO(alexkirsz) Remove this from the chunking context. This should be at the + // discretion of chunking context implementors. However, we currently use this + // in a couple of places in `turbopack-css`, so we need to remove that + // dependency first. + fn chunk_path(self: Vc, ident: Vc, extension: RcStr) -> Vc; + + // TODO(alexkirsz) Remove this from the chunking context. + /// Reference Source Map Assets for chunks + fn reference_chunk_source_maps(self: Vc, chunk: Vc>) -> Vc; + + /// Returns a URL (relative or absolute, depending on the asset prefix) to + /// the static asset based on its `ident`. + fn asset_url(self: Vc, ident: Vc) -> Result>; + + fn asset_path( + self: Vc, + content_hash: RcStr, + original_asset_ident: Vc, + ) -> Vc; + + fn is_hot_module_replacement_enabled(self: Vc) -> Vc { + Vc::cell(false) + } + + fn async_loader_chunk_item( + &self, + module: Vc>, + availability_info: Value, + ) -> Vc>; + fn async_loader_chunk_item_id(&self, module: Vc>) -> Vc; + + fn chunk_group( + self: Vc, + module: Vc>, + availability_info: Value, + ) -> Vc; + + fn evaluated_chunk_group( + self: Vc, + ident: Vc, + evaluatable_assets: Vc, + availability_info: Value, + ) -> Vc; + + /// Generates an output chunk that: + /// * evaluates the given assets; and + /// * exports the result of evaluating the given module as a CommonJS + /// default export. + fn entry_chunk_group( + self: Vc, + path: Vc, + module: Vc>, + evaluatable_assets: Vc, + availability_info: Value, + ) -> Result>; + + async fn chunk_item_id_from_ident( + self: Vc, + ident: Vc, + ) -> Result> { + Ok(ModuleId::String(ident.to_string().await?.clone_value()).cell()) + } + + fn chunk_item_id(self: Vc, chunk_item: Vc>) -> Vc { + self.chunk_item_id_from_ident(chunk_item.asset_ident()) + } +} + +pub trait ChunkingContextExt { + fn root_chunk_group( + self: Vc, + module: Vc>, + ) -> Vc + where + Self: Send; + + fn root_chunk_group_assets( + self: Vc, + module: Vc>, + ) -> Vc + where + Self: Send; + + fn evaluated_chunk_group_assets( + self: Vc, + ident: Vc, + evaluatable_assets: Vc, + availability_info: Value, + ) -> Vc + where + Self: Send; + + fn entry_chunk_group_asset( + self: Vc, + path: Vc, + module: Vc>, + evaluatable_assets: Vc, + availability_info: Value, + ) -> Vc> + where + Self: Send; + + fn root_entry_chunk_group( + self: Vc, + path: Vc, + module: Vc>, + evaluatable_assets: Vc, + ) -> Vc + where + Self: Send; + + fn root_entry_chunk_group_asset( + self: Vc, + path: Vc, + module: Vc>, + evaluatable_assets: Vc, + ) -> Vc> + where + Self: Send; + + fn chunk_group_assets( + self: Vc, + module: Vc>, + availability_info: Value, + ) -> Vc + where + Self: Send; +} + +impl>> ChunkingContextExt for T { + fn root_chunk_group( + self: Vc, + module: Vc>, + ) -> Vc { + self.chunk_group(module, Value::new(AvailabilityInfo::Root)) + } + + fn root_chunk_group_assets( + self: Vc, + module: Vc>, + ) -> Vc { + root_chunk_group_assets(Vc::upcast(self), module) + } + + fn evaluated_chunk_group_assets( + self: Vc, + ident: Vc, + evaluatable_assets: Vc, + availability_info: Value, + ) -> Vc { + evaluated_chunk_group_assets( + Vc::upcast(self), + ident, + evaluatable_assets, + availability_info, + ) + } + + fn entry_chunk_group_asset( + self: Vc, + path: Vc, + module: Vc>, + evaluatable_assets: Vc, + availability_info: Value, + ) -> Vc> { + entry_chunk_group_asset( + path, + Vc::upcast(self), + module, + evaluatable_assets, + availability_info, + ) + } + + fn root_entry_chunk_group( + self: Vc, + path: Vc, + module: Vc>, + evaluatable_assets: Vc, + ) -> Vc { + self.entry_chunk_group( + path, + module, + evaluatable_assets, + Value::new(AvailabilityInfo::Root), + ) + } + + fn root_entry_chunk_group_asset( + self: Vc, + path: Vc, + module: Vc>, + evaluatable_assets: Vc, + ) -> Vc> { + entry_chunk_group_asset( + path, + Vc::upcast(self), + module, + evaluatable_assets, + Value::new(AvailabilityInfo::Root), + ) + } + + fn chunk_group_assets( + self: Vc, + module: Vc>, + availability_info: Value, + ) -> Vc { + chunk_group_assets(Vc::upcast(self), module, availability_info) + } +} + +#[turbo_tasks::function] +async fn root_chunk_group_assets( + chunking_context: Vc>, + module: Vc>, +) -> Result> { + Ok(chunking_context.root_chunk_group(module).await?.assets) +} + +#[turbo_tasks::function] +async fn evaluated_chunk_group_assets( + chunking_context: Vc>, + ident: Vc, + evaluatable_assets: Vc, + availability_info: Value, +) -> Result> { + Ok(chunking_context + .evaluated_chunk_group(ident, evaluatable_assets, availability_info) + .await? + .assets) +} + +#[turbo_tasks::function] +async fn entry_chunk_group_asset( + path: Vc, + chunking_context: Vc>, + module: Vc>, + evaluatable_assets: Vc, + availability_info: Value, +) -> Result>> { + Ok(chunking_context + .entry_chunk_group(path, module, evaluatable_assets, availability_info) + .await? + .asset) +} + +#[turbo_tasks::function] +async fn chunk_group_assets( + chunking_context: Vc>, + module: Vc>, + availability_info: Value, +) -> Result> { + Ok(chunking_context + .chunk_group(module, availability_info) + .await? + .assets) +} diff --git a/turbopack/crates/turbopack-core/src/chunk/containment_tree.rs b/turbopack/crates/turbopack-core/src/chunk/containment_tree.rs new file mode 100644 index 0000000000000..3c4fa45fc1144 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/containment_tree.rs @@ -0,0 +1,277 @@ +use std::{cell::RefCell, mem::take, rc::Rc}; + +use anyhow::Result; +use indexmap::{IndexMap, IndexSet}; +use turbo_tasks::TryJoinIterExt; + +#[derive(Debug, Default, Clone, Eq, PartialEq)] +pub struct ContainmentTree { + pub key: Option, + pub values: Option>, + pub children: Vec>, +} + +// Temp structure which uses Rc and RefCell +struct Node { + key: K, + values: Vec, + children: Vec>>>, +} + +#[async_trait::async_trait] +pub trait ContainmentTreeKey: Sized { + async fn parent(&self) -> Result; +} + +impl ContainmentTree +where + K: ContainmentTreeKey + std::hash::Hash + Eq + Clone, +{ + pub async fn build(values: I) -> Result> + where + I: IntoIterator, V)>, + { + let values: Vec<_> = values.into_iter().collect(); + + // compute all unique common_parents + let mut common_parents = values + .iter() + .filter_map(|(key, _)| key.clone()) + .collect::>(); + + Self::expand_common_parents(&mut common_parents).await?; + + let relationships = Self::compute_relationships(&common_parents).await?; + + let mut trees = Self::create_node_tree(common_parents); + + let orphan_values = Self::add_values_to_tree(&mut trees, values); + + let roots = Self::treeify(relationships, &trees); + + // optimize tree by removing unnecessary nodes + Self::skip_unnecessary_nodes(&mut trees); + + // do conversion + let roots = Self::convert_into_common_parent_tree(roots, orphan_values); + + // top level nesting + Ok(if roots.len() == 1 { + roots.into_iter().next().unwrap() + } else { + ContainmentTree { + key: None, + values: None, + children: roots, + } + }) + } + + /// Expand all common parents to include all their parents. + async fn expand_common_parents(common_parents: &mut IndexSet) -> Result<()> { + // This is mutated while iterating, so we need to loop with index + let mut i = 0; + while i < common_parents.len() { + let current = &common_parents[i]; + let parent = current.parent().await?; + common_parents.insert(parent); + i += 1; + } + Ok(()) + } + + /// Compute parent -> child relationships between common_parents. + async fn compute_relationships(common_parents: &IndexSet) -> Result, K)>> { + common_parents + .iter() + .map(|key| { + let common_parents = &common_parents; + async move { + let mut current = key.clone(); + loop { + let parent = current.parent().await?; + if parent == current { + return Ok((None, key.clone())); + } + if common_parents.contains(&parent) { + // Can't insert here into the parent tree, since we want the order + // of children to be deterministic + return Ok((Some(parent), key.clone())); + } + current = parent; + } + } + }) + .try_join() + .await + } + + /// Create the tree nodes. + fn create_node_tree(common_parents: IndexSet) -> IndexMap>>> { + let mut trees = IndexMap::>>>::new(); + for common_parent in common_parents { + trees.insert( + common_parent.clone(), + Rc::new(RefCell::new(Node { + key: common_parent, + values: Vec::new(), + children: Vec::new(), + })), + ); + } + trees + } + + /// Add chunks to nodes. + fn add_values_to_tree( + trees: &mut IndexMap>>>, + values: Vec<(Option, V)>, + ) -> Vec { + let mut orphan_values = Vec::new(); + for (common_parent, chunk) in values { + if let Some(common_parent) = common_parent { + trees + .get_mut(&common_parent) + .unwrap() + .borrow_mut() + .values + .push(chunk); + } else { + orphan_values.push(chunk); + } + } + orphan_values + } + + /// Nest each tree by relationship, compute the roots + fn treeify( + relationships: Vec<(Option, K)>, + trees: &IndexMap>>>, + ) -> Vec>>> { + relationships + .into_iter() + .flat_map(|(parent, key)| { + let tree = trees.get(&key).unwrap().clone(); + if let Some(parent) = parent { + trees.get(&parent).unwrap().borrow_mut().children.push(tree); + None + } else { + Some(tree) + } + }) + .collect::>() + } + + /// Optimize tree by removing unnecessary nodes. + fn skip_unnecessary_nodes(trees: &mut IndexMap>>>) { + for tree in trees.values_mut() { + let mut tree = tree.borrow_mut(); + if tree.values.is_empty() && tree.children.len() == 1 { + let child = tree.children.pop().unwrap(); + let mut child = child.borrow_mut(); + tree.key = child.key.clone(); + tree.values.append(&mut child.values); + tree.children.append(&mut child.children); + } + } + } + + // Convert function to the real data structure + fn node_to_common_parent_tree(node: Rc>>) -> ContainmentTree { + let mut node = node.borrow_mut(); + let children = take(&mut node.children) + .into_iter() + .map(Self::node_to_common_parent_tree) + .collect(); + // TODO keyed cell: this would benefit from keying the cell by node.path + let values = Some(take(&mut node.values)); + ContainmentTree { + key: Some(node.key.clone()), + values, + children, + } + } + + fn convert_into_common_parent_tree( + roots: Vec>>>, + orphan_values: Vec, + ) -> Vec> { + roots + .into_iter() + .map(Self::node_to_common_parent_tree) + .chain(orphan_values.into_iter().map(|value| ContainmentTree { + key: None, + values: Some(vec![value]), + children: Vec::new(), + })) + .collect::>() + } +} + +#[cfg(test)] +mod tests { + use async_trait::async_trait; + + use super::*; + + #[derive(Clone, Debug, PartialEq, Eq, Hash)] + struct TestKey(u32, u32); + + #[async_trait] + impl ContainmentTreeKey for TestKey { + async fn parent(&self) -> Result { + if self.1 == 0 { + Ok(TestKey(self.0, 0)) + } else { + Ok(TestKey(self.0, self.1 - 1)) + } + } + } + + #[tokio::test] + async fn test_build_simple_input() -> Result<()> { + let input = vec![ + (None, "value0"), + (Some(TestKey(0, 0)), "value1"), + (Some(TestKey(0, 1)), "value2"), + (Some(TestKey(0, 2)), "value3"), + (Some(TestKey(1, 2)), "value4"), + ]; + + let tree = ContainmentTree::::build(input).await?; + + assert_eq!( + tree, + ContainmentTree { + key: None, + values: None, + children: vec![ + ContainmentTree { + key: Some(TestKey(0, 0)), + values: Some(vec!["value1"]), + children: vec![ContainmentTree { + key: Some(TestKey(0, 1)), + values: Some(vec!["value2"]), + children: vec![ContainmentTree { + key: Some(TestKey(0, 2)), + values: Some(vec!["value3"]), + children: vec![] + }] + }] + }, + ContainmentTree { + key: Some(TestKey(1, 2)), + values: Some(vec!["value4"]), + children: vec![] + }, + ContainmentTree { + key: None, + values: Some(vec!["value0"]), + children: vec![] + }, + ] + } + ); + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-core/src/chunk/data.rs b/turbopack/crates/turbopack-core/src/chunk/data.rs new file mode 100644 index 0000000000000..900ebd9edff5c --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/data.rs @@ -0,0 +1,143 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, ReadRef, TryJoinIterExt, Vc}; +use turbo_tasks_fs::FileSystemPath; + +use crate::{ + chunk::{ModuleId, OutputChunk, OutputChunkRuntimeInfo}, + output::{OutputAsset, OutputAssets}, +}; + +#[turbo_tasks::value] +pub struct ChunkData { + pub path: String, + pub included: Vec>, + pub excluded: Vec>, + pub module_chunks: Vec, + pub references: Vc, +} + +#[turbo_tasks::value(transparent)] +pub struct ChunkDataOption(Option>); + +// NOTE(alexkirsz) Our convention for naming vector types is to add an "s" to +// the end of the type name, but in this case it would be both gramatically +// incorrect and clash with the variable names everywhere. +// TODO(WEB-101) Should fix this. +#[turbo_tasks::value(transparent)] +pub struct ChunksData(Vec>); + +#[turbo_tasks::function] +fn module_chunk_reference_description() -> Vc { + Vc::cell("module chunk".into()) +} + +#[turbo_tasks::value_impl] +impl ChunkData { + #[turbo_tasks::function] + pub async fn from_asset( + output_root: Vc, + chunk: Vc>, + ) -> Result> { + let output_root = output_root.await?; + let path = chunk.ident().path().await?; + // The "path" in this case is the chunk's path, not the chunk item's path. + // The difference is a chunk is a file served by the dev server, and an + // item is one of several that are contained in that chunk file. + let Some(path) = output_root.get_path_to(&path) else { + return Ok(Vc::cell(None)); + }; + let path = path.to_string(); + + let Some(output_chunk) = Vc::try_resolve_sidecast::>(chunk).await? + else { + return Ok(Vc::cell(Some( + ChunkData { + path, + included: Vec::new(), + excluded: Vec::new(), + module_chunks: Vec::new(), + references: OutputAssets::empty(), + } + .cell(), + ))); + }; + + let runtime_info = output_chunk.runtime_info().await?; + + let OutputChunkRuntimeInfo { + included_ids, + excluded_ids, + module_chunks, + placeholder_for_future_extensions: _, + } = &*runtime_info; + + let included = if let Some(included_ids) = included_ids { + included_ids.await?.iter().copied().try_join().await? + } else { + Vec::new() + }; + let excluded = if let Some(excluded_ids) = excluded_ids { + excluded_ids.await?.iter().copied().try_join().await? + } else { + Vec::new() + }; + let (module_chunks, module_chunks_references) = if let Some(module_chunks) = module_chunks { + module_chunks + .await? + .iter() + .copied() + .map(|chunk| { + let output_root = output_root.clone(); + + async move { + let chunk_path = chunk.ident().path().await?; + Ok(output_root + .get_path_to(&chunk_path) + .map(|path| (path.to_owned(), chunk))) + } + }) + .try_join() + .await? + .into_iter() + .flatten() + .unzip() + } else { + (Vec::new(), Vec::new()) + }; + + Ok(Vc::cell(Some( + ChunkData { + path, + included, + excluded, + module_chunks, + references: Vc::cell(module_chunks_references), + } + .cell(), + ))) + } + + #[turbo_tasks::function] + pub async fn from_assets( + output_root: Vc, + chunks: Vc, + ) -> Result> { + Ok(Vc::cell( + chunks + .await? + .iter() + .map(|&chunk| ChunkData::from_asset(output_root, chunk)) + .try_join() + .await? + .into_iter() + .flat_map(|chunk| *chunk) + .collect(), + )) + } + + /// Returns [`OutputAsset`]s that this chunk data references. + #[turbo_tasks::function] + pub async fn references(self: Vc) -> Result> { + Ok(self.await?.references) + } +} diff --git a/turbopack/crates/turbopack-core/src/chunk/evaluate.rs b/turbopack/crates/turbopack-core/src/chunk/evaluate.rs new file mode 100644 index 0000000000000..1d2f49c7284ad --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/evaluate.rs @@ -0,0 +1,88 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{Upcast, Value, ValueToString, Vc}; + +use super::ChunkableModule; +use crate::{ + asset::Asset, + context::AssetContext, + module::Module, + reference_type::{EntryReferenceSubType, ReferenceType}, + source::Source, +}; + +/// Marker trait for the chunking context to accept evaluated entries. +/// +/// The chunking context implementation will resolve the dynamic entry to a +/// well-known value or trait object. +#[turbo_tasks::value_trait] +pub trait EvaluatableAsset: Asset + Module + ChunkableModule {} + +pub trait EvaluatableAssetExt: Send { + fn to_evaluatable( + self: Vc, + asset_context: Vc>, + ) -> Vc>; +} + +impl EvaluatableAssetExt for T +where + T: Upcast>, +{ + fn to_evaluatable( + self: Vc, + asset_context: Vc>, + ) -> Vc> { + to_evaluatable(Vc::upcast(self), asset_context) + } +} + +#[turbo_tasks::function] +async fn to_evaluatable( + asset: Vc>, + asset_context: Vc>, +) -> Result>> { + let module = asset_context + .process( + asset, + Value::new(ReferenceType::Entry(EntryReferenceSubType::Runtime)), + ) + .module(); + let Some(entry) = Vc::try_resolve_downcast::>(module).await? else { + bail!( + "{} is not a valid evaluated entry", + module.ident().to_string().await? + ) + }; + Ok(entry) +} + +#[turbo_tasks::value(transparent)] +pub struct EvaluatableAssets(Vec>>); + +#[turbo_tasks::value_impl] +impl EvaluatableAssets { + #[turbo_tasks::function] + pub fn empty() -> Vc { + EvaluatableAssets(vec![]).cell() + } + + #[turbo_tasks::function] + pub fn one(entry: Vc>) -> Vc { + EvaluatableAssets(vec![entry]).cell() + } + + #[turbo_tasks::function] + pub fn many(assets: Vec>>) -> Vc { + EvaluatableAssets(assets).cell() + } + + #[turbo_tasks::function] + pub async fn with_entry( + self: Vc, + entry: Vc>, + ) -> Result> { + let mut entries = self.await?.clone_value(); + entries.push(entry); + Ok(EvaluatableAssets(entries).cell()) + } +} diff --git a/turbopack/crates/turbopack-core/src/chunk/mod.rs b/turbopack/crates/turbopack-core/src/chunk/mod.rs new file mode 100644 index 0000000000000..bfc69139cb57e --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/mod.rs @@ -0,0 +1,750 @@ +pub mod availability_info; +pub mod available_chunk_items; +pub mod chunk_group; +pub mod chunking; +pub(crate) mod chunking_context; +pub(crate) mod containment_tree; +pub(crate) mod data; +pub(crate) mod evaluate; +pub mod optimize; + +use std::{ + collections::{HashMap, HashSet}, + fmt::{Debug, Display}, + future::Future, + hash::Hash, +}; + +use anyhow::Result; +use auto_hash_map::AutoSet; +use indexmap::{IndexMap, IndexSet}; +use serde::{Deserialize, Serialize}; +use tracing::{info_span, Span}; +use turbo_tasks::{ + debug::ValueDebugFormat, + graph::{AdjacencyMap, GraphTraversal, GraphTraversalResult, Visit, VisitControlFlow}, + trace::TraceRawVcs, + RcStr, ReadRef, TaskInput, TryFlatJoinIterExt, TryJoinIterExt, Upcast, ValueToString, Vc, +}; +use turbo_tasks_fs::FileSystemPath; +use turbo_tasks_hash::DeterministicHash; + +use self::{availability_info::AvailabilityInfo, available_chunk_items::AvailableChunkItems}; +pub use self::{ + chunking_context::{ + ChunkGroupResult, ChunkingContext, ChunkingContextExt, EntryChunkGroupResult, MinifyType, + }, + data::{ChunkData, ChunkDataOption, ChunksData}, + evaluate::{EvaluatableAsset, EvaluatableAssetExt, EvaluatableAssets}, +}; +use crate::{ + asset::Asset, + environment::ChunkLoading, + ident::AssetIdent, + module::Module, + output::OutputAssets, + reference::{ModuleReference, ModuleReferences}, +}; + +/// A module id, which can be a number or string +#[turbo_tasks::value(shared)] +#[derive(Debug, Clone, Hash, Ord, PartialOrd, DeterministicHash)] +#[serde(untagged)] +pub enum ModuleId { + Number(u32), + String(RcStr), +} + +impl Display for ModuleId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + ModuleId::Number(i) => write!(f, "{}", i), + ModuleId::String(s) => write!(f, "{}", s), + } + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for ModuleId { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell(self.to_string().into()) + } +} + +impl ModuleId { + pub fn parse(id: &str) -> Result { + Ok(match id.parse::() { + Ok(i) => ModuleId::Number(i), + Err(_) => ModuleId::String(id.into()), + }) + } +} + +/// A list of module ids. +#[turbo_tasks::value(transparent, shared)] +pub struct ModuleIds(Vec>); + +/// A [Module] that can be converted into a [Chunk]. +#[turbo_tasks::value_trait] +pub trait ChunkableModule: Module + Asset { + fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Vc>; +} + +#[turbo_tasks::value(transparent)] +pub struct Chunks(Vec>>); + +#[turbo_tasks::value_impl] +impl Chunks { + /// Creates a new empty [Vc]. + #[turbo_tasks::function] + pub fn empty() -> Vc { + Vc::cell(vec![]) + } +} + +/// A chunk is one type of asset. +/// It usually contains multiple chunk items. +#[turbo_tasks::value_trait] +pub trait Chunk: Asset { + fn ident(self: Vc) -> Vc; + fn chunking_context(self: Vc) -> Vc>; + // TODO Once output assets have their own trait, this path() method will move + // into that trait and ident() will be removed from that. Assets on the + // output-level only have a path and no complex ident. + /// The path of the chunk. + fn path(self: Vc) -> Vc { + self.ident().path() + } + + /// Other [OutputAsset]s referenced from this [Chunk]. + fn references(self: Vc) -> Vc { + OutputAssets::empty() + } +} + +/// Aggregated information about a chunk content that can be used by the runtime +/// code to optimize chunk loading. +#[turbo_tasks::value(shared)] +#[derive(Default)] +pub struct OutputChunkRuntimeInfo { + pub included_ids: Option>, + pub excluded_ids: Option>, + /// List of paths of chunks containing individual modules that are part of + /// this chunk. This is useful for selectively loading modules from a chunk + /// without loading the whole chunk. + pub module_chunks: Option>, + pub placeholder_for_future_extensions: (), +} + +#[turbo_tasks::value_trait] +pub trait OutputChunk: Asset { + fn runtime_info(self: Vc) -> Vc; +} + +/// Specifies how a chunk interacts with other chunks when building a chunk +/// group +#[derive( + Copy, Default, Clone, Hash, TraceRawVcs, Serialize, Deserialize, Eq, PartialEq, ValueDebugFormat, +)] +pub enum ChunkingType { + /// Module is placed in the same chunk group and is loaded in parallel. It + /// doesn't become an async module when the referenced module is async. + #[default] + Parallel, + /// Module is placed in the same chunk group and is loaded in parallel. It + /// becomes an async module when the referenced module is async. + ParallelInheritAsync, + /// An async loader is placed into the referencing chunk and loads the + /// separate chunk group in which the module is placed. + Async, + /// Module not placed in chunk group, but its references are still followed. + Passthrough, +} + +#[turbo_tasks::value(transparent)] +pub struct ChunkingTypeOption(Option); + +/// A [ModuleReference] implementing this trait and returning true for +/// [ChunkableModuleReference::is_chunkable] are considered as potentially +/// chunkable references. When all [Module]s of such a reference implement +/// [ChunkableModule] they are placed in [Chunk]s during chunking. +/// They are even potentially placed in the same [Chunk] when a chunk type +/// specific interface is implemented. +#[turbo_tasks::value_trait] +pub trait ChunkableModuleReference: ModuleReference + ValueToString { + fn chunking_type(self: Vc) -> Vc { + Vc::cell(Some(ChunkingType::default())) + } +} + +type AsyncInfo = IndexMap>, Vec>>>; + +pub struct ChunkContentResult { + pub chunk_items: IndexSet>>, + pub async_modules: IndexSet>>, + pub external_module_references: IndexSet>>, + /// A map from local module to all children from which the async module + /// status is inherited + pub forward_edges_inherit_async: AsyncInfo, + /// A map from local module to all parents that inherit the async module + /// status + pub local_back_edges_inherit_async: AsyncInfo, + /// A map from already available async modules to all local parents that + /// inherit the async module status + pub available_async_modules_back_edges_inherit_async: AsyncInfo, +} + +pub async fn chunk_content( + chunking_context: Vc>, + entries: impl IntoIterator>>, + availability_info: AvailabilityInfo, +) -> Result { + chunk_content_internal_parallel(chunking_context, entries, availability_info).await +} + +#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, TraceRawVcs, Debug)] +enum InheritAsyncEdge { + /// The chunk item is in the current chunk group and async module info need + /// to be computed for it + LocalModule, + /// The chunk item is already available in the parent chunk group and is an + /// async module. Chunk items that are available but not async modules are + /// not included in back edges at all since they don't influence the parent + /// module in terms of being an async module. + AvailableAsyncModule, +} + +#[derive(Eq, PartialEq, Clone, Hash, Serialize, Deserialize, TraceRawVcs, Debug)] +enum ChunkContentGraphNode { + // A chunk item not placed in the current chunk, but whose references we will + // follow to find more graph nodes. + PassthroughChunkItem { + item: Vc>, + }, + // Chunk items that are placed into the current chunk group + ChunkItem { + item: Vc>, + ident: ReadRef, + }, + // Async module that is referenced from the chunk group + AsyncModule { + module: Vc>, + }, + // ModuleReferences that are not placed in the current chunk group + ExternalModuleReference(Vc>), + /// A list of directly referenced chunk items from which `is_async_module` + /// will be inherited. + InheritAsyncInfo { + item: Vc>, + references: Vec<(Vc>, InheritAsyncEdge)>, + }, +} + +#[derive(Debug, Clone, Copy, TaskInput, PartialEq, Eq, Hash, Serialize, Deserialize)] +enum ChunkGraphNodeToReferences { + PassthroughChunkItem(Vc>), + ChunkItem(Vc>), +} + +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, TraceRawVcs)] +struct ChunkGraphEdge { + key: Option>>, + node: ChunkContentGraphNode, +} + +#[derive(Debug, Clone)] +#[turbo_tasks::value(transparent)] +struct ChunkGraphEdges(Vec); + +#[turbo_tasks::function] +async fn graph_node_to_referenced_nodes_with_available_chunk_items( + node: ChunkGraphNodeToReferences, + chunking_context: Vc>, + available_chunk_items: Vc, +) -> Result> { + let edges = graph_node_to_referenced_nodes(node, chunking_context); + let edges_ref = edges.await?; + for (unchanged, edge) in edges_ref.iter().enumerate() { + if let ChunkContentGraphNode::ChunkItem { item, .. } = edge.node { + if let Some(info) = *available_chunk_items.get(item).await? { + let mut new_edges = Vec::with_capacity(edges_ref.len()); + new_edges.extend(edges_ref[0..unchanged].iter().cloned()); + let mut available_chunk_item_info = HashMap::new(); + available_chunk_item_info.insert(item, info); + for edge in edges_ref[unchanged + 1..].iter() { + match edge.node { + ChunkContentGraphNode::ChunkItem { item, .. } => { + if let Some(info) = *available_chunk_items.get(item).await? { + available_chunk_item_info.insert(item, info); + continue; + } + } + ChunkContentGraphNode::InheritAsyncInfo { + item, + ref references, + } => { + let new_references = references + .iter() + .filter_map(|&(r, _)| { + if let Some(info) = available_chunk_item_info.get(&r) { + if info.is_async { + Some((r, InheritAsyncEdge::AvailableAsyncModule)) + } else { + None + } + } else { + Some((r, InheritAsyncEdge::LocalModule)) + } + }) + .collect(); + new_edges.push(ChunkGraphEdge { + key: edge.key, + node: ChunkContentGraphNode::InheritAsyncInfo { + item, + references: new_references, + }, + }); + continue; + } + _ => {} + } + new_edges.push(edge.clone()) + } + return Ok(Vc::cell(new_edges)); + } + } + } + Ok(edges) +} + +#[turbo_tasks::function] +async fn graph_node_to_referenced_nodes( + node: ChunkGraphNodeToReferences, + chunking_context: Vc>, +) -> Result> { + let (parent, references) = match &node { + ChunkGraphNodeToReferences::PassthroughChunkItem(item) => (None, item.references()), + ChunkGraphNodeToReferences::ChunkItem(item) => (Some(*item), item.references()), + }; + + let references = references.await?; + let graph_nodes = references + .iter() + .map(|reference| async { + let reference = *reference; + let Some(chunkable_module_reference) = + Vc::try_resolve_downcast::>(reference).await? + else { + return Ok(vec![ChunkGraphEdge { + key: None, + node: ChunkContentGraphNode::ExternalModuleReference(reference), + }]); + }; + + let Some(chunking_type) = *chunkable_module_reference.chunking_type().await? else { + return Ok(vec![ChunkGraphEdge { + key: None, + node: ChunkContentGraphNode::ExternalModuleReference(reference), + }]); + }; + + let module_data = reference + .resolve_reference() + .resolve() + .await? + .primary_modules() + .await? + .into_iter() + .map(|&module| async move { + let Some(chunkable_module) = + Vc::try_resolve_sidecast::>(module).await? + else { + return Ok(( + Some(ChunkGraphEdge { + key: None, + node: ChunkContentGraphNode::ExternalModuleReference(reference), + }), + None, + )); + }; + + match chunking_type { + ChunkingType::Parallel => { + let chunk_item = chunkable_module + .as_chunk_item(chunking_context) + .resolve() + .await?; + Ok(( + Some(ChunkGraphEdge { + key: Some(module), + node: ChunkContentGraphNode::ChunkItem { + item: chunk_item, + ident: module.ident().to_string().await?, + }, + }), + None, + )) + } + ChunkingType::ParallelInheritAsync => { + let chunk_item = chunkable_module + .as_chunk_item(chunking_context) + .resolve() + .await?; + Ok(( + Some(ChunkGraphEdge { + key: Some(module), + node: ChunkContentGraphNode::ChunkItem { + item: chunk_item, + ident: module.ident().to_string().await?, + }, + }), + Some((chunk_item, InheritAsyncEdge::LocalModule)), + )) + } + ChunkingType::Passthrough => { + let chunk_item = chunkable_module + .as_chunk_item(chunking_context) + .resolve() + .await?; + + Ok(( + Some(ChunkGraphEdge { + key: None, + node: ChunkContentGraphNode::PassthroughChunkItem { + item: chunk_item, + }, + }), + None, + )) + } + ChunkingType::Async => { + let chunk_loading = + chunking_context.environment().chunk_loading().await?; + if matches!(*chunk_loading, ChunkLoading::Edge) { + let chunk_item = chunkable_module + .as_chunk_item(chunking_context) + .resolve() + .await?; + Ok(( + Some(ChunkGraphEdge { + key: Some(module), + node: ChunkContentGraphNode::ChunkItem { + item: chunk_item, + ident: module.ident().to_string().await?, + }, + }), + None, + )) + } else { + Ok(( + Some(ChunkGraphEdge { + key: None, + node: ChunkContentGraphNode::AsyncModule { + module: chunkable_module, + }, + }), + None, + )) + } + } + } + }) + .try_join() + .await?; + + let mut graph_nodes = vec![]; + let mut inherit_async_references = vec![]; + for (n, iar) in module_data { + if let Some(n) = n { + graph_nodes.push(n); + } + if let Some(iar) = iar { + inherit_async_references.push(iar); + } + } + + if !inherit_async_references.is_empty() { + if let Some(parent) = parent { + graph_nodes.push(ChunkGraphEdge { + key: None, + node: ChunkContentGraphNode::InheritAsyncInfo { + item: parent, + references: inherit_async_references, + }, + }) + } + } + + Ok(graph_nodes) + }) + .try_flat_join() + .await?; + + Ok(Vc::cell(graph_nodes)) +} + +struct ChunkContentVisit { + chunking_context: Vc>, + available_chunk_items: Option>, + processed_modules: HashSet>>, +} + +type ChunkItemToGraphNodesEdges = impl Iterator; + +type ChunkItemToGraphNodesFuture = impl Future>; + +impl Visit for ChunkContentVisit { + type Edge = ChunkGraphEdge; + type EdgesIntoIter = ChunkItemToGraphNodesEdges; + type EdgesFuture = ChunkItemToGraphNodesFuture; + + fn visit(&mut self, edge: ChunkGraphEdge) -> VisitControlFlow { + let ChunkGraphEdge { key, node } = edge; + let Some(module) = key else { + if matches!(node, ChunkContentGraphNode::PassthroughChunkItem { .. }) { + return VisitControlFlow::Continue(node); + } else { + // All other types don't have edges + return VisitControlFlow::Skip(node); + } + }; + + if !self.processed_modules.insert(module) { + return VisitControlFlow::Skip(node); + } + + VisitControlFlow::Continue(node) + } + + fn edges(&mut self, node: &ChunkContentGraphNode) -> Self::EdgesFuture { + let node = node.clone(); + + let chunking_context = self.chunking_context; + let available_chunk_items = self.available_chunk_items; + + async move { + let node = match node { + ChunkContentGraphNode::PassthroughChunkItem { item } => { + ChunkGraphNodeToReferences::PassthroughChunkItem(item) + } + ChunkContentGraphNode::ChunkItem { item, .. } => { + ChunkGraphNodeToReferences::ChunkItem(item) + } + _ => { + return Ok(None.into_iter().flatten()); + } + }; + + let nodes = if let Some(available_chunk_items) = available_chunk_items { + graph_node_to_referenced_nodes_with_available_chunk_items( + node, + chunking_context, + available_chunk_items, + ) + } else { + graph_node_to_referenced_nodes(node, chunking_context) + } + .await?; + Ok(Some(nodes.into_iter().cloned()).into_iter().flatten()) + } + } + + fn span(&mut self, node: &ChunkContentGraphNode) -> Span { + if let ChunkContentGraphNode::ChunkItem { ident, .. } = node { + info_span!("chunking module", name = display(ident)) + } else { + Span::current() + } + } +} + +async fn chunk_content_internal_parallel( + chunking_context: Vc>, + entries: impl IntoIterator>>, + availability_info: AvailabilityInfo, +) -> Result { + let root_edges = entries + .into_iter() + .map(|entry| async move { + let entry = entry.resolve().await?; + let Some(chunkable_module) = + Vc::try_resolve_downcast::>(entry).await? + else { + return Ok(None); + }; + Ok(Some(ChunkGraphEdge { + key: Some(entry), + node: ChunkContentGraphNode::ChunkItem { + item: chunkable_module + .as_chunk_item(chunking_context) + .resolve() + .await?, + ident: chunkable_module.ident().to_string().await?, + }, + })) + }) + .try_flat_join() + .await?; + + let visit = ChunkContentVisit { + chunking_context, + available_chunk_items: availability_info.available_chunk_items(), + processed_modules: Default::default(), + }; + + let GraphTraversalResult::Completed(traversal_result) = + AdjacencyMap::new().visit(root_edges, visit).await + else { + unreachable!(); + }; + + let graph_nodes: Vec<_> = traversal_result?.into_reverse_topological().collect(); + + let mut chunk_items = IndexSet::new(); + let mut async_modules = IndexSet::new(); + let mut external_module_references = IndexSet::new(); + let mut forward_edges_inherit_async = IndexMap::new(); + let mut local_back_edges_inherit_async = IndexMap::new(); + let mut available_async_modules_back_edges_inherit_async = IndexMap::new(); + + for graph_node in graph_nodes { + match graph_node { + ChunkContentGraphNode::PassthroughChunkItem { .. } => {} + ChunkContentGraphNode::ChunkItem { item, .. } => { + chunk_items.insert(item); + } + ChunkContentGraphNode::AsyncModule { module } => { + let module = module.resolve().await?; + async_modules.insert(module); + } + ChunkContentGraphNode::ExternalModuleReference(reference) => { + let reference = reference.resolve().await?; + external_module_references.insert(reference); + } + ChunkContentGraphNode::InheritAsyncInfo { item, references } => { + for &(reference, ty) in &references { + match ty { + InheritAsyncEdge::LocalModule => local_back_edges_inherit_async + .entry(reference) + .or_insert_with(Vec::new) + .push(item), + InheritAsyncEdge::AvailableAsyncModule => { + available_async_modules_back_edges_inherit_async + .entry(reference) + .or_insert_with(Vec::new) + .push(item) + } + } + } + forward_edges_inherit_async + .entry(item) + .or_insert_with(Vec::new) + .extend(references.into_iter().map(|(r, _)| r)); + } + } + } + + Ok(ChunkContentResult { + chunk_items, + async_modules, + external_module_references, + forward_edges_inherit_async, + local_back_edges_inherit_async, + available_async_modules_back_edges_inherit_async, + }) +} + +#[turbo_tasks::value_trait] +pub trait ChunkItem { + /// The [AssetIdent] of the [Module] that this [ChunkItem] was created from. + /// For most chunk types this must uniquely identify the chunk item at + /// runtime as it's the source of the module id used at runtime. + fn asset_ident(self: Vc) -> Vc; + /// A [AssetIdent] that uniquely identifies the content of this [ChunkItem]. + /// It is unusally identical to [ChunkItem::asset_ident] but can be + /// different when the chunk item content depends on available modules e. g. + /// for chunk loaders. + fn content_ident(self: Vc) -> Vc { + self.asset_ident() + } + /// A [ChunkItem] can describe different `references` than its original + /// [Module]. + /// TODO(alexkirsz) This should have a default impl that returns empty + /// references. + fn references(self: Vc) -> Vc; + + /// The type of chunk this item should be assembled into. + fn ty(self: Vc) -> Vc>; + + /// A temporary method to retrieve the module associated with this + /// ChunkItem. TODO: Remove this as part of the chunk refactoring. + fn module(self: Vc) -> Vc>; + + fn chunking_context(self: Vc) -> Vc>; + + fn is_self_async(self: Vc) -> Vc { + Vc::cell(false) + } +} + +#[turbo_tasks::value_trait] +pub trait ChunkType: ValueToString { + /// Create a new chunk for the given chunk items + fn chunk( + &self, + chunking_context: Vc>, + chunk_items: Vec, + referenced_output_assets: Vc, + ) -> Vc>; + + fn chunk_item_size( + &self, + chunking_context: Vc>, + chunk_item: Vc>, + async_module_info: Option>, + ) -> Vc; +} + +#[turbo_tasks::value(transparent)] +pub struct ChunkItems(Vec>>); + +#[turbo_tasks::value] +pub struct AsyncModuleInfo { + pub referenced_async_modules: AutoSet>>, +} + +#[turbo_tasks::value_impl] +impl AsyncModuleInfo { + #[turbo_tasks::function] + pub fn new(referenced_async_modules: Vec>>) -> Vc { + Self { + referenced_async_modules: referenced_async_modules.into_iter().collect(), + } + .cell() + } +} + +pub type ChunkItemWithAsyncModuleInfo = (Vc>, Option>); + +#[turbo_tasks::value(transparent)] +pub struct ChunkItemsWithAsyncModuleInfo(Vec); + +pub trait ChunkItemExt: Send { + /// Returns the module id of this chunk item. + fn id(self: Vc) -> Vc; +} + +impl ChunkItemExt for T +where + T: Upcast>, +{ + /// Returns the module id of this chunk item. + fn id(self: Vc) -> Vc { + let chunk_item = Vc::upcast(self); + chunk_item.chunking_context().chunk_item_id(chunk_item) + } +} diff --git a/turbopack/crates/turbopack-core/src/chunk/optimize.rs b/turbopack/crates/turbopack-core/src/chunk/optimize.rs new file mode 100644 index 0000000000000..d216b25174bb0 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/chunk/optimize.rs @@ -0,0 +1,75 @@ +//! Traits and functions to optimize a list of chunks. +//! +//! Usually chunks are optimized by limiting their total count, restricting +//! their size and eliminating duplicates between them. + +use anyhow::Result; +use turbo_tasks::{TryJoinIterExt, Vc}; +use turbo_tasks_fs::{FileSystemPath, FileSystemPathOption}; + +use crate::chunk::containment_tree::{ContainmentTree, ContainmentTreeKey}; + +#[derive(Debug, Clone, Eq, PartialEq, Hash)] +struct FileSystemPathKey(Vc); + +impl FileSystemPathKey { + async fn new(path: Vc) -> Result { + Ok(Self(path.resolve().await?)) + } +} + +#[async_trait::async_trait] +impl ContainmentTreeKey for FileSystemPathKey { + async fn parent(&self) -> Result { + Ok(FileSystemPathKey::new(self.0.parent()).await?) + } +} + +pub async fn optimize_by_common_parent( + chunks: &[T], + get_common_parent: GetCommonParent, + optimize: Optimize, +) -> Result +where + T: Clone, + GetCommonParent: Fn(T) -> Vc + Clone, + Optimize: Fn(Option>, Vec) -> Acc, +{ + let tree = ContainmentTree::build( + chunks + .iter() + .map(move |chunk| { + let get_common_parent = get_common_parent.clone(); + async move { + let common_parent = get_common_parent(chunk.clone()).await?; + + Ok(( + if let Some(common_parent) = &*common_parent { + Some(FileSystemPathKey::new(*common_parent).await?) + } else { + None + }, + chunk.clone(), + )) + } + }) + .try_join() + .await?, + ) + .await?; + + fn optimize_tree( + tree: ContainmentTree, + optimize: &impl Fn(Option>, Vec) -> Acc, + ) -> Acc { + let children = tree + .children + .into_iter() + .map(|tree| optimize_tree(tree, optimize)) + .collect::>(); + + optimize(tree.values, children) + } + + Ok(optimize_tree(tree, &optimize)) +} diff --git a/turbopack/crates/turbopack-core/src/code_builder.rs b/turbopack/crates/turbopack-core/src/code_builder.rs new file mode 100644 index 0000000000000..8c39858a74b1c --- /dev/null +++ b/turbopack/crates/turbopack-core/src/code_builder.rs @@ -0,0 +1,199 @@ +use std::{ + cmp::min, + io::{BufRead, Result as IoResult, Write}, + ops, +}; + +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_fs::rope::{Rope, RopeBuilder}; +use turbo_tasks_hash::hash_xxh3_hash64; + +use crate::{ + source_map::{GenerateSourceMap, OptionSourceMap, SourceMap, SourceMapSection}, + source_pos::SourcePos, +}; + +/// A mapping of byte-offset in the code string to an associated source map. +pub type Mapping = (usize, Option>>); + +/// Code stores combined output code and the source map of that output code. +#[turbo_tasks::value(shared)] +#[derive(Debug, Clone)] +pub struct Code { + code: Rope, + + mappings: Vec, +} + +/// CodeBuilder provides a mutable container to append source code. +#[derive(Default)] +pub struct CodeBuilder { + code: RopeBuilder, + + mappings: Vec, +} + +impl Code { + pub fn source_code(&self) -> &Rope { + &self.code + } + + /// Tests if any code in this Code contains an associated source map. + pub fn has_source_map(&self) -> bool { + !self.mappings.is_empty() + } +} + +impl CodeBuilder { + /// Pushes synthetic runtime code without an associated source map. This is + /// the default concatenation operation, but it's designed to be used + /// with the `+=` operator. + fn push_static_bytes(&mut self, code: &'static [u8]) { + self.push_map(None); + self.code.push_static_bytes(code); + } + + /// Pushes original user code with an optional source map if one is + /// available. If it's not, this is no different than pushing Synthetic + /// code. + pub fn push_source(&mut self, code: &Rope, map: Option>>) { + self.push_map(map); + self.code += code; + } + + /// Copies the Synthetic/Original code of an already constructed Code into + /// this instance. + pub fn push_code(&mut self, prebuilt: &Code) { + if let Some((index, _)) = prebuilt.mappings.first() { + if *index > 0 { + // If the index is positive, then the code starts with a synthetic section. We + // may need to push an empty map in order to end the current + // section's mappings. + self.push_map(None); + } + + let len = self.code.len(); + self.mappings.extend( + prebuilt + .mappings + .iter() + .map(|(index, map)| (index + len, *map)), + ); + } else { + self.push_map(None); + } + + self.code += &prebuilt.code; + } + + /// Setting breakpoints on synthetic code can cause weird behaviors + /// because Chrome will treat the location as belonging to the previous + /// original code section. By inserting an empty source map when reaching a + /// synthetic section directly after an original section, we tell Chrome + /// that the previous map ended at this point. + fn push_map(&mut self, map: Option>>) { + if map.is_none() && matches!(self.mappings.last(), None | Some((_, None))) { + // No reason to push an empty map directly after an empty map + return; + } + + debug_assert!( + map.is_some() || !self.mappings.is_empty(), + "the first mapping is never a None" + ); + self.mappings.push((self.code.len(), map)); + } + + /// Tests if any code in this CodeBuilder contains an associated source map. + pub fn has_source_map(&self) -> bool { + !self.mappings.is_empty() + } + + pub fn build(self) -> Code { + Code { + code: self.code.build(), + mappings: self.mappings, + } + } +} + +impl ops::AddAssign<&'static str> for CodeBuilder { + fn add_assign(&mut self, rhs: &'static str) { + self.push_static_bytes(rhs.as_bytes()); + } +} + +impl ops::AddAssign<&'static str> for &mut CodeBuilder { + fn add_assign(&mut self, rhs: &'static str) { + self.push_static_bytes(rhs.as_bytes()); + } +} + +impl Write for CodeBuilder { + fn write(&mut self, bytes: &[u8]) -> IoResult { + self.push_map(None); + self.code.write(bytes) + } + + fn flush(&mut self) -> IoResult<()> { + self.code.flush() + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for Code { + /// Generates the source map out of all the pushed Original code. + /// The SourceMap v3 spec has a "sectioned" source map specifically designed + /// for concatenation in post-processing steps. This format consists of + /// a `sections` array, with section item containing a `offset` object + /// and a `map` object. The section's map applies only after the + /// starting offset, and until the start of the next section. This is by + /// far the simplest way to concatenate the source maps of the multiple + /// chunk items into a single map file. + #[turbo_tasks::function] + pub async fn generate_source_map(&self) -> Result> { + let mut pos = SourcePos::new(); + let mut last_byte_pos = 0; + + let mut sections = Vec::with_capacity(self.mappings.len()); + let mut read = self.code.read(); + for (byte_pos, map) in &self.mappings { + let mut want = byte_pos - last_byte_pos; + while want > 0 { + let buf = read.fill_buf()?; + debug_assert!(!buf.is_empty()); + + let end = min(want, buf.len()); + pos.update(&buf[0..end]); + + read.consume(end); + want -= end; + } + last_byte_pos = *byte_pos; + + let encoded = match map { + None => SourceMap::empty(), + Some(map) => match *map.generate_source_map().await? { + None => SourceMap::empty(), + Some(map) => map, + }, + }; + + sections.push(SourceMapSection::new(pos, encoded)) + } + + Ok(Vc::cell(Some(SourceMap::new_sectioned(sections).cell()))) + } +} + +#[turbo_tasks::value_impl] +impl Code { + /// Returns the hash of the source code of this Code. + #[turbo_tasks::function] + pub async fn source_code_hash(self: Vc) -> Result> { + let code = self.await?; + let hash = hash_xxh3_hash64(code.source_code()); + Ok(Vc::cell(hash)) + } +} diff --git a/turbopack/crates/turbopack-core/src/compile_time_info.rs b/turbopack/crates/turbopack-core/src/compile_time_info.rs new file mode 100644 index 0000000000000..fc4ef30178bc2 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/compile_time_info.rs @@ -0,0 +1,250 @@ +use anyhow::Result; +use indexmap::IndexMap; +use turbo_tasks::{RcStr, Vc}; +use turbo_tasks_fs::FileSystemPath; + +use crate::environment::Environment; + +// TODO stringify split map collect could be optimized with a marco +#[macro_export] +macro_rules! definable_name_map_internal { + ($map:ident, .. $value:expr) => { + for (key, value) in $value { + $map.insert( + key.into(), + value.into() + ); + } + }; + ($map:ident, $($name:ident).+ = $value:expr) => { + $map.insert( + $crate::definable_name_map_internal!($($name).+).into(), + $value.into() + ); + }; + ($map:ident, $($name:ident).+ = $value:expr,) => { + $map.insert( + $crate::definable_name_map_internal!($($name).+).into(), + $value.into() + ); + }; + ($map:ident, $($name:ident).+ = $value:expr, $($more:tt)+) => { + $crate::definable_name_map_internal!($map, $($name).+ = $value); + $crate::definable_name_map_internal!($map, $($more)+); + }; + ($map:ident, .. $value:expr, $($more:tt)+) => { + $crate::definable_name_map_internal!($map, .. $value); + $crate::definable_name_map_internal!($map, $($more)+); + }; + ($name:ident) => { + [stringify!($name).into()] + }; + ($name:ident . $($more:ident).+) => { + $crate::definable_name_map_internal!($($more).+, [stringify!($name).into()]) + }; + ($name:ident, [$($array:expr),+]) => { + [$($array),+, stringify!($name).into()] + }; + ($name:ident . $($more:ident).+, [$($array:expr),+]) => { + $crate::definable_name_map_internal!($($more).+, [$($array),+, stringify!($name).into()]) + }; +} + +#[macro_export] +macro_rules! compile_time_defines { + ($($more:tt)+) => { + { + let mut map = $crate::__private::IndexMap::new(); + $crate::definable_name_map_internal!(map, $($more)+); + $crate::compile_time_info::CompileTimeDefines(map) + } + }; +} + +#[macro_export] +macro_rules! free_var_references { + ($($more:tt)+) => { + { + let mut map = $crate::__private::IndexMap::new(); + $crate::definable_name_map_internal!(map, $($more)+); + $crate::compile_time_info::FreeVarReferences(map) + } + }; +} + +// TODO: replace with just a `serde_json::Value` +// https://linear.app/vercel/issue/WEB-1641/compiletimedefinevalue-should-just-use-serde-jsonvalue +#[turbo_tasks::value(serialization = "auto_for_input")] +#[derive(Debug, Clone, Hash)] +pub enum CompileTimeDefineValue { + Bool(bool), + String(RcStr), + JSON(RcStr), +} + +impl From for CompileTimeDefineValue { + fn from(value: bool) -> Self { + Self::Bool(value) + } +} + +impl From for CompileTimeDefineValue { + fn from(value: RcStr) -> Self { + Self::String(value) + } +} + +impl From for CompileTimeDefineValue { + fn from(value: String) -> Self { + Self::String(value.into()) + } +} + +impl From<&str> for CompileTimeDefineValue { + fn from(value: &str) -> Self { + Self::String(value.into()) + } +} + +impl From for CompileTimeDefineValue { + fn from(value: serde_json::Value) -> Self { + Self::JSON(value.to_string().into()) + } +} + +#[turbo_tasks::value(transparent)] +#[derive(Debug, Clone)] +pub struct CompileTimeDefines(pub IndexMap, CompileTimeDefineValue>); + +impl IntoIterator for CompileTimeDefines { + type Item = (Vec, CompileTimeDefineValue); + type IntoIter = indexmap::map::IntoIter, CompileTimeDefineValue>; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + +#[turbo_tasks::value_impl] +impl CompileTimeDefines { + #[turbo_tasks::function] + pub fn empty() -> Vc { + Vc::cell(IndexMap::new()) + } +} + +#[turbo_tasks::value] +#[derive(Debug, Clone)] +pub enum FreeVarReference { + EcmaScriptModule { + request: RcStr, + lookup_path: Option>, + export: Option, + }, + Value(CompileTimeDefineValue), + Error(RcStr), +} + +impl From for FreeVarReference { + fn from(value: bool) -> Self { + Self::Value(value.into()) + } +} + +impl From for FreeVarReference { + fn from(value: String) -> Self { + Self::Value(value.into()) + } +} + +impl From<&str> for FreeVarReference { + fn from(value: &str) -> Self { + Self::Value(value.into()) + } +} + +impl From for FreeVarReference { + fn from(value: CompileTimeDefineValue) -> Self { + Self::Value(value) + } +} + +#[turbo_tasks::value(transparent)] +#[derive(Debug, Clone)] +pub struct FreeVarReferences(pub IndexMap, FreeVarReference>); + +#[turbo_tasks::value_impl] +impl FreeVarReferences { + #[turbo_tasks::function] + pub fn empty() -> Vc { + Vc::cell(IndexMap::new()) + } +} + +#[turbo_tasks::value(shared)] +#[derive(Debug, Clone)] +pub struct CompileTimeInfo { + pub environment: Vc, + pub defines: Vc, + pub free_var_references: Vc, +} + +impl CompileTimeInfo { + pub fn builder(environment: Vc) -> CompileTimeInfoBuilder { + CompileTimeInfoBuilder { + environment, + defines: None, + free_var_references: None, + } + } +} + +#[turbo_tasks::value_impl] +impl CompileTimeInfo { + #[turbo_tasks::function] + pub fn new(environment: Vc) -> Vc { + CompileTimeInfo { + environment, + defines: CompileTimeDefines::empty(), + free_var_references: FreeVarReferences::empty(), + } + .cell() + } + + #[turbo_tasks::function] + pub async fn environment(self: Vc) -> Result> { + Ok(self.await?.environment) + } +} + +pub struct CompileTimeInfoBuilder { + environment: Vc, + defines: Option>, + free_var_references: Option>, +} + +impl CompileTimeInfoBuilder { + pub fn defines(mut self, defines: Vc) -> Self { + self.defines = Some(defines); + self + } + + pub fn free_var_references(mut self, free_var_references: Vc) -> Self { + self.free_var_references = Some(free_var_references); + self + } + + pub fn build(self) -> CompileTimeInfo { + CompileTimeInfo { + environment: self.environment, + defines: self.defines.unwrap_or_else(CompileTimeDefines::empty), + free_var_references: self + .free_var_references + .unwrap_or_else(FreeVarReferences::empty), + } + } + + pub fn cell(self) -> Vc { + self.build().cell() + } +} diff --git a/turbopack/crates/turbopack-core/src/condition.rs b/turbopack/crates/turbopack-core/src/condition.rs new file mode 100644 index 0000000000000..b3435050da4fe --- /dev/null +++ b/turbopack/crates/turbopack-core/src/condition.rs @@ -0,0 +1,66 @@ +use anyhow::Result; +use async_recursion::async_recursion; +use futures::{stream, StreamExt}; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, Vc}; +use turbo_tasks_fs::FileSystemPath; + +#[derive(Debug, Clone, Serialize, Deserialize, TraceRawVcs, PartialEq, Eq)] +pub enum ContextCondition { + All(Vec), + Any(Vec), + Not(Box), + InDirectory(String), + InPath(Vc), +} + +impl ContextCondition { + /// Creates a condition that matches if all of the given conditions match. + pub fn all(conditions: Vec) -> ContextCondition { + ContextCondition::All(conditions) + } + + /// Creates a condition that matches if any of the given conditions match. + pub fn any(conditions: Vec) -> ContextCondition { + ContextCondition::Any(conditions) + } + + /// Creates a condition that matches if the given condition does not match. + #[allow(clippy::should_implement_trait)] + pub fn not(condition: ContextCondition) -> ContextCondition { + ContextCondition::Not(Box::new(condition)) + } + + #[async_recursion] + /// Returns true if the condition matches the context. + pub async fn matches(&self, path: &FileSystemPath) -> Result { + match self { + ContextCondition::All(conditions) => { + // False positive. + #[allow(clippy::manual_try_fold)] + stream::iter(conditions) + .fold(Ok(true), |acc, c| async move { + Ok(acc? && c.matches(path).await?) + }) + .await + } + ContextCondition::Any(conditions) => { + // False positive. + #[allow(clippy::manual_try_fold)] + stream::iter(conditions) + .fold(Ok(false), |acc, c| async move { + Ok(acc? || c.matches(path).await?) + }) + .await + } + ContextCondition::Not(condition) => condition.matches(path).await.map(|b| !b), + ContextCondition::InPath(other_path) => { + Ok(path.is_inside_or_equal_ref(&*other_path.await?)) + } + ContextCondition::InDirectory(dir) => Ok(path.path.starts_with(&format!("{dir}/")) + || path.path.contains(&format!("/{dir}/")) + || path.path.ends_with(&format!("/{dir}")) + || path.path == *dir), + } + } +} diff --git a/turbopack/crates/turbopack-core/src/context.rs b/turbopack/crates/turbopack-core/src/context.rs new file mode 100644 index 0000000000000..30f7052fa0606 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/context.rs @@ -0,0 +1,81 @@ +use anyhow::{bail, Result}; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_fs::{glob::Glob, FileSystemPath}; + +use crate::{ + compile_time_info::CompileTimeInfo, + module::Module, + reference_type::ReferenceType, + resolve::{options::ResolveOptions, parse::Request, ModuleResolveResult, ResolveResult}, + source::Source, +}; + +#[turbo_tasks::value(shared)] +pub enum ProcessResult { + /// A module was created. + Module(Vc>), + + /// Reference is ignored. This should lead to no module being included by + /// the reference. + Ignore, +} + +#[turbo_tasks::value_impl] +impl ProcessResult { + #[turbo_tasks::function] + pub async fn module(&self) -> Result>> { + match *self { + ProcessResult::Module(m) => Ok(m), + ProcessResult::Ignore => { + bail!("Expected process result to be a module, but it was ignored") + } + } + } +} + +/// A context for building an asset graph. It's passed through the assets while +/// creating them. It's needed to resolve assets and upgrade assets to a higher +/// type (e. g. from FileSource to ModuleAsset). +#[turbo_tasks::value_trait] +pub trait AssetContext { + /// Gets the compile time info of the asset context. + fn compile_time_info(self: Vc) -> Vc; + + /// Gets the layer of the asset context. + fn layer(self: Vc) -> Vc; + + /// Gets the resolve options for a given path. + fn resolve_options( + self: Vc, + origin_path: Vc, + reference_type: Value, + ) -> Vc; + + /// Resolves an request to an [ModuleResolveResult]. + fn resolve_asset( + self: Vc, + origin_path: Vc, + request: Vc, + resolve_options: Vc, + reference_type: Value, + ) -> Vc; + + /// Process a source into a module. + fn process( + self: Vc, + asset: Vc>, + reference_type: Value, + ) -> Vc; + + /// Process an [ResolveResult] into an [ModuleResolveResult]. + fn process_resolve_result( + self: Vc, + result: Vc, + reference_type: Value, + ) -> Vc; + + /// Gets a new AssetContext with the transition applied. + fn with_transition(self: Vc, transition: RcStr) -> Vc>; + + fn side_effect_free_packages(self: Vc) -> Vc; +} diff --git a/turbopack/crates/turbopack-core/src/diagnostics/mod.rs b/turbopack/crates/turbopack-core/src/diagnostics/mod.rs new file mode 100644 index 0000000000000..171d6e260a508 --- /dev/null +++ b/turbopack/crates/turbopack-core/src/diagnostics/mod.rs @@ -0,0 +1,115 @@ +use std::cmp::Ordering; + +use anyhow::Result; +use async_trait::async_trait; +use indexmap::IndexMap; +use turbo_tasks::{emit, CollectiblesSource, RcStr, Upcast, Vc}; + +#[turbo_tasks::value(serialization = "none")] +#[derive(Clone, Debug)] +pub struct PlainDiagnostic { + pub category: RcStr, + pub name: RcStr, + pub payload: IndexMap, +} + +impl Ord for PlainDiagnostic { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.name + .cmp(&other.name) + .then_with(|| self.category.cmp(&other.category)) + .then_with(|| self.payload.len().cmp(&other.payload.len())) + .then_with(|| { + for ((a_key, a_value), (b_key, b_value)) in + self.payload.iter().zip(other.payload.iter()) + { + match a_key.cmp(b_key) { + Ordering::Equal => {} + other => return other, + } + match a_value.cmp(b_value) { + Ordering::Equal => {} + other => return other, + } + } + Ordering::Equal + }) + } +} + +impl PartialOrd for PlainDiagnostic { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +#[turbo_tasks::value(transparent)] +pub struct DiagnosticPayload(pub IndexMap); + +/// An arbitrary payload can be used to analyze, diagnose +/// Turbopack's behavior. +#[turbo_tasks::value_trait] +pub trait Diagnostic { + /// [NOTE]: Psuedo-reserved; this is not being used currently. + /// The `type` of the diagnostics that can be used selectively filtered by + /// consumers. For example, this could be `telemetry`, or + /// `slow_perf_event`, or something else. This is not strongly typed + /// though; since consumer or implementation may need to define own + /// category. + fn category(&self) -> Vc; + /// Name of the specific diagnostic event. + fn name(&self) -> Vc; + /// Arbitarary payload included in the diagnostic event. + fn payload(&self) -> Vc; + + async fn into_plain(self: Vc) -> Result> { + Ok(PlainDiagnostic { + category: self.category().await?.clone_value(), + name: self.name().await?.clone_value(), + payload: self.payload().await?.clone_value(), + } + .cell()) + } +} + +pub trait DiagnosticExt { + fn emit(self); +} + +impl DiagnosticExt for Vc +where + T: Upcast>, +{ + fn emit(self) { + let diagnostic = Vc::upcast::>(self); + emit(diagnostic); + } +} + +#[async_trait] +pub trait DiagnosticContextExt +where + Self: Sized, +{ + async fn peek_diagnostics(self) -> Result; +} + +#[async_trait] +impl DiagnosticContextExt for T +where + T: CollectiblesSource + Copy + Send, +{ + async fn peek_diagnostics(self) -> Result { + Ok(CapturedDiagnostics { + diagnostics: self.peek_collectibles(), + }) + } +} + +/// A list of diagnostics captured with +/// [`DiagnosticsVc::peek_diagnostics_with_path`] and +#[derive(Debug)] +#[turbo_tasks::value] +pub struct CapturedDiagnostics { + pub diagnostics: auto_hash_map::AutoSet>>, +} diff --git a/turbopack/crates/turbopack-core/src/environment.rs b/turbopack/crates/turbopack-core/src/environment.rs new file mode 100644 index 0000000000000..89f40160dab6f --- /dev/null +++ b/turbopack/crates/turbopack-core/src/environment.rs @@ -0,0 +1,324 @@ +use std::{ + process::{Command, Stdio}, + str::FromStr, +}; + +use anyhow::{anyhow, Context, Result}; +use swc_core::ecma::preset_env::{Version, Versions}; +use turbo_tasks::{RcStr, Value, Vc}; +use turbo_tasks_env::ProcessEnv; + +use crate::target::CompileTarget; + +static DEFAULT_NODEJS_VERSION: &str = "16.0.0"; + +#[turbo_tasks::value] +#[derive(Default)] +pub enum Rendering { + #[default] + None, + Client, + Server, +} + +impl Rendering { + pub fn is_none(&self) -> bool { + matches!(self, Rendering::None) + } +} + +#[turbo_tasks::value] +pub enum ChunkLoading { + Edge, + /// CommonJS in Node.js + NodeJs, + /// + +`; + +async function createServer() { + const app = express(); + const vite = await createViteServer({ + server: { middlewareMode: true }, + appType: "custom", + }); + app.use(vite.middlewares); + app.use("*", async (req, res, next) => { + const url = req.originalUrl; + try { + const template = await vite.transformIndexHtml(url, TEMPLATE); + const { render } = await vite.ssrLoadModule("/src/vite-entry-server.jsx"); + const appHtml = await render(url); + const html = template.replace(``, appHtml); + res.status(200).set({ "Content-Type": "text/html" }).end(html); + } catch (e) { + vite.ssrFixStacktrace(e); + next(e); + } + }); + + const listener = app.listen(0, () => { + console.log(`Local: http://localhost:${listener.address().port}`); + }); +} + +createServer(); diff --git a/turbopack/crates/turbopack-create-test-app/src/test_app_builder.rs b/turbopack/crates/turbopack-create-test-app/src/test_app_builder.rs new file mode 100644 index 0000000000000..3d120d01cbb53 --- /dev/null +++ b/turbopack/crates/turbopack-create-test-app/src/test_app_builder.rs @@ -0,0 +1,579 @@ +use std::{ + collections::VecDeque, + fs::{create_dir_all, File}, + io::prelude::*, + path::{Path, PathBuf}, + str::FromStr, +}; + +use anyhow::{anyhow, Context, Result}; +use indoc::{formatdoc, indoc}; +use serde_json::json; +use tempfile::TempDir; + +fn decide(remaining: usize, min_remaining_decisions: usize) -> bool { + if remaining == 0 { + false + } else if min_remaining_decisions <= remaining { + true + } else { + let urgentness = min_remaining_decisions / remaining; + (min_remaining_decisions * 11 * 7 * 5) % urgentness == 0 + } +} + +fn decide_early(remaining: usize, min_remaining_decisions: usize) -> bool { + if remaining == 0 { + false + } else if min_remaining_decisions <= remaining { + true + } else { + let urgentness = min_remaining_decisions / remaining / remaining; + (min_remaining_decisions * 11 * 7 * 5) % urgentness == 0 + } +} + +fn write_file>(name: &str, path: P, content: &[u8]) -> Result<()> { + File::create(path) + .with_context(|| format!("creating {name}"))? + .write_all(content) + .with_context(|| format!("writing {name}")) +} + +/// How to run effects in components. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub enum EffectMode { + /// No effects at all. + #[default] + None, + /// As a direct `useEffect` hook in the component's body. + Hook, + /// Rendering an client-side component that has the `useEffect` + /// hook instead. Good for testing React Server Components, as they can't + /// use `useEffect` hooks directly. + Component, +} + +impl FromStr for EffectMode { + type Err = anyhow::Error; + + fn from_str(s: &str) -> Result { + match s { + "none" => Ok(EffectMode::None), + "hook" => Ok(EffectMode::Hook), + "component" => Ok(EffectMode::Component), + _ => Err(anyhow!("unknown effect mode: {}", s)), + } + } +} + +#[derive(Debug)] +pub struct TestAppBuilder { + pub target: Option, + pub module_count: usize, + pub directories_count: usize, + pub dynamic_import_count: usize, + pub flatness: usize, + pub package_json: Option, + pub effect_mode: EffectMode, + pub leaf_client_components: bool, +} + +impl Default for TestAppBuilder { + fn default() -> Self { + Self { + target: None, + module_count: 1000, + directories_count: 50, + dynamic_import_count: 0, + flatness: 5, + package_json: Some(Default::default()), + effect_mode: EffectMode::Hook, + leaf_client_components: false, + } + } +} + +const SETUP_IMPORTS: &str = indoc! {r#" +import React from "react"; +"#}; +const SETUP_EFFECT_PROPS: &str = indoc! {r#" +let EFFECT_PROPS = {}; +"#}; +const SETUP_EVAL: &str = indoc! {r#" +/* @turbopack-bench:eval-start */ +/* @turbopack-bench:eval-end */ +"#}; +const USE_EFFECT: &str = indoc! {r#" +React.useEffect(() => { + if (EFFECT_PROPS.hydration) { + globalThis.__turbopackBenchBinding && globalThis.__turbopackBenchBinding("Hydration done"); + } + if (EFFECT_PROPS.message) { + globalThis.__turbopackBenchBinding && globalThis.__turbopackBenchBinding(EFFECT_PROPS.message); + } +}, [EFFECT_PROPS]); +"#}; +const EFFECT_ELEMENT: &str = indoc! {r#" + +"#}; + +impl TestAppBuilder { + pub fn build(&self) -> Result { + let target = if let Some(target) = self.target.clone() { + TestAppTarget::Set(target) + } else { + TestAppTarget::Temp(tempfile::tempdir().context("creating tempdir")?) + }; + let path = target.path(); + let mut modules = vec![]; + let src = path.join("src"); + create_dir_all(&src).context("creating src dir")?; + + let mut remaining_modules = self.module_count - 1; + let mut remaining_directories = self.directories_count; + let mut remaining_dynamic_imports = self.dynamic_import_count; + + let mut queue = VecDeque::with_capacity(32); + queue.push_back((src.join("triangle.jsx"), 0)); + remaining_modules -= 1; + let mut is_root = true; + + let (additional_body, additional_elements) = match self.effect_mode { + EffectMode::None => ("", ""), + EffectMode::Component => ("", EFFECT_ELEMENT), + EffectMode::Hook => (USE_EFFECT, ""), + }; + + while let Some((file, depth)) = queue.pop_front() { + modules.push((file.clone(), depth)); + + let setup_imports = match self.effect_mode { + EffectMode::Hook | EffectMode::None => SETUP_IMPORTS.to_string(), + EffectMode::Component => { + let relative_effect = if src == file.parent().unwrap() { + "./effect.jsx".to_string() + } else { + pathdiff::diff_paths(src.join("effect.jsx"), file.parent().unwrap()) + .unwrap() + .display() + .to_string() + }; + + #[cfg(windows)] + let relative_effect = relative_effect.replace('\\', "/"); + + formatdoc! {r#" + {SETUP_IMPORTS} + import Effect from "{relative_effect}"; + "#} + } + }; + + let leaf = remaining_modules == 0 + || (!queue.is_empty() + && (queue.len() + remaining_modules) % (self.flatness + 1) == 0); + if leaf { + let maybe_use_client = if self.leaf_client_components { + r#""use client";"# + } else { + "" + }; + write_file( + &format!("leaf file {}", file.display()), + &file, + formatdoc! {r#" + {maybe_use_client} + + {setup_imports} + + {SETUP_EFFECT_PROPS} + {SETUP_EVAL} + + function Triangle({{ style }}) {{ + {additional_body} + return <> + + {additional_elements} + ; + }} + + export default React.memo(Triangle); + "#} + .as_bytes(), + )?; + } else { + let in_subdirectory = decide(remaining_directories, remaining_modules / 3); + + let import_path; + let base_file = file.with_extension(""); + let base_file = if in_subdirectory { + remaining_directories -= 1; + create_dir_all(&base_file).context("creating subdirectory")?; + import_path = format!( + "./{}/triangle_", + base_file.file_name().unwrap().to_str().unwrap() + ); + base_file.join("triangle") + } else { + import_path = + format!("./{}_", base_file.file_name().unwrap().to_str().unwrap()); + base_file + }; + + for i in 1..=3 { + let mut f = base_file.clone(); + f.set_file_name(format!( + "{}_{}.jsx", + f.file_name().unwrap().to_str().unwrap(), + i + )); + queue.push_back((f, depth + 1)); + } + remaining_modules = remaining_modules.saturating_sub(3); + + if let [(a, a_), (b, b_), (c, c_)] = &*[("A", "1"), ("B", "2"), ("C", "3")] + .into_iter() + .enumerate() + .map(|(i, (name, n))| { + if decide_early(remaining_dynamic_imports, remaining_modules + (2 - i)) { + remaining_dynamic_imports -= 1; + ( + format!( + "const {name}Lazy = React.lazy(() => \ + import('{import_path}{n}'));" + ), + format!( + "<{name}Lazy style={{style}} \ + />" + ), + ) + } else { + ( + format!("import {name} from '{import_path}{n}'"), + format!("<{name} style={{style}} />"), + ) + } + }) + .collect::>() + { + let setup_hydration = if is_root { + is_root = false; + "\nEFFECT_PROPS.hydration = true;" + } else { + "" + }; + write_file( + &format!("file with children {}", file.display()), + &file, + formatdoc! {r#" + {setup_imports} + {a} + {b} + {c} + + {SETUP_EFFECT_PROPS}{setup_hydration} + {SETUP_EVAL} + + function Container({{ style }}) {{ + {additional_body} + return <> + + {a_} + + + {b_} + + + {c_} + + {additional_elements} + ; + }} + + export default React.memo(Container); + "#} + .as_bytes(), + )?; + } else { + unreachable!() + } + } + } + + let bootstrap = indoc! {r#" + import React from "react"; + import { createRoot } from "react-dom/client"; + import Triangle from "./triangle.jsx"; + + function App() { + return + + + } + + document.body.style.backgroundColor = "black"; + let root = document.createElement("main"); + document.body.appendChild(root); + createRoot(root).render(); + "#}; + write_file( + "bootstrap file", + src.join("index.jsx"), + bootstrap.as_bytes(), + )?; + + let pages = src.join("pages"); + create_dir_all(&pages)?; + + // The page is e. g. used by Next.js + let bootstrap_page = indoc! {r#" + import React from "react"; + import Triangle from "../triangle.jsx"; + + export default function Page() { + return + + + } + "#}; + write_file( + "bootstrap page", + pages.join("page.jsx"), + bootstrap_page.as_bytes(), + )?; + + // The page is e. g. used by Next.js + let bootstrap_static_page = indoc! {r#" + import React from "react"; + import Triangle from "../triangle.jsx"; + + export default function Page() { + return + + + } + + export function getStaticProps() { + return { + props: {} + }; + } + "#}; + write_file( + "bootstrap static page", + pages.join("static.jsx"), + bootstrap_static_page.as_bytes(), + )?; + + let app_dir = src.join("app"); + create_dir_all(app_dir.join("app"))?; + create_dir_all(app_dir.join("client"))?; + + // The page is e. g. used by Next.js + let bootstrap_app_page = indoc! {r#" + import React from "react"; + import Triangle from "../../triangle.jsx"; + + export default function Page() { + return + + + } + "#}; + write_file( + "bootstrap app page", + app_dir.join("app/page.jsx"), + bootstrap_app_page.as_bytes(), + )?; + + if matches!(self.effect_mode, EffectMode::Component) { + // The component is used to measure hydration and commit time for app/page.jsx + let effect_component = formatdoc! {r#" + "use client"; + + import React from "react"; + + export default function Effect(EFFECT_PROPS) {{ + {USE_EFFECT} + return null; + }} + "#}; + write_file( + "effect component", + src.join("effect.jsx"), + effect_component.as_bytes(), + )?; + } + + // The page is e. g. used by Next.js + let bootstrap_app_client_page = indoc! {r#" + "use client"; + import React from "react"; + import Triangle from "../../triangle.jsx"; + + export default function Page() { + return + + + } + "#}; + write_file( + "bootstrap app client page", + app_dir.join("client/page.jsx"), + bootstrap_app_client_page.as_bytes(), + )?; + + // This root layout is e. g. used by Next.js + let bootstrap_layout = indoc! {r#" + export default function RootLayout({ children }) { + return ( + + + + + Turbopack Test App + + + {children} + + + ); + } + "#}; + write_file( + "bootstrap layout", + app_dir.join("layout.jsx"), + bootstrap_layout.as_bytes(), + )?; + + // This HTML is used e. g. by Vite + let bootstrap_html = indoc! {r#" + + + + + + Turbopack Test App + + + + + + "#}; + write_file( + "bootstrap html in root", + path.join("index.html"), + bootstrap_html.as_bytes(), + )?; + + // This HTML is used e. g. by webpack + let bootstrap_html2 = indoc! {r#" + + + + + + Turbopack Test App + + + + + + "#}; + + let public = path.join("public"); + create_dir_all(&public).context("creating public dir")?; + + write_file( + "bootstrap html", + public.join("index.html"), + bootstrap_html2.as_bytes(), + )?; + + write_file( + "vite node.js server", + path.join("vite-server.mjs"), + include_bytes!("templates/vite-server.mjs"), + )?; + write_file( + "vite server entry", + path.join("src/vite-entry-server.jsx"), + include_bytes!("templates/vite-entry-server.jsx"), + )?; + write_file( + "vite client entry", + path.join("src/vite-entry-client.jsx"), + include_bytes!("templates/vite-entry-client.jsx"), + )?; + + if let Some(package_json) = &self.package_json { + // These dependencies are needed + let package_json = json!({ + "name": "turbopack-test-app", + "private": true, + "version": "0.0.0", + "dependencies": { + "react": package_json.react_version.clone(), + "react-dom": package_json.react_version.clone(), + } + }); + write_file( + "package.json", + path.join("package.json"), + format!("{:#}", package_json).as_bytes(), + )?; + } + + Ok(TestApp { target, modules }) + } +} + +/// Configuration struct to generate the `package.json` file of the test app. +#[derive(Debug)] +pub struct PackageJsonConfig { + /// The version of React to use. + pub react_version: String, +} + +impl Default for PackageJsonConfig { + fn default() -> Self { + Self { + react_version: "^18.2.0".to_string(), + } + } +} + +#[derive(Debug)] +enum TestAppTarget { + Set(PathBuf), + Temp(TempDir), +} + +impl TestAppTarget { + /// Returns the path to the directory containing the app. + fn path(&self) -> &Path { + match &self { + TestAppTarget::Set(target) => target.as_path(), + TestAppTarget::Temp(target) => target.path(), + } + } +} + +#[derive(Debug)] +pub struct TestApp { + target: TestAppTarget, + modules: Vec<(PathBuf, usize)>, +} + +impl TestApp { + /// Returns the path to the directory containing the app. + pub fn path(&self) -> &Path { + self.target.path() + } + + /// Returns the list of modules and their depth in this app. + pub fn modules(&self) -> &[(PathBuf, usize)] { + &self.modules + } +} diff --git a/turbopack/crates/turbopack-css/Cargo.toml b/turbopack/crates/turbopack-css/Cargo.toml new file mode 100644 index 0000000000000..c9d329168b392 --- /dev/null +++ b/turbopack/crates/turbopack-css/Cargo.toml @@ -0,0 +1,49 @@ +[package] +name = "turbopack-css" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +indexmap = { workspace = true } +indoc = { workspace = true } +lightningcss = { workspace = true } +once_cell = { workspace = true } +parcel_selectors = { workspace = true } +regex = { workspace = true } +serde = { workspace = true } +urlencoding = { workspace = true } + +tracing = { workspace = true } +turbo-tasks = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-hash = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } +turbopack-swc-utils = { workspace = true } + +parcel_sourcemap = "2.1.1" +smallvec = { workspace = true } +swc_core = { workspace = true, features = [ + "css_ast", + "css_codegen", + "css_compat", + "css_modules", + "css_parser", + "css_visit", + "ecma_ast", + "common", + "common_concurrent", +] } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-css/build.rs b/turbopack/crates/turbopack-css/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-css/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-css/src/asset.rs b/turbopack/crates/turbopack-css/src/asset.rs new file mode 100644 index 0000000000000..6ad1ef026f42c --- /dev/null +++ b/turbopack/crates/turbopack-css/src/asset.rs @@ -0,0 +1,318 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, TryJoinIterExt, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkItem, ChunkType, ChunkableModule, ChunkingContext}, + context::AssetContext, + ident::AssetIdent, + module::Module, + reference::{ModuleReference, ModuleReferences}, + reference_type::ImportContext, + resolve::origin::ResolveOrigin, + source::Source, +}; + +use crate::{ + chunk::{CssChunkItem, CssChunkItemContent, CssChunkPlaceable, CssChunkType, CssImport}, + code_gen::CodeGenerateable, + process::{ + finalize_css, parse_css, process_css_with_placeholder, CssWithPlaceholderResult, + FinalCssResult, ParseCss, ParseCssResult, ProcessCss, + }, + references::{compose::CssModuleComposeReference, import::ImportAssetReference}, + CssModuleAssetType, +}; + +#[turbo_tasks::function] +fn modifier(use_swc_css: bool) -> Vc { + if use_swc_css { + Vc::cell("swc css".into()) + } else { + Vc::cell("css".into()) + } +} + +#[turbo_tasks::value] +#[derive(Clone)] +pub struct CssModuleAsset { + source: Vc>, + asset_context: Vc>, + import_context: Option>, + ty: CssModuleAssetType, + use_swc_css: bool, +} + +#[turbo_tasks::value_impl] +impl CssModuleAsset { + /// Creates a new CSS asset. + #[turbo_tasks::function] + pub fn new( + source: Vc>, + asset_context: Vc>, + ty: CssModuleAssetType, + use_swc_css: bool, + import_context: Option>, + ) -> Vc { + Self::cell(CssModuleAsset { + source, + asset_context, + import_context, + ty, + use_swc_css, + }) + } + + /// Retrns the asset ident of the source without the "css" modifier + #[turbo_tasks::function] + pub async fn source_ident(self: Vc) -> Result> { + Ok(self.await?.source.ident()) + } +} + +#[turbo_tasks::value_impl] +impl ParseCss for CssModuleAsset { + #[turbo_tasks::function] + async fn parse_css(self: Vc) -> Result> { + let this = self.await?; + + Ok(parse_css( + this.source, + Vc::upcast(self), + this.import_context + .unwrap_or_else(|| ImportContext::new(vec![], vec![], vec![])), + this.ty, + this.use_swc_css, + )) + } +} + +#[turbo_tasks::value_impl] +impl ProcessCss for CssModuleAsset { + #[turbo_tasks::function] + async fn get_css_with_placeholder(self: Vc) -> Result> { + let parse_result = self.parse_css(); + + Ok(process_css_with_placeholder(parse_result)) + } + + #[turbo_tasks::function] + async fn finalize_css( + self: Vc, + chunking_context: Vc>, + ) -> Result> { + let process_result = self.get_css_with_placeholder(); + + Ok(finalize_css(process_result, chunking_context)) + } +} + +#[turbo_tasks::value_impl] +impl Module for CssModuleAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + let mut ident = self + .source + .ident() + .with_modifier(modifier(self.use_swc_css)) + .with_layer(self.asset_context.layer()); + if let Some(import_context) = self.import_context { + ident = ident.with_modifier(import_context.modifier()) + } + ident + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let result = self.parse_css().await?; + // TODO: include CSS source map + + match &*result { + ParseCssResult::Ok { references, .. } => Ok(*references), + ParseCssResult::Unparseable => Ok(ModuleReferences::empty()), + ParseCssResult::NotFound => Ok(ModuleReferences::empty()), + } + } +} + +#[turbo_tasks::value_impl] +impl Asset for CssModuleAsset { + #[turbo_tasks::function] + fn content(&self) -> Vc { + self.source.content() + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for CssModuleAsset { + #[turbo_tasks::function] + fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Vc> { + Vc::upcast(CssModuleChunkItem::cell(CssModuleChunkItem { + module: self, + chunking_context, + })) + } +} + +#[turbo_tasks::value_impl] +impl CssChunkPlaceable for CssModuleAsset {} + +#[turbo_tasks::value_impl] +impl ResolveOrigin for CssModuleAsset { + #[turbo_tasks::function] + fn origin_path(&self) -> Vc { + self.source.ident().path() + } + + #[turbo_tasks::function] + fn asset_context(&self) -> Vc> { + self.asset_context + } +} + +#[turbo_tasks::value] +struct CssModuleChunkItem { + module: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for CssModuleChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + fn ty(&self) -> Vc> { + Vc::upcast(Vc::::default()) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } +} + +#[turbo_tasks::value_impl] +impl CssChunkItem for CssModuleChunkItem { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let references = &*self.module.references().await?; + let mut imports = vec![]; + let chunking_context = self.chunking_context; + + for reference in references.iter() { + if let Some(import_ref) = + Vc::try_resolve_downcast_type::(*reference).await? + { + for &module in import_ref + .resolve_reference() + .resolve() + .await? + .primary_modules() + .await? + .iter() + { + if let Some(placeable) = + Vc::try_resolve_downcast::>(module).await? + { + let item = placeable.as_chunk_item(chunking_context); + if let Some(css_item) = + Vc::try_resolve_downcast::>(item).await? + { + imports.push(CssImport::Internal(import_ref, css_item)); + } + } + } + } else if let Some(compose_ref) = + Vc::try_resolve_downcast_type::(*reference).await? + { + for &module in compose_ref + .resolve_reference() + .resolve() + .await? + .primary_modules() + .await? + .iter() + { + if let Some(placeable) = + Vc::try_resolve_downcast::>(module).await? + { + let item = placeable.as_chunk_item(chunking_context); + if let Some(css_item) = + Vc::try_resolve_downcast::>(item).await? + { + imports.push(CssImport::Composes(css_item)); + } + } + } + } + } + + let mut code_gens = Vec::new(); + for r in references.iter() { + if let Some(code_gen) = + Vc::try_resolve_sidecast::>(*r).await? + { + code_gens.push(code_gen.code_generation(chunking_context)); + } + } + // need to keep that around to allow references into that + let code_gens = code_gens.into_iter().try_join().await?; + let code_gens = code_gens.iter().map(|cg| &**cg).collect::>(); + // TOOD use interval tree with references into "code_gens" + for code_gen in code_gens { + for import in &code_gen.imports { + imports.push(import.clone()); + } + } + + let result = self.module.finalize_css(chunking_context).await?; + + if let FinalCssResult::Ok { + output_code, + source_map, + .. + } = &*result + { + Ok(CssChunkItemContent { + inner_code: output_code.to_owned().into(), + imports, + import_context: self.module.await?.import_context, + source_map: Some(*source_map), + } + .into()) + } else { + Ok(CssChunkItemContent { + inner_code: format!( + "/* unparseable {} */", + self.module.ident().to_string().await? + ) + .into(), + imports: vec![], + import_context: None, + source_map: None, + } + .into()) + } + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } +} diff --git a/turbopack/crates/turbopack-css/src/chunk/mod.rs b/turbopack/crates/turbopack-css/src/chunk/mod.rs new file mode 100644 index 0000000000000..2f6d8c3b6d9cd --- /dev/null +++ b/turbopack/crates/turbopack-css/src/chunk/mod.rs @@ -0,0 +1,504 @@ +pub(crate) mod single_item_chunk; +pub mod source_map; + +use std::fmt::Write; + +use anyhow::{bail, Result}; +use indexmap::IndexSet; +use turbo_tasks::{RcStr, TryJoinIterExt, Value, ValueDefault, ValueToString, Vc}; +use turbo_tasks_fs::{rope::Rope, File, FileSystem}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ + AsyncModuleInfo, Chunk, ChunkItem, ChunkItemWithAsyncModuleInfo, ChunkType, + ChunkableModule, ChunkingContext, ModuleId, OutputChunk, OutputChunkRuntimeInfo, + }, + code_builder::{Code, CodeBuilder}, + ident::AssetIdent, + introspect::{ + module::IntrospectableModule, + utils::{children_from_output_assets, content_to_details}, + Introspectable, IntrospectableChildren, + }, + module::Module, + output::{OutputAsset, OutputAssets}, + reference_type::ImportContext, + server_fs::ServerFileSystem, + source_map::{GenerateSourceMap, OptionSourceMap}, +}; + +use self::{single_item_chunk::chunk::SingleItemCssChunk, source_map::CssChunkSourceMapAsset}; +use crate::{process::ParseCssResultSourceMap, util::stringify_js, ImportAssetReference}; + +#[turbo_tasks::value] +pub struct CssChunk { + pub chunking_context: Vc>, + pub content: Vc, +} + +#[turbo_tasks::value(transparent)] +pub struct CssChunks(Vec>); + +#[turbo_tasks::value_impl] +impl CssChunk { + #[turbo_tasks::function] + pub fn new( + chunking_context: Vc>, + content: Vc, + ) -> Vc { + CssChunk { + chunking_context, + content, + } + .cell() + } + + #[turbo_tasks::function] + fn chunk_content(&self) -> Vc { + self.content + } + + #[turbo_tasks::function] + async fn code(self: Vc) -> Result> { + use std::io::Write; + + let this = self.await?; + + let mut code = CodeBuilder::default(); + let mut body = CodeBuilder::default(); + let mut external_imports = IndexSet::new(); + for css_item in &this.content.await?.chunk_items { + let id = &*css_item.id().await?; + + let content = &css_item.content().await?; + for import in &content.imports { + if let CssImport::External(external_import) = import { + external_imports.insert((*external_import.await?).to_string()); + } + } + + writeln!(body, "/* {} */", id)?; + let close = write_import_context(&mut body, content.import_context).await?; + + body.push_source(&content.inner_code, content.source_map.map(Vc::upcast)); + + writeln!(body, "{close}")?; + writeln!(body)?; + } + + for external_import in external_imports { + writeln!(code, "@import {};", stringify_js(&external_import))?; + } + + let built = &body.build(); + code.push_code(built); + + if *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await? + && code.has_source_map() + { + let chunk_path = self.path().await?; + writeln!( + code, + "/*# sourceMappingURL={}.map*/", + urlencoding::encode(chunk_path.file_name()) + )?; + } + + let c = code.build().cell(); + Ok(c) + } + + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let code = self.code().await?; + Ok(AssetContent::file( + File::from(code.source_code().clone()).into(), + )) + } +} + +pub async fn write_import_context( + body: &mut impl std::io::Write, + import_context: Option>, +) -> Result { + let mut close = String::new(); + if let Some(import_context) = import_context { + let import_context = &*import_context.await?; + if !&import_context.layers.is_empty() { + writeln!(body, "@layer {} {{", import_context.layers.join("."))?; + close.push_str("\n}"); + } + if !&import_context.media.is_empty() { + writeln!(body, "@media {} {{", import_context.media.join(" and "))?; + close.push_str("\n}"); + } + if !&import_context.supports.is_empty() { + writeln!( + body, + "@supports {} {{", + import_context.supports.join(" and ") + )?; + close.push_str("\n}"); + } + } + Ok(close) +} + +#[turbo_tasks::value] +pub struct CssChunkContent { + pub chunk_items: Vec>>, + pub referenced_output_assets: Vc, +} + +#[turbo_tasks::value_impl] +impl Chunk for CssChunk { + #[turbo_tasks::function] + fn ident(self: Vc) -> Vc { + let self_as_output_asset: Vc> = Vc::upcast(self); + self_as_output_asset.ident() + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + fn references(self: Vc) -> Vc { + OutputAsset::references(self) + } +} + +#[turbo_tasks::value_impl] +impl OutputChunk for CssChunk { + #[turbo_tasks::function] + async fn runtime_info(&self) -> Result> { + let content = self.content.await?; + let entries_chunk_items = &content.chunk_items; + let included_ids = entries_chunk_items + .iter() + .map(|chunk_item| CssChunkItem::id(*chunk_item)) + .collect(); + let imports_chunk_items: Vec<_> = entries_chunk_items + .iter() + .map(|&chunk_item| async move { + let Some(css_item) = + Vc::try_resolve_downcast::>(chunk_item).await? + else { + return Ok(vec![]); + }; + Ok(css_item + .content() + .await? + .imports + .iter() + .filter_map(|import| { + if let CssImport::Internal(_, item) = import { + Some(*item) + } else { + None + } + }) + .collect::>()) + }) + .try_join() + .await? + .into_iter() + .flatten() + .collect(); + let module_chunks: Vec<_> = content + .chunk_items + .iter() + .chain(imports_chunk_items.iter()) + .map(|item| Vc::upcast(SingleItemCssChunk::new(self.chunking_context, *item))) + .collect(); + Ok(OutputChunkRuntimeInfo { + included_ids: Some(Vc::cell(included_ids)), + module_chunks: Some(Vc::cell(module_chunks)), + ..Default::default() + } + .cell()) + } +} + +#[turbo_tasks::function] +fn chunk_item_key() -> Vc { + Vc::cell("chunk item".into()) +} + +#[turbo_tasks::value_impl] +impl OutputAsset for CssChunk { + #[turbo_tasks::function] + async fn ident(self: Vc) -> Result> { + let this = self.await?; + + let mut assets = Vec::new(); + + let CssChunkContent { chunk_items, .. } = &*this.content.await?; + let mut common_path = if let Some(chunk_item) = chunk_items.first() { + let path = chunk_item.asset_ident().path().resolve().await?; + Some((path, path.await?)) + } else { + None + }; + + // The included chunk items and the availability info describe the chunk + // uniquely + let chunk_item_key = chunk_item_key(); + for &chunk_item in chunk_items.iter() { + if let Some((common_path_vc, common_path_ref)) = common_path.as_mut() { + let path = chunk_item.asset_ident().path().await?; + while !path.is_inside_or_equal_ref(common_path_ref) { + let parent = common_path_vc.parent().resolve().await?; + if parent == *common_path_vc { + common_path = None; + break; + } + *common_path_vc = parent; + *common_path_ref = (*common_path_vc).await?; + } + } + assets.push((chunk_item_key, chunk_item.content_ident())); + } + + // Make sure the idents are resolved + for (_, ident) in assets.iter_mut() { + *ident = ident.resolve().await?; + } + + let ident = AssetIdent { + path: if let Some((common_path, _)) = common_path { + common_path + } else { + ServerFileSystem::new().root() + }, + query: Vc::::default(), + fragment: None, + assets, + modifiers: Vec::new(), + part: None, + layer: None, + }; + + Ok(AssetIdent::from_path(this.chunking_context.chunk_path( + AssetIdent::new(Value::new(ident)), + ".css".into(), + ))) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let content = this.content.await?; + let mut references = content.referenced_output_assets.await?.clone_value(); + for item in content.chunk_items.iter() { + references.push(Vc::upcast(SingleItemCssChunk::new( + this.chunking_context, + *item, + ))); + } + if *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await? + { + references.push(Vc::upcast(CssChunkSourceMapAsset::new(self))); + } + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for CssChunk { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + self.content() + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for CssChunk { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.code().generate_source_map() + } +} + +#[turbo_tasks::value] +pub struct CssChunkContext { + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl CssChunkContext { + #[turbo_tasks::function] + pub fn of(chunking_context: Vc>) -> Vc { + CssChunkContext { chunking_context }.cell() + } + + #[turbo_tasks::function] + pub async fn chunk_item_id( + self: Vc, + chunk_item: Vc>, + ) -> Result> { + Ok(ModuleId::String(chunk_item.asset_ident().to_string().await?.clone_value()).cell()) + } +} + +// TODO: remove +#[turbo_tasks::value_trait] +pub trait CssChunkPlaceable: ChunkableModule + Module + Asset {} + +#[turbo_tasks::value(transparent)] +pub struct CssChunkPlaceables(Vec>>); + +#[derive(Clone, Debug)] +#[turbo_tasks::value(shared)] +pub enum CssImport { + External(Vc), + Internal(Vc, Vc>), + Composes(Vc>), +} + +#[derive(Debug)] +#[turbo_tasks::value(shared)] +pub struct CssChunkItemContent { + pub import_context: Option>, + pub imports: Vec, + pub inner_code: Rope, + pub source_map: Option>, +} + +#[turbo_tasks::value_trait] +pub trait CssChunkItem: ChunkItem { + fn content(self: Vc) -> Vc; + fn chunking_context(self: Vc) -> Vc>; + fn id(self: Vc) -> Vc { + CssChunkContext::of(CssChunkItem::chunking_context(self)).chunk_item_id(self) + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("css chunk".into()) +} + +#[turbo_tasks::function] +fn entry_module_key() -> Vc { + Vc::cell("entry module".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for CssChunk { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + fn title(self: Vc) -> Vc { + self.path().to_string() + } + + #[turbo_tasks::function] + async fn details(self: Vc) -> Result> { + let content = content_to_details(self.content()); + let mut details = String::new(); + let this = self.await?; + let chunk_content = this.content.await?; + details += "Chunk items:\n\n"; + for item in chunk_content.chunk_items.iter() { + writeln!(details, "- {}", item.asset_ident().to_string().await?)?; + } + details += "\nContent:\n\n"; + write!(details, "{}", content.await?)?; + Ok(Vc::cell(details.into())) + } + + #[turbo_tasks::function] + async fn children(self: Vc) -> Result> { + let mut children = children_from_output_assets(OutputAsset::references(self)) + .await? + .clone_value(); + for &chunk_item in self.await?.content.await?.chunk_items.iter() { + children.insert(( + entry_module_key(), + IntrospectableModule::new(chunk_item.module()), + )); + } + Ok(Vc::cell(children)) + } +} + +#[derive(Default)] +#[turbo_tasks::value] +pub struct CssChunkType {} + +#[turbo_tasks::value_impl] +impl ValueToString for CssChunkType { + #[turbo_tasks::function] + fn to_string(&self) -> Vc { + Vc::cell("css".into()) + } +} + +#[turbo_tasks::value_impl] +impl ChunkType for CssChunkType { + #[turbo_tasks::function] + async fn chunk( + &self, + chunking_context: Vc>, + chunk_items: Vec, + referenced_output_assets: Vc, + ) -> Result>> { + let content = CssChunkContent { + chunk_items: chunk_items + .iter() + .map(|(chunk_item, _async_info)| async move { + let Some(chunk_item) = + Vc::try_resolve_downcast::>(*chunk_item).await? + else { + bail!("Chunk item is not an css chunk item but reporting chunk type css"); + }; + // CSS doesn't need to care about async_info, so we can discard it + Ok(chunk_item) + }) + .try_join() + .await?, + referenced_output_assets, + } + .cell(); + Ok(Vc::upcast(CssChunk::new(chunking_context, content))) + } + + #[turbo_tasks::function] + async fn chunk_item_size( + &self, + _chunking_context: Vc>, + chunk_item: Vc>, + _async_module_info: Option>, + ) -> Result> { + let Some(chunk_item) = + Vc::try_resolve_downcast::>(chunk_item).await? + else { + bail!("Chunk item is not an css chunk item but reporting chunk type css"); + }; + Ok(Vc::cell( + chunk_item + .content() + .await + .map_or(0, |content| content.inner_code.len()), + )) + } +} + +#[turbo_tasks::value_impl] +impl ValueDefault for CssChunkType { + #[turbo_tasks::function] + fn value_default() -> Vc { + Self::default().cell() + } +} diff --git a/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/chunk.rs b/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/chunk.rs new file mode 100644 index 0000000000000..b394b402566fa --- /dev/null +++ b/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/chunk.rs @@ -0,0 +1,181 @@ +use std::fmt::Write; + +use anyhow::Result; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks_fs::File; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{Chunk, ChunkItem, ChunkingContext}, + code_builder::{Code, CodeBuilder}, + ident::AssetIdent, + introspect::Introspectable, + output::{OutputAsset, OutputAssets}, + source_map::{GenerateSourceMap, OptionSourceMap}, +}; + +use super::source_map::SingleItemCssChunkSourceMapAsset; +use crate::chunk::{write_import_context, CssChunkItem}; + +/// A CSS chunk that only contains a single item. This is used for selectively +/// loading CSS modules that are part of a larger chunk in development mode, and +/// avoiding rule duplication. +#[turbo_tasks::value] +pub struct SingleItemCssChunk { + chunking_context: Vc>, + item: Vc>, +} + +#[turbo_tasks::value_impl] +impl SingleItemCssChunk { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new( + chunking_context: Vc>, + item: Vc>, + ) -> Vc { + SingleItemCssChunk { + chunking_context, + item, + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl SingleItemCssChunk { + #[turbo_tasks::function] + async fn code(self: Vc) -> Result> { + use std::io::Write; + + let this = self.await?; + let mut code = CodeBuilder::default(); + + let id = &*this.item.id().await?; + + writeln!(code, "/* {} */", id)?; + let content = this.item.content().await?; + let close = write_import_context(&mut code, content.import_context).await?; + + code.push_source(&content.inner_code, content.source_map.map(Vc::upcast)); + write!(code, "{close}")?; + + if *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await? + && code.has_source_map() + { + let chunk_path = self.path().await?; + write!( + code, + "\n/*# sourceMappingURL={}.map*/", + urlencoding::encode(chunk_path.file_name()) + )?; + } + + let c = code.build().cell(); + Ok(c) + } +} + +#[turbo_tasks::value_impl] +impl Chunk for SingleItemCssChunk { + #[turbo_tasks::function] + fn ident(self: Vc) -> Vc { + let self_as_output_asset: Vc> = Vc::upcast(self); + self_as_output_asset.ident() + } + + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } +} + +#[turbo_tasks::function] +fn single_item_modifier() -> Vc { + Vc::cell("single item css chunk".into()) +} + +#[turbo_tasks::value_impl] +impl OutputAsset for SingleItemCssChunk { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + Ok(AssetIdent::from_path( + self.chunking_context.chunk_path( + self.item + .asset_ident() + .with_modifier(single_item_modifier()), + ".css".into(), + ), + )) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + let this = self.await?; + let mut references = Vec::new(); + if *this + .chunking_context + .reference_chunk_source_maps(Vc::upcast(self)) + .await? + { + references.push(Vc::upcast(SingleItemCssChunkSourceMapAsset::new(self))); + } + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for SingleItemCssChunk { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let code = self.code().await?; + Ok(AssetContent::file( + File::from(code.source_code().clone()).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for SingleItemCssChunk { + #[turbo_tasks::function] + fn generate_source_map(self: Vc) -> Vc { + self.code().generate_source_map() + } +} + +#[turbo_tasks::function] +fn introspectable_type() -> Vc { + Vc::cell("single asset css chunk".into()) +} + +#[turbo_tasks::function] +fn entry_module_key() -> Vc { + Vc::cell("entry module".into()) +} + +#[turbo_tasks::value_impl] +impl Introspectable for SingleItemCssChunk { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + introspectable_type() + } + + #[turbo_tasks::function] + fn title(self: Vc) -> Vc { + self.path().to_string() + } + + #[turbo_tasks::function] + async fn details(self: Vc) -> Result> { + let this = self.await?; + let mut details = String::new(); + write!( + details, + "Chunk item: {}", + this.item.asset_ident().to_string().await? + )?; + Ok(Vc::cell(details.into())) + } +} diff --git a/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/mod.rs b/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/mod.rs new file mode 100644 index 0000000000000..9950d4389711d --- /dev/null +++ b/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/mod.rs @@ -0,0 +1,2 @@ +pub(crate) mod chunk; +pub(crate) mod source_map; diff --git a/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/source_map.rs b/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/source_map.rs new file mode 100644 index 0000000000000..1b0f42359dad1 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/chunk/single_item_chunk/source_map.rs @@ -0,0 +1,50 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_fs::File; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::Chunk, + ident::AssetIdent, + output::OutputAsset, + source_map::{GenerateSourceMap, SourceMap}, +}; + +use super::chunk::SingleItemCssChunk; + +/// Represents the source map of a single item CSS chunk. +#[turbo_tasks::value] +pub struct SingleItemCssChunkSourceMapAsset { + chunk: Vc, +} + +#[turbo_tasks::value_impl] +impl SingleItemCssChunkSourceMapAsset { + #[turbo_tasks::function] + pub fn new(chunk: Vc) -> Vc { + SingleItemCssChunkSourceMapAsset { chunk }.cell() + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for SingleItemCssChunkSourceMapAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + Ok(AssetIdent::from_path( + self.chunk.path().append(".map".into()), + )) + } +} + +#[turbo_tasks::value_impl] +impl Asset for SingleItemCssChunkSourceMapAsset { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let sm = if let Some(sm) = *self.chunk.generate_source_map().await? { + sm + } else { + SourceMap::empty() + }; + let sm = sm.to_rope().await?; + Ok(AssetContent::file(File::from(sm).into())) + } +} diff --git a/turbopack/crates/turbopack-css/src/chunk/source_map.rs b/turbopack/crates/turbopack-css/src/chunk/source_map.rs new file mode 100644 index 0000000000000..7be9a1b14f03e --- /dev/null +++ b/turbopack/crates/turbopack-css/src/chunk/source_map.rs @@ -0,0 +1,50 @@ +use anyhow::Result; +use turbo_tasks::Vc; +use turbo_tasks_fs::File; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::Chunk, + ident::AssetIdent, + output::OutputAsset, + source_map::{GenerateSourceMap, SourceMap}, +}; + +use super::CssChunk; + +/// Represents the source map of an css chunk. +#[turbo_tasks::value] +pub struct CssChunkSourceMapAsset { + chunk: Vc, +} + +#[turbo_tasks::value_impl] +impl CssChunkSourceMapAsset { + #[turbo_tasks::function] + pub fn new(chunk: Vc) -> Vc { + CssChunkSourceMapAsset { chunk }.cell() + } +} + +#[turbo_tasks::value_impl] +impl OutputAsset for CssChunkSourceMapAsset { + #[turbo_tasks::function] + async fn ident(&self) -> Result> { + Ok(AssetIdent::from_path( + self.chunk.path().append(".map".into()), + )) + } +} + +#[turbo_tasks::value_impl] +impl Asset for CssChunkSourceMapAsset { + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let sm = if let Some(sm) = *self.chunk.generate_source_map().await? { + sm + } else { + SourceMap::empty() + }; + let sm = sm.to_rope().await?; + Ok(AssetContent::file(File::from(sm).into())) + } +} diff --git a/turbopack/crates/turbopack-css/src/code_gen.rs b/turbopack/crates/turbopack-css/src/code_gen.rs new file mode 100644 index 0000000000000..20855e79a1597 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/code_gen.rs @@ -0,0 +1,29 @@ +use turbo_tasks::Vc; +use turbopack_core::chunk::ChunkingContext; + +use crate::chunk::CssImport; + +/// impl of code generation inferred from a ModuleReference. +/// This is rust only and can't be implemented by non-rust plugins. +#[turbo_tasks::value( + shared, + serialization = "none", + eq = "manual", + into = "new", + cell = "new" +)] +pub struct CodeGeneration { + #[turbo_tasks(debug_ignore, trace_ignore)] + pub imports: Vec, +} + +#[turbo_tasks::value_trait] +pub trait CodeGenerateable { + fn code_generation( + self: Vc, + chunking_context: Vc>, + ) -> Vc; +} + +#[turbo_tasks::value(transparent)] +pub struct CodeGenerateables(Vec>>); diff --git a/turbopack/crates/turbopack-css/src/embed.rs b/turbopack/crates/turbopack-css/src/embed.rs new file mode 100644 index 0000000000000..9ab396bdf6934 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/embed.rs @@ -0,0 +1,7 @@ +use turbo_tasks::Vc; +use turbopack_core::{chunk::ChunkItem, output::OutputAsset}; + +#[turbo_tasks::value_trait] +pub trait CssEmbed: ChunkItem { + fn embedded_asset(self: Vc) -> Vc>; +} diff --git a/turbopack/crates/turbopack-css/src/lib.rs b/turbopack/crates/turbopack-css/src/lib.rs new file mode 100644 index 0000000000000..45c5bb65a07f6 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/lib.rs @@ -0,0 +1,55 @@ +#![feature(min_specialization)] +#![feature(box_patterns)] +#![feature(iter_intersperse)] +#![feature(int_roundings)] +#![feature(arbitrary_self_types)] + +mod asset; +pub mod chunk; +mod code_gen; +pub mod embed; +mod lifetime_util; +mod module_asset; +pub(crate) mod parse; +pub(crate) mod process; +pub(crate) mod references; +pub(crate) mod util; + +pub use asset::CssModuleAsset; +pub use module_asset::ModuleCssAsset; +use serde::{Deserialize, Serialize}; +use turbo_tasks::{trace::TraceRawVcs, TaskInput}; + +pub use self::process::*; +use crate::references::import::ImportAssetReference; + +#[derive( + PartialOrd, + Ord, + Eq, + PartialEq, + Hash, + Debug, + Copy, + Clone, + Default, + Serialize, + Deserialize, + TaskInput, + TraceRawVcs, +)] +pub enum CssModuleAssetType { + /// Default parsing mode. + #[default] + Default, + /// The CSS is parsed as CSS modules. + Module, +} + +pub fn register() { + turbo_tasks::register(); + turbo_tasks_fs::register(); + turbopack_core::register(); + turbopack_ecmascript::register(); + include!(concat!(env!("OUT_DIR"), "/register.rs")); +} diff --git a/turbopack/crates/turbopack-css/src/lifetime_util.rs b/turbopack/crates/turbopack-css/src/lifetime_util.rs new file mode 100644 index 0000000000000..38aade884bb6b --- /dev/null +++ b/turbopack/crates/turbopack-css/src/lifetime_util.rs @@ -0,0 +1,16 @@ +use lightningcss::{ + stylesheet::{ParserOptions, StyleSheet}, + traits::IntoOwned, +}; + +pub fn stylesheet_into_static<'i, 'o>( + ss: &StyleSheet, + options: ParserOptions<'o, 'i>, +) -> StyleSheet<'i, 'o> { + let sources = ss.sources.clone(); + let rules = ss.rules.clone().into_owned(); + + // + + StyleSheet::new(sources, rules, options) +} diff --git a/turbopack/crates/turbopack-css/src/module_asset.rs b/turbopack/crates/turbopack-css/src/module_asset.rs new file mode 100644 index 0000000000000..08c76694f2dda --- /dev/null +++ b/turbopack/crates/turbopack-css/src/module_asset.rs @@ -0,0 +1,464 @@ +use std::{fmt::Write, sync::Arc}; + +use anyhow::{bail, Context, Result}; +use indexmap::IndexMap; +use indoc::formatdoc; +use lightningcss::css_modules::CssModuleReference; +use swc_core::common::{BytePos, FileName, LineCol, SourceMap}; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbo_tasks_fs::FileSystemPath; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ChunkItem, ChunkItemExt, ChunkType, ChunkableModule, ChunkingContext}, + context::{AssetContext, ProcessResult}, + ident::AssetIdent, + issue::{Issue, IssueExt, IssueSeverity, IssueStage, OptionStyledString, StyledString}, + module::Module, + reference::{ModuleReference, ModuleReferences}, + reference_type::{CssReferenceSubType, ReferenceType}, + resolve::{origin::ResolveOrigin, parse::Request}, + source::Source, + source_map::OptionSourceMap, +}; +use turbopack_ecmascript::{ + chunk::{ + EcmascriptChunkItem, EcmascriptChunkItemContent, EcmascriptChunkPlaceable, + EcmascriptChunkType, EcmascriptExports, + }, + utils::StringifyJs, + ParseResultSourceMap, +}; + +use crate::{ + process::{CssWithPlaceholderResult, ProcessCss}, + references::{compose::CssModuleComposeReference, internal::InternalCssAssetReference}, +}; + +#[turbo_tasks::function] +fn modifier() -> Vc { + Vc::cell("css module".into()) +} + +#[turbo_tasks::value] +#[derive(Clone)] +pub struct ModuleCssAsset { + pub source: Vc>, + pub asset_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ModuleCssAsset { + #[turbo_tasks::function] + pub async fn new( + source: Vc>, + asset_context: Vc>, + ) -> Result> { + Ok(Self::cell(ModuleCssAsset { + source, + asset_context, + })) + } +} + +#[turbo_tasks::value_impl] +impl Module for ModuleCssAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + self.source + .ident() + .with_modifier(modifier()) + .with_layer(self.asset_context.layer()) + } + + #[turbo_tasks::function] + async fn references(self: Vc) -> Result> { + // The inner reference must come last so it is loaded as the last in the + // resulting css. @import or composes references must be loaded first so + // that the css style rules in them are overridable from the local css. + + // This affects the order in which the resulting CSS chunks will be loaded: + // 1. @import or composes references are loaded first + // 2. The local CSS is loaded last + + let references = self + .module_references() + .await? + .iter() + .copied() + .chain(match *self.inner().await? { + ProcessResult::Module(inner) => { + Some(Vc::upcast(InternalCssAssetReference::new(inner))) + } + ProcessResult::Ignore => None, + }) + .collect(); + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl Asset for ModuleCssAsset { + #[turbo_tasks::function] + fn content(&self) -> Result> { + bail!("CSS module asset has no contents") + } +} + +/// A CSS class that is exported from a CSS module. +/// +/// See [`ModuleCssClasses`] for more information. +#[turbo_tasks::value] +#[derive(Debug, Clone)] +enum ModuleCssClass { + Local { + name: String, + }, + Global { + name: String, + }, + Import { + original: String, + from: Vc, + }, +} + +/// A map of CSS classes exported from a CSS module. +/// +/// ## Example +/// +/// ```css +/// :global(.class1) { +/// color: red; +/// } +/// +/// .class2 { +/// color: blue; +/// } +/// +/// .class3 { +/// composes: class4 from "./other.module.css"; +/// } +/// ``` +/// +/// The above CSS module would have the following exports: +/// 1. class1: [Global("exported_class1")] +/// 2. class2: [Local("exported_class2")] +/// 3. class3: [Local("exported_class3), Import("class4", "./other.module.css")] +#[turbo_tasks::value(transparent)] +#[derive(Debug, Clone)] +struct ModuleCssClasses(IndexMap>); + +#[turbo_tasks::value_impl] +impl ModuleCssAsset { + #[turbo_tasks::function] + async fn inner(self: Vc) -> Result> { + let this = self.await?; + Ok(this.asset_context.process( + this.source, + Value::new(ReferenceType::Css(CssReferenceSubType::Internal)), + )) + } + + #[turbo_tasks::function] + async fn classes(self: Vc) -> Result> { + let inner = self.inner().module(); + + let inner = Vc::try_resolve_sidecast::>(inner) + .await? + .context("inner asset should be CSS processable")?; + + let result = inner.get_css_with_placeholder().await?; + let mut classes = IndexMap::default(); + + // TODO(alexkirsz) Should we report an error on parse error here? + if let CssWithPlaceholderResult::Ok { + exports: Some(exports), + .. + } = &*result + { + for (class_name, export_class_names) in exports { + let mut export = Vec::default(); + + export.push(ModuleCssClass::Local { + name: export_class_names.name.clone(), + }); + + for export_class_name in &export_class_names.composes { + export.push(match export_class_name { + CssModuleReference::Dependency { specifier, name } => { + ModuleCssClass::Import { + original: name.to_string(), + from: CssModuleComposeReference::new( + Vc::upcast(self), + Request::parse(Value::new( + RcStr::from(specifier.clone()).into(), + )), + ), + } + } + CssModuleReference::Local { name } => ModuleCssClass::Local { + name: name.to_string(), + }, + CssModuleReference::Global { name } => ModuleCssClass::Global { + name: name.to_string(), + }, + }) + } + + classes.insert(class_name.to_string(), export); + } + } + + Ok(Vc::cell(classes)) + } + + #[turbo_tasks::function] + async fn module_references(self: Vc) -> Result> { + let mut references = vec![]; + + for (_, class_names) in &*self.classes().await? { + for class_name in class_names { + match class_name { + ModuleCssClass::Import { from, .. } => { + references.push(Vc::upcast(*from)); + } + ModuleCssClass::Local { .. } | ModuleCssClass::Global { .. } => {} + } + } + } + + Ok(Vc::cell(references)) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModule for ModuleCssAsset { + #[turbo_tasks::function] + async fn as_chunk_item( + self: Vc, + chunking_context: Vc>, + ) -> Result>> { + Ok(Vc::upcast( + ModuleChunkItem { + chunking_context, + module: self, + } + .cell(), + )) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkPlaceable for ModuleCssAsset { + #[turbo_tasks::function] + fn get_exports(&self) -> Vc { + EcmascriptExports::Value.cell() + } +} + +#[turbo_tasks::value_impl] +impl ResolveOrigin for ModuleCssAsset { + #[turbo_tasks::function] + fn origin_path(&self) -> Vc { + self.source.ident().path() + } + + #[turbo_tasks::function] + fn asset_context(&self) -> Vc> { + self.asset_context + } +} + +#[turbo_tasks::value] +struct ModuleChunkItem { + module: Vc, + chunking_context: Vc>, +} + +#[turbo_tasks::value_impl] +impl ChunkItem for ModuleChunkItem { + #[turbo_tasks::function] + fn asset_ident(&self) -> Vc { + self.module.ident() + } + + #[turbo_tasks::function] + fn references(&self) -> Vc { + self.module.references() + } + + #[turbo_tasks::function] + async fn chunking_context(&self) -> Vc> { + Vc::upcast(self.chunking_context) + } + + #[turbo_tasks::function] + async fn ty(&self) -> Result>> { + Ok(Vc::upcast( + Vc::::default().resolve().await?, + )) + } + + #[turbo_tasks::function] + fn module(&self) -> Vc> { + Vc::upcast(self.module) + } +} + +#[turbo_tasks::value_impl] +impl EcmascriptChunkItem for ModuleChunkItem { + #[turbo_tasks::function] + fn chunking_context(&self) -> Vc> { + self.chunking_context + } + + #[turbo_tasks::function] + async fn content(&self) -> Result> { + let classes = self.module.classes().await?; + + let mut code = "__turbopack_export_value__({\n".to_string(); + for (export_name, class_names) in &*classes { + let mut exported_class_names = Vec::with_capacity(class_names.len()); + + for class_name in class_names { + match class_name { + ModuleCssClass::Import { + original: original_name, + from, + } => { + let resolved_module = from.resolve_reference().first_module().await?; + + let Some(resolved_module) = &*resolved_module else { + CssModuleComposesIssue { + severity: IssueSeverity::Error.cell(), + source: self.module.ident(), + message: formatdoc! { + r#" + Module {from} referenced in `composes: ... from {from};` can't be resolved. + "#, + from = &*from.await?.request.to_string().await? + }.into(), + }.cell().emit(); + continue; + }; + + let Some(css_module) = + Vc::try_resolve_downcast_type::(*resolved_module) + .await? + else { + CssModuleComposesIssue { + severity: IssueSeverity::Error.cell(), + source: self.module.ident(), + message: formatdoc! { + r#" + Module {from} referenced in `composes: ... from {from};` is not a CSS module. + "#, + from = &*from.await?.request.to_string().await? + }.into(), + }.cell().emit(); + continue; + }; + + // TODO(alexkirsz) We should also warn if `original_name` can't be found in + // the target module. + + let placeable: Vc> = + Vc::upcast(css_module); + + let module_id = placeable + .as_chunk_item(Vc::upcast(self.chunking_context)) + .id() + .await?; + let module_id = StringifyJs(&*module_id); + let original_name = StringifyJs(&original_name); + exported_class_names.push(format! { + "__turbopack_import__({module_id})[{original_name}]" + }); + } + ModuleCssClass::Local { name: class_name } + | ModuleCssClass::Global { name: class_name } => { + exported_class_names.push(StringifyJs(&class_name).to_string()); + } + } + } + + writeln!( + code, + " {}: {},", + StringifyJs(export_name), + exported_class_names.join(" + \" \" + ") + )?; + } + code += "});\n"; + Ok(EcmascriptChunkItemContent { + inner_code: code.clone().into(), + // We generate a minimal map for runtime code so that the filename is + // displayed in dev tools. + source_map: Some(Vc::upcast(generate_minimal_source_map( + self.module.ident().to_string().await?.to_string(), + code, + ))), + ..Default::default() + } + .cell()) + } +} + +fn generate_minimal_source_map(filename: String, source: String) -> Vc { + let mut mappings = vec![]; + // Start from 1 because 0 is reserved for dummy spans in SWC. + let mut pos = 1; + for (index, line) in source.split_inclusive('\n').enumerate() { + mappings.push(( + BytePos(pos), + LineCol { + line: index as u32, + col: 0, + }, + )); + pos += line.len() as u32; + } + let sm: Arc = Default::default(); + sm.new_source_file(FileName::Custom(filename), source); + let map = ParseResultSourceMap::new(sm, mappings, OptionSourceMap::none()); + map.cell() +} + +#[turbo_tasks::value(shared)] +struct CssModuleComposesIssue { + severity: Vc, + source: Vc, + message: RcStr, +} + +#[turbo_tasks::value_impl] +impl Issue for CssModuleComposesIssue { + #[turbo_tasks::function] + fn severity(&self) -> Vc { + self.severity + } + + #[turbo_tasks::function] + async fn title(&self) -> Result> { + Ok(StyledString::Text( + "An issue occurred while resolving a CSS module `composes:` rule".into(), + ) + .cell()) + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::CodeGen.cell() + } + + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.source.path() + } + + #[turbo_tasks::function] + fn description(&self) -> Vc { + Vc::cell(Some(StyledString::Text(self.message.clone()).cell())) + } +} diff --git a/turbopack/crates/turbopack-css/src/parse.rs b/turbopack/crates/turbopack-css/src/parse.rs new file mode 100644 index 0000000000000..c1efd0ea8bc12 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/parse.rs @@ -0,0 +1,20 @@ +use swc_core::common::{source_map::SourceMapGenConfig, FileName}; +use turbopack_core::SOURCE_MAP_PREFIX; + +/// A config to generate a source map which includes the source content of every +/// source file. SWC doesn't inline sources content by default when generating a +/// sourcemap, so we need to provide a custom config to do it. +pub struct InlineSourcesContentConfig {} + +impl SourceMapGenConfig for InlineSourcesContentConfig { + fn file_name_to_source(&self, f: &FileName) -> String { + match f { + FileName::Custom(s) => format!("{SOURCE_MAP_PREFIX}{s}"), + _ => f.to_string(), + } + } + + fn inline_sources_content(&self, _f: &FileName) -> bool { + true + } +} diff --git a/turbopack/crates/turbopack-css/src/process.rs b/turbopack/crates/turbopack-css/src/process.rs new file mode 100644 index 0000000000000..202a309261f97 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/process.rs @@ -0,0 +1,1300 @@ +use std::{ + collections::HashMap, + sync::{Arc, RwLock}, +}; + +use anyhow::{bail, Context, Result}; +use indexmap::IndexMap; +use lightningcss::{ + css_modules::{CssModuleExport, CssModuleExports, CssModuleReference, Pattern, Segment}, + dependencies::{Dependency, ImportDependency, Location, SourceRange}, + stylesheet::{ParserOptions, PrinterOptions, StyleSheet, ToCssResult}, + targets::{Features, Targets}, + values::url::Url, + visit_types, + visitor::Visit, +}; +use once_cell::sync::Lazy; +use regex::Regex; +use smallvec::smallvec; +use swc_core::{ + atoms::Atom, + base::sourcemap::SourceMapBuilder, + common::{BytePos, FileName, LineCol, Span}, + css::{ + ast::{ + ComplexSelector, ComplexSelectorChildren, CompoundSelector, ForgivingComplexSelector, + ForgivingRelativeSelector, PseudoClassSelectorChildren, PseudoElementSelectorChildren, + RelativeSelector, SubclassSelector, TypeSelector, UrlValue, + }, + codegen::{writer::basic::BasicCssWriter, CodeGenerator}, + modules::{CssClassName, TransformConfig}, + visit::{VisitMut, VisitMutWith, VisitWith}, + }, +}; +use tracing::Instrument; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbo_tasks_fs::{FileContent, FileSystemPath}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::ChunkingContext, + issue::{ + Issue, IssueExt, IssueSource, IssueStage, OptionIssueSource, OptionStyledString, + StyledString, + }, + reference::ModuleReferences, + reference_type::ImportContext, + resolve::origin::ResolveOrigin, + source::Source, + source_map::{GenerateSourceMap, OptionSourceMap}, + source_pos::SourcePos, + SOURCE_MAP_PREFIX, +}; +use turbopack_swc_utils::emitter::IssueEmitter; + +use crate::{ + lifetime_util::stylesheet_into_static, + parse::InlineSourcesContentConfig, + references::{ + analyze_references, + url::{replace_url_references, resolve_url_reference, UrlAssetReference}, + }, + CssModuleAssetType, +}; + +// Capture up until the first "." +static BASENAME_RE: Lazy = Lazy::new(|| Regex::new(r"^[^.]*").unwrap()); + +#[derive(Debug)] +pub enum StyleSheetLike<'i, 'o> { + LightningCss(StyleSheet<'i, 'o>), + Swc { + stylesheet: swc_core::css::ast::Stylesheet, + css_modules: Option, + }, +} + +#[derive(Debug, Clone)] +pub struct SwcCssModuleMode { + basename: String, + path_hash: u32, +} + +impl PartialEq for StyleSheetLike<'_, '_> { + fn eq(&self, _: &Self) -> bool { + false + } +} + +pub type CssOutput = (ToCssResult, Option); + +impl<'i, 'o> StyleSheetLike<'i, 'o> { + pub fn to_static( + &self, + options: ParserOptions<'static, 'static>, + ) -> StyleSheetLike<'static, 'static> { + match self { + StyleSheetLike::LightningCss(ss) => { + StyleSheetLike::LightningCss(stylesheet_into_static(ss, options)) + } + StyleSheetLike::Swc { + stylesheet, + css_modules, + } => StyleSheetLike::Swc { + stylesheet: stylesheet.clone(), + css_modules: css_modules.clone(), + }, + } + } + + pub fn to_css( + &self, + cm: Arc, + code: &str, + enable_srcmap: bool, + remove_imports: bool, + handle_nesting: bool, + ) -> Result { + match self { + StyleSheetLike::LightningCss(ss) => { + let mut srcmap = if enable_srcmap { + Some(parcel_sourcemap::SourceMap::new("")) + } else { + None + }; + + let result = ss.to_css(PrinterOptions { + minify: false, + source_map: srcmap.as_mut(), + targets: if handle_nesting { + Targets { + include: Features::Nesting, + ..Default::default() + } + } else { + Default::default() + }, + analyze_dependencies: None, + ..Default::default() + })?; + + if let Some(srcmap) = &mut srcmap { + debug_assert_eq!(ss.sources.len(), 1); + + srcmap.add_sources(ss.sources.clone()); + srcmap.set_source_content(0, code)?; + } + + Ok(( + result, + srcmap.map(ParseCssResultSourceMap::new_lightningcss), + )) + } + StyleSheetLike::Swc { + stylesheet, + css_modules, + } => { + let mut stylesheet = stylesheet.clone(); + // We always analyze dependencies, but remove them only if remove_imports is + // true + let mut deps = vec![]; + stylesheet.visit_mut_with(&mut SwcDepColllector { + deps: &mut deps, + remove_imports, + }); + + // lightningcss specifies css module mode in the parser options. + let mut css_module_exports = None; + if let Some(SwcCssModuleMode { + basename, + path_hash, + }) = css_modules + { + let output = swc_core::css::modules::compile( + &mut stylesheet, + ModuleTransformConfig { + suffix: format!("__{}__{:x}", basename, path_hash), + }, + ); + + let mut map = CssModuleExports::default(); + + for (class_name, export_class_names) in output.renamed { + for export_class_name in export_class_names { + // If the class name is already in the map, the first + // one is the reference to itself and the current one is + // the reference to the other class. + match export_class_name { + CssClassName::Local { name } => { + map.entry(class_name.to_string()) + .and_modify(|e| { + e.composes.push(CssModuleReference::Local { + name: name.value.to_string(), + }) + }) + .or_insert_with(|| CssModuleExport { + name: name.value.to_string(), + composes: Vec::new(), + is_referenced: true, + }); + } + CssClassName::Global { name } => { + map.entry(class_name.to_string()) + .and_modify(|e| { + e.composes.push(CssModuleReference::Global { + name: name.value.to_string(), + }) + }) + .or_insert_with(|| CssModuleExport { + name: name.value.to_string(), + composes: Vec::new(), + is_referenced: true, + }); + } + CssClassName::Import { name, from } => { + let e = + map.entry(class_name.to_string()).or_insert_with(|| { + CssModuleExport { + name: name.value.to_string(), + composes: Vec::new(), + is_referenced: true, + } + }); + + e.composes.push(CssModuleReference::Dependency { + name: name.value.to_string(), + specifier: from.to_string(), + }); + } + } + } + } + + css_module_exports = Some(map); + } + + if handle_nesting { + stylesheet.visit_mut_with(&mut swc_core::css::compat::compiler::Compiler::new( + swc_core::css::compat::compiler::Config { + process: swc_core::css::compat::feature::Features::NESTING, + }, + )); + } + + use swc_core::css::codegen::Emit; + + let mut code_string = String::new(); + let mut srcmap = if enable_srcmap { Some(vec![]) } else { None }; + + let mut code_gen = CodeGenerator::new( + BasicCssWriter::new(&mut code_string, srcmap.as_mut(), Default::default()), + Default::default(), + ); + + code_gen.emit(&stylesheet)?; + + let srcmap = + srcmap.map(|srcmap| ParseCssResultSourceMap::new_swc(cm.clone(), srcmap)); + + Ok(( + ToCssResult { + code: code_string, + dependencies: Some(deps), + exports: css_module_exports, + references: None, + }, + srcmap, + )) + } + } + } +} + +/// Multiple [ModuleReference]s +#[turbo_tasks::value(transparent)] +pub struct UnresolvedUrlReferences(pub Vec<(String, Vc)>); + +#[turbo_tasks::value(shared, serialization = "none", eq = "manual", cell = "new")] +pub enum ParseCssResult { + Ok { + #[turbo_tasks(debug_ignore, trace_ignore)] + cm: Arc, + + code: Vc, + + #[turbo_tasks(trace_ignore)] + stylesheet: StyleSheetLike<'static, 'static>, + + references: Vc, + + url_references: Vc, + + #[turbo_tasks(trace_ignore)] + options: ParserOptions<'static, 'static>, + }, + Unparseable, + NotFound, +} + +#[turbo_tasks::value(shared, serialization = "none", eq = "manual", cell = "new")] +pub enum CssWithPlaceholderResult { + Ok { + parse_result: Vc, + + #[turbo_tasks(debug_ignore, trace_ignore)] + cm: Arc, + + references: Vc, + + url_references: Vc, + + #[turbo_tasks(trace_ignore)] + exports: Option>, + + #[turbo_tasks(trace_ignore)] + placeholders: HashMap>, + }, + Unparseable, + NotFound, +} + +#[turbo_tasks::value(shared, serialization = "none", eq = "manual")] +pub enum FinalCssResult { + Ok { + #[turbo_tasks(trace_ignore)] + output_code: String, + + #[turbo_tasks(trace_ignore)] + exports: Option, + + source_map: Vc, + }, + Unparseable, + NotFound, +} + +impl PartialEq for FinalCssResult { + fn eq(&self, _: &Self) -> bool { + false + } +} + +#[turbo_tasks::function] +pub async fn process_css_with_placeholder( + parse_result: Vc, +) -> Result> { + let result = parse_result.await?; + + match &*result { + ParseCssResult::Ok { + cm, + stylesheet, + references, + url_references, + code, + .. + } => { + let code = code.await?; + let code = match &*code { + FileContent::Content(v) => v.content().to_str()?, + _ => bail!("this case should be filtered out while parsing"), + }; + + let (result, _) = stylesheet.to_css(cm.clone(), &code, false, false, false)?; + + let exports = result.exports.map(|exports| { + let mut exports = exports.into_iter().collect::>(); + + exports.sort_keys(); + + exports + }); + + Ok(CssWithPlaceholderResult::Ok { + parse_result, + cm: cm.clone(), + exports, + references: *references, + url_references: *url_references, + placeholders: HashMap::new(), + } + .cell()) + } + ParseCssResult::Unparseable => Ok(CssWithPlaceholderResult::Unparseable.cell()), + ParseCssResult::NotFound => Ok(CssWithPlaceholderResult::NotFound.cell()), + } +} + +#[turbo_tasks::function] +pub async fn finalize_css( + result: Vc, + chunking_context: Vc>, +) -> Result> { + let result = result.await?; + match &*result { + CssWithPlaceholderResult::Ok { + cm, + parse_result, + url_references, + .. + } => { + let (mut stylesheet, code) = match &*parse_result.await? { + ParseCssResult::Ok { + stylesheet, + options, + code, + .. + } => (stylesheet.to_static(options.clone()), *code), + ParseCssResult::Unparseable => return Ok(FinalCssResult::Unparseable.into()), + ParseCssResult::NotFound => return Ok(FinalCssResult::NotFound.into()), + }; + + let url_references = *url_references; + + let mut url_map = HashMap::new(); + + for (src, reference) in (*url_references.await?).iter() { + let resolved = resolve_url_reference(*reference, chunking_context).await?; + if let Some(v) = resolved.as_ref().cloned() { + url_map.insert(RcStr::from(src.as_str()), v); + } + } + + replace_url_references(&mut stylesheet, &url_map); + + let code = code.await?; + let code = match &*code { + FileContent::Content(v) => v.content().to_str()?, + _ => bail!("this case should be filtered out while parsing"), + }; + let (result, srcmap) = stylesheet.to_css(cm.clone(), &code, true, true, true)?; + + Ok(FinalCssResult::Ok { + output_code: result.code, + exports: result.exports, + source_map: srcmap.unwrap().cell(), + } + .into()) + } + CssWithPlaceholderResult::Unparseable => Ok(FinalCssResult::Unparseable.into()), + CssWithPlaceholderResult::NotFound => Ok(FinalCssResult::NotFound.into()), + } +} + +#[turbo_tasks::value_trait] +pub trait ParseCss { + async fn parse_css(self: Vc) -> Result>; +} + +#[turbo_tasks::value_trait] +pub trait ProcessCss: ParseCss { + async fn get_css_with_placeholder(self: Vc) -> Result>; + + async fn finalize_css( + self: Vc, + chunking_context: Vc>, + ) -> Result>; +} + +#[turbo_tasks::function] +pub async fn parse_css( + source: Vc>, + origin: Vc>, + import_context: Vc, + ty: CssModuleAssetType, + use_swc_css: bool, +) -> Result> { + let span = { + let name = source.ident().to_string().await?.to_string(); + tracing::info_span!("parse css", name = name) + }; + async move { + let content = source.content(); + let fs_path = source.ident().path(); + let ident_str = &*source.ident().to_string().await?; + Ok(match &*content.await? { + AssetContent::Redirect { .. } => ParseCssResult::Unparseable.cell(), + AssetContent::File(file_content) => match &*file_content.await? { + FileContent::NotFound => ParseCssResult::NotFound.cell(), + FileContent::Content(file) => match file.content().to_str() { + Err(_err) => ParseCssResult::Unparseable.cell(), + Ok(string) => { + process_content( + *file_content, + string.into_owned(), + fs_path, + ident_str, + source, + origin, + import_context, + ty, + use_swc_css, + ) + .await? + } + }, + }, + }) + } + .instrument(span) + .await +} + +async fn process_content( + content_vc: Vc, + code: String, + fs_path_vc: Vc, + filename: &str, + source: Vc>, + origin: Vc>, + import_context: Vc, + ty: CssModuleAssetType, + use_swc_css: bool, +) -> Result> { + #[allow(clippy::needless_lifetimes)] + fn without_warnings<'o, 'i>(config: ParserOptions<'o, 'i>) -> ParserOptions<'o, 'static> { + ParserOptions { + filename: config.filename, + css_modules: config.css_modules, + source_index: config.source_index, + error_recovery: config.error_recovery, + warnings: None, + flags: config.flags, + } + } + + let config = ParserOptions { + css_modules: match ty { + CssModuleAssetType::Module => Some(lightningcss::css_modules::Config { + pattern: Pattern { + segments: smallvec![ + Segment::Name, + Segment::Literal("__"), + Segment::Hash, + Segment::Literal("__"), + Segment::Local, + ], + }, + dashed_idents: false, + grid: false, + ..Default::default() + }), + + _ => None, + }, + filename: filename.to_string(), + error_recovery: true, + ..Default::default() + }; + + let cm: Arc = Default::default(); + + let stylesheet = if !use_swc_css { + StyleSheetLike::LightningCss({ + let warnings: Arc> = Default::default(); + + match StyleSheet::parse( + &code, + ParserOptions { + warnings: Some(warnings.clone()), + ..config.clone() + }, + ) { + Ok(mut ss) => { + if matches!(ty, CssModuleAssetType::Module) { + let mut validator = CssValidator { errors: Vec::new() }; + ss.visit(&mut validator).unwrap(); + + for err in validator.errors { + err.report(source, fs_path_vc); + } + } + + for err in warnings.read().unwrap().iter() { + match err.kind { + lightningcss::error::ParserError::UnexpectedToken(_) + | lightningcss::error::ParserError::UnexpectedImportRule + | lightningcss::error::ParserError::EndOfInput => { + let source = err.loc.as_ref().map(|loc| { + let pos = SourcePos { + line: loc.line as _, + column: loc.column as _, + }; + IssueSource::from_line_col(source, pos, pos) + }); + + ParsingIssue { + file: fs_path_vc, + msg: Vc::cell(err.to_string().into()), + source: Vc::cell(source), + } + .cell() + .emit(); + return Ok(ParseCssResult::Unparseable.cell()); + } + + _ => { + // Ignore + } + } + } + + stylesheet_into_static(&ss, without_warnings(config.clone())) + } + Err(e) => { + let source = e.loc.as_ref().map(|loc| { + let pos = SourcePos { + line: loc.line as _, + column: loc.column as _, + }; + IssueSource::from_line_col(source, pos, pos) + }); + + ParsingIssue { + file: fs_path_vc, + msg: Vc::cell(e.to_string().into()), + source: Vc::cell(source), + } + .cell() + .emit(); + return Ok(ParseCssResult::Unparseable.cell()); + } + } + }) + } else { + let fs_path = &*fs_path_vc.await?; + + let handler = swc_core::common::errors::Handler::with_emitter( + true, + false, + Box::new(IssueEmitter::new( + source, + cm.clone(), + Some("Parsing css source code failed".into()), + )), + ); + + let fm = cm.new_source_file(FileName::Custom(filename.to_string()), code.clone()); + let mut errors = vec![]; + + let ss = swc_core::css::parser::parse_file( + &fm, + Default::default(), + swc_core::css::parser::parser::ParserConfig { + css_modules: true, + legacy_ie: true, + legacy_nesting: true, + ..Default::default() + }, + &mut errors, + ); + + for err in errors { + err.to_diagnostics(&handler).emit(); + } + + let ss: swc_core::css::ast::Stylesheet = match ss { + Ok(v) => v, + Err(err) => { + err.to_diagnostics(&handler).emit(); + return Ok(ParseCssResult::Unparseable.cell()); + } + }; + + if handler.has_errors() { + return Ok(ParseCssResult::Unparseable.cell()); + } + + if matches!(ty, CssModuleAssetType::Module) { + let mut validator = CssValidator { errors: vec![] }; + ss.visit_with(&mut validator); + + for err in validator.errors { + err.report(source, fs_path_vc); + } + } + + StyleSheetLike::Swc { + stylesheet: ss, + css_modules: if matches!(ty, CssModuleAssetType::Module) { + let basename = BASENAME_RE + .captures(fs_path.file_name()) + .context("Must include basename preceding .")? + .get(0) + .context("Must include basename preceding .")? + .as_str(); + // Truncate this as u32 so it's formated as 8-character hex in the suffic below + let path_hash = turbo_tasks_hash::hash_xxh3_hash64(filename) as u32; + + Some(SwcCssModuleMode { + basename: basename.to_string(), + path_hash, + }) + } else { + None + }, + } + }; + + let config = without_warnings(config); + let mut stylesheet = stylesheet.to_static(config.clone()); + + let (references, url_references) = + analyze_references(&mut stylesheet, source, origin, import_context)?; + + Ok(ParseCssResult::Ok { + cm, + code: content_vc, + stylesheet, + references: Vc::cell(references), + url_references: Vc::cell(url_references), + options: config, + } + .cell()) +} + +/// Visitor that lints wrong css module usage. +/// +/// ```css +/// button { +/// } +/// ``` +/// +/// is wrong for a css module because it doesn't have a class name. +struct CssValidator { + errors: Vec, +} + +#[derive(Debug, PartialEq, Eq)] +enum CssError { + SwcSelectorInModuleNotPure { span: Span }, + LightningCssSelectorInModuleNotPure { selector: String }, +} + +impl CssError { + fn report(self, source: Vc>, file: Vc) { + match self { + CssError::SwcSelectorInModuleNotPure { span } => { + ParsingIssue { + file, + msg: Vc::cell(CSS_MODULE_ERROR.into()), + source: Vc::cell(Some(IssueSource::from_swc_offsets( + source, + span.lo.0 as _, + span.hi.0 as _, + ))), + } + .cell() + .emit(); + } + CssError::LightningCssSelectorInModuleNotPure { selector } => { + ParsingIssue { + file, + msg: Vc::cell(format!("{CSS_MODULE_ERROR}, (lightningcss, {selector})").into()), + source: Vc::cell(None), + } + .cell() + .emit(); + } + } + } +} + +const CSS_MODULE_ERROR: &str = + "Selector is not pure (pure selectors must contain at least one local class or id)"; + +/// We only vist top-level selectors. +impl swc_core::css::visit::Visit for CssValidator { + fn visit_complex_selector(&mut self, n: &ComplexSelector) { + fn is_complex_not_pure(sel: &ComplexSelector) -> bool { + sel.children.iter().all(|sel| match sel { + ComplexSelectorChildren::CompoundSelector(sel) => is_compound_not_pure(sel), + ComplexSelectorChildren::Combinator(_) => true, + }) + } + + fn is_forgiving_selector_not_pure(sel: &ForgivingComplexSelector) -> bool { + match sel { + ForgivingComplexSelector::ComplexSelector(sel) => is_complex_not_pure(sel), + ForgivingComplexSelector::ListOfComponentValues(_) => false, + } + } + + fn is_forgiving_relative_selector_not_pure(sel: &ForgivingRelativeSelector) -> bool { + match sel { + ForgivingRelativeSelector::RelativeSelector(sel) => { + is_relative_selector_not_pure(sel) + } + ForgivingRelativeSelector::ListOfComponentValues(_) => false, + } + } + + fn is_relative_selector_not_pure(sel: &RelativeSelector) -> bool { + is_complex_not_pure(&sel.selector) + } + + fn is_compound_not_pure(sel: &CompoundSelector) -> bool { + sel.subclass_selectors.iter().all(|sel| match sel { + SubclassSelector::Attribute { .. } => true, + SubclassSelector::PseudoClass(cls) => { + cls.name.value == "not" + || cls.name.value == "has" + || if let Some(c) = &cls.children { + c.iter().all(|c| match c { + PseudoClassSelectorChildren::ComplexSelector(sel) => { + is_complex_not_pure(sel) + } + + PseudoClassSelectorChildren::CompoundSelector(sel) => { + is_compound_not_pure(sel) + } + + PseudoClassSelectorChildren::SelectorList(sels) => { + sels.children.iter().all(is_complex_not_pure) + } + PseudoClassSelectorChildren::ForgivingSelectorList(sels) => { + sels.children.iter().all(is_forgiving_selector_not_pure) + } + PseudoClassSelectorChildren::CompoundSelectorList(sels) => { + sels.children.iter().all(is_compound_not_pure) + } + PseudoClassSelectorChildren::RelativeSelectorList(sels) => { + sels.children.iter().all(is_relative_selector_not_pure) + } + PseudoClassSelectorChildren::ForgivingRelativeSelectorList( + sels, + ) => sels + .children + .iter() + .all(is_forgiving_relative_selector_not_pure), + + PseudoClassSelectorChildren::Ident(_) + | PseudoClassSelectorChildren::Str(_) + | PseudoClassSelectorChildren::Delimiter(_) + | PseudoClassSelectorChildren::PreservedToken(_) + | PseudoClassSelectorChildren::AnPlusB(_) => false, + }) + } else { + true + } + } + SubclassSelector::PseudoElement(el) => match &el.children { + Some(c) => c.iter().all(|c| match c { + PseudoElementSelectorChildren::CompoundSelector(sel) => { + is_compound_not_pure(sel) + } + + _ => false, + }), + None => true, + }, + _ => false, + }) && match &sel.type_selector.as_deref() { + Some(TypeSelector::TagName(tag)) => { + !matches!(&*tag.name.value.value, "html" | "body") + } + Some(TypeSelector::Universal(..)) => true, + None => true, + } + } + + if is_complex_not_pure(n) { + self.errors + .push(CssError::SwcSelectorInModuleNotPure { span: n.span }); + } + } + + fn visit_simple_block(&mut self, _: &swc_core::css::ast::SimpleBlock) {} +} + +/// We only vist top-level selectors. +impl lightningcss::visitor::Visitor<'_> for CssValidator { + type Error = (); + + fn visit_types(&self) -> lightningcss::visitor::VisitTypes { + visit_types!(SELECTORS) + } + + fn visit_selector( + &mut self, + selector: &mut lightningcss::selector::Selector<'_>, + ) -> Result<(), Self::Error> { + fn is_selector_problematic(sel: &lightningcss::selector::Selector) -> bool { + sel.iter_raw_parse_order_from(0).all(is_problematic) + } + + fn is_problematic(c: &lightningcss::selector::Component) -> bool { + match c { + parcel_selectors::parser::Component::ID(..) + | parcel_selectors::parser::Component::Class(..) => false, + + parcel_selectors::parser::Component::Combinator(..) + | parcel_selectors::parser::Component::AttributeOther(..) + | parcel_selectors::parser::Component::AttributeInNoNamespaceExists { .. } + | parcel_selectors::parser::Component::AttributeInNoNamespace { .. } + | parcel_selectors::parser::Component::ExplicitUniversalType + | parcel_selectors::parser::Component::Negation(..) => true, + + parcel_selectors::parser::Component::Where(sel) => { + sel.iter().all(is_selector_problematic) + } + + parcel_selectors::parser::Component::LocalName(local) => { + // Allow html and body. They are not pure selectors but are allowed. + !matches!(&*local.name.0, "html" | "body") + } + _ => false, + } + } + + if is_selector_problematic(selector) { + self.errors + .push(CssError::LightningCssSelectorInModuleNotPure { + selector: format!("{selector:?}"), + }); + } + + Ok(()) + } +} + +#[turbo_tasks::value(shared, serialization = "none", eq = "manual")] +pub enum ParseCssResultSourceMap { + Parcel { + #[turbo_tasks(debug_ignore, trace_ignore)] + source_map: parcel_sourcemap::SourceMap, + }, + + Swc { + #[turbo_tasks(debug_ignore, trace_ignore)] + source_map: Arc, + + /// The position mappings that can generate a real source map given a + /// (SWC) SourceMap. + #[turbo_tasks(debug_ignore, trace_ignore)] + mappings: Vec<(BytePos, LineCol)>, + }, +} + +impl PartialEq for ParseCssResultSourceMap { + fn eq(&self, _: &Self) -> bool { + false + } +} + +impl ParseCssResultSourceMap { + pub fn new_lightningcss(source_map: parcel_sourcemap::SourceMap) -> Self { + ParseCssResultSourceMap::Parcel { source_map } + } + + pub fn new_swc( + source_map: Arc, + mappings: Vec<(BytePos, LineCol)>, + ) -> Self { + ParseCssResultSourceMap::Swc { + source_map, + mappings, + } + } +} + +#[turbo_tasks::value_impl] +impl GenerateSourceMap for ParseCssResultSourceMap { + #[turbo_tasks::function] + fn generate_source_map(&self) -> Vc { + match self { + ParseCssResultSourceMap::Parcel { source_map } => { + let mut builder = SourceMapBuilder::new(None); + + for src in source_map.get_sources() { + builder.add_source(&format!("{SOURCE_MAP_PREFIX}{src}")); + } + + for (idx, content) in source_map.get_sources_content().iter().enumerate() { + builder.set_source_contents(idx as _, Some(content)); + } + + for m in source_map.get_mappings() { + builder.add_raw( + m.generated_line, + m.generated_column, + m.original.map(|v| v.original_line).unwrap_or_default(), + m.original.map(|v| v.original_column).unwrap_or_default(), + Some(0), + None, + false, + ); + } + + Vc::cell(Some( + turbopack_core::source_map::SourceMap::new_regular(builder.into_sourcemap()) + .cell(), + )) + } + ParseCssResultSourceMap::Swc { + source_map, + mappings, + } => { + let map = source_map.build_source_map_with_config( + mappings, + None, + InlineSourcesContentConfig {}, + ); + Vc::cell(Some( + turbopack_core::source_map::SourceMap::new_regular(map).cell(), + )) + } + } + } +} + +struct SwcDepColllector<'a> { + deps: &'a mut Vec, + remove_imports: bool, +} + +impl VisitMut for SwcDepColllector<'_> { + fn visit_mut_rules(&mut self, n: &mut Vec) { + n.visit_mut_children_with(self); + + if self.remove_imports { + n.retain(|v| match v { + swc_core::css::ast::Rule::AtRule(v) => match &v.name { + swc_core::css::ast::AtRuleName::DashedIdent(_) => true, + swc_core::css::ast::AtRuleName::Ident(name) => name.value != "import", + }, + _ => true, + }); + } + } + + fn visit_mut_at_rule_prelude(&mut self, node: &mut swc_core::css::ast::AtRulePrelude) { + match node { + swc_core::css::ast::AtRulePrelude::ImportPrelude(i) => { + let src = match &*i.href { + swc_core::css::ast::ImportHref::Url(v) => match v.value.as_deref().unwrap() { + UrlValue::Str(v) => v.value.clone(), + UrlValue::Raw(v) => v.value.clone(), + }, + swc_core::css::ast::ImportHref::Str(v) => v.value.clone(), + }; + + self.deps.push(Dependency::Import(ImportDependency { + url: src.to_string(), + placeholder: Default::default(), + supports: None, + media: None, + loc: SourceRange { + file_path: String::new(), + start: Location { line: 0, column: 0 }, + end: Location { line: 0, column: 0 }, + }, + })); + } + + _ => { + node.visit_mut_children_with(self); + } + } + } +} + +struct ModuleTransformConfig { + suffix: String, +} + +impl TransformConfig for ModuleTransformConfig { + fn new_name_for(&self, local: &Atom) -> Atom { + format!("{}{}", *local, self.suffix).into() + } +} + +#[turbo_tasks::value] +struct ParsingIssue { + msg: Vc, + file: Vc, + source: Vc, +} + +#[turbo_tasks::value_impl] +impl Issue for ParsingIssue { + #[turbo_tasks::function] + fn file_path(&self) -> Vc { + self.file + } + + #[turbo_tasks::function] + fn stage(&self) -> Vc { + IssueStage::Parse.cell() + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + StyledString::Text("Parsing css source code failed".into()).cell() + } + + #[turbo_tasks::function] + fn source(&self) -> Vc { + self.source + } + + #[turbo_tasks::function] + async fn description(&self) -> Result> { + Ok(Vc::cell(Some( + StyledString::Text(self.msg.await?.as_str().into()).cell(), + ))) + } +} + +#[cfg(test)] +mod tests { + use lightningcss::{ + css_modules::Pattern, + stylesheet::{ParserOptions, StyleSheet}, + visitor::Visit, + }; + use swc_core::{ + common::{FileName, FilePathMapping}, + css::{ast::Stylesheet, parser::parser::ParserConfig, visit::VisitWith}, + }; + + use super::{CssError, CssValidator}; + + fn lint_lightningcss(code: &str) -> Vec { + let mut ss = StyleSheet::parse( + code, + ParserOptions { + css_modules: Some(lightningcss::css_modules::Config { + pattern: Pattern::default(), + dashed_idents: false, + grid: false, + ..Default::default() + }), + ..Default::default() + }, + ) + .unwrap(); + + let mut validator = CssValidator { errors: Vec::new() }; + ss.visit(&mut validator).unwrap(); + + validator.errors + } + + fn lint_swc(code: &str) -> Vec { + let cm = swc_core::common::SourceMap::new(FilePathMapping::empty()); + + let fm = cm.new_source_file(FileName::Custom("test.css".to_string()), code.to_string()); + + let ss: Stylesheet = swc_core::css::parser::parse_file( + &fm, + None, + ParserConfig { + css_modules: true, + ..Default::default() + }, + &mut vec![], + ) + .unwrap(); + + let mut validator = CssValidator { errors: Vec::new() }; + ss.visit_with(&mut validator); + + validator.errors + } + + #[track_caller] + fn assert_lint_success(code: &str) { + assert_eq!(lint_lightningcss(code), vec![], "lightningcss: {code}"); + assert_eq!(lint_swc(code), vec![], "swc: {code}"); + } + + #[track_caller] + fn assert_lint_failure(code: &str) { + assert_ne!(lint_lightningcss(code), vec![], "lightningcss: {code}"); + assert_ne!(lint_swc(code), vec![], "swc: {code}"); + } + + #[test] + fn css_module_pure_lint() { + assert_lint_success( + "html { + --foo: 1; + }", + ); + + assert_lint_success( + "#id { + color: red; + }", + ); + + assert_lint_success( + ".class { + color: red; + }", + ); + + assert_lint_success( + "html.class { + color: red; + }", + ); + + assert_lint_success( + ".class > * { + color: red; + }", + ); + + assert_lint_success( + ".class * { + color: red; + }", + ); + + assert_lint_success( + ":where(.main > *) { + color: red; + }", + ); + + assert_lint_success( + ":where(.main > *, .root > *) { + color: red; + }", + ); + + assert_lint_failure( + "div { + color: red; + }", + ); + + assert_lint_failure( + "div > span { + color: red; + }", + ); + + assert_lint_failure( + "div span { + color: red; + }", + ); + + assert_lint_failure( + "div[data-foo] { + color: red; + }", + ); + + assert_lint_failure( + "div[data-foo=\"bar\"] { + color: red; + }", + ); + + assert_lint_failure( + "div[data-foo=\"bar\"] span { + color: red; + }", + ); + + assert_lint_failure( + "* { + --foo: 1; + }", + ); + + assert_lint_failure( + "[data-foo] { + --foo: 1; + }", + ); + + assert_lint_failure( + ":not(.class) { + --foo: 1; + }", + ); + + assert_lint_failure( + ":not(div) { + --foo: 1; + }", + ); + + assert_lint_failure( + ":where(div > *) { + color: red; + }", + ); + + assert_lint_failure( + ":where(div) { + color: red; + }", + ); + } +} diff --git a/turbopack/crates/turbopack-css/src/references/compose.rs b/turbopack/crates/turbopack-css/src/references/compose.rs new file mode 100644 index 0000000000000..d605d1599cef0 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/references/compose.rs @@ -0,0 +1,56 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + chunk::ChunkableModuleReference, + reference::ModuleReference, + reference_type::CssReferenceSubType, + resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, +}; + +use crate::references::css_resolve; + +/// A `composes: ... from ...` CSS module reference. +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct CssModuleComposeReference { + pub origin: Vc>, + pub request: Vc, +} + +#[turbo_tasks::value_impl] +impl CssModuleComposeReference { + /// Creates a new [`CssModuleComposeReference`]. + #[turbo_tasks::function] + pub fn new(origin: Vc>, request: Vc) -> Vc { + Self::cell(CssModuleComposeReference { origin, request }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for CssModuleComposeReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + css_resolve( + self.origin, + self.request, + Value::new(CssReferenceSubType::Compose), + // TODO: add real issue source, currently impossible because `CssClassName` doesn't + // contain the source span + // https://docs.rs/swc_css_modules/0.21.16/swc_css_modules/enum.CssClassName.html + None, + ) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for CssModuleComposeReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("compose(url) {}", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for CssModuleComposeReference {} diff --git a/turbopack/crates/turbopack-css/src/references/import.rs b/turbopack/crates/turbopack-css/src/references/import.rs new file mode 100644 index 0000000000000..8154a145af8a8 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/references/import.rs @@ -0,0 +1,281 @@ +use anyhow::Result; +use lightningcss::{ + media_query::MediaList, + rules::{import::ImportRule, layer::LayerName, supports::SupportsCondition}, + traits::ToCss, +}; +use swc_core::{ + common::{Spanned, DUMMY_SP}, + css::codegen::{ + writer::basic::{BasicCssWriter, BasicCssWriterConfig}, + CodeGenerator, CodegenConfig, Emit, + }, +}; +use turbo_tasks::{RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ChunkableModuleReference, ChunkingContext}, + issue::IssueSource, + reference::ModuleReference, + reference_type::{CssReferenceSubType, ImportContext}, + resolve::{origin::ResolveOrigin, parse::Request, ModuleResolveResult}, +}; + +use crate::{ + chunk::CssImport, + code_gen::{CodeGenerateable, CodeGeneration}, + references::css_resolve, +}; + +#[turbo_tasks::value(into = "new", eq = "manual", serialization = "none")] +pub enum ImportAttributes { + LightningCss { + #[turbo_tasks(trace_ignore)] + layer_name: Option>, + #[turbo_tasks(trace_ignore)] + supports: Option>, + #[turbo_tasks(trace_ignore)] + media: MediaList<'static>, + }, + Swc { + #[turbo_tasks(trace_ignore)] + layer_name: Option, + #[turbo_tasks(trace_ignore)] + supports: Option, + #[turbo_tasks(trace_ignore)] + media: Option>, + }, +} + +impl PartialEq for ImportAttributes { + fn eq(&self, _: &Self) -> bool { + false + } +} + +impl ImportAttributes { + pub fn new_from_lightningcss(prelude: &ImportRule<'static>) -> Self { + let layer_name = prelude.layer.clone().flatten(); + + let supports = prelude.supports.clone(); + + let media = prelude.media.clone(); + + Self::LightningCss { + layer_name, + supports, + media, + } + } + + pub fn new_from_swc(prelude: &swc_core::css::ast::ImportPrelude) -> Self { + let layer_name = prelude.layer_name.as_ref().map(|l| match l { + box swc_core::css::ast::ImportLayerName::Ident(_) => swc_core::css::ast::LayerName { + span: DUMMY_SP, + name: vec![], + }, + box swc_core::css::ast::ImportLayerName::Function(f) => { + assert_eq!(f.value.len(), 1); + assert!(matches!( + &f.value[0], + swc_core::css::ast::ComponentValue::LayerName(_) + )); + if let swc_core::css::ast::ComponentValue::LayerName(layer_name) = &f.value[0] { + *layer_name.clone() + } else { + unreachable!() + } + } + }); + + let (supports, media) = prelude + .import_conditions + .as_ref() + .map(|c| { + let supports = if let Some(supports) = &c.supports { + let v = supports.value.iter().find(|v| { + matches!( + v, + swc_core::css::ast::ComponentValue::SupportsCondition(..) + | swc_core::css::ast::ComponentValue::Declaration(..) + ) + }); + + if let Some(supports) = v { + match &supports { + swc_core::css::ast::ComponentValue::SupportsCondition(s) => { + Some(*s.clone()) + } + swc_core::css::ast::ComponentValue::Declaration(d) => { + Some(swc_core::css::ast::SupportsCondition { + span: DUMMY_SP, + conditions: vec![ + swc_core::css::ast::SupportsConditionType::SupportsInParens( + swc_core::css::ast::SupportsInParens::Feature( + swc_core::css::ast::SupportsFeature::Declaration( + d.clone(), + ), + ), + ), + ], + }) + } + _ => None, + } + } else { + None + } + } else { + None + }; + + let media = c.media.as_ref().map(|m| m.queries.clone()); + + (supports, media) + }) + .unwrap_or_else(|| (None, None)); + + Self::Swc { + layer_name, + supports, + media, + } + } + + fn as_reference_import_attributes(&self) -> turbopack_core::reference_type::ImportAttributes { + match self { + ImportAttributes::LightningCss { + layer_name, + supports, + media, + } => turbopack_core::reference_type::ImportAttributes { + layer: layer_name + .as_ref() + .map(|l| l.to_css_string(Default::default()).unwrap()) + .map(From::from), + supports: supports + .as_ref() + .map(|s| s.to_css_string(Default::default()).unwrap()) + .map(From::from), + media: { + if media.always_matches() { + None + } else { + Some(media.to_css_string(Default::default()).unwrap().into()) + } + }, + }, + ImportAttributes::Swc { + layer_name, + supports, + media, + } => turbopack_core::reference_type::ImportAttributes { + layer: layer_name.as_ref().map(gen_swc_node).map(From::from), + supports: supports.as_ref().map(gen_swc_node).map(From::from), + media: media + .as_ref() + .map(|queries| queries.iter().map(gen_swc_node).collect::().into()), + }, + } + } +} + +fn gen_swc_node(node: N) -> String +where + N: Spanned, + for<'a> CodeGenerator>: Emit, +{ + let mut code = String::new(); + { + let wr = BasicCssWriter::new(&mut code, None, BasicCssWriterConfig::default()); + let mut gen = CodeGenerator::new(wr, CodegenConfig { minify: true }); + + gen.emit(&node).unwrap(); + } + code +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct ImportAssetReference { + pub origin: Vc>, + pub request: Vc, + pub attributes: Vc, + pub import_context: Vc, + pub issue_source: Vc, +} + +#[turbo_tasks::value_impl] +impl ImportAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + attributes: Vc, + import_context: Vc, + issue_source: Vc, + ) -> Vc { + Self::cell(ImportAssetReference { + origin, + request, + attributes, + import_context, + issue_source, + }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for ImportAssetReference { + #[turbo_tasks::function] + async fn resolve_reference(&self) -> Result> { + let import_context = { + let own_attrs = (*self.attributes.await?).as_reference_import_attributes(); + self.import_context + .add_attributes(own_attrs.layer, own_attrs.media, own_attrs.supports) + }; + + Ok(css_resolve( + self.origin, + self.request, + Value::new(CssReferenceSubType::AtImport(Some(import_context))), + Some(self.issue_source), + )) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for ImportAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("import(url) {}", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl CodeGenerateable for ImportAssetReference { + #[turbo_tasks::function] + async fn code_generation( + self: Vc, + _context: Vc>, + ) -> Result> { + let this = &*self.await?; + let mut imports = vec![]; + if let Request::Uri { + protocol, + remainder, + .. + } = &*this.request.await? + { + imports.push(CssImport::External(Vc::cell( + format!("{}{}", protocol, remainder).into(), + ))) + } + + Ok(CodeGeneration { imports }.into()) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for ImportAssetReference {} diff --git a/turbopack/crates/turbopack-css/src/references/internal.rs b/turbopack/crates/turbopack-css/src/references/internal.rs new file mode 100644 index 0000000000000..cdba0d33a5067 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/references/internal.rs @@ -0,0 +1,43 @@ +use anyhow::Result; +use turbo_tasks::{RcStr, ValueToString, Vc}; +use turbopack_core::{ + chunk::ChunkableModuleReference, module::Module, reference::ModuleReference, + resolve::ModuleResolveResult, +}; + +/// A reference to an internal CSS asset. +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct InternalCssAssetReference { + module: Vc>, +} + +#[turbo_tasks::value_impl] +impl InternalCssAssetReference { + /// Creates a new [`Vc`]. + #[turbo_tasks::function] + pub fn new(module: Vc>) -> Vc { + Self::cell(InternalCssAssetReference { module }) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for InternalCssAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + ModuleResolveResult::module(self.module).cell() + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for InternalCssAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("internal css {}", self.module.ident().to_string().await?).into(), + )) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for InternalCssAssetReference {} diff --git a/turbopack/crates/turbopack-css/src/references/mod.rs b/turbopack/crates/turbopack-css/src/references/mod.rs new file mode 100644 index 0000000000000..159dce8a4a487 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/references/mod.rs @@ -0,0 +1,255 @@ +use std::convert::Infallible; + +use anyhow::Result; +use lightningcss::{ + rules::CssRule, + traits::IntoOwned, + values::url::Url, + visitor::{Visit, Visitor}, +}; +use swc_core::css::{ + ast::UrlValue, + visit::{VisitMut, VisitMutWith}, +}; +use turbo_tasks::{RcStr, Value, Vc}; +use turbopack_core::{ + issue::{IssueSeverity, IssueSource}, + reference::ModuleReference, + reference_type::{CssReferenceSubType, ImportContext, ReferenceType}, + resolve::{origin::ResolveOrigin, parse::Request, url_resolve, ModuleResolveResult}, + source::Source, + source_pos::SourcePos, +}; + +use crate::{ + references::{ + import::{ImportAssetReference, ImportAttributes}, + url::UrlAssetReference, + }, + StyleSheetLike, +}; + +pub(crate) mod compose; +pub(crate) mod import; +pub(crate) mod internal; +pub(crate) mod url; + +pub type AnalyzedRefs = ( + Vec>>, + Vec<(String, Vc)>, +); + +/// Returns `(all_references, urls)`. +pub fn analyze_references( + stylesheet: &mut StyleSheetLike<'static, 'static>, + source: Vc>, + origin: Vc>, + import_context: Vc, +) -> Result { + let mut references = Vec::new(); + let mut urls = Vec::new(); + + let mut visitor = + ModuleReferencesVisitor::new(source, origin, import_context, &mut references, &mut urls); + match stylesheet { + StyleSheetLike::LightningCss(ss) => { + ss.visit(&mut visitor).unwrap(); + } + StyleSheetLike::Swc { stylesheet, .. } => { + stylesheet.visit_mut_with(&mut visitor); + } + } + + Ok((references, urls)) +} + +struct ModuleReferencesVisitor<'a> { + source: Vc>, + origin: Vc>, + import_context: Vc, + references: &'a mut Vec>>, + urls: &'a mut Vec<(String, Vc)>, +} + +impl<'a> ModuleReferencesVisitor<'a> { + fn new( + source: Vc>, + origin: Vc>, + import_context: Vc, + references: &'a mut Vec>>, + urls: &'a mut Vec<(String, Vc)>, + ) -> Self { + Self { + source, + origin, + import_context, + references, + urls, + } + } +} + +impl VisitMut for ModuleReferencesVisitor<'_> { + fn visit_mut_import_prelude(&mut self, i: &mut swc_core::css::ast::ImportPrelude) { + let src = match &*i.href { + swc_core::css::ast::ImportHref::Url(v) => match v.value.as_deref().unwrap() { + UrlValue::Str(v) => v.value.clone(), + UrlValue::Raw(v) => v.value.clone(), + }, + swc_core::css::ast::ImportHref::Str(v) => v.value.clone(), + }; + + let issue_span = i.span; + + self.references.push(Vc::upcast(ImportAssetReference::new( + self.origin, + Request::parse(Value::new(RcStr::from(src.as_str()).into())), + ImportAttributes::new_from_swc(&i.clone()).into(), + self.import_context, + IssueSource::from_swc_offsets( + Vc::upcast(self.source), + issue_span.lo.0 as _, + issue_span.hi.0 as _, + ), + ))); + + // let res = i.visit_children(self); + // res + } + + /// Noop. Urls in `@supports` are not used. + /// + /// See https://github.com/vercel/next.js/issues/63102 + fn visit_mut_supports_condition(&mut self, _: &mut swc_core::css::ast::SupportsCondition) {} + + fn visit_mut_url(&mut self, u: &mut swc_core::css::ast::Url) { + u.visit_mut_children_with(self); + + let src = match u.value.as_deref().unwrap() { + UrlValue::Str(v) => v.value.clone(), + UrlValue::Raw(v) => v.value.clone(), + }; + + // ignore internal urls like `url(#noiseFilter)` + // ignore server-relative urls like `url(/foo)` + if !matches!(src.bytes().next(), Some(b'#') | Some(b'/')) { + let issue_span = u.span; + + let vc = UrlAssetReference::new( + self.origin, + Request::parse(Value::new(RcStr::from(src.as_str()).into())), + IssueSource::from_swc_offsets( + Vc::upcast(self.source), + issue_span.lo.0 as _, + issue_span.hi.0 as _, + ), + ); + + self.references.push(Vc::upcast(vc)); + self.urls.push((src.to_string(), vc)); + } + } +} + +impl<'a> Visitor<'_> for ModuleReferencesVisitor<'a> { + type Error = Infallible; + + fn visit_types(&self) -> lightningcss::visitor::VisitTypes { + lightningcss::visitor::VisitTypes::all() + } + + fn visit_rule(&mut self, rule: &mut CssRule) -> std::result::Result<(), Self::Error> { + match rule { + CssRule::Import(i) => { + let src = &*i.url; + + let issue_span = i.loc; + + self.references.push(Vc::upcast(ImportAssetReference::new( + self.origin, + Request::parse(Value::new(RcStr::from(src).into())), + ImportAttributes::new_from_lightningcss(&i.clone().into_owned()).into(), + self.import_context, + IssueSource::from_line_col( + Vc::upcast(self.source), + SourcePos { + line: issue_span.line as _, + column: issue_span.column as _, + }, + SourcePos { + line: issue_span.line as _, + column: issue_span.column as _, + }, + ), + ))); + + *rule = CssRule::Ignored; + + // let res = i.visit_children(self); + // res + Ok(()) + } + + _ => rule.visit_children(self), + } + } + + fn visit_url(&mut self, u: &mut Url) -> std::result::Result<(), Self::Error> { + let src = &*u.url; + + // ignore internal urls like `url(#noiseFilter)` + // ignore server-relative urls like `url(/foo)` + if !matches!(src.bytes().next(), Some(b'#') | Some(b'/')) { + let issue_span = u.loc; + + let vc = UrlAssetReference::new( + self.origin, + Request::parse(Value::new(RcStr::from(src).into())), + IssueSource::from_line_col( + Vc::upcast(self.source), + SourcePos { + line: issue_span.line as _, + column: issue_span.column as _, + }, + SourcePos { + line: issue_span.line as _, + column: issue_span.column as _, + }, + ), + ); + + self.references.push(Vc::upcast(vc)); + self.urls.push((u.url.to_string(), vc)); + } + + // u.visit_children(self)?; + + Ok(()) + } + + /// Noop. Urls in `@supports` are not used. + /// + /// See https://github.com/vercel/next.js/issues/63102 + fn visit_supports_condition( + &mut self, + _: &mut lightningcss::rules::supports::SupportsCondition<'_>, + ) -> Result<(), Self::Error> { + Ok(()) + } +} + +#[turbo_tasks::function] +pub async fn css_resolve( + origin: Vc>, + request: Vc, + ty: Value, + issue_source: Option>, +) -> Vc { + url_resolve( + origin, + request, + Value::new(ReferenceType::Css(ty.into_value())), + issue_source, + IssueSeverity::Error.cell(), + ) +} diff --git a/turbopack/crates/turbopack-css/src/references/url.rs b/turbopack/crates/turbopack-css/src/references/url.rs new file mode 100644 index 0000000000000..e59e92cb66163 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/references/url.rs @@ -0,0 +1,201 @@ +use std::{collections::HashMap, convert::Infallible}; + +use anyhow::{bail, Result}; +use lightningcss::{ + values::url::Url, + visit_types, + visitor::{Visit, Visitor}, +}; +use swc_core::css::{ + ast::UrlValue, + visit::{VisitMut, VisitMutWith}, +}; +use turbo_tasks::{debug::ValueDebug, RcStr, Value, ValueToString, Vc}; +use turbopack_core::{ + chunk::{ + ChunkableModule, ChunkableModuleReference, ChunkingContext, ChunkingType, + ChunkingTypeOption, + }, + ident::AssetIdent, + issue::{IssueSeverity, IssueSource}, + output::OutputAsset, + reference::ModuleReference, + reference_type::{ReferenceType, UrlReferenceSubType}, + resolve::{origin::ResolveOrigin, parse::Request, url_resolve, ModuleResolveResult}, +}; + +use crate::{embed::CssEmbed, StyleSheetLike}; + +#[turbo_tasks::value(into = "new")] +pub enum ReferencedAsset { + Some(Vc>), + None, +} + +#[turbo_tasks::value] +#[derive(Hash, Debug)] +pub struct UrlAssetReference { + pub origin: Vc>, + pub request: Vc, + pub issue_source: Vc, +} + +#[turbo_tasks::value_impl] +impl UrlAssetReference { + #[turbo_tasks::function] + pub fn new( + origin: Vc>, + request: Vc, + issue_source: Vc, + ) -> Vc { + Self::cell(UrlAssetReference { + origin, + request, + issue_source, + }) + } + + #[turbo_tasks::function] + async fn get_referenced_asset( + self: Vc, + chunking_context: Vc>, + ) -> Result> { + if let Some(module) = *self.resolve_reference().first_module().await? { + if let Some(chunkable) = + Vc::try_resolve_downcast::>(module).await? + { + let chunk_item = chunkable.as_chunk_item(chunking_context); + if let Some(embeddable) = + Vc::try_resolve_downcast::>(chunk_item).await? + { + return Ok(ReferencedAsset::Some(embeddable.embedded_asset()).into()); + } + } + bail!( + "A module referenced by a url() reference must be chunkable and the chunk item \ + must be css embeddable\nreferenced module: {:?}", + module.dbg_depth(1).await? + ) + } + Ok(ReferencedAsset::cell(ReferencedAsset::None)) + } +} + +#[turbo_tasks::value_impl] +impl ModuleReference for UrlAssetReference { + #[turbo_tasks::function] + fn resolve_reference(&self) -> Vc { + url_resolve( + self.origin, + self.request, + Value::new(ReferenceType::Url(UrlReferenceSubType::CssUrl)), + Some(self.issue_source), + IssueSeverity::Error.cell(), + ) + } +} + +#[turbo_tasks::value_impl] +impl ChunkableModuleReference for UrlAssetReference { + #[turbo_tasks::function] + fn chunking_type(self: Vc) -> Vc { + // Since this chunk item is embedded, we don't want to put it in the chunk group + Vc::cell(Some(ChunkingType::Passthrough)) + } +} + +#[turbo_tasks::value_impl] +impl ValueToString for UrlAssetReference { + #[turbo_tasks::function] + async fn to_string(&self) -> Result> { + Ok(Vc::cell( + format!("url {}", self.request.to_string().await?,).into(), + )) + } +} + +#[turbo_tasks::function] +pub async fn resolve_url_reference( + url: Vc, + chunking_context: Vc>, +) -> Result>> { + let this = url.await?; + // TODO(WEB-662) This is not the correct way to get the current chunk path. It + // currently works as all chunks are in the same directory. + let chunk_path = chunking_context.chunk_path( + AssetIdent::from_path(this.origin.origin_path()), + ".css".into(), + ); + let context_path = chunk_path.parent().await?; + + if let ReferencedAsset::Some(asset) = &*url.get_referenced_asset(chunking_context).await? { + // TODO(WEB-662) This is not the correct way to get the path of the asset. + // `asset` is on module-level, but we need the output-level asset instead. + let path = asset.ident().path().await?; + let relative_path = context_path + .get_relative_path_to(&path) + .unwrap_or_else(|| format!("/{}", path.path).into()); + + return Ok(Vc::cell(Some(relative_path))); + } + + Ok(Vc::cell(None)) +} + +pub fn replace_url_references( + ss: &mut StyleSheetLike<'static, 'static>, + urls: &HashMap, +) { + let mut replacer = AssetReferenceReplacer { urls }; + match ss { + StyleSheetLike::LightningCss(ss) => { + ss.visit(&mut replacer).unwrap(); + } + StyleSheetLike::Swc { stylesheet, .. } => { + stylesheet.visit_mut_with(&mut replacer); + } + } +} + +struct AssetReferenceReplacer<'a> { + urls: &'a HashMap, +} + +impl VisitMut for AssetReferenceReplacer<'_> { + fn visit_mut_url_value(&mut self, u: &mut UrlValue) { + u.visit_mut_children_with(self); + + match u { + UrlValue::Str(v) => { + if let Some(new) = self.urls.get(&*v.value) { + v.value = (&**new).into(); + v.raw = None; + } + } + UrlValue::Raw(v) => { + if let Some(new) = self.urls.get(&*v.value) { + v.value = (&**new).into(); + v.raw = None; + } + } + } + } +} + +impl<'i> Visitor<'i> for AssetReferenceReplacer<'_> { + type Error = Infallible; + + fn visit_types(&self) -> lightningcss::visitor::VisitTypes { + visit_types!(URLS) + } + + fn visit_url(&mut self, u: &mut Url) -> std::result::Result<(), Self::Error> { + u.visit_children(self)?; + + if let Some(new) = self.urls.get(&*u.url) { + u.url = new.to_string().into(); + } + + Ok(()) + } +} diff --git a/turbopack/crates/turbopack-css/src/util.rs b/turbopack/crates/turbopack-css/src/util.rs new file mode 100644 index 0000000000000..30041e05218e9 --- /dev/null +++ b/turbopack/crates/turbopack-css/src/util.rs @@ -0,0 +1,53 @@ +pub fn stringify_js(str: &str) -> String { + let mut escaped = String::with_capacity(str.len()); + for char in str.chars() { + match char { + // Escape the following characters required for strings by the CSS scanner: + // https://www.w3.org/TR/CSS21/grammar.html#scanner + // https://github.com/vercel/turbo/pull/2598#discussion_r1022625909 + // + // Note that the form feed character is not representable as \f in Rust strings, so + // the unicode representation \u{0c} is used. + '\\' => escaped.push_str(r"\\"), + '\n' => escaped.push_str(r"\n"), + '\r' => escaped.push_str(r"\r"), + '"' => escaped.push_str(r#"\""#), + '\u{0c}' => escaped.push_str(r"\f"), + _ => escaped.push(char), + } + } + + format!("\"{}\"", escaped) +} + +#[cfg(test)] +mod tests { + use crate::util::stringify_js; + + #[test] + fn surrounds_with_double_quotes() { + assert_eq!(stringify_js("foo"), r#""foo""#); + } + + #[test] + fn escapes_double_quotes() { + assert_eq!(stringify_js(r#""""#), r#""\"\"""#); + } + + #[test] + fn escapes_backslash() { + assert_eq!(stringify_js(r"\"), r#""\\""#); + assert_eq!(stringify_js(r"\\"), r#""\\\\""#); + assert_eq!(stringify_js(r"\n"), r#""\\n""#); + } + + #[test] + fn escapes_newlines() { + assert_eq!(stringify_js("\n"), r#""\n""#); + } + + #[test] + fn escapes_mixed() { + assert_eq!(stringify_js("\n\r\u{0c}"), r#""\n\r\f""#); + } +} diff --git a/turbopack/crates/turbopack-dev-server/Cargo.toml b/turbopack/crates/turbopack-dev-server/Cargo.toml new file mode 100644 index 0000000000000..99d581864d192 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "turbopack-dev-server" +version = "0.1.0" +description = "TBD" +license = "MPL-2.0" +edition = "2021" +autobenches = false + +[lib] +bench = false + +[features] +log_request_stats = [] + +[lints] +workspace = true + +[dependencies] +anyhow = { workspace = true } +async-compression = { workspace = true } +auto-hash-map = { workspace = true } +futures = { workspace = true } +hyper = { version = "0.14", features = ["full"] } +hyper-tungstenite = "0.9.0" +indexmap = { workspace = true, features = ["serde"] } +mime = { workspace = true } +mime_guess = "2.0.4" +parking_lot = { workspace = true } +pin-project-lite = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +serde_qs = { workspace = true } +socket2 = "0.4.9" +tokio = { workspace = true } +tokio-stream = "0.1.9" +tokio-util = { workspace = true } +tracing = { workspace = true } +urlencoding = "2.1.2" + +turbo-tasks = { workspace = true } +turbo-tasks-bytes = { workspace = true } +turbo-tasks-fs = { workspace = true } +turbo-tasks-hash = { workspace = true } +turbopack-core = { workspace = true } +turbopack-ecmascript = { workspace = true } +turbopack-ecmascript-hmr-protocol = { workspace = true } +# TODO remove this dependency +turbopack-cli-utils = { workspace = true } + +[build-dependencies] +turbo-tasks-build = { workspace = true } diff --git a/turbopack/crates/turbopack-dev-server/build.rs b/turbopack/crates/turbopack-dev-server/build.rs new file mode 100644 index 0000000000000..1673efed59cce --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/build.rs @@ -0,0 +1,5 @@ +use turbo_tasks_build::generate_register; + +fn main() { + generate_register(); +} diff --git a/turbopack/crates/turbopack-dev-server/src/html.rs b/turbopack/crates/turbopack-dev-server/src/html.rs new file mode 100644 index 0000000000000..fdd2d2f3188d4 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/html.rs @@ -0,0 +1,260 @@ +use anyhow::{anyhow, Result}; +use mime_guess::mime::TEXT_HTML_UTF_8; +use turbo_tasks::{RcStr, ReadRef, TryJoinIterExt, Value, Vc}; +use turbo_tasks_fs::{File, FileSystemPath}; +use turbo_tasks_hash::{encode_hex, Xxh3Hash64Hasher}; +use turbopack_core::{ + asset::{Asset, AssetContent}, + chunk::{ + availability_info::AvailabilityInfo, ChunkableModule, ChunkingContext, ChunkingContextExt, + EvaluatableAssets, + }, + ident::AssetIdent, + module::Module, + output::{OutputAsset, OutputAssets}, + version::{Version, VersionedContent}, +}; + +// TODO(WEB-945) This should become a struct once we have a +// `turbo_tasks::input` attribute macro/`Input` derive macro. +type DevHtmlEntry = ( + Vc>, + Vc>, + Option>, +); + +/// The HTML entry point of the dev server. +/// +/// Generates an HTML page that includes the ES and CSS chunks. +#[turbo_tasks::value(shared)] +#[derive(Clone)] +pub struct DevHtmlAsset { + path: Vc, + entries: Vec, + body: Option, +} + +#[turbo_tasks::function] +fn dev_html_chunk_reference_description() -> Vc { + Vc::cell("dev html chunk".into()) +} + +#[turbo_tasks::value_impl] +impl OutputAsset for DevHtmlAsset { + #[turbo_tasks::function] + fn ident(&self) -> Vc { + AssetIdent::from_path(self.path) + } + + #[turbo_tasks::function] + fn references(self: Vc) -> Vc { + self.chunks() + } +} + +#[turbo_tasks::value_impl] +impl Asset for DevHtmlAsset { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + self.html_content().content() + } + + #[turbo_tasks::function] + fn versioned_content(self: Vc) -> Vc> { + Vc::upcast(self.html_content()) + } +} + +impl DevHtmlAsset { + /// Create a new dev HTML asset. + pub fn new(path: Vc, entries: Vec) -> Vc { + DevHtmlAsset { + path, + entries, + body: None, + } + .cell() + } + + /// Create a new dev HTML asset. + pub fn new_with_body( + path: Vc, + entries: Vec, + body: RcStr, + ) -> Vc { + DevHtmlAsset { + path, + entries, + body: Some(body), + } + .cell() + } +} + +#[turbo_tasks::value_impl] +impl DevHtmlAsset { + #[turbo_tasks::function] + pub async fn with_path(self: Vc, path: Vc) -> Result> { + let mut html: DevHtmlAsset = self.await?.clone_value(); + html.path = path; + Ok(html.cell()) + } + + #[turbo_tasks::function] + pub async fn with_body(self: Vc, body: RcStr) -> Result> { + let mut html: DevHtmlAsset = self.await?.clone_value(); + html.body = Some(body); + Ok(html.cell()) + } +} + +#[turbo_tasks::value_impl] +impl DevHtmlAsset { + #[turbo_tasks::function] + async fn html_content(self: Vc) -> Result> { + let this = self.await?; + let context_path = this.path.parent().await?; + let mut chunk_paths = vec![]; + for chunk in &*self.chunks().await? { + let chunk_path = &*chunk.ident().path().await?; + if let Some(relative_path) = context_path.get_path_to(chunk_path) { + chunk_paths.push(format!("/{relative_path}").into()); + } + } + + Ok(DevHtmlAssetContent::new(chunk_paths, this.body.clone())) + } + + #[turbo_tasks::function] + async fn chunks(self: Vc) -> Result> { + let this = self.await?; + + let all_assets = this + .entries + .iter() + .map(|entry| async move { + let &(chunkable_module, chunking_context, runtime_entries) = entry; + + let assets = if let Some(runtime_entries) = runtime_entries { + let runtime_entries = if let Some(evaluatable) = + Vc::try_resolve_downcast(chunkable_module).await? + { + runtime_entries.with_entry(evaluatable) + } else { + runtime_entries + }; + chunking_context.evaluated_chunk_group_assets( + chunkable_module.ident(), + runtime_entries, + Value::new(AvailabilityInfo::Root), + ) + } else { + chunking_context.root_chunk_group_assets(Vc::upcast(chunkable_module)) + }; + + assets.await + }) + .try_join() + .await? + .iter() + .flatten() + .copied() + .collect(); + + Ok(Vc::cell(all_assets)) + } +} + +#[turbo_tasks::value] +struct DevHtmlAssetContent { + chunk_paths: Vec, + body: Option, +} + +impl DevHtmlAssetContent { + fn new(chunk_paths: Vec, body: Option) -> Vc { + DevHtmlAssetContent { chunk_paths, body }.cell() + } +} + +#[turbo_tasks::value_impl] +impl DevHtmlAssetContent { + #[turbo_tasks::function] + async fn content(self: Vc) -> Result> { + let this = self.await?; + + let mut scripts = Vec::new(); + let mut stylesheets = Vec::new(); + + for relative_path in &*this.chunk_paths { + if relative_path.ends_with(".js") { + scripts.push(format!("", relative_path)); + } else if relative_path.ends_with(".css") { + stylesheets.push(format!( + "", + relative_path + )); + } else { + return Err(anyhow!("chunk with unknown asset type: {}", relative_path)); + } + } + + let body = match &this.body { + Some(body) => body.as_str(), + None => "", + }; + + let html: RcStr = format!( + "\n\n\n{}\n\n\n{}\n{}\n\n", + stylesheets.join("\n"), + body, + scripts.join("\n"), + ) + .into(); + + Ok(AssetContent::file( + File::from(html).with_content_type(TEXT_HTML_UTF_8).into(), + )) + } + + #[turbo_tasks::function] + async fn version(self: Vc) -> Result> { + let this = self.await?; + Ok(DevHtmlAssetVersion { content: this }.cell()) + } +} + +#[turbo_tasks::value_impl] +impl VersionedContent for DevHtmlAssetContent { + #[turbo_tasks::function] + fn content(self: Vc) -> Vc { + self.content() + } + + #[turbo_tasks::function] + fn version(self: Vc) -> Vc> { + Vc::upcast(self.version()) + } +} + +#[turbo_tasks::value] +struct DevHtmlAssetVersion { + content: ReadRef, +} + +#[turbo_tasks::value_impl] +impl Version for DevHtmlAssetVersion { + #[turbo_tasks::function] + async fn id(&self) -> Result> { + let mut hasher = Xxh3Hash64Hasher::new(); + for relative_path in &*self.content.chunk_paths { + hasher.write_ref(relative_path); + } + if let Some(body) = &self.content.body { + hasher.write_ref(body); + } + let hash = hasher.finish(); + let hex_hash = encode_hex(hash); + Ok(Vc::cell(hex_hash.into())) + } +} diff --git a/turbopack/crates/turbopack-dev-server/src/http.rs b/turbopack/crates/turbopack-dev-server/src/http.rs new file mode 100644 index 0000000000000..ad8d50e0b0472 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/http.rs @@ -0,0 +1,245 @@ +use std::io::{Error, ErrorKind}; + +use anyhow::{anyhow, Result}; +use auto_hash_map::AutoSet; +use futures::{StreamExt, TryStreamExt}; +use hyper::{ + header::{HeaderName, CONTENT_ENCODING, CONTENT_LENGTH}, + http::HeaderValue, + Request, Response, +}; +use mime::Mime; +use tokio_util::io::{ReaderStream, StreamReader}; +use turbo_tasks::{util::SharedError, CollectiblesSource, ReadRef, TransientInstance, Vc}; +use turbo_tasks_bytes::Bytes; +use turbo_tasks_fs::FileContent; +use turbopack_core::{ + asset::AssetContent, + issue::{handle_issues, IssueReporter, IssueSeverity}, + version::VersionedContent, +}; + +use crate::source::{ + request::SourceRequest, + resolve::{resolve_source_request, ResolveSourceRequestResult}, + Body, ContentSource, ContentSourceSideEffect, HeaderList, ProxyResult, +}; + +#[turbo_tasks::value(serialization = "none")] +enum GetFromSourceResult { + Static { + content: ReadRef, + status_code: u16, + headers: ReadRef, + header_overwrites: ReadRef, + }, + HttpProxy(ReadRef), + NotFound, +} + +/// Resolves a [SourceRequest] within a [super::ContentSource], returning the +/// corresponding content as a +#[turbo_tasks::function] +async fn get_from_source( + source: Vc>, + request: TransientInstance, +) -> Result> { + Ok(match &*resolve_source_request(source, request).await? { + ResolveSourceRequestResult::Static(static_content_vc, header_overwrites) => { + let static_content = static_content_vc.await?; + if let AssetContent::File(file) = &*static_content.content.content().await? { + GetFromSourceResult::Static { + content: file.await?, + status_code: static_content.status_code, + headers: static_content.headers.await?, + header_overwrites: header_overwrites.await?, + } + } else { + GetFromSourceResult::NotFound + } + } + ResolveSourceRequestResult::HttpProxy(proxy) => { + GetFromSourceResult::HttpProxy(proxy.await?) + } + ResolveSourceRequestResult::NotFound => GetFromSourceResult::NotFound, + } + .cell()) +} + +/// Processes an HTTP request within a given content source and returns the +/// response. +pub async fn process_request_with_content_source( + source: Vc>, + request: Request, + issue_reporter: Vc>, +) -> Result<( + Response, + AutoSet>>, +)> { + let original_path = request.uri().path().to_string(); + let request = http_request_to_source_request(request).await?; + let result = get_from_source(source, TransientInstance::new(request)); + let resolved_result = result.resolve_strongly_consistent().await?; + let side_effects: AutoSet>> = result.peek_collectibles(); + handle_issues( + result, + issue_reporter, + IssueSeverity::Fatal.cell(), + Some(&original_path), + Some("get_from_source"), + ) + .await?; + match &*resolved_result.await? { + GetFromSourceResult::Static { + content, + status_code, + headers, + header_overwrites, + } => { + if let FileContent::Content(file) = &**content { + let mut response = Response::builder().status(*status_code); + + let header_map = response.headers_mut().expect("headers must be defined"); + + for (header_name, header_value) in headers { + header_map.append( + HeaderName::try_from(header_name.as_str())?, + hyper::header::HeaderValue::try_from(header_value.as_str())?, + ); + } + + for (header_name, header_value) in header_overwrites.iter() { + header_map.insert( + HeaderName::try_from(header_name.as_str())?, + hyper::header::HeaderValue::try_from(header_value.as_str())?, + ); + } + + // naively checking if content is `compressible`. + let mut should_compress = false; + let should_compress_predicate = |mime: &Mime| { + matches!( + (mime.type_(), mime.subtype(), mime.suffix()), + (_, mime::PLAIN, _) + | (_, mime::JSON, _) + | (mime::TEXT, _, _) + | (mime::APPLICATION, mime::XML, _) + | (mime::APPLICATION, mime::JAVASCRIPT, _) + | (_, _, Some(mime::XML)) + | (_, _, Some(mime::JSON)) + | (_, _, Some(mime::TEXT)) + ) + }; + + if let Some(content_type) = file.content_type() { + header_map.append( + "content-type", + hyper::header::HeaderValue::try_from(content_type.to_string())?, + ); + + should_compress = should_compress_predicate(content_type); + } else if let hyper::header::Entry::Vacant(entry) = header_map.entry("content-type") + { + let guess = mime_guess::from_path(&original_path).first_or_octet_stream(); + should_compress = should_compress_predicate(&guess); + // If a text type, application/javascript, or application/json was + // guessed, use a utf-8 charset as we most likely generated it as + // such. + entry.insert(hyper::header::HeaderValue::try_from( + if (guess.type_() == mime::TEXT + || guess.subtype() == mime::JAVASCRIPT + || guess.subtype() == mime::JSON) + && guess.get_param("charset").is_none() + { + guess.to_string() + "; charset=utf-8" + } else { + guess.to_string() + }, + )?); + } + + if !header_map.contains_key("cache-control") { + // The dev server contents might change at any time, we can't cache them. + header_map.append( + "cache-control", + hyper::header::HeaderValue::try_from("must-revalidate")?, + ); + } + + let content = file.content(); + let response = if should_compress { + header_map.insert(CONTENT_ENCODING, HeaderValue::from_static("gzip")); + + // Grab ropereader stream, coerce anyhow::Error to std::io::Error + let stream_ext = content + .read() + .into_stream() + .map_err(|err| Error::new(ErrorKind::Other, err)); + + let gzipped_stream = + ReaderStream::new(async_compression::tokio::bufread::GzipEncoder::new( + StreamReader::new(stream_ext), + )); + + response.body(hyper::Body::wrap_stream(gzipped_stream))? + } else { + header_map.insert( + CONTENT_LENGTH, + hyper::header::HeaderValue::try_from(content.len().to_string())?, + ); + + response.body(hyper::Body::wrap_stream(content.read()))? + }; + + return Ok((response, side_effects)); + } + } + GetFromSourceResult::HttpProxy(proxy_result) => { + let mut response = Response::builder().status(proxy_result.status); + let headers = response.headers_mut().expect("headers must be defined"); + + for (name, value) in &proxy_result.headers { + headers.append( + HeaderName::from_bytes(name.as_bytes())?, + hyper::header::HeaderValue::from_str(value)?, + ); + } + + return Ok(( + response.body(hyper::Body::wrap_stream(proxy_result.body.read()))?, + side_effects, + )); + } + GetFromSourceResult::NotFound => {} + } + + Ok(( + Response::builder().status(404).body(hyper::Body::empty())?, + side_effects, + )) +} + +async fn http_request_to_source_request(request: Request) -> Result { + let (parts, body) = request.into_parts(); + + // For simplicity, we fully consume the body now and early return if there were + // any errors. + let bytes: Vec<_> = body + .map(|bytes| { + bytes.map_or_else( + |e| Err(SharedError::new(anyhow!(e))), + // The outer Ok is consumed by try_collect, but the Body type requires a Result, so + // we need to double wrap. + |b| Ok(Ok(Bytes::from(b))), + ) + }) + .try_collect::>() + .await?; + + Ok(SourceRequest { + method: parts.method.to_string(), + uri: parts.uri, + headers: parts.headers, + body: Body::new(bytes), + }) +} diff --git a/turbopack/crates/turbopack-dev-server/src/introspect/mod.rs b/turbopack/crates/turbopack-dev-server/src/introspect/mod.rs new file mode 100644 index 0000000000000..49ed924a4b454 --- /dev/null +++ b/turbopack/crates/turbopack-dev-server/src/introspect/mod.rs @@ -0,0 +1,181 @@ +use std::{borrow::Cow, collections::HashSet, fmt::Display}; + +use anyhow::Result; +use turbo_tasks::{RcStr, ReadRef, TryJoinIterExt, Vc}; +use turbo_tasks_fs::{json::parse_json_with_source_context, File}; +use turbopack_core::{ + asset::AssetContent, + introspect::{Introspectable, IntrospectableChildren}, + version::VersionedContentExt, +}; +use turbopack_ecmascript::utils::FormatIter; + +use crate::source::{ + route_tree::{RouteTree, RouteTrees, RouteType}, + ContentSource, ContentSourceContent, ContentSourceData, GetContentSourceContent, +}; + +#[turbo_tasks::value(shared)] +pub struct IntrospectionSource { + pub roots: HashSet>>, +} + +#[turbo_tasks::value_impl] +impl Introspectable for IntrospectionSource { + #[turbo_tasks::function] + fn ty(&self) -> Vc { + Vc::cell("introspection-source".into()) + } + + #[turbo_tasks::function] + fn title(&self) -> Vc { + Vc::cell("introspection-source".into()) + } + + #[turbo_tasks::function] + fn children(&self) -> Vc { + let name = Vc::cell("root".into()); + Vc::cell(self.roots.iter().map(|root| (name, *root)).collect()) + } +} + +struct HtmlEscaped(T); + +impl Display for HtmlEscaped { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str( + &self + .0 + .to_string() + // TODO this is pretty inefficient + .replace('&', "&") + .replace('>', ">") + .replace('<', "<"), + ) + } +} + +struct HtmlStringEscaped(T); + +impl Display for HtmlStringEscaped { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str( + &self + .0 + .to_string() + // TODO this is pretty inefficient + .replace('&', "&") + .replace('"', """) + .replace('>', ">") + .replace('<', "<"), + ) + } +} + +#[turbo_tasks::value_impl] +impl ContentSource for IntrospectionSource { + #[turbo_tasks::function] + fn get_routes(self: Vc) -> Vc { + Vc::::cell(vec![ + RouteTree::new_route(Vec::new(), RouteType::Exact, Vc::upcast(self)), + RouteTree::new_route(Vec::new(), RouteType::CatchAll, Vc::upcast(self)), + ]) + .merge() + } +} + +#[turbo_tasks::value_impl] +impl GetContentSourceContent for IntrospectionSource { + #[turbo_tasks::function] + async fn get( + self: Vc, + path: RcStr, + _data: turbo_tasks::Value, + ) -> Result> { + // get last segment + let path = &path[path.rfind('/').unwrap_or(0) + 1..]; + let introspectable = if path.is_empty() { + let roots = &self.await?.roots; + if roots.len() == 1 { + *roots.iter().next().unwrap() + } else { + Vc::upcast(self) + } + } else { + parse_json_with_source_context(path)? + }; + let internal_ty = Vc::debug_identifier(introspectable).await?; + fn str_or_err(s: &Result>) -> Cow<'_, str> { + s.as_ref().map_or_else( + |e| Cow::<'_, str>::Owned(format!("ERROR: {:?}", e)), + |d| Cow::Borrowed(&**d), + ) + } + let ty = introspectable.ty().await; + let ty = str_or_err(&ty); + let title = introspectable.title().await; + let title = str_or_err(&title); + let details = introspectable.details().await; + let details = str_or_err(&details); + let children = introspectable.children().await?; + let has_children = !children.is_empty(); + let children = children + .iter() + .map(|&(name, child)| async move { + let name = name.await; + let name = str_or_err(&name); + let ty = child.ty().await; + let ty = str_or_err(&ty); + let title = child.title().await; + let title = str_or_err(&title); + let path = serde_json::to_string(&child)?; + Ok(format!( + "